aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2006-06-29 17:36:52 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-06-29 19:37:23 -0400
commitee5caf0ee19f65a5e29bf20a0dffd8be8b4827fd (patch)
tree68eaa50b1bcc4eda6200d4121248354766e77a1d /arch
parent36a59bd89c50c1090c7438db89f751720974a6fc (diff)
[SPARC]: Convert clock drivers to of_driver framework.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc/kernel/time.c109
-rw-r--r--arch/sparc64/kernel/pci.c2
-rw-r--r--arch/sparc64/kernel/sbus.c2
-rw-r--r--arch/sparc64/kernel/time.c246
4 files changed, 94 insertions, 265 deletions
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
index 7dadcdb4ca42..9631e8f4ae60 100644
--- a/arch/sparc/kernel/time.c
+++ b/arch/sparc/kernel/time.c
@@ -42,6 +42,7 @@
42#include <asm/sun4paddr.h> 42#include <asm/sun4paddr.h>
43#include <asm/page.h> 43#include <asm/page.h>
44#include <asm/pcic.h> 44#include <asm/pcic.h>
45#include <asm/of_device.h>
45 46
46extern unsigned long wall_jiffies; 47extern unsigned long wall_jiffies;
47 48
@@ -273,83 +274,31 @@ static __inline__ void sun4_clock_probe(void)
273#endif 274#endif
274} 275}
275 276
276/* Probe for the mostek real time clock chip. */ 277static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match)
277static __inline__ void clock_probe(void)
278{ 278{
279 struct linux_prom_registers clk_reg[2]; 279 struct device_node *dp = op->node;
280 char model[128]; 280 char *model = of_get_property(dp, "model", NULL);
281 register int node, cpuunit, bootbus;
282 struct resource r;
283
284 cpuunit = bootbus = 0;
285 memset(&r, 0, sizeof(r));
286
287 /* Determine the correct starting PROM node for the probe. */
288 node = prom_getchild(prom_root_node);
289 switch (sparc_cpu_model) {
290 case sun4c:
291 break;
292 case sun4m:
293 node = prom_getchild(prom_searchsiblings(node, "obio"));
294 break;
295 case sun4d:
296 node = prom_getchild(bootbus = prom_searchsiblings(prom_getchild(cpuunit = prom_searchsiblings(node, "cpu-unit")), "bootbus"));
297 break;
298 default:
299 prom_printf("CLOCK: Unsupported architecture!\n");
300 prom_halt();
301 }
302 281
303 /* Find the PROM node describing the real time clock. */ 282 if (!model)
304 sp_clock_typ = MSTK_INVALID; 283 return -ENODEV;
305 node = prom_searchsiblings(node,"eeprom");
306 if (!node) {
307 prom_printf("CLOCK: No clock found!\n");
308 prom_halt();
309 }
310 284
311 /* Get the model name and setup everything up. */ 285 if (!strcmp(model, "mk48t02")) {
312 model[0] = '\0';
313 prom_getstring(node, "model", model, sizeof(model));
314 if (strcmp(model, "mk48t02") == 0) {
315 sp_clock_typ = MSTK48T02; 286 sp_clock_typ = MSTK48T02;
316 if (prom_getproperty(node, "reg", (char *) clk_reg, sizeof(clk_reg)) == -1) { 287
317 prom_printf("clock_probe: FAILED!\n");
318 prom_halt();
319 }
320 if (sparc_cpu_model == sun4d)
321 prom_apply_generic_ranges (bootbus, cpuunit, clk_reg, 1);
322 else
323 prom_apply_obio_ranges(clk_reg, 1);
324 /* Map the clock register io area read-only */ 288 /* Map the clock register io area read-only */
325 r.flags = clk_reg[0].which_io; 289 mstk48t02_regs = of_ioremap(&op->resource[0], 0,
326 r.start = clk_reg[0].phys_addr; 290 sizeof(struct mostek48t02),
327 mstk48t02_regs = sbus_ioremap(&r, 0, 291 "mk48t02");
328 sizeof(struct mostek48t02), "mk48t02");
329 mstk48t08_regs = NULL; /* To catch weirdness */ 292 mstk48t08_regs = NULL; /* To catch weirdness */
330 } else if (strcmp(model, "mk48t08") == 0) { 293 } else if (!strcmp(model, "mk48t08")) {
331 sp_clock_typ = MSTK48T08; 294 sp_clock_typ = MSTK48T08;
332 if(prom_getproperty(node, "reg", (char *) clk_reg, 295 mstk48t08_regs = of_ioremap(&op->resource[0], 0,
333 sizeof(clk_reg)) == -1) { 296 sizeof(struct mostek48t08),
334 prom_printf("clock_probe: FAILED!\n"); 297 "mk48t08");
335 prom_halt();
336 }
337 if (sparc_cpu_model == sun4d)
338 prom_apply_generic_ranges (bootbus, cpuunit, clk_reg, 1);
339 else
340 prom_apply_obio_ranges(clk_reg, 1);
341 /* Map the clock register io area read-only */
342 /* XXX r/o attribute is somewhere in r.flags */
343 r.flags = clk_reg[0].which_io;
344 r.start = clk_reg[0].phys_addr;
345 mstk48t08_regs = sbus_ioremap(&r, 0,
346 sizeof(struct mostek48t08), "mk48t08");
347 298
348 mstk48t02_regs = &mstk48t08_regs->regs; 299 mstk48t02_regs = &mstk48t08_regs->regs;
349 } else { 300 } else
350 prom_printf("CLOCK: Unknown model name '%s'\n",model); 301 return -ENODEV;
351 prom_halt();
352 }
353 302
354 /* Report a low battery voltage condition. */ 303 /* Report a low battery voltage condition. */
355 if (has_low_battery()) 304 if (has_low_battery())
@@ -358,6 +307,28 @@ static __inline__ void clock_probe(void)
358 /* Kick start the clock if it is completely stopped. */ 307 /* Kick start the clock if it is completely stopped. */
359 if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP) 308 if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP)
360 kick_start_clock(); 309 kick_start_clock();
310
311 return 0;
312}
313
314static struct of_device_id clock_match[] = {
315 {
316 .name = "eeprom",
317 },
318 {},
319};
320
321static struct of_platform_driver clock_driver = {
322 .name = "clock",
323 .match_table = clock_match,
324 .probe = clock_probe,
325};
326
327
328/* Probe for the mostek real time clock chip. */
329static void clock_init(void)
330{
331 of_register_driver(&clock_driver, &of_bus_type);
361} 332}
362 333
363void __init sbus_time_init(void) 334void __init sbus_time_init(void)
@@ -376,7 +347,7 @@ void __init sbus_time_init(void)
376 if (ARCH_SUN4) 347 if (ARCH_SUN4)
377 sun4_clock_probe(); 348 sun4_clock_probe();
378 else 349 else
379 clock_probe(); 350 clock_init();
380 351
381 sparc_init_timers(timer_interrupt); 352 sparc_init_timers(timer_interrupt);
382 353
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index 20ca9ec8fd3b..7b9625828603 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -307,7 +307,6 @@ static void __init pci_scan_each_controller_bus(void)
307 p->scan_bus(p); 307 p->scan_bus(p);
308} 308}
309 309
310extern void clock_probe(void);
311extern void power_init(void); 310extern void power_init(void);
312 311
313static int __init pcibios_init(void) 312static int __init pcibios_init(void)
@@ -320,7 +319,6 @@ static int __init pcibios_init(void)
320 319
321 isa_init(); 320 isa_init();
322 ebus_init(); 321 ebus_init();
323 clock_probe();
324 power_init(); 322 power_init();
325 323
326 return 0; 324 return 0;
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c
index 945222e66980..ef68aa4fec65 100644
--- a/arch/sparc64/kernel/sbus.c
+++ b/arch/sparc64/kernel/sbus.c
@@ -1267,8 +1267,6 @@ int __init sbus_arch_preinit(void)
1267void __init sbus_arch_postinit(void) 1267void __init sbus_arch_postinit(void)
1268{ 1268{
1269 extern void firetruck_init(void); 1269 extern void firetruck_init(void);
1270 extern void clock_probe(void);
1271 1270
1272 firetruck_init(); 1271 firetruck_init();
1273 clock_probe();
1274} 1272}
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index 348b82035561..540e4b6c2dee 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -770,237 +770,99 @@ static int __init clock_model_matches(char *model)
770 return 1; 770 return 1;
771} 771}
772 772
773static void __init __clock_assign_common(void __iomem *addr, char *model) 773static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match)
774{ 774{
775 if (model[5] == '0' && model[6] == '2') { 775 struct device_node *dp = op->node;
776 mstk48t02_regs = addr; 776 char *model = of_get_property(dp, "model", NULL);
777 } else if(model[5] == '0' && model[6] == '8') { 777 unsigned long size, flags;
778 mstk48t08_regs = addr; 778 void __iomem *regs;
779 mstk48t02_regs = mstk48t08_regs + MOSTEK_48T08_48T02;
780 } else {
781 mstk48t59_regs = addr;
782 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
783 }
784}
785
786static void __init clock_assign_clk_reg(struct linux_prom_registers *clk_reg,
787 char *model)
788{
789 unsigned long addr;
790 779
791 addr = ((unsigned long) clk_reg[0].phys_addr | 780 if (!model || !clock_model_matches(model))
792 (((unsigned long) clk_reg[0].which_io) << 32UL)); 781 return -ENODEV;
793
794 __clock_assign_common((void __iomem *) addr, model);
795}
796
797static int __init clock_probe_central(void)
798{
799 struct linux_prom_registers clk_reg[2], *pr;
800 struct device_node *dp;
801 char *model;
802
803 if (!central_bus)
804 return 0;
805
806 /* Get Central FHC's prom node. */
807 dp = central_bus->child->prom_node;
808
809 /* Then get the first child device below it. */
810 dp = dp->child;
811
812 while (dp) {
813 model = of_get_property(dp, "model", NULL);
814 if (!model || !clock_model_matches(model))
815 goto next_sibling;
816
817 pr = of_get_property(dp, "reg", NULL);
818 memcpy(clk_reg, pr, sizeof(clk_reg));
819
820 apply_fhc_ranges(central_bus->child, clk_reg, 1);
821 apply_central_ranges(central_bus, clk_reg, 1);
822
823 clock_assign_clk_reg(clk_reg, model);
824 return 1;
825
826 next_sibling:
827 dp = dp->sibling;
828 }
829 782
830 return 0; 783 size = (op->resource[0].end - op->resource[0].start) + 1;
831} 784 regs = of_ioremap(&op->resource[0], 0, size, "clock");
785 if (!regs)
786 return -ENOMEM;
832 787
833#ifdef CONFIG_PCI
834static void __init clock_isa_ebus_assign_regs(struct resource *res, char *model)
835{
836 if (!strcmp(model, "ds1287") || 788 if (!strcmp(model, "ds1287") ||
837 !strcmp(model, "m5819") || 789 !strcmp(model, "m5819") ||
838 !strcmp(model, "m5819p") || 790 !strcmp(model, "m5819p") ||
839 !strcmp(model, "m5823")) { 791 !strcmp(model, "m5823")) {
840 ds1287_regs = res->start; 792 ds1287_regs = (unsigned long) regs;
793 } else if (model[5] == '0' && model[6] == '2') {
794 mstk48t02_regs = regs;
795 } else if(model[5] == '0' && model[6] == '8') {
796 mstk48t08_regs = regs;
797 mstk48t02_regs = mstk48t08_regs + MOSTEK_48T08_48T02;
841 } else { 798 } else {
842 mstk48t59_regs = (void __iomem *) res->start; 799 mstk48t59_regs = regs;
843 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02; 800 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
844 } 801 }
845}
846
847static int __init clock_probe_one_ebus_dev(struct linux_ebus_device *edev)
848{
849 struct device_node *dp = edev->prom_node;
850 char *model;
851 802
852 model = of_get_property(dp, "model", NULL); 803 printk(KERN_INFO "%s: Clock regs at %p\n", dp->full_name, regs);
853 if (!clock_model_matches(model))
854 return 0;
855
856 clock_isa_ebus_assign_regs(&edev->resource[0], model);
857 804
858 return 1; 805 local_irq_save(flags);
859}
860
861static int __init clock_probe_ebus(void)
862{
863 struct linux_ebus *ebus;
864 806
865 for_each_ebus(ebus) { 807 if (mstk48t02_regs != NULL) {
866 struct linux_ebus_device *edev; 808 /* Report a low battery voltage condition. */
809 if (has_low_battery())
810 prom_printf("NVRAM: Low battery voltage!\n");
867 811
868 for_each_ebusdev(edev, ebus) { 812 /* Kick start the clock if it is completely stopped. */
869 if (clock_probe_one_ebus_dev(edev)) 813 if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP)
870 return 1; 814 kick_start_clock();
871 }
872 } 815 }
873 816
874 return 0; 817 set_system_time();
875} 818
876 819 local_irq_restore(flags);
877static int __init clock_probe_one_isa_dev(struct sparc_isa_device *idev)
878{
879 struct device_node *dp = idev->prom_node;
880 char *model;
881
882 model = of_get_property(dp, "model", NULL);
883 if (!clock_model_matches(model))
884 return 0;
885
886 clock_isa_ebus_assign_regs(&idev->resource, model);
887
888 return 1;
889}
890
891static int __init clock_probe_isa(void)
892{
893 struct sparc_isa_bridge *isa_br;
894
895 for_each_isa(isa_br) {
896 struct sparc_isa_device *isa_dev;
897
898 for_each_isadev(isa_dev, isa_br) {
899 if (clock_probe_one_isa_dev(isa_dev))
900 return 1;
901 }
902 }
903 820
904 return 0; 821 return 0;
905} 822}
906#endif /* CONFIG_PCI */
907
908#ifdef CONFIG_SBUS
909static int __init clock_probe_one_sbus_dev(struct sbus_bus *sbus, struct sbus_dev *sdev)
910{
911 struct resource *res;
912 char model[64];
913 void __iomem *addr;
914
915 prom_getstring(sdev->prom_node, "model", model, sizeof(model));
916 if (!clock_model_matches(model))
917 return 0;
918
919 res = &sdev->resource[0];
920 addr = sbus_ioremap(res, 0, 0x800UL, "eeprom");
921
922 __clock_assign_common(addr, model);
923 823
924 return 1; 824static struct of_device_id clock_match[] = {
925} 825 {
926 826 .name = "eeprom",
927static int __init clock_probe_sbus(void) 827 },
928{ 828 {
929 struct sbus_bus *sbus; 829 .name = "rtc",
930 830 },
931 for_each_sbus(sbus) { 831 {},
932 struct sbus_dev *sdev; 832};
933
934 for_each_sbusdev(sdev, sbus) {
935 if (clock_probe_one_sbus_dev(sbus, sdev))
936 return 1;
937 }
938 }
939 833
940 return 0; 834static struct of_platform_driver clock_driver = {
941} 835 .name = "clock",
942#endif 836 .match_table = clock_match,
837 .probe = clock_probe,
838};
943 839
944void __init clock_probe(void) 840static int __init clock_init(void)
945{ 841{
946 static int invoked;
947 unsigned long flags;
948
949 if (invoked)
950 return;
951 invoked = 1;
952
953 if (this_is_starfire) { 842 if (this_is_starfire) {
954 xtime.tv_sec = starfire_get_time(); 843 xtime.tv_sec = starfire_get_time();
955 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); 844 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
956 set_normalized_timespec(&wall_to_monotonic, 845 set_normalized_timespec(&wall_to_monotonic,
957 -xtime.tv_sec, -xtime.tv_nsec); 846 -xtime.tv_sec, -xtime.tv_nsec);
958 return; 847 return 0;
959 } 848 }
960 if (tlb_type == hypervisor) { 849 if (tlb_type == hypervisor) {
961 xtime.tv_sec = hypervisor_get_time(); 850 xtime.tv_sec = hypervisor_get_time();
962 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); 851 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
963 set_normalized_timespec(&wall_to_monotonic, 852 set_normalized_timespec(&wall_to_monotonic,
964 -xtime.tv_sec, -xtime.tv_nsec); 853 -xtime.tv_sec, -xtime.tv_nsec);
965 return; 854 return 0;
966 }
967
968 /* Check FHC Central then EBUSs then ISA bridges then SBUSs.
969 * That way we handle the presence of multiple properly.
970 *
971 * As a special case, machines with Central must provide the
972 * timer chip there.
973 */
974 if (!clock_probe_central() &&
975#ifdef CONFIG_PCI
976 !clock_probe_ebus() &&
977 !clock_probe_isa() &&
978#endif
979#ifdef CONFIG_SBUS
980 !clock_probe_sbus()
981#endif
982 ) {
983 printk(KERN_WARNING "No clock chip found.\n");
984 return;
985 }
986
987 local_irq_save(flags);
988
989 if (mstk48t02_regs != NULL) {
990 /* Report a low battery voltage condition. */
991 if (has_low_battery())
992 prom_printf("NVRAM: Low battery voltage!\n");
993
994 /* Kick start the clock if it is completely stopped. */
995 if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP)
996 kick_start_clock();
997 } 855 }
998 856
999 set_system_time(); 857 return of_register_driver(&clock_driver, &of_bus_type);
1000
1001 local_irq_restore(flags);
1002} 858}
1003 859
860/* Must be after subsys_initcall() so that busses are probed. Must
861 * be before device_initcall() because things like the RTC driver
862 * need to see the clock registers.
863 */
864fs_initcall(clock_init);
865
1004/* This is gets the master TICK_INT timer going. */ 866/* This is gets the master TICK_INT timer going. */
1005static unsigned long sparc64_init_timers(void) 867static unsigned long sparc64_init_timers(void)
1006{ 868{