diff options
author | Huang Shijie <shijie8@gmail.com> | 2012-07-02 21:39:32 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2012-09-29 14:50:02 +0100 |
commit | ff506172a30080963853dc0d259566c82fe8626c (patch) | |
tree | 2959ffd3912316c17e19a645310e86bf36859600 /drivers/mtd/nand/gpmi-nand/gpmi-lib.c | |
parent | 894824f9731a805b70b553220ae58e5475ff6ff1 (diff) |
mtd: gpmi: change the code for clocks
The gpmi nand driver may needs several clocks(MX6Q needs five clocks).
In the old clock framework, all these clocks are chained together,
all you need is to manipulate the first clock.
But the kernel uses the common clk framework now, which forces us to
get the clocks one by one. When we use them, we have to enable them
one by one too.
Signed-off-by: Huang Shijie <shijie8@gmail.com>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/nand/gpmi-nand/gpmi-lib.c')
-rw-r--r-- | drivers/mtd/nand/gpmi-nand/gpmi-lib.c | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c index a1f43329ad4..6bb0998dcb4 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c @@ -124,12 +124,42 @@ error: return -ETIMEDOUT; } +static int __gpmi_enable_clk(struct gpmi_nand_data *this, bool v) +{ + struct clk *clk; + int ret; + int i; + + for (i = 0; i < GPMI_CLK_MAX; i++) { + clk = this->resources.clock[i]; + if (!clk) + break; + + if (v) { + ret = clk_prepare_enable(clk); + if (ret) + goto err_clk; + } else { + clk_disable_unprepare(clk); + } + } + return 0; + +err_clk: + for (; i > 0; i--) + clk_disable_unprepare(this->resources.clock[i - 1]); + return ret; +} + +#define gpmi_enable_clk(x) __gpmi_enable_clk(x, true) +#define gpmi_disable_clk(x) __gpmi_enable_clk(x, false) + int gpmi_init(struct gpmi_nand_data *this) { struct resources *r = &this->resources; int ret; - ret = clk_prepare_enable(r->clock); + ret = gpmi_enable_clk(this); if (ret) goto err_out; ret = gpmi_reset_block(r->gpmi_regs, false); @@ -149,7 +179,7 @@ int gpmi_init(struct gpmi_nand_data *this) /* Select BCH ECC. */ writel(BM_GPMI_CTRL1_BCH_MODE, r->gpmi_regs + HW_GPMI_CTRL1_SET); - clk_disable_unprepare(r->clock); + gpmi_disable_clk(this); return 0; err_out: return ret; @@ -205,7 +235,7 @@ int bch_set_geometry(struct gpmi_nand_data *this) ecc_strength = bch_geo->ecc_strength >> 1; page_size = bch_geo->page_size; - ret = clk_prepare_enable(r->clock); + ret = gpmi_enable_clk(this); if (ret) goto err_out; @@ -240,7 +270,7 @@ int bch_set_geometry(struct gpmi_nand_data *this) writel(BM_BCH_CTRL_COMPLETE_IRQ_EN, r->bch_regs + HW_BCH_CTRL_SET); - clk_disable_unprepare(r->clock); + gpmi_disable_clk(this); return 0; err_out: return ret; @@ -716,7 +746,7 @@ void gpmi_begin(struct gpmi_nand_data *this) int ret; /* Enable the clock. */ - ret = clk_prepare_enable(r->clock); + ret = gpmi_enable_clk(this); if (ret) { pr_err("We failed in enable the clk\n"); goto err_out; @@ -727,7 +757,7 @@ void gpmi_begin(struct gpmi_nand_data *this) gpmi_regs + HW_GPMI_TIMING1); /* Get the timing information we need. */ - nfc->clock_frequency_in_hz = clk_get_rate(r->clock); + nfc->clock_frequency_in_hz = clk_get_rate(r->clock[0]); clock_period_in_ns = 1000000000 / nfc->clock_frequency_in_hz; gpmi_nfc_compute_hardware_timing(this, &hw); @@ -784,8 +814,7 @@ err_out: void gpmi_end(struct gpmi_nand_data *this) { - struct resources *r = &this->resources; - clk_disable_unprepare(r->clock); + gpmi_disable_clk(this); } /* Clears a BCH interrupt. */ |