[SPARC]: Convert clock drivers to of_driver framework.

Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
index 7dadcdb..9631e8f 100644
--- a/arch/sparc/kernel/time.c
+++ b/arch/sparc/kernel/time.c
@@ -42,6 +42,7 @@
 #include <asm/sun4paddr.h>
 #include <asm/page.h>
 #include <asm/pcic.h>
+#include <asm/of_device.h>
 
 extern unsigned long wall_jiffies;
 
@@ -273,83 +274,31 @@
 #endif
 }
 
-/* Probe for the mostek real time clock chip. */
-static __inline__ void clock_probe(void)
+static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match)
 {
-	struct linux_prom_registers clk_reg[2];
-	char model[128];
-	register int node, cpuunit, bootbus;
-	struct resource r;
+	struct device_node *dp = op->node;
+	char *model = of_get_property(dp, "model", NULL);
 
-	cpuunit = bootbus = 0;
-	memset(&r, 0, sizeof(r));
+	if (!model)
+		return -ENODEV;
 
-	/* Determine the correct starting PROM node for the probe. */
-	node = prom_getchild(prom_root_node);
-	switch (sparc_cpu_model) {
-	case sun4c:
-		break;
-	case sun4m:
-		node = prom_getchild(prom_searchsiblings(node, "obio"));
-		break;
-	case sun4d:
-		node = prom_getchild(bootbus = prom_searchsiblings(prom_getchild(cpuunit = prom_searchsiblings(node, "cpu-unit")), "bootbus"));
-		break;
-	default:
-		prom_printf("CLOCK: Unsupported architecture!\n");
-		prom_halt();
-	}
-
-	/* Find the PROM node describing the real time clock. */
-	sp_clock_typ = MSTK_INVALID;
-	node = prom_searchsiblings(node,"eeprom");
-	if (!node) {
-		prom_printf("CLOCK: No clock found!\n");
-		prom_halt();
-	}
-
-	/* Get the model name and setup everything up. */
-	model[0] = '\0';
-	prom_getstring(node, "model", model, sizeof(model));
-	if (strcmp(model, "mk48t02") == 0) {
+	if (!strcmp(model, "mk48t02")) {
 		sp_clock_typ = MSTK48T02;
-		if (prom_getproperty(node, "reg", (char *) clk_reg, sizeof(clk_reg)) == -1) {
-			prom_printf("clock_probe: FAILED!\n");
-			prom_halt();
-		}
-		if (sparc_cpu_model == sun4d)
-			prom_apply_generic_ranges (bootbus, cpuunit, clk_reg, 1);
-		else
-			prom_apply_obio_ranges(clk_reg, 1);
+
 		/* Map the clock register io area read-only */
-		r.flags = clk_reg[0].which_io;
-		r.start = clk_reg[0].phys_addr;
-		mstk48t02_regs = sbus_ioremap(&r, 0,
-		    sizeof(struct mostek48t02), "mk48t02");
+		mstk48t02_regs = of_ioremap(&op->resource[0], 0,
+					    sizeof(struct mostek48t02),
+					    "mk48t02");
 		mstk48t08_regs = NULL;  /* To catch weirdness */
-	} else if (strcmp(model, "mk48t08") == 0) {
+	} else if (!strcmp(model, "mk48t08")) {
 		sp_clock_typ = MSTK48T08;
-		if(prom_getproperty(node, "reg", (char *) clk_reg,
-				    sizeof(clk_reg)) == -1) {
-			prom_printf("clock_probe: FAILED!\n");
-			prom_halt();
-		}
-		if (sparc_cpu_model == sun4d)
-			prom_apply_generic_ranges (bootbus, cpuunit, clk_reg, 1);
-		else
-			prom_apply_obio_ranges(clk_reg, 1);
-		/* Map the clock register io area read-only */
-		/* XXX r/o attribute is somewhere in r.flags */
-		r.flags = clk_reg[0].which_io;
-		r.start = clk_reg[0].phys_addr;
-		mstk48t08_regs = sbus_ioremap(&r, 0,
-		    sizeof(struct mostek48t08), "mk48t08");
+		mstk48t08_regs = of_ioremap(&op->resource[0], 0,
+					    sizeof(struct mostek48t08),
+					    "mk48t08");
 
 		mstk48t02_regs = &mstk48t08_regs->regs;
-	} else {
-		prom_printf("CLOCK: Unknown model name '%s'\n",model);
-		prom_halt();
-	}
+	} else
+		return -ENODEV;
 
 	/* Report a low battery voltage condition. */
 	if (has_low_battery())
@@ -358,6 +307,28 @@
 	/* Kick start the clock if it is completely stopped. */
 	if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP)
 		kick_start_clock();
+
+	return 0;
+}
+
+static struct of_device_id clock_match[] = {
+	{
+		.name = "eeprom",
+	},
+	{},
+};
+
+static struct of_platform_driver clock_driver = {
+	.name		= "clock",
+	.match_table	= clock_match,
+	.probe		= clock_probe,
+};
+
+
+/* Probe for the mostek real time clock chip. */
+static void clock_init(void)
+{
+	of_register_driver(&clock_driver, &of_bus_type);
 }
 
 void __init sbus_time_init(void)
@@ -376,7 +347,7 @@
 	if (ARCH_SUN4)
 		sun4_clock_probe();
 	else
-		clock_probe();
+		clock_init();
 
 	sparc_init_timers(timer_interrupt);
 	
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index 20ca9ec..7b96258 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -307,7 +307,6 @@
 		p->scan_bus(p);
 }
 
-extern void clock_probe(void);
 extern void power_init(void);
 
 static int __init pcibios_init(void)
@@ -320,7 +319,6 @@
 
 	isa_init();
 	ebus_init();
-	clock_probe();
 	power_init();
 
 	return 0;
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c
index 945222e..ef68aa4 100644
--- a/arch/sparc64/kernel/sbus.c
+++ b/arch/sparc64/kernel/sbus.c
@@ -1267,8 +1267,6 @@
 void __init sbus_arch_postinit(void)
 {
 	extern void firetruck_init(void);
-	extern void clock_probe(void);
 
 	firetruck_init();
-	clock_probe();
 }
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index 348b820..540e4b6 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -770,219 +770,37 @@
 	return 1;
 }
 
-static void __init __clock_assign_common(void __iomem *addr, char *model)
+static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match)
 {
-	if (model[5] == '0' && model[6] == '2') {
-		mstk48t02_regs = addr;
-	} else if(model[5] == '0' && model[6] == '8') {
-		mstk48t08_regs = addr;
-		mstk48t02_regs = mstk48t08_regs + MOSTEK_48T08_48T02;
-	} else {
-		mstk48t59_regs = addr;
-		mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
-	}
-}
+	struct device_node *dp = op->node;
+	char *model = of_get_property(dp, "model", NULL);
+	unsigned long size, flags;
+	void __iomem *regs;
 
-static void __init clock_assign_clk_reg(struct linux_prom_registers *clk_reg,
-					char *model)
-{
-	unsigned long addr;
+	if (!model || !clock_model_matches(model))
+		return -ENODEV;
 
-	addr = ((unsigned long) clk_reg[0].phys_addr |
-		(((unsigned long) clk_reg[0].which_io) << 32UL));
+	size = (op->resource[0].end - op->resource[0].start) + 1;
+	regs = of_ioremap(&op->resource[0], 0, size, "clock");
+	if (!regs)
+		return -ENOMEM;
 
-	__clock_assign_common((void __iomem *) addr, model);
-}
-
-static int __init clock_probe_central(void)
-{
-	struct linux_prom_registers clk_reg[2], *pr;
-	struct device_node *dp;
-	char *model;
-
-	if (!central_bus)
-		return 0;
-
-	/* Get Central FHC's prom node.  */
-	dp = central_bus->child->prom_node;
-
-	/* Then get the first child device below it.  */
-	dp = dp->child;
-
-	while (dp) {
-		model = of_get_property(dp, "model", NULL);
-		if (!model || !clock_model_matches(model))
-			goto next_sibling;
-
-		pr = of_get_property(dp, "reg", NULL);
-		memcpy(clk_reg, pr, sizeof(clk_reg));
-
-		apply_fhc_ranges(central_bus->child, clk_reg, 1);
-		apply_central_ranges(central_bus, clk_reg, 1);
-
-		clock_assign_clk_reg(clk_reg, model);
-		return 1;
-
-	next_sibling:
-		dp = dp->sibling;
-	}
-
-	return 0;
-}
-
-#ifdef CONFIG_PCI
-static void __init clock_isa_ebus_assign_regs(struct resource *res, char *model)
-{
 	if (!strcmp(model, "ds1287") ||
 	    !strcmp(model, "m5819") ||
 	    !strcmp(model, "m5819p") ||
 	    !strcmp(model, "m5823")) {
-		ds1287_regs = res->start;
+		ds1287_regs = (unsigned long) regs;
+	} else if (model[5] == '0' && model[6] == '2') {
+		mstk48t02_regs = regs;
+	} else if(model[5] == '0' && model[6] == '8') {
+		mstk48t08_regs = regs;
+		mstk48t02_regs = mstk48t08_regs + MOSTEK_48T08_48T02;
 	} else {
-		mstk48t59_regs = (void __iomem *) res->start;
+		mstk48t59_regs = regs;
 		mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
 	}
-}
 
-static int __init clock_probe_one_ebus_dev(struct linux_ebus_device *edev)
-{
-	struct device_node *dp = edev->prom_node;
-	char *model;
-
-	model = of_get_property(dp, "model", NULL);
-	if (!clock_model_matches(model))
-		return 0;
-
-	clock_isa_ebus_assign_regs(&edev->resource[0], model);
-
-	return 1;
-}
-
-static int __init clock_probe_ebus(void)
-{
-	struct linux_ebus *ebus;
-
-	for_each_ebus(ebus) {
-		struct linux_ebus_device *edev;
-
-		for_each_ebusdev(edev, ebus) {
-			if (clock_probe_one_ebus_dev(edev))
-				return 1;
-		}
-	}
-
-	return 0;
-}
-
-static int __init clock_probe_one_isa_dev(struct sparc_isa_device *idev)
-{
-	struct device_node *dp = idev->prom_node;
-	char *model;
-
-	model = of_get_property(dp, "model", NULL);
-	if (!clock_model_matches(model))
-		return 0;
-
-	clock_isa_ebus_assign_regs(&idev->resource, model);
-
-	return 1;
-}
-
-static int __init clock_probe_isa(void)
-{
-	struct sparc_isa_bridge *isa_br;
-
-	for_each_isa(isa_br) {
-		struct sparc_isa_device *isa_dev;
-
-		for_each_isadev(isa_dev, isa_br) {
-			if (clock_probe_one_isa_dev(isa_dev))
-				return 1;
-		}
-	}
-
-	return 0;
-}
-#endif /* CONFIG_PCI */
-
-#ifdef CONFIG_SBUS
-static int __init clock_probe_one_sbus_dev(struct sbus_bus *sbus, struct sbus_dev *sdev)
-{
-	struct resource *res;
-	char model[64];
-	void __iomem *addr;
-
-	prom_getstring(sdev->prom_node, "model", model, sizeof(model));
-	if (!clock_model_matches(model))
-		return 0;
-
-	res = &sdev->resource[0];
-	addr = sbus_ioremap(res, 0, 0x800UL, "eeprom");
-
-	__clock_assign_common(addr, model);
-
-	return 1;
-}
-
-static int __init clock_probe_sbus(void)
-{
-	struct sbus_bus *sbus;
-
-	for_each_sbus(sbus) {
-		struct sbus_dev *sdev;
-
-		for_each_sbusdev(sdev, sbus) {
-			if (clock_probe_one_sbus_dev(sbus, sdev))
-				return 1;
-		}
-	}
-
-	return 0;
-}
-#endif
-
-void __init clock_probe(void)
-{
-	static int invoked;
-	unsigned long flags;
-
-	if (invoked)
-		return;
-	invoked = 1;
-
-	if (this_is_starfire) {
-		xtime.tv_sec = starfire_get_time();
-		xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
-		set_normalized_timespec(&wall_to_monotonic,
-		                        -xtime.tv_sec, -xtime.tv_nsec);
-		return;
-	}
-	if (tlb_type == hypervisor) {
-		xtime.tv_sec = hypervisor_get_time();
-		xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
-		set_normalized_timespec(&wall_to_monotonic,
-		                        -xtime.tv_sec, -xtime.tv_nsec);
-		return;
-	}
-
-	/* Check FHC Central then EBUSs then ISA bridges then SBUSs.
-	 * That way we handle the presence of multiple properly.
-	 *
-	 * As a special case, machines with Central must provide the
-	 * timer chip there.
-	 */
-	if (!clock_probe_central() &&
-#ifdef CONFIG_PCI
-	    !clock_probe_ebus() &&
-	    !clock_probe_isa() &&
-#endif
-#ifdef CONFIG_SBUS
-	    !clock_probe_sbus()
-#endif
-		) {
-		printk(KERN_WARNING "No clock chip found.\n");
-		return;
-	}
+	printk(KERN_INFO "%s: Clock regs at %p\n", dp->full_name, regs);
 
 	local_irq_save(flags);
 
@@ -999,8 +817,52 @@
 	set_system_time();
 	
 	local_irq_restore(flags);
+
+	return 0;
 }
 
+static struct of_device_id clock_match[] = {
+	{
+		.name = "eeprom",
+	},
+	{
+		.name = "rtc",
+	},
+	{},
+};
+
+static struct of_platform_driver clock_driver = {
+	.name		= "clock",
+	.match_table	= clock_match,
+	.probe		= clock_probe,
+};
+
+static int __init clock_init(void)
+{
+	if (this_is_starfire) {
+		xtime.tv_sec = starfire_get_time();
+		xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
+		set_normalized_timespec(&wall_to_monotonic,
+		                        -xtime.tv_sec, -xtime.tv_nsec);
+		return 0;
+	}
+	if (tlb_type == hypervisor) {
+		xtime.tv_sec = hypervisor_get_time();
+		xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
+		set_normalized_timespec(&wall_to_monotonic,
+		                        -xtime.tv_sec, -xtime.tv_nsec);
+		return 0;
+	}
+
+	return of_register_driver(&clock_driver, &of_bus_type);
+}
+
+/* Must be after subsys_initcall() so that busses are probed.  Must
+ * be before device_initcall() because things like the RTC driver
+ * need to see the clock registers.
+ */
+fs_initcall(clock_init);
+
 /* This is gets the master TICK_INT timer going. */
 static unsigned long sparc64_init_timers(void)
 {