diff options
| author | David S. Miller <davem@davemloft.net> | 2006-06-29 17:36:52 -0400 |
|---|---|---|
| committer | David S. Miller <davem@sunset.davemloft.net> | 2006-06-29 19:37:23 -0400 |
| commit | ee5caf0ee19f65a5e29bf20a0dffd8be8b4827fd (patch) | |
| tree | 68eaa50b1bcc4eda6200d4121248354766e77a1d | |
| parent | 36a59bd89c50c1090c7438db89f751720974a6fc (diff) | |
[SPARC]: Convert clock drivers to of_driver framework.
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | arch/sparc/kernel/time.c | 109 | ||||
| -rw-r--r-- | arch/sparc64/kernel/pci.c | 2 | ||||
| -rw-r--r-- | arch/sparc64/kernel/sbus.c | 2 | ||||
| -rw-r--r-- | arch/sparc64/kernel/time.c | 246 |
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 | ||
| 46 | extern unsigned long wall_jiffies; | 47 | extern 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. */ | 277 | static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match) |
| 277 | static __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 | |||
| 314 | static struct of_device_id clock_match[] = { | ||
| 315 | { | ||
| 316 | .name = "eeprom", | ||
| 317 | }, | ||
| 318 | {}, | ||
| 319 | }; | ||
| 320 | |||
| 321 | static 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. */ | ||
| 329 | static void clock_init(void) | ||
| 330 | { | ||
| 331 | of_register_driver(&clock_driver, &of_bus_type); | ||
| 361 | } | 332 | } |
| 362 | 333 | ||
| 363 | void __init sbus_time_init(void) | 334 | void __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 | ||
| 310 | extern void clock_probe(void); | ||
| 311 | extern void power_init(void); | 310 | extern void power_init(void); |
| 312 | 311 | ||
| 313 | static int __init pcibios_init(void) | 312 | static 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) | |||
| 1267 | void __init sbus_arch_postinit(void) | 1267 | void __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 | ||
| 773 | static void __init __clock_assign_common(void __iomem *addr, char *model) | 773 | static 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 | |||
| 786 | static 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 | |||
| 797 | static 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 | ||
| 834 | static 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 | |||
| 847 | static 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 | |||
| 861 | static 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); | |
| 877 | static 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 | |||
| 891 | static 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 | ||
| 909 | static 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; | 824 | static struct of_device_id clock_match[] = { |
| 925 | } | 825 | { |
| 926 | 826 | .name = "eeprom", | |
| 927 | static 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; | 834 | static struct of_platform_driver clock_driver = { |
| 941 | } | 835 | .name = "clock", |
| 942 | #endif | 836 | .match_table = clock_match, |
| 837 | .probe = clock_probe, | ||
| 838 | }; | ||
| 943 | 839 | ||
| 944 | void __init clock_probe(void) | 840 | static 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 | */ | ||
| 864 | fs_initcall(clock_init); | ||
| 865 | |||
| 1004 | /* This is gets the master TICK_INT timer going. */ | 866 | /* This is gets the master TICK_INT timer going. */ |
| 1005 | static unsigned long sparc64_init_timers(void) | 867 | static unsigned long sparc64_init_timers(void) |
| 1006 | { | 868 | { |
