Re: [PATCH v6 05/17] clk: mpc512x: add backwards compat to the CCF code

2013-12-07 Thread Anatolij Gustschin
On Sat, 30 Nov 2013 23:51:25 +0100
Gerhard Sittig g...@denx.de wrote:

 extend the recently added COMMON_CLK platform support for MPC512x such
 that it works with incomplete device tree data which lacks clock specs
 
 Cc: Mike Turquette mturque...@linaro.org
 Cc: Anatolij Gustschin ag...@denx.de
 Cc: linux-arm-ker...@lists.infradead.org
 Cc: linuxppc-dev@lists.ozlabs.org
 Signed-off-by: Gerhard Sittig g...@denx.de
 ---
  arch/powerpc/platforms/512x/clock-commonclk.c |  173 
 -
  1 file changed, 172 insertions(+), 1 deletion(-)

moved node macro definitions out of the function body and applied
to next. Thanks!

Anatolij
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v6 05/17] clk: mpc512x: add backwards compat to the CCF code

2013-11-30 Thread Gerhard Sittig
extend the recently added COMMON_CLK platform support for MPC512x such
that it works with incomplete device tree data which lacks clock specs

Cc: Mike Turquette mturque...@linaro.org
Cc: Anatolij Gustschin ag...@denx.de
Cc: linux-arm-ker...@lists.infradead.org
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Gerhard Sittig g...@denx.de
---
 arch/powerpc/platforms/512x/clock-commonclk.c |  173 -
 1 file changed, 172 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c 
b/arch/powerpc/platforms/512x/clock-commonclk.c
index 818927248392..945e4609e773 100644
--- a/arch/powerpc/platforms/512x/clock-commonclk.c
+++ b/arch/powerpc/platforms/512x/clock-commonclk.c
@@ -11,6 +11,7 @@
  * (at your option) any later version.
  */
 
+#include linux/bitops.h
 #include linux/clk-provider.h
 #include linux/clkdev.h
 #include linux/device.h
@@ -745,7 +746,177 @@ static void mpc5121_clk_provide_migration_support(void)
  */
 static void mpc5121_clk_provide_backwards_compat(void)
 {
-   /* TODO */
+   enum did_reg_flags {
+   DID_REG_PSC = BIT(0),
+   DID_REG_PSCFIFO = BIT(1),
+   DID_REG_NFC = BIT(2),
+   DID_REG_CAN = BIT(3),
+   DID_REG_I2C = BIT(4),
+   DID_REG_DIU = BIT(5),
+   DID_REG_VIU = BIT(6),
+   DID_REG_FEC = BIT(7),
+   DID_REG_USB = BIT(8),
+   DID_REG_PATA= BIT(9),
+   };
+
+   int did_register;
+   struct device_node *np;
+   struct resource res;
+   int idx;
+   char devname[32];
+
+   /*
+* those macros are not exactly pretty, but they encapsulate a lot
+* of copy'n'paste heavy code which is even more ugly, and reduce
+* the potential for inconsistencies in those many code copies
+*/
+
+#define FOR_NODES(compatname) \
+   for_each_compatible_node(np, NULL, compatname)
+
+#define NODE_PREP do { \
+   of_address_to_resource(np, 0, res); \
+   snprintf(devname, sizeof(devname), %08x.%s, res.start, np-name); \
+} while (0)
+
+#define NODE_CHK(clkname, clkitem, regnode, regflag) do { \
+   struct clk *clk; \
+   clk = of_clk_get_by_name(np, clkname); \
+   if (IS_ERR(clk)) { \
+   clk = clkitem; \
+   clk_register_clkdev(clk, clkname, devname); \
+   if (regnode) \
+   clk_register_clkdev(clk, clkname, np-name); \
+   did_register |= DID_REG_ ## regflag; \
+   pr_debug(clock alias name '%s' for dev '%s' pointer %p\n, \
+clkname, devname, clk); \
+   } else { \
+   clk_put(clk); \
+   } \
+} while (0)
+
+   did_register = 0;
+
+   FOR_NODES(mpc512x_select_psc_compat()) {
+   NODE_PREP;
+   idx = (res.start  8)  0xf;
+   NODE_CHK(ipg, clks[MPC512x_CLK_PSC0 + idx], 0, PSC);
+   NODE_CHK(mclk, clks[MPC512x_CLK_PSC0_MCLK + idx], 0, PSC);
+   }
+
+   FOR_NODES(fsl,mpc5121-psc-fifo) {
+   NODE_PREP;
+   NODE_CHK(ipg, clks[MPC512x_CLK_PSC_FIFO], 1, PSCFIFO);
+   }
+
+   FOR_NODES(fsl,mpc5121-nfc) {
+   NODE_PREP;
+   NODE_CHK(ipg, clks[MPC512x_CLK_NFC], 0, NFC);
+   }
+
+   FOR_NODES(fsl,mpc5121-mscan) {
+   NODE_PREP;
+   idx = 0;
+   idx += (res.start  0x2000) ? 2 : 0;
+   idx += (res.start  0x0080) ? 1 : 0;
+   NODE_CHK(ipg, clks[MPC512x_CLK_BDLC], 0, CAN);
+   NODE_CHK(mclk, clks[MPC512x_CLK_MSCAN0_MCLK + idx], 0, CAN);
+   }
+
+   /*
+* do register the 'ips', 'sys', and 'ref' names globally
+* instead of inside each individual CAN node, as there is no
+* potential for a name conflict (in contrast to 'ipg' and 'mclk')
+*/
+   if (did_register  DID_REG_CAN) {
+   clk_register_clkdev(clks[MPC512x_CLK_IPS], ips, NULL);
+   clk_register_clkdev(clks[MPC512x_CLK_SYS], sys, NULL);
+   clk_register_clkdev(clks[MPC512x_CLK_REF], ref, NULL);
+   }
+
+   FOR_NODES(fsl,mpc5121-i2c) {
+   NODE_PREP;
+   NODE_CHK(ipg, clks[MPC512x_CLK_I2C], 0, I2C);
+   }
+
+   /*
+* workaround for the fact that the I2C driver does an anonymous
+* lookup (NULL name spec, which yields the first clock spec) for
+* which we cannot register an alias -- a _global_ 'ipg' alias that
+* is not bound to any device name and returns the I2C clock item
+* is not a good idea
+*
+* so we have the lookup in the peripheral driver fail, which is
+* silent and non-fatal, and pre-enable the clock item here such
+* that register access is possible
+*
+* see commit b3bfce2b i2c: mpc: cleanup clock API use for
+* details, adjusting