Index: linux-work/arch/powerpc/include/asm/clk_interface.h
===================================================================
--- linux-work.orig/arch/powerpc/include/asm/clk_interface.h	2009-02-05 16:22:24.000000000 +1100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,20 +0,0 @@
-#ifndef __ASM_POWERPC_CLK_INTERFACE_H
-#define __ASM_POWERPC_CLK_INTERFACE_H
-
-#include <linux/clk.h>
-
-struct clk_interface {
-	struct clk*	(*clk_get)	(struct device *dev, const char *id);
-	int		(*clk_enable)	(struct clk *clk);
-	void		(*clk_disable)	(struct clk *clk);
-	unsigned long	(*clk_get_rate)	(struct clk *clk);
-	void		(*clk_put)	(struct clk *clk);
-	long		(*clk_round_rate) (struct clk *clk, unsigned long rate);
-	int 		(*clk_set_rate)	(struct clk *clk, unsigned long rate);
-	int		(*clk_set_parent) (struct clk *clk, struct clk *parent);
-	struct clk*	(*clk_get_parent) (struct clk *clk);
-};
-
-extern struct clk_interface clk_functions;
-
-#endif /* __ASM_POWERPC_CLK_INTERFACE_H */
Index: linux-work/arch/powerpc/kernel/clock.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/clock.c	2009-02-05 16:22:24.000000000 +1100
+++ linux-work/arch/powerpc/kernel/clock.c	2009-08-18 17:38:08.000000000 +1000
@@ -1,82 +1,282 @@
 /*
- * Dummy clk implementations for powerpc.
- * These need to be overridden in platform code.
+ * Clock infrastructure for PowerPC platform
+ *
  */
 
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/module.h>
-#include <asm/clk_interface.h>
+#include <linux/of.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/err.h>
+#include <asm/clk.h>
+#include <asm/machdep.h>
+
+struct clk_provider {
+	struct list_head	link;
+	struct device_node     	*node;
+
+	/* Return NULL if no such clock output, return PTR_ERR for
+	 * other errors
+	 */
+	struct clk *		(*get)(struct device_node *np,
+				       const char *output_id,
+				       void *data);
+	void			*data;
+};
+
+static LIST_HEAD(clk_providers);
+static DEFINE_MUTEX(clk_lock);
+
+int clk_add_provider(struct device_node *np,
+		     struct clk *(*clk_src_get)(struct device_node *np,
+						const char *output_id,
+						void *data),
+		     void *data)
+{
+	struct clk_provider *cp;
 
-struct clk_interface clk_functions;
+	cp = kzalloc(sizeof(struct clk_provider), GFP_KERNEL);
+	if (!cp)
+		return -ENOMEM;
+
+	cp->node = of_node_get(np);
+	cp->data = data;
+	cp->get = clk_src_get;
+
+	mutex_lock(&clk_lock);
+	list_add(&cp->link, &clk_providers);
+	mutex_unlock(&clk_lock);
 
-struct clk *clk_get(struct device *dev, const char *id)
+	return 0;
+}
+
+void clk_del_provider(struct device_node *np,
+		      struct clk *(*clk_src_get)(struct device_node *np,
+						 const char *output_id,
+						 void *data),
+		      void *data)
 {
-	if (clk_functions.clk_get)
-		return clk_functions.clk_get(dev, id);
-	return ERR_PTR(-ENOSYS);
+	struct clk_provider *cp, *tmp;
+
+	mutex_lock(&clk_lock);
+	list_for_each_entry_safe(cp, tmp, &clk_providers, link) {
+		if (cp->node == np && cp->get == clk_src_get && cp->data == data) {
+			list_del(&cp->link);
+			of_node_put(cp->node);
+			kfree(cp);
+			break;
+		}
+	}
+	mutex_unlock(&clk_lock);
 }
-EXPORT_SYMBOL(clk_get);
 
-void clk_put(struct clk *clk)
+static unsigned long clk_simple_get_rate(struct clk *clk)
 {
-	if (clk_functions.clk_put)
-		clk_functions.clk_put(clk);
+	struct clk_simple *cs = to_clk_simple(clk);
+
+	return cs->rate;
 }
-EXPORT_SYMBOL(clk_put);
+
+static void clk_simple_put(struct clk *clk)
+{
+	struct clk_simple *cs = to_clk_simple(clk);
+
+	kfree(cs);
+}
+
+static struct clk *__clk_get_simple(struct device_node *np)
+{
+	const u32 *freq;
+	struct clk_simple *cs;
+
+	freq = of_get_property(np, "clock-frequency", NULL);
+	if (!freq)
+		return ERR_PTR(-ENXIO);
+
+	cs = kzalloc(sizeof(struct clk_simple), GFP_KERNEL);
+	if (!cs)
+		return ERR_PTR(-ENOMEM);
+
+	cs->rate = *freq;
+	cs->clk.get_rate = clk_simple_get_rate;
+	cs->clk.put = clk_simple_put;
+
+	return &cs->clk;
+}
+
+static struct clk *__clk_get_from_provider(struct device_node *np, u32 index)
+{
+	struct clk_provider *provider;
+	const char *names, *id = NULL;
+	int sz, l, i;
+	struct clk *clk = NULL;
+
+	/* Look for "clock-output-names" in the provider's node, if it's missing
+	 * we don't bother looking for a clock provider, though we do fallback
+	 * to the "simple" clock case
+	 */
+	names = of_get_property(np, "clock-output-names", &sz);
+	if (!names)
+		return __clk_get_simple(np);
+
+	/* Lookup index */
+	for (i = 0; sz > 0; i++) {
+		if (index == i) {
+			id = names;
+			break;
+		}
+		l = strlen(names) + 1;
+		sz -= l;
+		names += l;
+	}
+	if (id == NULL)
+		return ERR_PTR(-ENXIO);
+
+	/* Check if we have such a provider in our array */
+	mutex_lock(&clk_lock);
+	list_for_each_entry(provider, &clk_providers, link) {
+		if (provider->node == np)
+			clk = provider->get(np, id, provider->data);
+		if (clk)
+			break;
+	}
+	mutex_unlock(&clk_lock);
+
+	/* Clock not found, return an error */
+	if (clk == NULL)
+		clk = ERR_PTR(-EINVAL);
+
+	return clk;
+}
+
+struct clk *of_clk_get(struct device_node *np, const char *id)
+{
+	int sz, l, index = 0;
+	struct device_node *provnode;
+	const u32 *map;
+	u32 provhandle, provindex;
+	struct clk *clk;
+
+	/* look for an id match in clock-names property */
+	if (id) {
+		const char *names = of_get_property(np, "clock-input-names", &sz);
+
+		/* no such property, fail for now. Maybe in the long run we might
+		 * consider allowing "generic" names such as "bus" for the bus
+		 * clock, effectively routing to the parent node...
+		 */
+		if (!names)
+			return ERR_PTR(-ENXIO);
+		while (sz > 0) {
+			if (strcasecmp(id, names) == 0)
+				break;
+			l = strlen(names) + 1;
+			sz -= l;
+			names += l;
+			index++;
+		}
+		if (sz < 1)
+			return ERR_PTR(-ENOENT);
+	}
+
+	/* now we have an index, lookup in clock-map */
+	map = of_get_property(np, "clock-map", &sz);
+	if (!map)
+		return ERR_PTR(-ENXIO);
+	sz /= sizeof(u32) * 2;
+	if (index >= sz)
+		return ERR_PTR(-EINVAL);
+	provhandle = map[index * 2];
+	provindex = map[index * 2] + 1;
+
+	provnode = of_find_node_by_phandle(provhandle);
+	if (!provnode)
+		return ERR_PTR(-EINVAL);
+
+	clk = __clk_get_from_provider(provnode, provindex);
+	of_node_put(provnode);
+
+	return clk;
+}
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+	if (ppc_md.clk_get)
+		return ppc_md.clk_get(dev, id);
+
+	if (dev->archdata.of_node)
+		return of_clk_get(dev->archdata.of_node, id);
+
+	return ERR_PTR(-ENODEV);
+}
+EXPORT_SYMBOL(clk_get);
+
+/*
+ * clk_* API is just wrappers to the function pointers
+ * inside of struct clk
+ */
 
 int clk_enable(struct clk *clk)
 {
-	if (clk_functions.clk_enable)
-		return clk_functions.clk_enable(clk);
-	return -ENOSYS;
+	if (clk->enable)
+		return clk->enable(clk);
+	return 0;
 }
 EXPORT_SYMBOL(clk_enable);
 
 void clk_disable(struct clk *clk)
 {
-	if (clk_functions.clk_disable)
-		clk_functions.clk_disable(clk);
+	if (clk->disable)
+		clk->disable(clk);
 }
 EXPORT_SYMBOL(clk_disable);
 
 unsigned long clk_get_rate(struct clk *clk)
 {
-	if (clk_functions.clk_get_rate)
-		return clk_functions.clk_get_rate(clk);
+	if (clk->get_rate)
+		return clk->get_rate(clk);
 	return 0;
 }
 EXPORT_SYMBOL(clk_get_rate);
 
+void clk_put(struct clk *clk)
+{
+	if (clk->put)
+		clk->put(clk);
+}
+EXPORT_SYMBOL(clk_put);
+
 long clk_round_rate(struct clk *clk, unsigned long rate)
 {
-	if (clk_functions.clk_round_rate)
-		return clk_functions.clk_round_rate(clk, rate);
+	if (clk->round_rate)
+		return clk->round_rate(clk, rate);
 	return -ENOSYS;
 }
 EXPORT_SYMBOL(clk_round_rate);
 
 int clk_set_rate(struct clk *clk, unsigned long rate)
 {
-	if (clk_functions.clk_set_rate)
-		return clk_functions.clk_set_rate(clk, rate);
+	if (clk->set_rate)
+		return clk->set_rate(clk, rate);
 	return -ENOSYS;
 }
 EXPORT_SYMBOL(clk_set_rate);
 
-struct clk *clk_get_parent(struct clk *clk)
-{
-	if (clk_functions.clk_get_parent)
-		return clk_functions.clk_get_parent(clk);
-	return ERR_PTR(-ENOSYS);
-}
-EXPORT_SYMBOL(clk_get_parent);
-
 int clk_set_parent(struct clk *clk, struct clk *parent)
 {
-	if (clk_functions.clk_set_parent)
-		return clk_functions.clk_set_parent(clk, parent);
+	if (clk->set_parent)
+		return clk->set_parent(clk, parent);
 	return -ENOSYS;
 }
 EXPORT_SYMBOL(clk_set_parent);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+	if (clk->get_parent)
+		return clk->get_parent(clk);
+	return ERR_PTR(-ENOSYS);
+}
+EXPORT_SYMBOL(clk_get_parent);
Index: linux-work/arch/powerpc/include/asm/clk.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-work/arch/powerpc/include/asm/clk.h	2009-08-18 17:38:08.000000000 +1000
@@ -0,0 +1,61 @@
+/*
+ * Clock infrastructure for PowerPC platform
+ */
+#ifndef __ASM_POWERPC_CLK_H
+#define __ASM_POWERPC_CLK_H
+
+struct device_node;
+
+/* The definition of struct clk for arch/powerpc is global, it's
+ * expected that clock providers generate "subclasses" embedding
+ * struct clk
+ */
+struct clk {
+	int		(*enable)(struct clk *);
+	void		(*disable)(struct clk *);
+	unsigned long	(*get_rate)(struct clk *);
+	void		(*put)(struct clk *);
+	long		(*round_rate)(struct clk *, unsigned long);
+	int		(*set_rate)(struct clk *, unsigned long);
+	int		(*set_parent)(struct clk *, struct clk *);
+	struct clk*	(*get_parent)(struct clk *);
+};
+
+/* The simple clock is exposed here for implementations that want
+ * to re-use it in case they don't need anything else
+ */
+struct clk_simple {
+	struct clk	clk;
+	unsigned long	rate;
+};
+#define	to_clk_simple(n) container_of(n, struct clk_simple, clk)
+
+
+/**
+ * clk_add_provier - Attach a clock provider to a clock source device node
+ * @node: device node of the clock source
+ * @clk_src_get: function pointer called to obtain a struct clk
+ * @data: arbitrary data passed back to clk_src_get() when called
+ *
+ * This will attach the clk_src_get() function to a given device_node,
+ * that function will then be called whenever a drivers does a clk_get()
+ * and that driver's clock-map references that clock source node.
+ */
+extern int clk_add_provider(struct device_node *np,
+			    struct clk *(*clk_src_get)(struct device_node *np,
+						       const char *output_id,
+						       void *data),
+			    void *data);
+/**
+ * clk_del_provier - Remove a clock provider from a clock source device node
+ * @node: device node of the clock source
+ * @clk_src_get: function pointer used in clk_add_provider()
+ * @data: data used in clk_add_provider()
+ */
+extern void clk_del_provider(struct device_node *np,
+			     struct clk *(*clk_src_get)(struct device_node *np,
+							const char *output_id,
+							void *data),
+			     void *data);
+
+#endif /* __ASM_POWERPC_CLK_H */
Index: linux-work/arch/powerpc/include/asm/machdep.h
===================================================================
--- linux-work.orig/arch/powerpc/include/asm/machdep.h	2009-08-18 17:36:53.000000000 +1000
+++ linux-work/arch/powerpc/include/asm/machdep.h	2009-08-18 17:38:08.000000000 +1000
@@ -27,6 +27,8 @@ struct iommu_table;
 struct rtc_time;
 struct file;
 struct pci_controller;
+struct clk;
+struct device;
 #ifdef CONFIG_KEXEC
 struct kimage;
 #endif
@@ -266,7 +268,11 @@ struct machdep_calls {
 	 */
 	void (*suspend_disable_irqs)(void);
 	void (*suspend_enable_irqs)(void);
-#endif
+#endif /* CONFIG_SUSPEND */
+
+#ifdef CONFIG_PPC_CLOCK
+	struct clk *(*clk_get)(struct device *dev, const char *id);
+#endif /* CONFIG_PPC_CLOCK */
 };
 
 extern void e500_idle(void);
Index: linux-work/arch/powerpc/platforms/512x/clock.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/512x/clock.c	2009-08-18 17:33:15.000000000 +1000
+++ linux-work/arch/powerpc/platforms/512x/clock.c	2009-08-18 17:38:30.000000000 +1000
@@ -25,7 +25,7 @@
 
 #include <linux/of_platform.h>
 #include <asm/mpc5xxx.h>
-#include <asm/clk_interface.h>
+#include <asm/clk.h>
 
 #undef CLK_DEBUG
 
@@ -34,25 +34,28 @@ static int clocks_initialized;
 #define CLK_HAS_RATE	0x1	/* has rate in MHz */
 #define CLK_HAS_CTRL	0x2	/* has control reg and bit */
 
-struct clk {
+struct mpc512x_clk {
+	struct clk 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;
+	void (*calc) (struct mpc512x_clk *);
+	struct mpc512x_clk *parent;
 	int reg, bit;		/* CLK_HAS_CTRL */
 	int div_shift;		/* only used by generic_div_clk_calc */
 };
+#define	to_mpc512x_clk(n) container_of(n, struct mpc512x_clk, clk)
 
 static LIST_HEAD(clocks);
 static DEFINE_MUTEX(clocks_mutex);
 
 static struct clk *mpc5121_clk_get(struct device *dev, const char *id)
 {
-	struct clk *p, *clk = ERR_PTR(-ENOENT);
+	struct clk *clk = ERR_PTR(-ENOENT);
+	struct mpc512x_clk *p;
 	int dev_match = 0;
 	int id_match = 0;
 
@@ -66,7 +69,7 @@ static struct clk *mpc5121_clk_get(struc
 		if (strcmp(id, p->name) == 0)
 			id_match++;
 		if ((dev_match || id_match) && try_module_get(p->owner)) {
-			clk = p;
+			clk = &p->clk;
 			break;
 		}
 	}
@@ -78,7 +81,7 @@ static struct clk *mpc5121_clk_get(struc
 #ifdef CLK_DEBUG
 static void dump_clocks(void)
 {
-	struct clk *p;
+	struct mpc512x_clk *p;
 
 	mutex_lock(&clocks_mutex);
 	printk(KERN_INFO "CLOCKS:\n");
@@ -101,7 +104,9 @@ static void dump_clocks(void)
 
 static void mpc5121_clk_put(struct clk *clk)
 {
-	module_put(clk->owner);
+	struct mpc512x_clk *mpclk = to_mpc512x_clk(clk);
+
+	module_put(mpclk->owner);
 }
 
 #define NRPSC 12
@@ -123,31 +128,35 @@ struct mpc512x_clockctl __iomem *clockct
 
 static int mpc5121_clk_enable(struct clk *clk)
 {
+	struct mpc512x_clk *mpclk = to_mpc512x_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);
+	if (mpclk->flags & CLK_HAS_CTRL) {
+		mask = in_be32(&clockctl->sccr[mpclk->reg]);
+		mask |= 1 << mpclk->bit;
+		out_be32(&clockctl->sccr[mpclk->reg], mask);
 	}
 	return 0;
 }
 
 static void mpc5121_clk_disable(struct clk *clk)
 {
+	struct mpc512x_clk *mpclk = to_mpc512x_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);
+	if (mpclk->flags & CLK_HAS_CTRL) {
+		mask = in_be32(&clockctl->sccr[mpclk->reg]);
+		mask &= ~(1 << mpclk->bit);
+		out_be32(&clockctl->sccr[mpclk->reg], mask);
 	}
 }
 
 static unsigned long mpc5121_clk_get_rate(struct clk *clk)
 {
-	if (clk->flags & CLK_HAS_RATE)
-		return clk->rate;
+	struct mpc512x_clk *mpclk = to_mpc512x_clk(clk);
+
+	if (mpclk->flags & CLK_HAS_RATE)
+		return mpclk->rate;
 	else
 		return 0;
 }
@@ -162,11 +171,21 @@ static int mpc5121_clk_set_rate(struct c
 	return 0;
 }
 
-static int clk_register(struct clk *clk)
+static int clk_register(struct mpc512x_clk *mpclk)
 {
+	mpclk.clk.enable	= mpc5121_clk_enable;
+	mpclk.clk.disable	= mpc5121_clk_disable;
+	mpclk.clk.get_rate	= mpc5121_clk_get_rate;
+	mpclk.clk.put		= mpc5121_clk_put;
+	mpclk.clk.round_rate	= mpc5121_clk_round_rate;
+	mpclk.clk.set_rate	= mpc5121_clk_set_rate;
+	mpclk.clk.set_paqrent	= NULL;
+	mpclk.clk.get_parent	= NULL;
+
 	mutex_lock(&clocks_mutex);
-	list_add(&clk->node, &clocks);
+	list_add(&mpclk->node, &clocks);
 	mutex_unlock(&clocks_mutex);
+
 	return 0;
 }
 
@@ -250,7 +269,7 @@ static unsigned long devtree_getfreq(cha
 	return val;
 }
 
-static void ref_clk_calc(struct clk *clk)
+static void ref_clk_calc(struct mpc512x_clk *mpclk)
 {
 	unsigned long rate;
 
@@ -260,26 +279,26 @@ static void ref_clk_calc(struct clk *clk
 		clk->rate = 0;
 		return;
 	}
-	clk->rate = ips_to_ref(rate);
+	mpclk->rate = ips_to_ref(rate);
 }
 
-static struct clk ref_clk = {
+static struct mpc512x_clk ref_clk = {
 	.name = "ref_clk",
 	.calc = ref_clk_calc,
 };
 
 
-static void sys_clk_calc(struct clk *clk)
+static void sys_clk_calc(struct mpc512x_clk *clk)
 {
 	clk->rate = ref_to_sys(ref_clk.rate);
 }
 
-static struct clk sys_clk = {
+static struct mpc512x_clk sys_clk = {
 	.name = "sys_clk",
 	.calc = sys_clk_calc,
 };
 
-static void diu_clk_calc(struct clk *clk)
+static void diu_clk_calc(struct mpc512x_clk *clk)
 {
 	int diudiv_x_2 = clockctl->scfr1 & 0xff;
 	unsigned long rate;
@@ -292,30 +311,30 @@ static void diu_clk_calc(struct clk *clk
 	clk->rate = rate;
 }
 
-static void half_clk_calc(struct clk *clk)
+static void half_clk_calc(struct mpc512x_clk *clk)
 {
 	clk->rate = clk->parent->rate / 2;
 }
 
-static void generic_div_clk_calc(struct clk *clk)
+static void generic_div_clk_calc(struct mpc512x_clk *clk)
 {
 	int div = (clockctl->scfr1 >> clk->div_shift) & 0x7;
 
 	clk->rate = clk->parent->rate / div;
 }
 
-static void unity_clk_calc(struct clk *clk)
+static void unity_clk_calc(struct mpc512x_clk *clk)
 {
 	clk->rate = clk->parent->rate;
 }
 
-static struct clk csb_clk = {
+static struct mpc512x_clk csb_clk = {
 	.name = "csb_clk",
 	.calc = half_clk_calc,
 	.parent = &sys_clk,
 };
 
-static void e300_clk_calc(struct clk *clk)
+static void e300_clk_calc(struct mpc512x_clk *clk)
 {
 	int spmf = (clockctl->spmr >> 16) & 0xf;
 	int ratex2 = clk->parent->rate * spmf;
@@ -323,13 +342,13 @@ static void e300_clk_calc(struct clk *cl
 	clk->rate = ratex2 / 2;
 }
 
-static struct clk e300_clk = {
+static struct mpc512x_clk e300_clk = {
 	.name = "e300_clk",
 	.calc = e300_clk_calc,
 	.parent = &csb_clk,
 };
 
-static struct clk ips_clk = {
+static struct mpc512x_clk ips_clk = {
 	.name = "ips_clk",
 	.calc = generic_div_clk_calc,
 	.parent = &csb_clk,
@@ -339,7 +358,7 @@ static struct clk ips_clk = {
 /*
  * Clocks controlled by SCCR1 (.reg = 0)
  */
-static struct clk lpc_clk = {
+static struct mpc512x_clk lpc_clk = {
 	.name = "lpc_clk",
 	.flags = CLK_HAS_CTRL,
 	.reg = 0,
@@ -349,7 +368,7 @@ static struct clk lpc_clk = {
 	.div_shift = 11,
 };
 
-static struct clk nfc_clk = {
+static struct mpc512x_clk nfc_clk = {
 	.name = "nfc_clk",
 	.flags = CLK_HAS_CTRL,
 	.reg = 0,
@@ -359,7 +378,7 @@ static struct clk nfc_clk = {
 	.div_shift = 8,
 };
 
-static struct clk pata_clk = {
+static struct mpc512x_clk pata_clk = {
 	.name = "pata_clk",
 	.flags = CLK_HAS_CTRL,
 	.reg = 0,
@@ -373,7 +392,7 @@ static struct clk pata_clk = {
  * are setup elsewhere
  */
 
-static struct clk sata_clk = {
+static struct mpc512x_clk sata_clk = {
 	.name = "sata_clk",
 	.flags = CLK_HAS_CTRL,
 	.reg = 0,
@@ -382,7 +401,7 @@ static struct clk sata_clk = {
 	.parent = &ips_clk,
 };
 
-static struct clk fec_clk = {
+static struct mpc512x_clk fec_clk = {
 	.name = "fec_clk",
 	.flags = CLK_HAS_CTRL,
 	.reg = 0,
@@ -391,7 +410,7 @@ static struct clk fec_clk = {
 	.parent = &ips_clk,
 };
 
-static struct clk pci_clk = {
+static struct mpc512x_clk pci_clk = {
 	.name = "pci_clk",
 	.flags = CLK_HAS_CTRL,
 	.reg = 0,
@@ -404,7 +423,7 @@ static struct clk pci_clk = {
 /*
  * Clocks controlled by SCCR2 (.reg = 1)
  */
-static struct clk diu_clk = {
+static struct mpc512x_clk diu_clk = {
 	.name = "diu_clk",
 	.flags = CLK_HAS_CTRL,
 	.reg = 1,
@@ -412,7 +431,7 @@ static struct clk diu_clk = {
 	.calc = diu_clk_calc,
 };
 
-static struct clk axe_clk = {
+static struct mpc512x_clk axe_clk = {
 	.name = "axe_clk",
 	.flags = CLK_HAS_CTRL,
 	.reg = 1,
@@ -421,7 +440,7 @@ static struct clk axe_clk = {
 	.parent = &csb_clk,
 };
 
-static struct clk usb1_clk = {
+static struct mpc512x_clk usb1_clk = {
 	.name = "usb1_clk",
 	.flags = CLK_HAS_CTRL,
 	.reg = 1,
@@ -430,7 +449,7 @@ static struct clk usb1_clk = {
 	.parent = &csb_clk,
 };
 
-static struct clk usb2_clk = {
+static struct mpc512x_clk usb2_clk = {
 	.name = "usb2_clk",
 	.flags = CLK_HAS_CTRL,
 	.reg = 1,
@@ -439,7 +458,7 @@ static struct clk usb2_clk = {
 	.parent = &csb_clk,
 };
 
-static struct clk i2c_clk = {
+static struct mpc512x_clk i2c_clk = {
 	.name = "i2c_clk",
 	.flags = CLK_HAS_CTRL,
 	.reg = 1,
@@ -448,7 +467,7 @@ static struct clk i2c_clk = {
 	.parent = &ips_clk,
 };
 
-static struct clk mscan_clk = {
+static struct mpc512x_clk mscan_clk = {
 	.name = "mscan_clk",
 	.flags = CLK_HAS_CTRL,
 	.reg = 1,
@@ -457,7 +476,7 @@ static struct clk mscan_clk = {
 	.parent = &ips_clk,
 };
 
-static struct clk sdhc_clk = {
+static struct mpc512x_clk sdhc_clk = {
 	.name = "sdhc_clk",
 	.flags = CLK_HAS_CTRL,
 	.reg = 1,
@@ -466,7 +485,7 @@ static struct clk sdhc_clk = {
 	.parent = &ips_clk,
 };
 
-static struct clk mbx_bus_clk = {
+static struct mpc512x_clk mbx_bus_clk = {
 	.name = "mbx_bus_clk",
 	.flags = CLK_HAS_CTRL,
 	.reg = 1,
@@ -475,7 +494,7 @@ static struct clk mbx_bus_clk = {
 	.parent = &csb_clk,
 };
 
-static struct clk mbx_clk = {
+static struct mpc512x_clk mbx_clk = {
 	.name = "mbx_clk",
 	.flags = CLK_HAS_CTRL,
 	.reg = 1,
@@ -484,7 +503,7 @@ static struct clk mbx_clk = {
 	.parent = &csb_clk,
 };
 
-static struct clk mbx_3d_clk = {
+static struct mpc512x_clk mbx_3d_clk = {
 	.name = "mbx_3d_clk",
 	.flags = CLK_HAS_CTRL,
 	.reg = 1,
@@ -494,44 +513,44 @@ static struct clk mbx_3d_clk = {
 	.div_shift = 14,
 };
 
-static void psc_mclk_in_calc(struct clk *clk)
+static void psc_mclk_in_calc(struct mpc512x_clk *clk)
 {
 	clk->rate = devtree_getfreq("psc_mclk_in");
 	if (!clk->rate)
 		clk->rate = 25000000;
 }
 
-static struct clk psc_mclk_in = {
+static struct mpc512x_clk psc_mclk_in = {
 	.name = "psc_mclk_in",
 	.calc = psc_mclk_in_calc,
 };
 
-static struct clk spdif_txclk = {
+static struct mpc512x_clk spdif_txclk = {
 	.name = "spdif_txclk",
 	.flags = CLK_HAS_CTRL,
 	.reg = 1,
 	.bit = 23,
 };
 
-static struct clk spdif_rxclk = {
+static struct mpc512x_clk spdif_rxclk = {
 	.name = "spdif_rxclk",
 	.flags = CLK_HAS_CTRL,
 	.reg = 1,
 	.bit = 23,
 };
 
-static void ac97_clk_calc(struct clk *clk)
+static void ac97_clk_calc(struct mpc512x_clk *clk)
 {
 	/* ac97 bit clock is always 24.567 MHz */
 	clk->rate = 24567000;
 }
 
-static struct clk ac97_clk = {
+static struct mpc512x_clk ac97_clk = {
 	.name = "ac97_clk_in",
 	.calc = ac97_clk_calc,
 };
 
-struct clk *rate_clks[] = {
+struct mpc512x_clk *rate_clks[] = {
 	&ref_clk,
 	&sys_clk,
 	&diu_clk,
@@ -560,7 +579,7 @@ struct clk *rate_clks[] = {
 	NULL
 };
 
-static void rate_clk_init(struct clk *clk)
+static void rate_clk_init(struct mpc512x_clk *clk)
 {
 	if (clk->calc) {
 		clk->calc(clk);
@@ -575,7 +594,7 @@ static void rate_clk_init(struct clk *cl
 
 static void rate_clks_init(void)
 {
-	struct clk **cpp, *clk;
+	struct mpc512x_clk **cpp, *clk;
 
 	cpp = rate_clks;
 	while ((clk = *cpp++))
@@ -586,16 +605,16 @@ static void rate_clks_init(void)
  * There are two clk enable registers with 32 enable bits each
  * psc clocks and device clocks are all stored in dev_clks
  */
-struct clk dev_clks[2][32];
+struct mpc512x_clk dev_clks[2][32];
 
 /*
  * Given a psc number return the dev_clk
  * associated with it
  */
-static struct clk *psc_dev_clk(int pscnum)
+static struct mpc512x_clk *psc_dev_clk(int pscnum)
 {
 	int reg, bit;
-	struct clk *clk;
+	struct mpc512x_clk *clk;
 
 	reg = 0;
 	bit = 27 - pscnum;
@@ -609,7 +628,7 @@ static struct clk *psc_dev_clk(int pscnu
 /*
  * PSC clock rate calculation
  */
-static void psc_calc_rate(struct clk *clk, int pscnum, struct device_node *np)
+static void psc_calc_rate(struct mpc512x_clk *clk, int pscnum, struct device_node *np)
 {
 	unsigned long mclk_src = sys_clk.rate;
 	unsigned long mclk_div;
@@ -666,7 +685,7 @@ static void psc_clks_init(void)
 		cell_index = of_get_property(np, "cell-index", NULL);
 		if (cell_index) {
 			int pscnum = *cell_index;
-			struct clk *clk = psc_dev_clk(pscnum);
+			struct mpc512x_clk *clk = psc_dev_clk(pscnum);
 
 			clk->flags = CLK_HAS_RATE | CLK_HAS_CTRL;
 			ofdev = of_find_device_by_node(np);
@@ -686,18 +705,6 @@ static void psc_clks_init(void)
 	}
 }
 
-static struct clk_interface mpc5121_clk_functions = {
-	.clk_get		= mpc5121_clk_get,
-	.clk_enable		= mpc5121_clk_enable,
-	.clk_disable		= mpc5121_clk_disable,
-	.clk_get_rate		= mpc5121_clk_get_rate,
-	.clk_put		= mpc5121_clk_put,
-	.clk_round_rate		= mpc5121_clk_round_rate,
-	.clk_set_rate		= mpc5121_clk_set_rate,
-	.clk_set_parent		= NULL,
-	.clk_get_parent		= NULL,
-};
-
 static int
 mpc5121_clk_init(void)
 {
@@ -721,7 +728,7 @@ mpc5121_clk_init(void)
 	/*iounmap(clockctl); */
 	DEBUG_CLK_DUMP();
 	clocks_initialized++;
-	clk_functions = mpc5121_clk_functions;
+	ppc_md.clk_get = mpc5121_clk_get;
 	return 0;
 }
 
