From mboxrd@z Thu Jan 1 00:00:00 1970 From: mturquette@ti.com (Mike Turquette) Date: Wed, 21 Nov 2012 11:10:10 -0800 Subject: [PATCH 3/3 v3] clk: move IM-PD1 clocks to drivers/clk In-Reply-To: <1353447589-12947-1-git-send-email-linus.walleij@linaro.org> References: <1353447589-12947-1-git-send-email-linus.walleij@linaro.org> Message-ID: <20121121191010.21126.91932@nucleus> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Quoting Linus Walleij (2012-11-20 13:39:49) > The ARM IM-PD1 add-on module has a few clock of its own, let's > move also these down to the drivers/clk/versatile driver dir > and get rid of any remaining oldschool Integrator clocks. > > Signed-off-by: Linus Walleij I replaced the v2 version in clk-next with this one. Thanks for the quick updates. Regards, Mike > --- > ChangeLog v1->v2: > - add GPL header > ChangeLov v2->v3: > - Provide exitpath, provide handling of multiple LMs > use new ICST VCO infrastructure. > --- > arch/arm/mach-integrator/impd1.c | 69 +------------------- > drivers/clk/versatile/Makefile | 1 + > drivers/clk/versatile/clk-impd1.c | 97 ++++++++++++++++++++++++++++ > include/linux/platform_data/clk-integrator.h | 2 + > 4 files changed, 103 insertions(+), 66 deletions(-) > create mode 100644 drivers/clk/versatile/clk-impd1.c > > diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c > index e428f3a..b3d86d7 100644 > --- a/arch/arm/mach-integrator/impd1.c > +++ b/arch/arm/mach-integrator/impd1.c > @@ -21,10 +21,9 @@ > #include > #include > #include > +#include > #include > -#include > > -#include > #include > #include > #include > @@ -36,45 +35,6 @@ MODULE_PARM_DESC(lmid, "logic module stack position"); > > struct impd1_module { > void __iomem *base; > - struct clk vcos[2]; > - struct clk_lookup *clks[3]; > -}; > - > -static const struct icst_params impd1_vco_params = { > - .ref = 24000000, /* 24 MHz */ > - .vco_max = ICST525_VCO_MAX_3V, > - .vco_min = ICST525_VCO_MIN, > - .vd_min = 12, > - .vd_max = 519, > - .rd_min = 3, > - .rd_max = 120, > - .s2div = icst525_s2div, > - .idx2s = icst525_idx2s, > -}; > - > -static void impd1_setvco(struct clk *clk, struct icst_vco vco) > -{ > - struct impd1_module *impd1 = clk->data; > - u32 val = vco.v | (vco.r << 9) | (vco.s << 16); > - > - writel(0xa05f, impd1->base + IMPD1_LOCK); > - writel(val, clk->vcoreg); > - writel(0, impd1->base + IMPD1_LOCK); > - > -#ifdef DEBUG > - vco.v = val & 0x1ff; > - vco.r = (val >> 9) & 0x7f; > - vco.s = (val >> 16) & 7; > - > - pr_debug("IM-PD1: VCO%d clock is %ld Hz\n", > - vconr, icst525_hz(&impd1_vco_params, vco)); > -#endif > -} > - > -static const struct clk_ops impd1_clk_ops = { > - .round = icst_clk_round, > - .set = icst_clk_set, > - .setvco = impd1_setvco, > }; > > void impd1_tweak_control(struct device *dev, u32 mask, u32 val) > @@ -344,10 +304,6 @@ static struct impd1_device impd1_devs[] = { > } > }; > > -static struct clk fixed_14745600 = { > - .rate = 14745600, > -}; > - > static int impd1_probe(struct lm_device *dev) > { > struct impd1_module *impd1; > @@ -376,23 +332,7 @@ static int impd1_probe(struct lm_device *dev) > printk("IM-PD1 found at 0x%08lx\n", > (unsigned long)dev->resource.start); > > - for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++) { > - impd1->vcos[i].ops = &impd1_clk_ops, > - impd1->vcos[i].owner = THIS_MODULE, > - impd1->vcos[i].params = &impd1_vco_params, > - impd1->vcos[i].data = impd1; > - } > - impd1->vcos[0].vcoreg = impd1->base + IMPD1_OSC1; > - impd1->vcos[1].vcoreg = impd1->base + IMPD1_OSC2; > - > - impd1->clks[0] = clkdev_alloc(&impd1->vcos[0], NULL, "lm%x:01000", > - dev->id); > - impd1->clks[1] = clkdev_alloc(&fixed_14745600, NULL, "lm%x:00100", > - dev->id); > - impd1->clks[2] = clkdev_alloc(&fixed_14745600, NULL, "lm%x:00200", > - dev->id); > - for (i = 0; i < ARRAY_SIZE(impd1->clks); i++) > - clkdev_add(impd1->clks[i]); > + integrator_impd1_clk_init(impd1->base, dev->id); > > for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) { > struct impd1_device *idev = impd1_devs + i; > @@ -431,12 +371,9 @@ static int impd1_remove_one(struct device *dev, void *data) > static void impd1_remove(struct lm_device *dev) > { > struct impd1_module *impd1 = lm_get_drvdata(dev); > - int i; > > device_for_each_child(&dev->dev, NULL, impd1_remove_one); > - > - for (i = 0; i < ARRAY_SIZE(impd1->clks); i++) > - clkdev_drop(impd1->clks[i]); > + integrator_impd1_clk_exit(dev->id); > > lm_set_drvdata(dev, NULL); > > diff --git a/drivers/clk/versatile/Makefile b/drivers/clk/versatile/Makefile > index c0a0f64..884e362 100644 > --- a/drivers/clk/versatile/Makefile > +++ b/drivers/clk/versatile/Makefile > @@ -1,4 +1,5 @@ > # Makefile for Versatile-specific clocks > obj-$(CONFIG_ICST) += clk-icst.o > obj-$(CONFIG_ARCH_INTEGRATOR) += clk-integrator.o > +obj-$(CONFIG_INTEGRATOR_IMPD1) += clk-impd1.o > obj-$(CONFIG_ARCH_REALVIEW) += clk-realview.o > diff --git a/drivers/clk/versatile/clk-impd1.c b/drivers/clk/versatile/clk-impd1.c > new file mode 100644 > index 0000000..369139a > --- /dev/null > +++ b/drivers/clk/versatile/clk-impd1.c > @@ -0,0 +1,97 @@ > +/* > + * Clock driver for the ARM Integrator/IM-PD1 board > + * Copyright (C) 2012 Linus Walleij > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + */ > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +#include "clk-icst.h" > + > +struct impd1_clk { > + struct clk *vcoclk; > + struct clk *uartclk; > + struct clk_lookup *clks[3]; > +}; > + > +static struct impd1_clk impd1_clks[4]; > + > +/* > + * There are two VCO's on the IM-PD1 but only one is used by the > + * kernel, that is why we are only implementing the control of > + * IMPD1_OSC1 here. > + */ > + > +static const struct icst_params impd1_vco_params = { > + .ref = 24000000, /* 24 MHz */ > + .vco_max = ICST525_VCO_MAX_3V, > + .vco_min = ICST525_VCO_MIN, > + .vd_min = 12, > + .vd_max = 519, > + .rd_min = 3, > + .rd_max = 120, > + .s2div = icst525_s2div, > + .idx2s = icst525_idx2s, > +}; > + > +static const struct clk_icst_desc impd1_icst1_desc = { > + .params = &impd1_vco_params, > + .vco_offset = IMPD1_OSC1, > + .lock_offset = IMPD1_LOCK, > +}; > + > +/** > + * integrator_impd1_clk_init() - set up the integrator clock tree > + * @base: base address of the logic module (LM) > + * @id: the ID of this LM > + */ > +void integrator_impd1_clk_init(void __iomem *base, unsigned int id) > +{ > + struct impd1_clk *imc; > + struct clk *clk; > + int i; > + > + if (id > 3) { > + pr_crit("no more than 4 LMs can be attached\n"); > + return; > + } > + imc = &impd1_clks[id]; > + > + clk = icst_clk_register(NULL, &impd1_icst1_desc, base); > + imc->vcoclk = clk; > + imc->clks[0] = clkdev_alloc(clk, NULL, "lm%x:01000", id); > + > + /* UART reference clock */ > + clk = clk_register_fixed_rate(NULL, "uartclk", NULL, CLK_IS_ROOT, > + 14745600); > + imc->uartclk = clk; > + imc->clks[1] = clkdev_alloc(clk, NULL, "lm%x:00100", id); > + imc->clks[2] = clkdev_alloc(clk, NULL, "lm%x:00200", id); > + > + for (i = 0; i < ARRAY_SIZE(imc->clks); i++) > + clkdev_add(imc->clks[i]); > +} > + > +void integrator_impd1_clk_exit(unsigned int id) > +{ > + int i; > + struct impd1_clk *imc; > + > + if (id > 3) > + return; > + imc = &impd1_clks[id]; > + > + for (i = 0; i < ARRAY_SIZE(imc->clks); i++) > + clkdev_drop(imc->clks[i]); > + clk_unregister(imc->uartclk); > + clk_unregister(imc->vcoclk); > +} > diff --git a/include/linux/platform_data/clk-integrator.h b/include/linux/platform_data/clk-integrator.h > index 83fe9c2..280edac 100644 > --- a/include/linux/platform_data/clk-integrator.h > +++ b/include/linux/platform_data/clk-integrator.h > @@ -1 +1,3 @@ > void integrator_clk_init(bool is_cp); > +void integrator_impd1_clk_init(void __iomem *base, unsigned int id); > +void integrator_impd1_clk_exit(unsigned int id); > -- > 1.7.11.7