Message ID | 1409132889-2080-2-git-send-email-ch.naveen@samsung.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hello All, On 27 August 2014 15:18, Naveen Krishna Chatradhi <ch.naveen@samsung.com> wrote: > This patch factors out the code that can be reused from > clk-exynos5260.c to clk-samsung/clk.c and clk-samsung/clk.h > > As Clock controller in Exynos7 support various blocks in > CMU. The common functions and structures can be reused to > support Clock controller in Exynos7. > > Signed-off-by: Naveen Krishna Chatradhi <ch.naveen@samsung.com> > Cc: Tomasz Figa <t.figa@samsung.com> > Cc: Mike Turquette <mturquette@linaro.org> > Cc: Thomas Abraham <thomas.ab@samsung.com> Not tested on Exynos5260.. Tested-by would be appreciated. > --- > drivers/clk/samsung/clk-exynos5260.c | 181 +++++----------------------------- > drivers/clk/samsung/clk.c | 101 +++++++++++++++++++ > drivers/clk/samsung/clk.h | 34 +++++++ > 3 files changed, 161 insertions(+), 155 deletions(-) > > diff --git a/drivers/clk/samsung/clk-exynos5260.c b/drivers/clk/samsung/clk-exynos5260.c > index ce3de97..7655d4e 100644 > --- a/drivers/clk/samsung/clk-exynos5260.c > +++ b/drivers/clk/samsung/clk-exynos5260.c > @@ -22,39 +22,6 @@ > > #include <dt-bindings/clock/exynos5260-clk.h> > > -static LIST_HEAD(clock_reg_cache_list); > - > -struct exynos5260_clock_reg_cache { > - struct list_head node; > - void __iomem *reg_base; > - struct samsung_clk_reg_dump *rdump; > - unsigned int rd_num; > -}; > - > -struct exynos5260_cmu_info { > - /* list of pll clocks and respective count */ > - struct samsung_pll_clock *pll_clks; > - unsigned int nr_pll_clks; > - /* list of mux clocks and respective count */ > - struct samsung_mux_clock *mux_clks; > - unsigned int nr_mux_clks; > - /* list of div clocks and respective count */ > - struct samsung_div_clock *div_clks; > - unsigned int nr_div_clks; > - /* list of gate clocks and respective count */ > - struct samsung_gate_clock *gate_clks; > - unsigned int nr_gate_clks; > - /* list of fixed clocks and respective count */ > - struct samsung_fixed_rate_clock *fixed_clks; > - unsigned int nr_fixed_clks; > - /* total number of clocks with IDs assigned*/ > - unsigned int nr_clk_ids; > - > - /* list and number of clocks registers */ > - unsigned long *clk_regs; > - unsigned int nr_clk_regs; > -}; > - > /* > * Applicable for all 2550 Type PLLS for Exynos5260, listed below > * DISP_PLL, EGL_PLL, KFC_PLL, MEM_PLL, BUS_PLL, MEDIA_PLL, G3D_PLL. > @@ -115,102 +82,6 @@ static struct samsung_pll_rate_table pll2650_24mhz_tbl[] __initdata = { > > #ifdef CONFIG_PM_SLEEP > > -static int exynos5260_clk_suspend(void) > -{ > - struct exynos5260_clock_reg_cache *cache; > - > - list_for_each_entry(cache, &clock_reg_cache_list, node) > - samsung_clk_save(cache->reg_base, cache->rdump, > - cache->rd_num); > - > - return 0; > -} > - > -static void exynos5260_clk_resume(void) > -{ > - struct exynos5260_clock_reg_cache *cache; > - > - list_for_each_entry(cache, &clock_reg_cache_list, node) > - samsung_clk_restore(cache->reg_base, cache->rdump, > - cache->rd_num); > -} > - > -static struct syscore_ops exynos5260_clk_syscore_ops = { > - .suspend = exynos5260_clk_suspend, > - .resume = exynos5260_clk_resume, > -}; > - > -static void exynos5260_clk_sleep_init(void __iomem *reg_base, > - unsigned long *rdump, > - unsigned long nr_rdump) > -{ > - struct exynos5260_clock_reg_cache *reg_cache; > - > - reg_cache = kzalloc(sizeof(struct exynos5260_clock_reg_cache), > - GFP_KERNEL); > - if (!reg_cache) > - panic("could not allocate register cache.\n"); > - > - reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump); > - > - if (!reg_cache->rdump) > - panic("could not allocate register dump storage.\n"); > - > - if (list_empty(&clock_reg_cache_list)) > - register_syscore_ops(&exynos5260_clk_syscore_ops); > - > - reg_cache->rd_num = nr_rdump; > - reg_cache->reg_base = reg_base; > - list_add_tail(®_cache->node, &clock_reg_cache_list); > -} > - > -#else > -static void exynos5260_clk_sleep_init(void __iomem *reg_base, > - unsigned long *rdump, > - unsigned long nr_rdump){} > -#endif > - > -/* > - * Common function which registers plls, muxes, dividers and gates > - * for each CMU. It also add CMU register list to register cache. > - */ > - > -void __init exynos5260_cmu_register_one(struct device_node *np, > - struct exynos5260_cmu_info *cmu) > -{ > - void __iomem *reg_base; > - struct samsung_clk_provider *ctx; > - > - reg_base = of_iomap(np, 0); > - if (!reg_base) > - panic("%s: failed to map registers\n", __func__); > - > - ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids); > - if (!ctx) > - panic("%s: unable to alllocate ctx\n", __func__); > - > - if (cmu->pll_clks) > - samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks, > - reg_base); > - if (cmu->mux_clks) > - samsung_clk_register_mux(ctx, cmu->mux_clks, > - cmu->nr_mux_clks); > - if (cmu->div_clks) > - samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks); > - if (cmu->gate_clks) > - samsung_clk_register_gate(ctx, cmu->gate_clks, > - cmu->nr_gate_clks); > - if (cmu->fixed_clks) > - samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks, > - cmu->nr_fixed_clks); > - if (cmu->clk_regs) > - exynos5260_clk_sleep_init(reg_base, cmu->clk_regs, > - cmu->nr_clk_regs); > - > - samsung_clk_of_add_provider(np, ctx); > -} > - > - > /* CMU_AUD */ > > static unsigned long aud_clk_regs[] __initdata = { > @@ -268,7 +139,7 @@ struct samsung_gate_clock aud_gate_clks[] __initdata = { > > static void __init exynos5260_clk_aud_init(struct device_node *np) > { > - struct exynos5260_cmu_info cmu = {0}; > + struct exynos_cmu_info cmu = {0}; > > cmu.mux_clks = aud_mux_clks; > cmu.nr_mux_clks = ARRAY_SIZE(aud_mux_clks); > @@ -280,7 +151,7 @@ static void __init exynos5260_clk_aud_init(struct device_node *np) > cmu.clk_regs = aud_clk_regs; > cmu.nr_clk_regs = ARRAY_SIZE(aud_clk_regs); > > - exynos5260_cmu_register_one(np, &cmu); > + exynos_cmu_register_one(np, &cmu); > } > > CLK_OF_DECLARE(exynos5260_clk_aud, "samsung,exynos5260-clock-aud", > @@ -458,7 +329,7 @@ struct samsung_gate_clock disp_gate_clks[] __initdata = { > > static void __init exynos5260_clk_disp_init(struct device_node *np) > { > - struct exynos5260_cmu_info cmu = {0}; > + struct exynos_cmu_info cmu = {0}; > > cmu.mux_clks = disp_mux_clks; > cmu.nr_mux_clks = ARRAY_SIZE(disp_mux_clks); > @@ -470,7 +341,7 @@ static void __init exynos5260_clk_disp_init(struct device_node *np) > cmu.clk_regs = disp_clk_regs; > cmu.nr_clk_regs = ARRAY_SIZE(disp_clk_regs); > > - exynos5260_cmu_register_one(np, &cmu); > + exynos_cmu_register_one(np, &cmu); > } > > CLK_OF_DECLARE(exynos5260_clk_disp, "samsung,exynos5260-clock-disp", > @@ -522,7 +393,7 @@ static struct samsung_pll_clock egl_pll_clks[] __initdata = { > > static void __init exynos5260_clk_egl_init(struct device_node *np) > { > - struct exynos5260_cmu_info cmu = {0}; > + struct exynos_cmu_info cmu = {0}; > > cmu.pll_clks = egl_pll_clks; > cmu.nr_pll_clks = ARRAY_SIZE(egl_pll_clks); > @@ -534,7 +405,7 @@ static void __init exynos5260_clk_egl_init(struct device_node *np) > cmu.clk_regs = egl_clk_regs; > cmu.nr_clk_regs = ARRAY_SIZE(egl_clk_regs); > > - exynos5260_cmu_register_one(np, &cmu); > + exynos_cmu_register_one(np, &cmu); > } > > CLK_OF_DECLARE(exynos5260_clk_egl, "samsung,exynos5260-clock-egl", > @@ -624,7 +495,7 @@ struct samsung_gate_clock fsys_gate_clks[] __initdata = { > > static void __init exynos5260_clk_fsys_init(struct device_node *np) > { > - struct exynos5260_cmu_info cmu = {0}; > + struct exynos_cmu_info cmu = {0}; > > cmu.mux_clks = fsys_mux_clks; > cmu.nr_mux_clks = ARRAY_SIZE(fsys_mux_clks); > @@ -634,7 +505,7 @@ static void __init exynos5260_clk_fsys_init(struct device_node *np) > cmu.clk_regs = fsys_clk_regs; > cmu.nr_clk_regs = ARRAY_SIZE(fsys_clk_regs); > > - exynos5260_cmu_register_one(np, &cmu); > + exynos_cmu_register_one(np, &cmu); > } > > CLK_OF_DECLARE(exynos5260_clk_fsys, "samsung,exynos5260-clock-fsys", > @@ -713,7 +584,7 @@ struct samsung_gate_clock g2d_gate_clks[] __initdata = { > > static void __init exynos5260_clk_g2d_init(struct device_node *np) > { > - struct exynos5260_cmu_info cmu = {0}; > + struct exynos_cmu_info cmu = {0}; > > cmu.mux_clks = g2d_mux_clks; > cmu.nr_mux_clks = ARRAY_SIZE(g2d_mux_clks); > @@ -725,7 +596,7 @@ static void __init exynos5260_clk_g2d_init(struct device_node *np) > cmu.clk_regs = g2d_clk_regs; > cmu.nr_clk_regs = ARRAY_SIZE(g2d_clk_regs); > > - exynos5260_cmu_register_one(np, &cmu); > + exynos_cmu_register_one(np, &cmu); > } > > CLK_OF_DECLARE(exynos5260_clk_g2d, "samsung,exynos5260-clock-g2d", > @@ -774,7 +645,7 @@ static struct samsung_pll_clock g3d_pll_clks[] __initdata = { > > static void __init exynos5260_clk_g3d_init(struct device_node *np) > { > - struct exynos5260_cmu_info cmu = {0}; > + struct exynos_cmu_info cmu = {0}; > > cmu.pll_clks = g3d_pll_clks; > cmu.nr_pll_clks = ARRAY_SIZE(g3d_pll_clks); > @@ -788,7 +659,7 @@ static void __init exynos5260_clk_g3d_init(struct device_node *np) > cmu.clk_regs = g3d_clk_regs; > cmu.nr_clk_regs = ARRAY_SIZE(g3d_clk_regs); > > - exynos5260_cmu_register_one(np, &cmu); > + exynos_cmu_register_one(np, &cmu); > } > > CLK_OF_DECLARE(exynos5260_clk_g3d, "samsung,exynos5260-clock-g3d", > @@ -909,7 +780,7 @@ struct samsung_gate_clock gscl_gate_clks[] __initdata = { > > static void __init exynos5260_clk_gscl_init(struct device_node *np) > { > - struct exynos5260_cmu_info cmu = {0}; > + struct exynos_cmu_info cmu = {0}; > > cmu.mux_clks = gscl_mux_clks; > cmu.nr_mux_clks = ARRAY_SIZE(gscl_mux_clks); > @@ -921,7 +792,7 @@ static void __init exynos5260_clk_gscl_init(struct device_node *np) > cmu.clk_regs = gscl_clk_regs; > cmu.nr_clk_regs = ARRAY_SIZE(gscl_clk_regs); > > - exynos5260_cmu_register_one(np, &cmu); > + exynos_cmu_register_one(np, &cmu); > } > > CLK_OF_DECLARE(exynos5260_clk_gscl, "samsung,exynos5260-clock-gscl", > @@ -1028,7 +899,7 @@ struct samsung_gate_clock isp_gate_clks[] __initdata = { > > static void __init exynos5260_clk_isp_init(struct device_node *np) > { > - struct exynos5260_cmu_info cmu = {0}; > + struct exynos_cmu_info cmu = {0}; > > cmu.mux_clks = isp_mux_clks; > cmu.nr_mux_clks = ARRAY_SIZE(isp_mux_clks); > @@ -1040,7 +911,7 @@ static void __init exynos5260_clk_isp_init(struct device_node *np) > cmu.clk_regs = isp_clk_regs; > cmu.nr_clk_regs = ARRAY_SIZE(isp_clk_regs); > > - exynos5260_cmu_register_one(np, &cmu); > + exynos_cmu_register_one(np, &cmu); > } > > CLK_OF_DECLARE(exynos5260_clk_isp, "samsung,exynos5260-clock-isp", > @@ -1092,7 +963,7 @@ static struct samsung_pll_clock kfc_pll_clks[] __initdata = { > > static void __init exynos5260_clk_kfc_init(struct device_node *np) > { > - struct exynos5260_cmu_info cmu = {0}; > + struct exynos_cmu_info cmu = {0}; > > cmu.pll_clks = kfc_pll_clks; > cmu.nr_pll_clks = ARRAY_SIZE(kfc_pll_clks); > @@ -1104,7 +975,7 @@ static void __init exynos5260_clk_kfc_init(struct device_node *np) > cmu.clk_regs = kfc_clk_regs; > cmu.nr_clk_regs = ARRAY_SIZE(kfc_clk_regs); > > - exynos5260_cmu_register_one(np, &cmu); > + exynos_cmu_register_one(np, &cmu); > } > > CLK_OF_DECLARE(exynos5260_clk_kfc, "samsung,exynos5260-clock-kfc", > @@ -1148,7 +1019,7 @@ struct samsung_gate_clock mfc_gate_clks[] __initdata = { > > static void __init exynos5260_clk_mfc_init(struct device_node *np) > { > - struct exynos5260_cmu_info cmu = {0}; > + struct exynos_cmu_info cmu = {0}; > > cmu.mux_clks = mfc_mux_clks; > cmu.nr_mux_clks = ARRAY_SIZE(mfc_mux_clks); > @@ -1160,7 +1031,7 @@ static void __init exynos5260_clk_mfc_init(struct device_node *np) > cmu.clk_regs = mfc_clk_regs; > cmu.nr_clk_regs = ARRAY_SIZE(mfc_clk_regs); > > - exynos5260_cmu_register_one(np, &cmu); > + exynos_cmu_register_one(np, &cmu); > } > > CLK_OF_DECLARE(exynos5260_clk_mfc, "samsung,exynos5260-clock-mfc", > @@ -1295,7 +1166,7 @@ static struct samsung_pll_clock mif_pll_clks[] __initdata = { > > static void __init exynos5260_clk_mif_init(struct device_node *np) > { > - struct exynos5260_cmu_info cmu = {0}; > + struct exynos_cmu_info cmu = {0}; > > cmu.pll_clks = mif_pll_clks; > cmu.nr_pll_clks = ARRAY_SIZE(mif_pll_clks); > @@ -1309,7 +1180,7 @@ static void __init exynos5260_clk_mif_init(struct device_node *np) > cmu.clk_regs = mif_clk_regs; > cmu.nr_clk_regs = ARRAY_SIZE(mif_clk_regs); > > - exynos5260_cmu_register_one(np, &cmu); > + exynos_cmu_register_one(np, &cmu); > } > > CLK_OF_DECLARE(exynos5260_clk_mif, "samsung,exynos5260-clock-mif", > @@ -1503,7 +1374,7 @@ struct samsung_gate_clock peri_gate_clks[] __initdata = { > > static void __init exynos5260_clk_peri_init(struct device_node *np) > { > - struct exynos5260_cmu_info cmu = {0}; > + struct exynos_cmu_info cmu = {0}; > > cmu.mux_clks = peri_mux_clks; > cmu.nr_mux_clks = ARRAY_SIZE(peri_mux_clks); > @@ -1515,7 +1386,7 @@ static void __init exynos5260_clk_peri_init(struct device_node *np) > cmu.clk_regs = peri_clk_regs; > cmu.nr_clk_regs = ARRAY_SIZE(peri_clk_regs); > > - exynos5260_cmu_register_one(np, &cmu); > + exynos_cmu_register_one(np, &cmu); > } > > CLK_OF_DECLARE(exynos5260_clk_peri, "samsung,exynos5260-clock-peri", > @@ -1959,7 +1830,7 @@ static struct samsung_pll_clock top_pll_clks[] __initdata = { > > static void __init exynos5260_clk_top_init(struct device_node *np) > { > - struct exynos5260_cmu_info cmu = {0}; > + struct exynos_cmu_info cmu = {0}; > > cmu.pll_clks = top_pll_clks; > cmu.nr_pll_clks = ARRAY_SIZE(top_pll_clks); > @@ -1975,7 +1846,7 @@ static void __init exynos5260_clk_top_init(struct device_node *np) > cmu.clk_regs = top_clk_regs; > cmu.nr_clk_regs = ARRAY_SIZE(top_clk_regs); > > - exynos5260_cmu_register_one(np, &cmu); > + exynos_cmu_register_one(np, &cmu); > } > > CLK_OF_DECLARE(exynos5260_clk_top, "samsung,exynos5260-clock-top", > diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c > index deab84d..ef73edf 100644 > --- a/drivers/clk/samsung/clk.c > +++ b/drivers/clk/samsung/clk.c > @@ -11,9 +11,14 @@ > * clock framework for Samsung platforms. > */ > > +#include <linux/clk.h> > +#include <linux/clkdev.h> > +#include <linux/clk-provider.h> > #include <linux/syscore_ops.h> > #include "clk.h" > > +static LIST_HEAD(clock_reg_cache_list); > + > void samsung_clk_save(void __iomem *base, > struct samsung_clk_reg_dump *rd, > unsigned int num_regs) > @@ -313,3 +318,99 @@ unsigned long _get_rate(const char *clk_name) > > return clk_get_rate(clk); > } > + > +#ifdef CONFIG_PM_SLEEP > +static int exynos_clk_suspend(void) > +{ > + struct exynos_clock_reg_cache *reg_cache; > + > + list_for_each_entry(reg_cache, &clock_reg_cache_list, node) > + samsung_clk_save(reg_cache->reg_base, reg_cache->rdump, > + reg_cache->rd_num); > + return 0; > +} > + > +static void exynos_clk_resume(void) > +{ > + struct exynos_clock_reg_cache *reg_cache; > + > + list_for_each_entry(reg_cache, &clock_reg_cache_list, node) > + samsung_clk_restore(reg_cache->reg_base, reg_cache->rdump, > + reg_cache->rd_num); > +} > + > +static struct syscore_ops exynos_clk_syscore_ops = { > + .suspend = exynos_clk_suspend, > + .resume = exynos_clk_resume, > +}; > + > +static void exynos_clk_sleep_init(void __iomem *reg_base, > + const unsigned long *rdump, > + unsigned long nr_rdump) > +{ > + struct exynos_clock_reg_cache *reg_cache; > + > + reg_cache = kzalloc(sizeof(struct exynos_clock_reg_cache), > + GFP_KERNEL); > + if (!reg_cache) > + panic("could not allocate register reg_cache.\n"); > + reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump); > + > + if (!reg_cache->rdump) > + panic("could not allocate register dump storage.\n"); > + > + /* since we should register syscore_ops only once > + * check for list emptyness > + */ > + if (list_empty(&clock_reg_cache_list)) > + register_syscore_ops(&exynos_clk_syscore_ops); > + > + reg_cache->reg_base = reg_base; > + reg_cache->rd_num = nr_rdump; > + list_add_tail(®_cache->node, &clock_reg_cache_list); > +} > + > +#else > +static void exynos_clk_sleep_init(void __iomem *reg_base, > + const unsigned long *rdump, > + unsigned long nr_rdump) {} > +#endif > + > +/* > + * Common function which registers plls, muxes, dividers and gates > + * for each CMU. It also add CMU register list to register cache. > + */ > +void __init exynos_cmu_register_one(struct device_node *np, > + struct exynos_cmu_info *cmu) > +{ > + void __iomem *reg_base; > + struct samsung_clk_provider *ctx; > + > + reg_base = of_iomap(np, 0); > + if (!reg_base) > + panic("%s: failed to map registers\n", __func__); > + > + ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids); > + if (!ctx) > + panic("%s: unable to alllocate ctx\n", __func__); > + > + if (cmu->pll_clks) > + samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks, > + reg_base); > + if (cmu->mux_clks) > + samsung_clk_register_mux(ctx, cmu->mux_clks, > + cmu->nr_mux_clks); > + if (cmu->div_clks) > + samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks); > + if (cmu->gate_clks) > + samsung_clk_register_gate(ctx, cmu->gate_clks, > + cmu->nr_gate_clks); > + if (cmu->fixed_clks) > + samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks, > + cmu->nr_fixed_clks); > + if (cmu->clk_regs) > + exynos_clk_sleep_init(reg_base, cmu->clk_regs, > + cmu->nr_clk_regs); > + > + samsung_clk_of_add_provider(np, ctx); > +} > diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h > index 66ab36b..552d155 100644 > --- a/drivers/clk/samsung/clk.h > +++ b/drivers/clk/samsung/clk.h > @@ -324,6 +324,37 @@ struct samsung_pll_clock { > __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \ > _lock, _con, _rtable, _alias) > > +struct exynos_clock_reg_cache { > + struct list_head node; > + void __iomem *reg_base; > + struct samsung_clk_reg_dump *rdump; > + unsigned int rd_num; > +}; > + > +struct exynos_cmu_info { > + /* list of pll clocks and respective count */ > + struct samsung_pll_clock *pll_clks; > + unsigned int nr_pll_clks; > + /* list of mux clocks and respective count */ > + struct samsung_mux_clock *mux_clks; > + unsigned int nr_mux_clks; > + /* list of div clocks and respective count */ > + struct samsung_div_clock *div_clks; > + unsigned int nr_div_clks; > + /* list of gate clocks and respective count */ > + struct samsung_gate_clock *gate_clks; > + unsigned int nr_gate_clks; > + /* list of fixed clocks and respective count */ > + struct samsung_fixed_rate_clock *fixed_clks; > + unsigned int nr_fixed_clks; > + /* total number of clocks with IDs assigned*/ > + unsigned int nr_clk_ids; > + > + /* list and number of clocks registers */ > + unsigned long *clk_regs; > + unsigned int nr_clk_regs; > +}; > + > extern struct samsung_clk_provider *__init samsung_clk_init( > struct device_node *np, void __iomem *base, > unsigned long nr_clks); > @@ -362,6 +393,9 @@ extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx, > struct samsung_pll_clock *pll_list, > unsigned int nr_clk, void __iomem *base); > > +extern void __init exynos_cmu_register_one(struct device_node *, > + struct exynos_cmu_info *); > + > extern unsigned long _get_rate(const char *clk_name); > > extern void samsung_clk_save(void __iomem *base, > -- > 1.7.9.5 >
diff --git a/drivers/clk/samsung/clk-exynos5260.c b/drivers/clk/samsung/clk-exynos5260.c index ce3de97..7655d4e 100644 --- a/drivers/clk/samsung/clk-exynos5260.c +++ b/drivers/clk/samsung/clk-exynos5260.c @@ -22,39 +22,6 @@ #include <dt-bindings/clock/exynos5260-clk.h> -static LIST_HEAD(clock_reg_cache_list); - -struct exynos5260_clock_reg_cache { - struct list_head node; - void __iomem *reg_base; - struct samsung_clk_reg_dump *rdump; - unsigned int rd_num; -}; - -struct exynos5260_cmu_info { - /* list of pll clocks and respective count */ - struct samsung_pll_clock *pll_clks; - unsigned int nr_pll_clks; - /* list of mux clocks and respective count */ - struct samsung_mux_clock *mux_clks; - unsigned int nr_mux_clks; - /* list of div clocks and respective count */ - struct samsung_div_clock *div_clks; - unsigned int nr_div_clks; - /* list of gate clocks and respective count */ - struct samsung_gate_clock *gate_clks; - unsigned int nr_gate_clks; - /* list of fixed clocks and respective count */ - struct samsung_fixed_rate_clock *fixed_clks; - unsigned int nr_fixed_clks; - /* total number of clocks with IDs assigned*/ - unsigned int nr_clk_ids; - - /* list and number of clocks registers */ - unsigned long *clk_regs; - unsigned int nr_clk_regs; -}; - /* * Applicable for all 2550 Type PLLS for Exynos5260, listed below * DISP_PLL, EGL_PLL, KFC_PLL, MEM_PLL, BUS_PLL, MEDIA_PLL, G3D_PLL. @@ -115,102 +82,6 @@ static struct samsung_pll_rate_table pll2650_24mhz_tbl[] __initdata = { #ifdef CONFIG_PM_SLEEP -static int exynos5260_clk_suspend(void) -{ - struct exynos5260_clock_reg_cache *cache; - - list_for_each_entry(cache, &clock_reg_cache_list, node) - samsung_clk_save(cache->reg_base, cache->rdump, - cache->rd_num); - - return 0; -} - -static void exynos5260_clk_resume(void) -{ - struct exynos5260_clock_reg_cache *cache; - - list_for_each_entry(cache, &clock_reg_cache_list, node) - samsung_clk_restore(cache->reg_base, cache->rdump, - cache->rd_num); -} - -static struct syscore_ops exynos5260_clk_syscore_ops = { - .suspend = exynos5260_clk_suspend, - .resume = exynos5260_clk_resume, -}; - -static void exynos5260_clk_sleep_init(void __iomem *reg_base, - unsigned long *rdump, - unsigned long nr_rdump) -{ - struct exynos5260_clock_reg_cache *reg_cache; - - reg_cache = kzalloc(sizeof(struct exynos5260_clock_reg_cache), - GFP_KERNEL); - if (!reg_cache) - panic("could not allocate register cache.\n"); - - reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump); - - if (!reg_cache->rdump) - panic("could not allocate register dump storage.\n"); - - if (list_empty(&clock_reg_cache_list)) - register_syscore_ops(&exynos5260_clk_syscore_ops); - - reg_cache->rd_num = nr_rdump; - reg_cache->reg_base = reg_base; - list_add_tail(®_cache->node, &clock_reg_cache_list); -} - -#else -static void exynos5260_clk_sleep_init(void __iomem *reg_base, - unsigned long *rdump, - unsigned long nr_rdump){} -#endif - -/* - * Common function which registers plls, muxes, dividers and gates - * for each CMU. It also add CMU register list to register cache. - */ - -void __init exynos5260_cmu_register_one(struct device_node *np, - struct exynos5260_cmu_info *cmu) -{ - void __iomem *reg_base; - struct samsung_clk_provider *ctx; - - reg_base = of_iomap(np, 0); - if (!reg_base) - panic("%s: failed to map registers\n", __func__); - - ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids); - if (!ctx) - panic("%s: unable to alllocate ctx\n", __func__); - - if (cmu->pll_clks) - samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks, - reg_base); - if (cmu->mux_clks) - samsung_clk_register_mux(ctx, cmu->mux_clks, - cmu->nr_mux_clks); - if (cmu->div_clks) - samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks); - if (cmu->gate_clks) - samsung_clk_register_gate(ctx, cmu->gate_clks, - cmu->nr_gate_clks); - if (cmu->fixed_clks) - samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks, - cmu->nr_fixed_clks); - if (cmu->clk_regs) - exynos5260_clk_sleep_init(reg_base, cmu->clk_regs, - cmu->nr_clk_regs); - - samsung_clk_of_add_provider(np, ctx); -} - - /* CMU_AUD */ static unsigned long aud_clk_regs[] __initdata = { @@ -268,7 +139,7 @@ struct samsung_gate_clock aud_gate_clks[] __initdata = { static void __init exynos5260_clk_aud_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.mux_clks = aud_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(aud_mux_clks); @@ -280,7 +151,7 @@ static void __init exynos5260_clk_aud_init(struct device_node *np) cmu.clk_regs = aud_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(aud_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_aud, "samsung,exynos5260-clock-aud", @@ -458,7 +329,7 @@ struct samsung_gate_clock disp_gate_clks[] __initdata = { static void __init exynos5260_clk_disp_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.mux_clks = disp_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(disp_mux_clks); @@ -470,7 +341,7 @@ static void __init exynos5260_clk_disp_init(struct device_node *np) cmu.clk_regs = disp_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(disp_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_disp, "samsung,exynos5260-clock-disp", @@ -522,7 +393,7 @@ static struct samsung_pll_clock egl_pll_clks[] __initdata = { static void __init exynos5260_clk_egl_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.pll_clks = egl_pll_clks; cmu.nr_pll_clks = ARRAY_SIZE(egl_pll_clks); @@ -534,7 +405,7 @@ static void __init exynos5260_clk_egl_init(struct device_node *np) cmu.clk_regs = egl_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(egl_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_egl, "samsung,exynos5260-clock-egl", @@ -624,7 +495,7 @@ struct samsung_gate_clock fsys_gate_clks[] __initdata = { static void __init exynos5260_clk_fsys_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.mux_clks = fsys_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(fsys_mux_clks); @@ -634,7 +505,7 @@ static void __init exynos5260_clk_fsys_init(struct device_node *np) cmu.clk_regs = fsys_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(fsys_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_fsys, "samsung,exynos5260-clock-fsys", @@ -713,7 +584,7 @@ struct samsung_gate_clock g2d_gate_clks[] __initdata = { static void __init exynos5260_clk_g2d_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.mux_clks = g2d_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(g2d_mux_clks); @@ -725,7 +596,7 @@ static void __init exynos5260_clk_g2d_init(struct device_node *np) cmu.clk_regs = g2d_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(g2d_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_g2d, "samsung,exynos5260-clock-g2d", @@ -774,7 +645,7 @@ static struct samsung_pll_clock g3d_pll_clks[] __initdata = { static void __init exynos5260_clk_g3d_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.pll_clks = g3d_pll_clks; cmu.nr_pll_clks = ARRAY_SIZE(g3d_pll_clks); @@ -788,7 +659,7 @@ static void __init exynos5260_clk_g3d_init(struct device_node *np) cmu.clk_regs = g3d_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(g3d_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_g3d, "samsung,exynos5260-clock-g3d", @@ -909,7 +780,7 @@ struct samsung_gate_clock gscl_gate_clks[] __initdata = { static void __init exynos5260_clk_gscl_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.mux_clks = gscl_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(gscl_mux_clks); @@ -921,7 +792,7 @@ static void __init exynos5260_clk_gscl_init(struct device_node *np) cmu.clk_regs = gscl_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(gscl_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_gscl, "samsung,exynos5260-clock-gscl", @@ -1028,7 +899,7 @@ struct samsung_gate_clock isp_gate_clks[] __initdata = { static void __init exynos5260_clk_isp_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.mux_clks = isp_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(isp_mux_clks); @@ -1040,7 +911,7 @@ static void __init exynos5260_clk_isp_init(struct device_node *np) cmu.clk_regs = isp_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(isp_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_isp, "samsung,exynos5260-clock-isp", @@ -1092,7 +963,7 @@ static struct samsung_pll_clock kfc_pll_clks[] __initdata = { static void __init exynos5260_clk_kfc_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.pll_clks = kfc_pll_clks; cmu.nr_pll_clks = ARRAY_SIZE(kfc_pll_clks); @@ -1104,7 +975,7 @@ static void __init exynos5260_clk_kfc_init(struct device_node *np) cmu.clk_regs = kfc_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(kfc_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_kfc, "samsung,exynos5260-clock-kfc", @@ -1148,7 +1019,7 @@ struct samsung_gate_clock mfc_gate_clks[] __initdata = { static void __init exynos5260_clk_mfc_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.mux_clks = mfc_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(mfc_mux_clks); @@ -1160,7 +1031,7 @@ static void __init exynos5260_clk_mfc_init(struct device_node *np) cmu.clk_regs = mfc_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(mfc_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_mfc, "samsung,exynos5260-clock-mfc", @@ -1295,7 +1166,7 @@ static struct samsung_pll_clock mif_pll_clks[] __initdata = { static void __init exynos5260_clk_mif_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.pll_clks = mif_pll_clks; cmu.nr_pll_clks = ARRAY_SIZE(mif_pll_clks); @@ -1309,7 +1180,7 @@ static void __init exynos5260_clk_mif_init(struct device_node *np) cmu.clk_regs = mif_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(mif_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_mif, "samsung,exynos5260-clock-mif", @@ -1503,7 +1374,7 @@ struct samsung_gate_clock peri_gate_clks[] __initdata = { static void __init exynos5260_clk_peri_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.mux_clks = peri_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(peri_mux_clks); @@ -1515,7 +1386,7 @@ static void __init exynos5260_clk_peri_init(struct device_node *np) cmu.clk_regs = peri_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(peri_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_peri, "samsung,exynos5260-clock-peri", @@ -1959,7 +1830,7 @@ static struct samsung_pll_clock top_pll_clks[] __initdata = { static void __init exynos5260_clk_top_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.pll_clks = top_pll_clks; cmu.nr_pll_clks = ARRAY_SIZE(top_pll_clks); @@ -1975,7 +1846,7 @@ static void __init exynos5260_clk_top_init(struct device_node *np) cmu.clk_regs = top_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(top_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_top, "samsung,exynos5260-clock-top", diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index deab84d..ef73edf 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -11,9 +11,14 @@ * clock framework for Samsung platforms. */ +#include <linux/clk.h> +#include <linux/clkdev.h> +#include <linux/clk-provider.h> #include <linux/syscore_ops.h> #include "clk.h" +static LIST_HEAD(clock_reg_cache_list); + void samsung_clk_save(void __iomem *base, struct samsung_clk_reg_dump *rd, unsigned int num_regs) @@ -313,3 +318,99 @@ unsigned long _get_rate(const char *clk_name) return clk_get_rate(clk); } + +#ifdef CONFIG_PM_SLEEP +static int exynos_clk_suspend(void) +{ + struct exynos_clock_reg_cache *reg_cache; + + list_for_each_entry(reg_cache, &clock_reg_cache_list, node) + samsung_clk_save(reg_cache->reg_base, reg_cache->rdump, + reg_cache->rd_num); + return 0; +} + +static void exynos_clk_resume(void) +{ + struct exynos_clock_reg_cache *reg_cache; + + list_for_each_entry(reg_cache, &clock_reg_cache_list, node) + samsung_clk_restore(reg_cache->reg_base, reg_cache->rdump, + reg_cache->rd_num); +} + +static struct syscore_ops exynos_clk_syscore_ops = { + .suspend = exynos_clk_suspend, + .resume = exynos_clk_resume, +}; + +static void exynos_clk_sleep_init(void __iomem *reg_base, + const unsigned long *rdump, + unsigned long nr_rdump) +{ + struct exynos_clock_reg_cache *reg_cache; + + reg_cache = kzalloc(sizeof(struct exynos_clock_reg_cache), + GFP_KERNEL); + if (!reg_cache) + panic("could not allocate register reg_cache.\n"); + reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump); + + if (!reg_cache->rdump) + panic("could not allocate register dump storage.\n"); + + /* since we should register syscore_ops only once + * check for list emptyness + */ + if (list_empty(&clock_reg_cache_list)) + register_syscore_ops(&exynos_clk_syscore_ops); + + reg_cache->reg_base = reg_base; + reg_cache->rd_num = nr_rdump; + list_add_tail(®_cache->node, &clock_reg_cache_list); +} + +#else +static void exynos_clk_sleep_init(void __iomem *reg_base, + const unsigned long *rdump, + unsigned long nr_rdump) {} +#endif + +/* + * Common function which registers plls, muxes, dividers and gates + * for each CMU. It also add CMU register list to register cache. + */ +void __init exynos_cmu_register_one(struct device_node *np, + struct exynos_cmu_info *cmu) +{ + void __iomem *reg_base; + struct samsung_clk_provider *ctx; + + reg_base = of_iomap(np, 0); + if (!reg_base) + panic("%s: failed to map registers\n", __func__); + + ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids); + if (!ctx) + panic("%s: unable to alllocate ctx\n", __func__); + + if (cmu->pll_clks) + samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks, + reg_base); + if (cmu->mux_clks) + samsung_clk_register_mux(ctx, cmu->mux_clks, + cmu->nr_mux_clks); + if (cmu->div_clks) + samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks); + if (cmu->gate_clks) + samsung_clk_register_gate(ctx, cmu->gate_clks, + cmu->nr_gate_clks); + if (cmu->fixed_clks) + samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks, + cmu->nr_fixed_clks); + if (cmu->clk_regs) + exynos_clk_sleep_init(reg_base, cmu->clk_regs, + cmu->nr_clk_regs); + + samsung_clk_of_add_provider(np, ctx); +} diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index 66ab36b..552d155 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -324,6 +324,37 @@ struct samsung_pll_clock { __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \ _lock, _con, _rtable, _alias) +struct exynos_clock_reg_cache { + struct list_head node; + void __iomem *reg_base; + struct samsung_clk_reg_dump *rdump; + unsigned int rd_num; +}; + +struct exynos_cmu_info { + /* list of pll clocks and respective count */ + struct samsung_pll_clock *pll_clks; + unsigned int nr_pll_clks; + /* list of mux clocks and respective count */ + struct samsung_mux_clock *mux_clks; + unsigned int nr_mux_clks; + /* list of div clocks and respective count */ + struct samsung_div_clock *div_clks; + unsigned int nr_div_clks; + /* list of gate clocks and respective count */ + struct samsung_gate_clock *gate_clks; + unsigned int nr_gate_clks; + /* list of fixed clocks and respective count */ + struct samsung_fixed_rate_clock *fixed_clks; + unsigned int nr_fixed_clks; + /* total number of clocks with IDs assigned*/ + unsigned int nr_clk_ids; + + /* list and number of clocks registers */ + unsigned long *clk_regs; + unsigned int nr_clk_regs; +}; + extern struct samsung_clk_provider *__init samsung_clk_init( struct device_node *np, void __iomem *base, unsigned long nr_clks); @@ -362,6 +393,9 @@ extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx, struct samsung_pll_clock *pll_list, unsigned int nr_clk, void __iomem *base); +extern void __init exynos_cmu_register_one(struct device_node *, + struct exynos_cmu_info *); + extern unsigned long _get_rate(const char *clk_name); extern void samsung_clk_save(void __iomem *base,
This patch factors out the code that can be reused from clk-exynos5260.c to clk-samsung/clk.c and clk-samsung/clk.h As Clock controller in Exynos7 support various blocks in CMU. The common functions and structures can be reused to support Clock controller in Exynos7. Signed-off-by: Naveen Krishna Chatradhi <ch.naveen@samsung.com> Cc: Tomasz Figa <t.figa@samsung.com> Cc: Mike Turquette <mturquette@linaro.org> Cc: Thomas Abraham <thomas.ab@samsung.com> --- drivers/clk/samsung/clk-exynos5260.c | 181 +++++----------------------------- drivers/clk/samsung/clk.c | 101 +++++++++++++++++++ drivers/clk/samsung/clk.h | 34 +++++++ 3 files changed, 161 insertions(+), 155 deletions(-)