[SPARC]: Convert clock drivers to of_driver framework.
David S. Miller [Thu, 29 Jun 2006 21:36:52 +0000 (14:36 -0700)]
Signed-off-by: David S. Miller <davem@davemloft.net>

arch/sparc/kernel/time.c
arch/sparc64/kernel/pci.c
arch/sparc64/kernel/sbus.c
arch/sparc64/kernel/time.c

index 7dadcdb..9631e8f 100644 (file)
@@ -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 @@ static __inline__ void sun4_clock_probe(void)
 #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;
-
-       cpuunit = bootbus = 0;
-       memset(&r, 0, sizeof(r));
-
-       /* 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();
-       }
+       struct device_node *dp = op->node;
+       char *model = of_get_property(dp, "model", NULL);
 
-       /* 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();
-       }
+       if (!model)
+               return -ENODEV;
 
-       /* 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 @@ static __inline__ void clock_probe(void)
        /* 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 @@ void __init sbus_time_init(void)
        if (ARCH_SUN4)
                sun4_clock_probe();
        else
-               clock_probe();
+               clock_init();
 
        sparc_init_timers(timer_interrupt);
        
index 20ca9ec..7b96258 100644 (file)
@@ -307,7 +307,6 @@ static void __init pci_scan_each_controller_bus(void)
                p->scan_bus(p);
 }
 
-extern void clock_probe(void);
 extern void power_init(void);
 
 static int __init pcibios_init(void)
@@ -320,7 +319,6 @@ static int __init pcibios_init(void)
 
        isa_init();
        ebus_init();
-       clock_probe();
        power_init();
 
        return 0;
index 945222e..ef68aa4 100644 (file)
@@ -1267,8 +1267,6 @@ int __init sbus_arch_preinit(void)
 void __init sbus_arch_postinit(void)
 {
        extern void firetruck_init(void);
-       extern void clock_probe(void);
 
        firetruck_init();
-       clock_probe();
 }
index 348b820..540e4b6 100644 (file)
@@ -770,237 +770,99 @@ static int __init clock_model_matches(char *model)
        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;
-       }
-}
-
-static void __init clock_assign_clk_reg(struct linux_prom_registers *clk_reg,
-                                       char *model)
-{
-       unsigned long addr;
+       struct device_node *dp = op->node;
+       char *model = of_get_property(dp, "model", NULL);
+       unsigned long size, flags;
+       void __iomem *regs;
 
-       addr = ((unsigned long) clk_reg[0].phys_addr |
-               (((unsigned long) clk_reg[0].which_io) << 32UL));
-
-       __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;
-       }
+       if (!model || !clock_model_matches(model))
+               return -ENODEV;
 
-       return 0;
-}
+       size = (op->resource[0].end - op->resource[0].start) + 1;
+       regs = of_ioremap(&op->resource[0], 0, size, "clock");
+       if (!regs)
+               return -ENOMEM;
 
-#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);
+       printk(KERN_INFO "%s: Clock regs at %p\n", dp->full_name, regs);
 
-       return 1;
-}
-
-static int __init clock_probe_ebus(void)
-{
-       struct linux_ebus *ebus;
+       local_irq_save(flags);
 
-       for_each_ebus(ebus) {
-               struct linux_ebus_device *edev;
+       if (mstk48t02_regs != NULL) {
+               /* Report a low battery voltage condition. */
+               if (has_low_battery())
+                       prom_printf("NVRAM: Low battery voltage!\n");
 
-               for_each_ebusdev(edev, ebus) {
-                       if (clock_probe_one_ebus_dev(edev))
-                               return 1;
-               }
+               /* Kick start the clock if it is completely stopped. */
+               if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP)
+                       kick_start_clock();
        }
 
-       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;
-               }
-       }
+       set_system_time();
+       
+       local_irq_restore(flags);
 
        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;
-               }
-       }
+static struct of_device_id clock_match[] = {
+       {
+               .name = "eeprom",
+       },
+       {
+               .name = "rtc",
+       },
+       {},
+};
 
-       return 0;
-}
-#endif
+static struct of_platform_driver clock_driver = {
+       .name           = "clock",
+       .match_table    = clock_match,
+       .probe          = clock_probe,
+};
 
-void __init clock_probe(void)
+static int __init clock_init(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;
+               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;
-       }
-
-       /* 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;
-       }
-
-       local_irq_save(flags);
-
-       if (mstk48t02_regs != NULL) {
-               /* Report a low battery voltage condition. */
-               if (has_low_battery())
-                       prom_printf("NVRAM: Low battery voltage!\n");
-
-               /* Kick start the clock if it is completely stopped. */
-               if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP)
-                       kick_start_clock();
+               return 0;
        }
 
-       set_system_time();
-       
-       local_irq_restore(flags);
+       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)
 {