[ARM] 3866/1: AT91 clock update

This patch makes the AT91 clock.c support processor-generic (AT91RM9200
and AT91SAM9xxx).  The clocks supported by a particular AT91 processor
are defined in the processor-specific file and are registered with
clock.c at startup.

Signed-off-by: Andrew Victor <andrew@sanpeople.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
diff --git a/arch/arm/mach-at91rm9200/clock.c b/arch/arm/mach-at91rm9200/clock.c
index 5b78922..a43b061 100644
--- a/arch/arm/mach-at91rm9200/clock.c
+++ b/arch/arm/mach-at91rm9200/clock.c
@@ -29,7 +29,7 @@
 
 #include <asm/hardware.h>
 
-#include "generic.h"
+#include "clock.h"
 
 
 /*
@@ -38,23 +38,15 @@
  * PLLB be used at other rates (on boards that don't need USB), etc.
  */
 
-struct clk {
-	const char	*name;		/* unique clock name */
-	const char	*function;	/* function of the clock */
-	struct device	*dev;		/* device associated with function */
-	unsigned long	rate_hz;
-	struct clk	*parent;
-	u32		pmc_mask;
-	void		(*mode)(struct clk *, int);
-	unsigned	id:2;		/* PCK0..3, or 32k/main/a/b */
-	unsigned	primary:1;
-	unsigned	pll:1;
-	unsigned	programmable:1;
-	u16		users;
-};
+#define clk_is_primary(x)	((x)->type & CLK_TYPE_PRIMARY)
+#define clk_is_programmable(x)	((x)->type & CLK_TYPE_PROGRAMMABLE)
+#define clk_is_peripheral(x)	((x)->type & CLK_TYPE_PERIPHERAL)
 
-static spinlock_t	clk_lock;
-static u32		at91_pllb_usb_init;
+
+static LIST_HEAD(clocks);
+static DEFINE_SPINLOCK(clk_lock);
+
+static u32 at91_pllb_usb_init;
 
 /*
  * Four primary clock sources:  two crystal oscillators (32K, main), and
@@ -67,21 +59,20 @@
 	.rate_hz	= AT91_SLOW_CLOCK,
 	.users		= 1,		/* always on */
 	.id		= 0,
-	.primary	= 1,
+	.type		= CLK_TYPE_PRIMARY,
 };
 static struct clk main_clk = {
 	.name		= "main",
 	.pmc_mask	= AT91_PMC_MOSCS,	/* in PMC_SR */
 	.id		= 1,
-	.primary	= 1,
+	.type		= CLK_TYPE_PRIMARY,
 };
 static struct clk plla = {
 	.name		= "plla",
 	.parent		= &main_clk,
 	.pmc_mask	= AT91_PMC_LOCKA,	/* in PMC_SR */
 	.id		= 2,
-	.primary	= 1,
-	.pll		= 1,
+	.type		= CLK_TYPE_PRIMARY | CLK_TYPE_PLL,
 };
 
 static void pllb_mode(struct clk *clk, int is_on)
@@ -94,6 +85,7 @@
 	} else
 		value = 0;
 
+	// REVISIT: Add work-around for AT91RM9200 Errata #26 ?
 	at91_sys_write(AT91_CKGR_PLLBR, value);
 
 	do {
@@ -107,8 +99,7 @@
 	.pmc_mask	= AT91_PMC_LOCKB,	/* in PMC_SR */
 	.mode		= pllb_mode,
 	.id		= 3,
-	.primary	= 1,
-	.pll		= 1,
+	.type		= CLK_TYPE_PRIMARY | CLK_TYPE_PLL,
 };
 
 static void pmc_sys_mode(struct clk *clk, int is_on)
@@ -133,41 +124,6 @@
 	.mode		= pmc_sys_mode,
 };
 
-#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
-/*
- * The four programmable clocks can be parented by any primary clock.
- * You must configure pin multiplexing to bring these signals out.
- */
-static struct clk pck0 = {
-	.name		= "pck0",
-	.pmc_mask	= AT91_PMC_PCK0,
-	.mode		= pmc_sys_mode,
-	.programmable	= 1,
-	.id		= 0,
-};
-static struct clk pck1 = {
-	.name		= "pck1",
-	.pmc_mask	= AT91_PMC_PCK1,
-	.mode		= pmc_sys_mode,
-	.programmable	= 1,
-	.id		= 1,
-};
-static struct clk pck2 = {
-	.name		= "pck2",
-	.pmc_mask	= AT91_PMC_PCK2,
-	.mode		= pmc_sys_mode,
-	.programmable	= 1,
-	.id		= 2,
-};
-static struct clk pck3 = {
-	.name		= "pck3",
-	.pmc_mask	= AT91_PMC_PCK3,
-	.mode		= pmc_sys_mode,
-	.programmable	= 1,
-	.id		= 3,
-};
-#endif	/* CONFIG_AT91_PROGRAMMABLE_CLOCKS */
-
 
 /*
  * The master clock is divided from the CPU clock (by 1-4).  It's used for
@@ -187,131 +143,21 @@
 		at91_sys_write(AT91_PMC_PCDR, clk->pmc_mask);
 }
 
-static struct clk udc_clk = {
-	.name		= "udc_clk",
-	.parent		= &mck,
-	.pmc_mask	= 1 << AT91RM9200_ID_UDP,
-	.mode		= pmc_periph_mode,
-};
-static struct clk ohci_clk = {
-	.name		= "ohci_clk",
-	.parent		= &mck,
-	.pmc_mask	= 1 << AT91RM9200_ID_UHP,
-	.mode		= pmc_periph_mode,
-};
-static struct clk ether_clk = {
-	.name		= "ether_clk",
-	.parent		= &mck,
-	.pmc_mask	= 1 << AT91RM9200_ID_EMAC,
-	.mode		= pmc_periph_mode,
-};
-static struct clk mmc_clk = {
-	.name		= "mci_clk",
-	.parent		= &mck,
-	.pmc_mask	= 1 << AT91RM9200_ID_MCI,
-	.mode		= pmc_periph_mode,
-};
-static struct clk twi_clk = {
-	.name		= "twi_clk",
-	.parent		= &mck,
-	.pmc_mask	= 1 << AT91RM9200_ID_TWI,
-	.mode		= pmc_periph_mode,
-};
-static struct clk usart0_clk = {
-	.name		= "usart0_clk",
-	.parent		= &mck,
-	.pmc_mask	= 1 << AT91RM9200_ID_US0,
-	.mode		= pmc_periph_mode,
-};
-static struct clk usart1_clk = {
-	.name		= "usart1_clk",
-	.parent		= &mck,
-	.pmc_mask	= 1 << AT91RM9200_ID_US1,
-	.mode		= pmc_periph_mode,
-};
-static struct clk usart2_clk = {
-	.name		= "usart2_clk",
-	.parent		= &mck,
-	.pmc_mask	= 1 << AT91RM9200_ID_US2,
-	.mode		= pmc_periph_mode,
-};
-static struct clk usart3_clk = {
-	.name		= "usart3_clk",
-	.parent		= &mck,
-	.pmc_mask	= 1 << AT91RM9200_ID_US3,
-	.mode		= pmc_periph_mode,
-};
-static struct clk spi_clk = {
-	.name		= "spi0_clk",
-	.parent		= &mck,
-	.pmc_mask	= 1 << AT91RM9200_ID_SPI,
-	.mode		= pmc_periph_mode,
-};
-static struct clk pioA_clk = {
-	.name		= "pioA_clk",
-	.parent		= &mck,
-	.pmc_mask	= 1 << AT91RM9200_ID_PIOA,
-	.mode		= pmc_periph_mode,
-};
-static struct clk pioB_clk = {
-	.name		= "pioB_clk",
-	.parent		= &mck,
-	.pmc_mask	= 1 << AT91RM9200_ID_PIOB,
-	.mode		= pmc_periph_mode,
-};
-static struct clk pioC_clk = {
-	.name		= "pioC_clk",
-	.parent		= &mck,
-	.pmc_mask	= 1 << AT91RM9200_ID_PIOC,
-	.mode		= pmc_periph_mode,
-};
-static struct clk pioD_clk = {
-	.name		= "pioD_clk",
-	.parent		= &mck,
-	.pmc_mask	= 1 << AT91RM9200_ID_PIOD,
-	.mode		= pmc_periph_mode,
-};
+static struct clk __init *at91_css_to_clk(unsigned long css)
+{
+	switch (css) {
+		case AT91_PMC_CSS_SLOW:
+			return &clk32k;
+		case AT91_PMC_CSS_MAIN:
+			return &main_clk;
+		case AT91_PMC_CSS_PLLA:
+			return &plla;
+		case AT91_PMC_CSS_PLLB:
+			return &pllb;
+	}
 
-static struct clk *const clock_list[] = {
-	/* four primary clocks -- MUST BE FIRST! */
-	&clk32k,
-	&main_clk,
-	&plla,
-	&pllb,
-
-	/* PLLB children (USB) */
-	&udpck,
-	&uhpck,
-
-#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
-	/* programmable clocks */
-	&pck0,
-	&pck1,
-	&pck2,
-	&pck3,
-#endif	/* CONFIG_AT91_PROGRAMMABLE_CLOCKS */
-
-	/* MCK and peripherals */
-	&mck,
-	&usart0_clk,
-	&usart1_clk,
-	&usart2_clk,
-	&usart3_clk,
-	&mmc_clk,
-	&udc_clk,
-	&twi_clk,
-	&spi_clk,
-	&pioA_clk,
-	&pioB_clk,
-	&pioC_clk,
-	&pioD_clk,
-	// ssc0..ssc2
-	// tc0..tc5
-	// irq0..irq6
-	&ohci_clk,
-	&ether_clk,
-};
-
+	return NULL;
+}
 
 /*
  * Associate a particular clock with a function (eg, "uart") and device.
@@ -329,14 +175,12 @@
 	clk->dev = dev;
 }
 
-/* clocks are all static for now; no refcounting necessary */
+/* clocks cannot be de-registered no refcounting necessary */
 struct clk *clk_get(struct device *dev, const char *id)
 {
-	int i;
+	struct clk *clk;
 
-	for (i = 0; i < ARRAY_SIZE(clock_list); i++) {
-		struct clk *clk = clock_list[i];
-
+	list_for_each_entry(clk, &clocks, node) {
 		if (strcmp(id, clk->name) == 0)
 			return clk;
 		if (clk->function && (dev == clk->dev) && strcmp(id, clk->function) == 0)
@@ -424,7 +268,7 @@
 	unsigned	prescale;
 	unsigned long	actual;
 
-	if (!clk->programmable)
+	if (!clk_is_programmable(clk))
 		return -EINVAL;
 	spin_lock_irqsave(&clk_lock, flags);
 
@@ -446,7 +290,7 @@
 	unsigned	prescale;
 	unsigned long	actual;
 
-	if (!clk->programmable)
+	if (!clk_is_programmable(clk))
 		return -EINVAL;
 	if (clk->users)
 		return -EBUSY;
@@ -484,7 +328,7 @@
 
 	if (clk->users)
 		return -EBUSY;
-	if (!parent->primary || !clk->programmable)
+	if (!clk_is_primary(parent) || !clk_is_programmable(clk))
 		return -EINVAL;
 	spin_lock_irqsave(&clk_lock, flags);
 
@@ -497,6 +341,18 @@
 }
 EXPORT_SYMBOL(clk_set_parent);
 
+/* establish PCK0..PCK3 parentage and rate */
+static void init_programmable_clock(struct clk *clk)
+{
+	struct clk	*parent;
+	u32		pckr;
+
+	pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
+	parent = at91_css_to_clk(pckr & AT91_PMC_CSS);
+	clk->parent = parent;
+	clk->rate_hz = parent->rate_hz / (1 << ((pckr >> 2) & 3));
+}
+
 #endif	/* CONFIG_AT91_PROGRAMMABLE_CLOCKS */
 
 /*------------------------------------------------------------------------*/
@@ -506,6 +362,7 @@
 static int at91_clk_show(struct seq_file *s, void *unused)
 {
 	u32		scsr, pcsr, sr;
+	struct clk	*clk;
 	unsigned	i;
 
 	seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR));
@@ -523,9 +380,8 @@
 
 	seq_printf(s, "\n");
 
-	for (i = 0; i < ARRAY_SIZE(clock_list); i++) {
-		char		*state;
-		struct clk	*clk = clock_list[i];
+	list_for_each_entry(clk, &clocks, node) {
+		char	*state;
 
 		if (clk->mode == pmc_sys_mode)
 			state = (scsr & clk->pmc_mask) ? "on" : "off";
@@ -570,6 +426,28 @@
 
 /*------------------------------------------------------------------------*/
 
+/* Register a new clock */
+int __init clk_register(struct clk *clk)
+{
+	if (clk_is_peripheral(clk)) {
+		clk->parent = &mck;
+		clk->mode = pmc_periph_mode;
+		list_add_tail(&clk->node, &clocks);
+	}
+#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
+	else if (clk_is_programmable(clk)) {
+		clk->mode = pmc_sys_mode;
+		init_programmable_clock(clk);
+		list_add_tail(&clk->node, &clocks);
+	}
+#endif
+
+	return 0;
+}
+
+
+/*------------------------------------------------------------------------*/
+
 static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg)
 {
 	unsigned mul, div;
@@ -640,20 +518,17 @@
 	return 0;
 }
 
-
 /*
  * Several unused clocks may be active.  Turn them off.
  */
-static void at91_periphclk_reset(void)
+static void __init at91_periphclk_reset(void)
 {
 	unsigned long reg;
-	int i;
+	struct clk *clk;
 
 	reg = at91_sys_read(AT91_PMC_PCSR);
 
-	for (i = 0; i < ARRAY_SIZE(clock_list); i++) {
-		struct clk	*clk = clock_list[i];
-
+	list_for_each_entry(clk, &clocks, node) {
 		if (clk->mode != pmc_periph_mode)
 			continue;
 
@@ -664,11 +539,25 @@
 	at91_sys_write(AT91_PMC_PCDR, reg);
 }
 
+static struct clk *const standard_pmc_clocks[] __initdata = {
+	/* four primary clocks */
+	&clk32k,
+	&main_clk,
+	&plla,
+	&pllb,
+
+	/* PLLB children (USB) */
+	&udpck,
+	&uhpck,
+
+	/* MCK */
+	&mck
+};
+
 int __init at91_clock_init(unsigned long main_clock)
 {
 	unsigned tmp, freq, mckr;
-
-	spin_lock_init(&clk_lock);
+	int i;
 
 	/*
 	 * When the bootloader initialized the main oscillator correctly,
@@ -709,11 +598,15 @@
 	 * For now, assume this parentage won't change.
 	 */
 	mckr = at91_sys_read(AT91_PMC_MCKR);
-	mck.parent = clock_list[mckr & AT91_PMC_CSS];
+	mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS);
 	freq = mck.parent->rate_hz;
 	freq /= (1 << ((mckr >> 2) & 3));		/* prescale */
 	mck.rate_hz = freq / (1 + ((mckr >> 8) & 3));	/* mdiv */
 
+	/* Register the PMC's standard clocks */
+	for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++)
+		list_add_tail(&standard_pmc_clocks[i]->node, &clocks);
+
 	/* MCK and CPU clock are "always on" */
 	clk_enable(&mck);
 
@@ -722,35 +615,8 @@
 		(unsigned) main_clock / 1000000,
 		((unsigned) main_clock % 1000000) / 1000);
 
-#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
-	/* establish PCK0..PCK3 parentage */
-	for (tmp = 0; tmp < ARRAY_SIZE(clock_list); tmp++) {
-		struct clk	*clk = clock_list[tmp], *parent;
-		u32		pckr;
-
-		if (!clk->programmable)
-			continue;
-
-		pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
-		parent = clock_list[pckr & AT91_PMC_CSS];
-		clk->parent = parent;
-		clk->rate_hz = parent->rate_hz / (1 << ((pckr >> 2) & 3));
-
-		if (clk->users == 0) {
-			/* not being used, so switch it off */
-			at91_sys_write(AT91_PMC_SCDR, clk->pmc_mask);
-		}
-	}
-#else
 	/* disable all programmable clocks */
 	at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK0 | AT91_PMC_PCK1 | AT91_PMC_PCK2 | AT91_PMC_PCK3);
-#endif
-
-	/* enable the PIO clocks */
-	clk_enable(&pioA_clk);
-	clk_enable(&pioB_clk);
-	clk_enable(&pioC_clk);
-	clk_enable(&pioD_clk);
 
 	/* disable all other unused peripheral clocks */
 	at91_periphclk_reset();