Re: [PATCH 2/6] MPC5121 clock driver

2008-06-28 Thread Grant Likely
Mostly looks good, a few comments below.

On Fri, Jun 20, 2008 at 10:58:35AM -0600, John Rigby wrote:
 Implements the api defined in include/clk.h
 
 Current only getting frequencies is supported
 not setting.

Need a more detailed commit message.  This doesn't tell me much.

 
 Signed-off-by: John Rigby [EMAIL PROTECTED]
 ---
  arch/powerpc/platforms/512x/Makefile |1 +
  arch/powerpc/platforms/512x/clock.c  |  729 
 ++
  2 files changed, 730 insertions(+), 0 deletions(-)
  create mode 100644 arch/powerpc/platforms/512x/clock.c
 
 diff --git a/arch/powerpc/platforms/512x/Makefile 
 b/arch/powerpc/platforms/512x/Makefile
 index 232c89f..ef6c925 100644
 --- a/arch/powerpc/platforms/512x/Makefile
 +++ b/arch/powerpc/platforms/512x/Makefile
 @@ -1,4 +1,5 @@
  #
  # Makefile for the Freescale PowerPC 512x linux kernel.
  #
 +obj-y:= clock.o

should be +=

  obj-$(CONFIG_MPC5121_ADS)+= mpc5121_ads.o
 diff --git a/arch/powerpc/platforms/512x/clock.c 
 b/arch/powerpc/platforms/512x/clock.c
 new file mode 100644
 index 000..39db722
 --- /dev/null
 +++ b/arch/powerpc/platforms/512x/clock.c
 @@ -0,0 +1,729 @@
 +/*
 + * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. All rights reserved.
 + *
 + * Author: John Rigby [EMAIL PROTECTED]
 + *
 + * Implements the clk api defined in include/linux/clk.h
 + *
 + *Original based on linux/arch/arm/mach-integrator/clock.c
 + *
 + *Copyright (C) 2004 ARM Limited.
 + *Written by Deep Blue Solutions Limited.
 + *
 + * 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 linux/module.h
 +#include linux/kernel.h
 +#include linux/list.h
 +#include linux/errno.h
 +#include linux/err.h
 +#include linux/string.h
 +#include linux/clk.h
 +#include linux/mutex.h
 +#include linux/io.h
 +
 +#include linux/of_platform.h
 +#include asm/mpc512x.h
 +
 +static int clocks_initialized;
 +
 +struct module;

This is already defined in linux/module.h?

 +
 +#undef CLK_DEBUG

I think this line should be at the top of the file to be easier to find
when toggling it.

 +#ifdef CLK_DEBUG
 +void dump_clocks(void)
 +{
 + struct clk *p;
 +
 + mutex_lock(clocks_mutex);
 + printk(KERN_INFO CLOCKS:\n);
 + list_for_each_entry(p, clocks, node) {
 + printk(KERN_INFO   %s %ld, p-name, p-rate);
 + if (p-parent)
 + printk(KERN_INFO  %s %ld, p-parent-name,
 +p-parent-rate);
 + if (p-flags  CLK_HAS_CTRL)
 + printk(KERN_INFO  reg/bit %d/%d, p-reg, p-bit);
 + printk(\n);
 + }
 + mutex_unlock(clocks_mutex);
 +}
 +#define  DEBUG_CLK_DUMP() dump_clocks()
 +#else
 +#define  DEBUG_CLK_DUMP()
 +#endif
 +
 +static long ips_to_ref(unsigned long rate)
 +{
 + int ips_div = (clockctl-scfr1  23)  0x7;
 +
 + rate *= ips_div;/* csb_clk = ips_clk * ips_div */
 + rate *= 2;  /* sys_clk = csb_clk * 2 */
 + return sys_to_ref(rate);
 +}
 +
 +static unsigned long devtree_getfreq(char *nodetype, char *clockname)

Why is nodetype even passed in here?  It isn't used, and besides, you
shouldn't test against device_type anyway.  Test against compatible
instead.

 +{
 + struct device_node *node;
 + const unsigned int *fp;
 + unsigned int val = 0;
 +
 + node = of_find_node_by_type(NULL, soc);

Once again; don't look for device_type == soc.  Use compatible.

 + if (node) {
 + fp = of_get_property(node, clockname, NULL);
 + if (fp)
 + val = of_read_ulong(fp, 1);
 + }
 + return val;
 +}
 +
 +static void ref_clk_calc(struct clk *clk)
 +{
 + unsigned long rate;
 +
 + rate = devtree_getfreq(soc, ref-frequency);
 + if (rate == 0) {
 + /*
 +  * no reference clock in device tree
 +  * get ips clock freq and go backwards from there
 +  */
 + rate = devtree_getfreq(soc, bus-frequency);
 + if (rate == 0) {
 + printk(KERN_WARNING
 + No bus-frequency in dev tree using 66MHz\n);
 + clk-rate = 6600;

Is it even worth trying to use a default here?  I think it should fail
loudly instead to reduce the risk of people shipping boards with badly
formed device trees.  I don't think there is any backwards compatibility
need for doing this.

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


[PATCH 2/6] MPC5121 clock driver

2008-06-20 Thread John Rigby
Implements the api defined in include/clk.h

Current only getting frequencies is supported
not setting.

Signed-off-by: John Rigby [EMAIL PROTECTED]
---
 arch/powerpc/platforms/512x/Makefile |1 +
 arch/powerpc/platforms/512x/clock.c  |  729 ++
 2 files changed, 730 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/platforms/512x/clock.c

diff --git a/arch/powerpc/platforms/512x/Makefile 
b/arch/powerpc/platforms/512x/Makefile
index 232c89f..ef6c925 100644
--- a/arch/powerpc/platforms/512x/Makefile
+++ b/arch/powerpc/platforms/512x/Makefile
@@ -1,4 +1,5 @@
 #
 # Makefile for the Freescale PowerPC 512x linux kernel.
 #
+obj-y  := clock.o
 obj-$(CONFIG_MPC5121_ADS)  += mpc5121_ads.o
diff --git a/arch/powerpc/platforms/512x/clock.c 
b/arch/powerpc/platforms/512x/clock.c
new file mode 100644
index 000..39db722
--- /dev/null
+++ b/arch/powerpc/platforms/512x/clock.c
@@ -0,0 +1,729 @@
+/*
+ * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: John Rigby [EMAIL PROTECTED]
+ *
+ * Implements the clk api defined in include/linux/clk.h
+ *
+ *Original based on linux/arch/arm/mach-integrator/clock.c
+ *
+ *Copyright (C) 2004 ARM Limited.
+ *Written by Deep Blue Solutions Limited.
+ *
+ * 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 linux/module.h
+#include linux/kernel.h
+#include linux/list.h
+#include linux/errno.h
+#include linux/err.h
+#include linux/string.h
+#include linux/clk.h
+#include linux/mutex.h
+#include linux/io.h
+
+#include linux/of_platform.h
+#include asm/mpc512x.h
+
+static int clocks_initialized;
+
+struct module;
+
+#define CLK_HAS_RATE   0x1 /* has rate in MHz */
+#define CLK_HAS_CTRL   0x2 /* has control reg and bit */
+
+struct clk {
+   struct list_head node;
+   char name[32];
+   int flags;
+   struct device *dev;
+   unsigned long rate;
+   struct module *owner;
+   void (*calc) (struct clk *);
+   struct clk *parent;
+   int reg, bit;   /* CLK_HAS_CTRL */
+   int div_shift;  /* only used by generic_div_clk_calc */
+};
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+   struct clk *p, *clk = ERR_PTR(-ENOENT);
+   int dev_match = 0;
+   int id_match = 0;
+
+   if (dev == NULL  id == NULL)
+   return NULL;
+
+   mutex_lock(clocks_mutex);
+   list_for_each_entry(p, clocks, node) {
+   if (dev  dev == p-dev)
+   dev_match++;
+   if (strcmp(id, p-name) == 0)
+   id_match++;
+   if ((dev_match || id_match)  try_module_get(p-owner)) {
+   clk = p;
+   break;
+   }
+   }
+   mutex_unlock(clocks_mutex);
+
+   return clk;
+}
+EXPORT_SYMBOL(clk_get);
+
+#undef CLK_DEBUG
+#ifdef CLK_DEBUG
+void dump_clocks(void)
+{
+   struct clk *p;
+
+   mutex_lock(clocks_mutex);
+   printk(KERN_INFO CLOCKS:\n);
+   list_for_each_entry(p, clocks, node) {
+   printk(KERN_INFO   %s %ld, p-name, p-rate);
+   if (p-parent)
+   printk(KERN_INFO  %s %ld, p-parent-name,
+  p-parent-rate);
+   if (p-flags  CLK_HAS_CTRL)
+   printk(KERN_INFO  reg/bit %d/%d, p-reg, p-bit);
+   printk(\n);
+   }
+   mutex_unlock(clocks_mutex);
+}
+#defineDEBUG_CLK_DUMP() dump_clocks()
+#else
+#defineDEBUG_CLK_DUMP()
+#endif
+
+
+void clk_put(struct clk *clk)
+{
+   module_put(clk-owner);
+}
+EXPORT_SYMBOL(clk_put);
+
+#define NRPSC 12
+
+struct mpc512x_clockctl {
+   u32 spmr;   /* System PLL Mode Reg */
+   u32 sccr[2];/* System Clk Ctrl Reg 1  2 */
+   u32 scfr1;  /* System Clk Freq Reg 1 */
+   u32 scfr2;  /* System Clk Freq Reg 2 */
+   u32 reserved;
+   u32 bcr;/* Bread Crumb Reg */
+   u32 pccr[NRPSC];/* PSC Clk Ctrl Reg 0-11 */
+   u32 spccr;  /* SPDIF Clk Ctrl Reg */
+   u32 cccr;   /* CFM Clk Ctrl Reg */
+   u32 dccr;   /* DIU Clk Cnfg Reg */
+};
+
+struct mpc512x_clockctl __iomem *clockctl;
+
+int clk_enable(struct clk *clk)
+{
+   unsigned int mask;
+
+   if (clk-flags  CLK_HAS_CTRL) {
+   mask = in_be32(clockctl-sccr[clk-reg]);
+   mask |= 1  clk-bit;
+   out_be32(clockctl-sccr[clk-reg], mask);
+   }
+   return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+   unsigned int mask;
+
+   if (clk-flags  CLK_HAS_CTRL) {
+   mask = 

Re: [PATCH 2/6] MPC5121 clock driver

2008-06-20 Thread Stephen Rothwell
Hi John,

On Fri, 20 Jun 2008 10:58:35 -0600 John Rigby [EMAIL PROTECTED] wrote:

 +struct module;

Since you include linux/module.h, you don't need this.

 +static unsigned long devtree_getfreq(char *nodetype, char *clockname)
 +{
 + struct device_node *node;
 + const unsigned int *fp;
 + unsigned int val = 0;
 +
 + node = of_find_node_by_type(NULL, soc);
 + if (node) {
 + fp = of_get_property(node, clockname, NULL);
 + if (fp)
 + val = of_read_ulong(fp, 1);
 + }
 + return val;

You leak a reference to the node here. Also every call has nodetype set to
soc and you don't use nodetype anyway.

-- 
Cheers,
Stephen Rothwell[EMAIL PROTECTED]
http://www.canb.auug.org.au/~sfr/


pgpW3etpiVRpY.pgp
Description: PGP signature
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev