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.c368
1 files changed, 194 insertions, 174 deletions
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index aa5438a4fd50..d072b8632ccd 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -756,24 +756,200 @@ retry:
756 return -EOPNOTSUPP; 756 return -EOPNOTSUPP;
757} 757}
758 758
759void __init clock_probe(void) 759static int __init clock_model_matches(char *model)
760{
761 if (strcmp(model, "mk48t02") &&
762 strcmp(model, "mk48t08") &&
763 strcmp(model, "mk48t59") &&
764 strcmp(model, "m5819") &&
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)
760{ 798{
761 struct linux_prom_registers clk_reg[2]; 799 struct linux_prom_registers clk_reg[2];
762 char model[128]; 800 char model[64];
763 int node, busnd = -1, err; 801 int node;
764 unsigned long flags; 802
765 struct linux_central *cbus; 803 if (!central_bus)
804 return 0;
805
806 /* Get Central FHC's prom node. */
807 node = central_bus->child->prom_node;
808
809 /* Then get the first child device below it. */
810 node = prom_getchild(node);
811
812 while (node) {
813 prom_getstring(node, "model", model, sizeof(model));
814 if (!clock_model_matches(model))
815 goto next_sibling;
816
817 prom_getproperty(node, "reg", (char *)clk_reg,
818 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 node = prom_getsibling(node);
828 }
829
830 return 0;
831}
832
766#ifdef CONFIG_PCI 833#ifdef CONFIG_PCI
767 struct linux_ebus *ebus = NULL; 834static void __init clock_isa_ebus_assign_regs(struct resource *res, char *model)
768 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}
769#endif 942#endif
943
944void __init clock_probe(void)
945{
770 static int invoked; 946 static int invoked;
947 unsigned long flags;
771 948
772 if (invoked) 949 if (invoked)
773 return; 950 return;
774 invoked = 1; 951 invoked = 1;
775 952
776
777 if (this_is_starfire) { 953 if (this_is_starfire) {
778 xtime.tv_sec = starfire_get_time(); 954 xtime.tv_sec = starfire_get_time();
779 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); 955 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
@@ -789,183 +965,27 @@ void __init clock_probe(void)
789 return; 965 return;
790 } 966 }
791 967
792 local_irq_save(flags);
793
794 cbus = central_bus;
795 if (cbus != NULL)
796 busnd = central_bus->child->prom_node;
797
798 /* Check FHC Central then EBUSs then ISA bridges then SBUSs. 968 /* Check FHC Central then EBUSs then ISA bridges then SBUSs.
799 * That way we handle the presence of multiple properly. 969 * That way we handle the presence of multiple properly.
800 * 970 *
801 * As a special case, machines with Central must provide the 971 * As a special case, machines with Central must provide the
802 * timer chip there. 972 * timer chip there.
803 */ 973 */
974 if (!clock_probe_central() &&
804#ifdef CONFIG_PCI 975#ifdef CONFIG_PCI
805 if (ebus_chain != NULL) { 976 !clock_probe_ebus() &&
806 ebus = ebus_chain; 977 !clock_probe_isa() &&
807 if (busnd == -1)
808 busnd = ebus->prom_node;
809 }
810 if (isa_chain != NULL) {
811 isa_br = isa_chain;
812 if (busnd == -1)
813 busnd = isa_br->prom_node;
814 }
815#endif
816 if (sbus_root != NULL && busnd == -1)
817 busnd = sbus_root->prom_node;
818
819 if (busnd == -1) {
820 prom_printf("clock_probe: problem, cannot find bus to search.\n");
821 prom_halt();
822 }
823
824 node = prom_getchild(busnd);
825
826 while (1) {
827 if (!node)
828 model[0] = 0;
829 else
830 prom_getstring(node, "model", model, sizeof(model));
831 if (strcmp(model, "mk48t02") &&
832 strcmp(model, "mk48t08") &&
833 strcmp(model, "mk48t59") &&
834 strcmp(model, "m5819") &&
835 strcmp(model, "m5819p") &&
836 strcmp(model, "m5823") &&
837 strcmp(model, "ds1287")) {
838 if (cbus != NULL) {
839 prom_printf("clock_probe: Central bus lacks timer chip.\n");
840 prom_halt();
841 }
842
843 if (node != 0)
844 node = prom_getsibling(node);
845#ifdef CONFIG_PCI
846 while ((node == 0) && ebus != NULL) {
847 ebus = ebus->next;
848 if (ebus != NULL) {
849 busnd = ebus->prom_node;
850 node = prom_getchild(busnd);
851 }
852 }
853 while ((node == 0) && isa_br != NULL) {
854 isa_br = isa_br->next;
855 if (isa_br != NULL) {
856 busnd = isa_br->prom_node;
857 node = prom_getchild(busnd);
858 }
859 }
860#endif 978#endif
861 if (node == 0) { 979#ifdef CONFIG_SBUS
862 prom_printf("clock_probe: Cannot find timer chip\n"); 980 !clock_probe_sbus()
863 prom_halt();
864 }
865 continue;
866 }
867
868 err = prom_getproperty(node, "reg", (char *)clk_reg,
869 sizeof(clk_reg));
870 if(err == -1) {
871 prom_printf("clock_probe: Cannot get Mostek reg property\n");
872 prom_halt();
873 }
874
875 if (cbus != NULL) {
876 apply_fhc_ranges(central_bus->child, clk_reg, 1);
877 apply_central_ranges(central_bus, clk_reg, 1);
878 }
879#ifdef CONFIG_PCI
880 else if (ebus != NULL) {
881 struct linux_ebus_device *edev;
882
883 for_each_ebusdev(edev, ebus)
884 if (edev->prom_node == node)
885 break;
886 if (edev == NULL) {
887 if (isa_chain != NULL)
888 goto try_isa_clock;
889 prom_printf("%s: Mostek not probed by EBUS\n",
890 __FUNCTION__);
891 prom_halt();
892 }
893
894 if (!strcmp(model, "ds1287") ||
895 !strcmp(model, "m5819") ||
896 !strcmp(model, "m5819p") ||
897 !strcmp(model, "m5823")) {
898 ds1287_regs = edev->resource[0].start;
899 } else {
900 mstk48t59_regs = (void __iomem *)
901 edev->resource[0].start;
902 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
903 }
904 break;
905 }
906 else if (isa_br != NULL) {
907 struct sparc_isa_device *isadev;
908
909try_isa_clock:
910 for_each_isadev(isadev, isa_br)
911 if (isadev->prom_node == node)
912 break;
913 if (isadev == NULL) {
914 prom_printf("%s: Mostek not probed by ISA\n");
915 prom_halt();
916 }
917 if (!strcmp(model, "ds1287") ||
918 !strcmp(model, "m5819") ||
919 !strcmp(model, "m5819p") ||
920 !strcmp(model, "m5823")) {
921 ds1287_regs = isadev->resource.start;
922 } else {
923 mstk48t59_regs = (void __iomem *)
924 isadev->resource.start;
925 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
926 }
927 break;
928 }
929#endif 981#endif
930 else { 982 ) {
931 if (sbus_root->num_sbus_ranges) { 983 printk(KERN_WARNING "No clock chip found.\n");
932 int nranges = sbus_root->num_sbus_ranges; 984 return;
933 int rngc;
934
935 for (rngc = 0; rngc < nranges; rngc++)
936 if (clk_reg[0].which_io ==
937 sbus_root->sbus_ranges[rngc].ot_child_space)
938 break;
939 if (rngc == nranges) {
940 prom_printf("clock_probe: Cannot find ranges for "
941 "clock regs.\n");
942 prom_halt();
943 }
944 clk_reg[0].which_io =
945 sbus_root->sbus_ranges[rngc].ot_parent_space;
946 clk_reg[0].phys_addr +=
947 sbus_root->sbus_ranges[rngc].ot_parent_base;
948 }
949 }
950
951 if(model[5] == '0' && model[6] == '2') {
952 mstk48t02_regs = (void __iomem *)
953 (((u64)clk_reg[0].phys_addr) |
954 (((u64)clk_reg[0].which_io)<<32UL));
955 } else if(model[5] == '0' && model[6] == '8') {
956 mstk48t08_regs = (void __iomem *)
957 (((u64)clk_reg[0].phys_addr) |
958 (((u64)clk_reg[0].which_io)<<32UL));
959 mstk48t02_regs = mstk48t08_regs + MOSTEK_48T08_48T02;
960 } else {
961 mstk48t59_regs = (void __iomem *)
962 (((u64)clk_reg[0].phys_addr) |
963 (((u64)clk_reg[0].which_io)<<32UL));
964 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
965 }
966 break;
967 } 985 }
968 986
987 local_irq_save(flags);
988
969 if (mstk48t02_regs != NULL) { 989 if (mstk48t02_regs != NULL) {
970 /* Report a low battery voltage condition. */ 990 /* Report a low battery voltage condition. */
971 if (has_low_battery()) 991 if (has_low_battery())