aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/time.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/time.c')
-rw-r--r--arch/sparc64/kernel/time.c386
1 files changed, 204 insertions, 182 deletions
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index 0f00a99927e9..348b82035561 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -48,6 +48,7 @@
48#include <asm/sections.h> 48#include <asm/sections.h>
49#include <asm/cpudata.h> 49#include <asm/cpudata.h>
50#include <asm/uaccess.h> 50#include <asm/uaccess.h>
51#include <asm/prom.h>
51 52
52DEFINE_SPINLOCK(mostek_lock); 53DEFINE_SPINLOCK(mostek_lock);
53DEFINE_SPINLOCK(rtc_lock); 54DEFINE_SPINLOCK(rtc_lock);
@@ -755,24 +756,200 @@ retry:
755 return -EOPNOTSUPP; 756 return -EOPNOTSUPP;
756} 757}
757 758
758void __init clock_probe(void) 759static int __init clock_model_matches(char *model)
759{ 760{
760 struct linux_prom_registers clk_reg[2]; 761 if (strcmp(model, "mk48t02") &&
761 char model[128]; 762 strcmp(model, "mk48t08") &&
762 int node, busnd = -1, err; 763 strcmp(model, "mk48t59") &&
763 unsigned long flags; 764 strcmp(model, "m5819") &&
764 struct linux_central *cbus; 765 strcmp(model, "m5819p") &&
766 strcmp(model, "m5823") &&
767 strcmp(model, "ds1287"))
768 return 0;
769
770 return 1;
771}
772
773static void __init __clock_assign_common(void __iomem *addr, char *model)
774{
775 if (model[5] == '0' && model[6] == '2') {
776 mstk48t02_regs = addr;
777 } else if(model[5] == '0' && model[6] == '8') {
778 mstk48t08_regs = addr;
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
791 addr = ((unsigned long) clk_reg[0].phys_addr |
792 (((unsigned long) clk_reg[0].which_io) << 32UL));
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
830 return 0;
831}
832
765#ifdef CONFIG_PCI 833#ifdef CONFIG_PCI
766 struct linux_ebus *ebus = NULL; 834static void __init clock_isa_ebus_assign_regs(struct resource *res, char *model)
767 struct sparc_isa_bridge *isa_br = NULL; 835{
836 if (!strcmp(model, "ds1287") ||
837 !strcmp(model, "m5819") ||
838 !strcmp(model, "m5819p") ||
839 !strcmp(model, "m5823")) {
840 ds1287_regs = res->start;
841 } else {
842 mstk48t59_regs = (void __iomem *) res->start;
843 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
844 }
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
852 model = of_get_property(dp, "model", NULL);
853 if (!clock_model_matches(model))
854 return 0;
855
856 clock_isa_ebus_assign_regs(&edev->resource[0], model);
857
858 return 1;
859}
860
861static int __init clock_probe_ebus(void)
862{
863 struct linux_ebus *ebus;
864
865 for_each_ebus(ebus) {
866 struct linux_ebus_device *edev;
867
868 for_each_ebusdev(edev, ebus) {
869 if (clock_probe_one_ebus_dev(edev))
870 return 1;
871 }
872 }
873
874 return 0;
875}
876
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
904 return 0;
905}
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
924 return 1;
925}
926
927static int __init clock_probe_sbus(void)
928{
929 struct sbus_bus *sbus;
930
931 for_each_sbus(sbus) {
932 struct sbus_dev *sdev;
933
934 for_each_sbusdev(sdev, sbus) {
935 if (clock_probe_one_sbus_dev(sbus, sdev))
936 return 1;
937 }
938 }
939
940 return 0;
941}
768#endif 942#endif
943
944void __init clock_probe(void)
945{
769 static int invoked; 946 static int invoked;
947 unsigned long flags;
770 948
771 if (invoked) 949 if (invoked)
772 return; 950 return;
773 invoked = 1; 951 invoked = 1;
774 952
775
776 if (this_is_starfire) { 953 if (this_is_starfire) {
777 xtime.tv_sec = starfire_get_time(); 954 xtime.tv_sec = starfire_get_time();
778 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); 955 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
@@ -788,183 +965,27 @@ void __init clock_probe(void)
788 return; 965 return;
789 } 966 }
790 967
791 local_irq_save(flags);
792
793 cbus = central_bus;
794 if (cbus != NULL)
795 busnd = central_bus->child->prom_node;
796
797 /* Check FHC Central then EBUSs then ISA bridges then SBUSs. 968 /* Check FHC Central then EBUSs then ISA bridges then SBUSs.
798 * That way we handle the presence of multiple properly. 969 * That way we handle the presence of multiple properly.
799 * 970 *
800 * As a special case, machines with Central must provide the 971 * As a special case, machines with Central must provide the
801 * timer chip there. 972 * timer chip there.
802 */ 973 */
974 if (!clock_probe_central() &&
803#ifdef CONFIG_PCI 975#ifdef CONFIG_PCI
804 if (ebus_chain != NULL) { 976 !clock_probe_ebus() &&
805 ebus = ebus_chain; 977 !clock_probe_isa() &&
806 if (busnd == -1)
807 busnd = ebus->prom_node;
808 }
809 if (isa_chain != NULL) {
810 isa_br = isa_chain;
811 if (busnd == -1)
812 busnd = isa_br->prom_node;
813 }
814#endif
815 if (sbus_root != NULL && busnd == -1)
816 busnd = sbus_root->prom_node;
817
818 if (busnd == -1) {
819 prom_printf("clock_probe: problem, cannot find bus to search.\n");
820 prom_halt();
821 }
822
823 node = prom_getchild(busnd);
824
825 while (1) {
826 if (!node)
827 model[0] = 0;
828 else
829 prom_getstring(node, "model", model, sizeof(model));
830 if (strcmp(model, "mk48t02") &&
831 strcmp(model, "mk48t08") &&
832 strcmp(model, "mk48t59") &&
833 strcmp(model, "m5819") &&
834 strcmp(model, "m5819p") &&
835 strcmp(model, "m5823") &&
836 strcmp(model, "ds1287")) {
837 if (cbus != NULL) {
838 prom_printf("clock_probe: Central bus lacks timer chip.\n");
839 prom_halt();
840 }
841
842 if (node != 0)
843 node = prom_getsibling(node);
844#ifdef CONFIG_PCI
845 while ((node == 0) && ebus != NULL) {
846 ebus = ebus->next;
847 if (ebus != NULL) {
848 busnd = ebus->prom_node;
849 node = prom_getchild(busnd);
850 }
851 }
852 while ((node == 0) && isa_br != NULL) {
853 isa_br = isa_br->next;
854 if (isa_br != NULL) {
855 busnd = isa_br->prom_node;
856 node = prom_getchild(busnd);
857 }
858 }
859#endif 978#endif
860 if (node == 0) { 979#ifdef CONFIG_SBUS
861 prom_printf("clock_probe: Cannot find timer chip\n"); 980 !clock_probe_sbus()
862 prom_halt();
863 }
864 continue;
865 }
866
867 err = prom_getproperty(node, "reg", (char *)clk_reg,
868 sizeof(clk_reg));
869 if(err == -1) {
870 prom_printf("clock_probe: Cannot get Mostek reg property\n");
871 prom_halt();
872 }
873
874 if (cbus != NULL) {
875 apply_fhc_ranges(central_bus->child, clk_reg, 1);
876 apply_central_ranges(central_bus, clk_reg, 1);
877 }
878#ifdef CONFIG_PCI
879 else if (ebus != NULL) {
880 struct linux_ebus_device *edev;
881
882 for_each_ebusdev(edev, ebus)
883 if (edev->prom_node == node)
884 break;
885 if (edev == NULL) {
886 if (isa_chain != NULL)
887 goto try_isa_clock;
888 prom_printf("%s: Mostek not probed by EBUS\n",
889 __FUNCTION__);
890 prom_halt();
891 }
892
893 if (!strcmp(model, "ds1287") ||
894 !strcmp(model, "m5819") ||
895 !strcmp(model, "m5819p") ||
896 !strcmp(model, "m5823")) {
897 ds1287_regs = edev->resource[0].start;
898 } else {
899 mstk48t59_regs = (void __iomem *)
900 edev->resource[0].start;
901 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
902 }
903 break;
904 }
905 else if (isa_br != NULL) {
906 struct sparc_isa_device *isadev;
907
908try_isa_clock:
909 for_each_isadev(isadev, isa_br)
910 if (isadev->prom_node == node)
911 break;
912 if (isadev == NULL) {
913 prom_printf("%s: Mostek not probed by ISA\n");
914 prom_halt();
915 }
916 if (!strcmp(model, "ds1287") ||
917 !strcmp(model, "m5819") ||
918 !strcmp(model, "m5819p") ||
919 !strcmp(model, "m5823")) {
920 ds1287_regs = isadev->resource.start;
921 } else {
922 mstk48t59_regs = (void __iomem *)
923 isadev->resource.start;
924 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
925 }
926 break;
927 }
928#endif 981#endif
929 else { 982 ) {
930 if (sbus_root->num_sbus_ranges) { 983 printk(KERN_WARNING "No clock chip found.\n");
931 int nranges = sbus_root->num_sbus_ranges; 984 return;
932 int rngc;
933
934 for (rngc = 0; rngc < nranges; rngc++)
935 if (clk_reg[0].which_io ==
936 sbus_root->sbus_ranges[rngc].ot_child_space)
937 break;
938 if (rngc == nranges) {
939 prom_printf("clock_probe: Cannot find ranges for "
940 "clock regs.\n");
941 prom_halt();
942 }
943 clk_reg[0].which_io =
944 sbus_root->sbus_ranges[rngc].ot_parent_space;
945 clk_reg[0].phys_addr +=
946 sbus_root->sbus_ranges[rngc].ot_parent_base;
947 }
948 }
949
950 if(model[5] == '0' && model[6] == '2') {
951 mstk48t02_regs = (void __iomem *)
952 (((u64)clk_reg[0].phys_addr) |
953 (((u64)clk_reg[0].which_io)<<32UL));
954 } else if(model[5] == '0' && model[6] == '8') {
955 mstk48t08_regs = (void __iomem *)
956 (((u64)clk_reg[0].phys_addr) |
957 (((u64)clk_reg[0].which_io)<<32UL));
958 mstk48t02_regs = mstk48t08_regs + MOSTEK_48T08_48T02;
959 } else {
960 mstk48t59_regs = (void __iomem *)
961 (((u64)clk_reg[0].phys_addr) |
962 (((u64)clk_reg[0].which_io)<<32UL));
963 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
964 }
965 break;
966 } 985 }
967 986
987 local_irq_save(flags);
988
968 if (mstk48t02_regs != NULL) { 989 if (mstk48t02_regs != NULL) {
969 /* Report a low battery voltage condition. */ 990 /* Report a low battery voltage condition. */
970 if (has_low_battery()) 991 if (has_low_battery())
@@ -983,12 +1004,14 @@ try_isa_clock:
983/* This is gets the master TICK_INT timer going. */ 1004/* This is gets the master TICK_INT timer going. */
984static unsigned long sparc64_init_timers(void) 1005static unsigned long sparc64_init_timers(void)
985{ 1006{
1007 struct device_node *dp;
1008 struct property *prop;
986 unsigned long clock; 1009 unsigned long clock;
987 int node;
988#ifdef CONFIG_SMP 1010#ifdef CONFIG_SMP
989 extern void smp_tick_init(void); 1011 extern void smp_tick_init(void);
990#endif 1012#endif
991 1013
1014 dp = of_find_node_by_path("/");
992 if (tlb_type == spitfire) { 1015 if (tlb_type == spitfire) {
993 unsigned long ver, manuf, impl; 1016 unsigned long ver, manuf, impl;
994 1017
@@ -999,18 +1022,17 @@ static unsigned long sparc64_init_timers(void)
999 if (manuf == 0x17 && impl == 0x13) { 1022 if (manuf == 0x17 && impl == 0x13) {
1000 /* Hummingbird, aka Ultra-IIe */ 1023 /* Hummingbird, aka Ultra-IIe */
1001 tick_ops = &hbtick_operations; 1024 tick_ops = &hbtick_operations;
1002 node = prom_root_node; 1025 prop = of_find_property(dp, "stick-frequency", NULL);
1003 clock = prom_getint(node, "stick-frequency");
1004 } else { 1026 } else {
1005 tick_ops = &tick_operations; 1027 tick_ops = &tick_operations;
1006 cpu_find_by_instance(0, &node, NULL); 1028 cpu_find_by_instance(0, &dp, NULL);
1007 clock = prom_getint(node, "clock-frequency"); 1029 prop = of_find_property(dp, "clock-frequency", NULL);
1008 } 1030 }
1009 } else { 1031 } else {
1010 tick_ops = &stick_operations; 1032 tick_ops = &stick_operations;
1011 node = prom_root_node; 1033 prop = of_find_property(dp, "stick-frequency", NULL);
1012 clock = prom_getint(node, "stick-frequency");
1013 } 1034 }
1035 clock = *(unsigned int *) prop->value;
1014 timer_tick_offset = clock / HZ; 1036 timer_tick_offset = clock / HZ;
1015 1037
1016#ifdef CONFIG_SMP 1038#ifdef CONFIG_SMP