diff options
Diffstat (limited to 'arch/arm/mach-shmobile/clock-sh7372.c')
-rw-r--r-- | arch/arm/mach-shmobile/clock-sh7372.c | 94 |
1 files changed, 12 insertions, 82 deletions
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index 430a90ffa120..4d57e342537b 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c @@ -420,87 +420,11 @@ static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = { }; /* FSI DIV */ -static unsigned long fsidiv_recalc(struct clk *clk) -{ - unsigned long value; - - value = __raw_readl(clk->mapping->base); - - value >>= 16; - if (value < 2) - return 0; - - return clk->parent->rate / value; -} - -static long fsidiv_round_rate(struct clk *clk, unsigned long rate) -{ - return clk_rate_div_range_round(clk, 2, 0xffff, rate); -} - -static void fsidiv_disable(struct clk *clk) -{ - __raw_writel(0, clk->mapping->base); -} - -static int fsidiv_enable(struct clk *clk) -{ - unsigned long value; - - value = __raw_readl(clk->mapping->base) >> 16; - if (value < 2) - return -EIO; - - __raw_writel((value << 16) | 0x3, clk->mapping->base); - - return 0; -} +enum { FSIDIV_A, FSIDIV_B, FSIDIV_REPARENT_NR }; -static int fsidiv_set_rate(struct clk *clk, unsigned long rate) -{ - int idx; - - idx = (clk->parent->rate / rate) & 0xffff; - if (idx < 2) - return -EINVAL; - - __raw_writel(idx << 16, clk->mapping->base); - return 0; -} - -static struct sh_clk_ops fsidiv_clk_ops = { - .recalc = fsidiv_recalc, - .round_rate = fsidiv_round_rate, - .set_rate = fsidiv_set_rate, - .enable = fsidiv_enable, - .disable = fsidiv_disable, -}; - -static struct clk_mapping fsidiva_clk_mapping = { - .phys = FSIDIVA, - .len = 8, -}; - -struct clk sh7372_fsidiva_clk = { - .ops = &fsidiv_clk_ops, - .parent = &div6_reparent_clks[DIV6_FSIA], /* late install */ - .mapping = &fsidiva_clk_mapping, -}; - -static struct clk_mapping fsidivb_clk_mapping = { - .phys = FSIDIVB, - .len = 8, -}; - -struct clk sh7372_fsidivb_clk = { - .ops = &fsidiv_clk_ops, - .parent = &div6_reparent_clks[DIV6_FSIB], /* late install */ - .mapping = &fsidivb_clk_mapping, -}; - -static struct clk *late_main_clks[] = { - &sh7372_fsidiva_clk, - &sh7372_fsidivb_clk, +static struct clk fsidivs[] = { + [FSIDIV_A] = SH_CLK_FSIDIV(FSIDIVA, &div6_reparent_clks[DIV6_FSIA]), + [FSIDIV_B] = SH_CLK_FSIDIV(FSIDIVB, &div6_reparent_clks[DIV6_FSIB]), }; enum { MSTP001, MSTP000, @@ -583,6 +507,8 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("pllc1_clk", &pllc1_clk), CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk), CLKDEV_CON_ID("pllc2_clk", &sh7372_pllc2_clk), + CLKDEV_CON_ID("fsidiva", &fsidivs[FSIDIV_A]), + CLKDEV_CON_ID("fsidivb", &fsidivs[FSIDIV_B]), /* DIV4 clocks */ CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), @@ -678,6 +604,10 @@ static struct clk_lookup lookups[] = { CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]), CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]), CLKDEV_ICK_ID("spu2", "sh_fsi2", &mstp_clks[MSTP223]), + CLKDEV_ICK_ID("diva", "sh_fsi2", &fsidivs[FSIDIV_A]), + CLKDEV_ICK_ID("divb", "sh_fsi2", &fsidivs[FSIDIV_B]), + CLKDEV_ICK_ID("xcka", "sh_fsi2", &sh7372_fsiack_clk), + CLKDEV_ICK_ID("xckb", "sh_fsi2", &sh7372_fsibck_clk), }; void __init sh7372_clock_init(void) @@ -706,8 +636,8 @@ void __init sh7372_clock_init(void) if (!ret) ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); - for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++) - ret = clk_register(late_main_clks[k]); + if (!ret) + ret = sh_clk_fsidiv_register(fsidivs, FSIDIV_REPARENT_NR); clkdev_add_table(lookups, ARRAY_SIZE(lookups)); |