diff options
Diffstat (limited to 'drivers/clocksource/arm_arch_timer.c')
-rw-r--r-- | drivers/clocksource/arm_arch_timer.c | 52 |
1 files changed, 33 insertions, 19 deletions
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 4814446a0024..d0cda68e2c41 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c | |||
@@ -693,25 +693,26 @@ arch_timer_needs_probing(int type, const struct of_device_id *matches) | |||
693 | return needs_probing; | 693 | return needs_probing; |
694 | } | 694 | } |
695 | 695 | ||
696 | static void __init arch_timer_common_init(void) | 696 | static int __init arch_timer_common_init(void) |
697 | { | 697 | { |
698 | unsigned mask = ARCH_CP15_TIMER | ARCH_MEM_TIMER; | 698 | unsigned mask = ARCH_CP15_TIMER | ARCH_MEM_TIMER; |
699 | 699 | ||
700 | /* Wait until both nodes are probed if we have two timers */ | 700 | /* Wait until both nodes are probed if we have two timers */ |
701 | if ((arch_timers_present & mask) != mask) { | 701 | if ((arch_timers_present & mask) != mask) { |
702 | if (arch_timer_needs_probing(ARCH_MEM_TIMER, arch_timer_mem_of_match)) | 702 | if (arch_timer_needs_probing(ARCH_MEM_TIMER, arch_timer_mem_of_match)) |
703 | return; | 703 | return 0; |
704 | if (arch_timer_needs_probing(ARCH_CP15_TIMER, arch_timer_of_match)) | 704 | if (arch_timer_needs_probing(ARCH_CP15_TIMER, arch_timer_of_match)) |
705 | return; | 705 | return 0; |
706 | } | 706 | } |
707 | 707 | ||
708 | arch_timer_banner(arch_timers_present); | 708 | arch_timer_banner(arch_timers_present); |
709 | arch_counter_register(arch_timers_present); | 709 | arch_counter_register(arch_timers_present); |
710 | arch_timer_arch_init(); | 710 | return arch_timer_arch_init(); |
711 | } | 711 | } |
712 | 712 | ||
713 | static void __init arch_timer_init(void) | 713 | static int __init arch_timer_init(void) |
714 | { | 714 | { |
715 | int ret; | ||
715 | /* | 716 | /* |
716 | * If HYP mode is available, we know that the physical timer | 717 | * If HYP mode is available, we know that the physical timer |
717 | * has been configured to be accessible from PL1. Use it, so | 718 | * has been configured to be accessible from PL1. Use it, so |
@@ -739,23 +740,30 @@ static void __init arch_timer_init(void) | |||
739 | 740 | ||
740 | if (!has_ppi) { | 741 | if (!has_ppi) { |
741 | pr_warn("arch_timer: No interrupt available, giving up\n"); | 742 | pr_warn("arch_timer: No interrupt available, giving up\n"); |
742 | return; | 743 | return -EINVAL; |
743 | } | 744 | } |
744 | } | 745 | } |
745 | 746 | ||
746 | arch_timer_register(); | 747 | ret = arch_timer_register(); |
747 | arch_timer_common_init(); | 748 | if (ret) |
749 | return ret; | ||
750 | |||
751 | ret = arch_timer_common_init(); | ||
752 | if (ret) | ||
753 | return ret; | ||
748 | 754 | ||
749 | arch_timer_kvm_info.virtual_irq = arch_timer_ppi[VIRT_PPI]; | 755 | arch_timer_kvm_info.virtual_irq = arch_timer_ppi[VIRT_PPI]; |
756 | |||
757 | return 0; | ||
750 | } | 758 | } |
751 | 759 | ||
752 | static void __init arch_timer_of_init(struct device_node *np) | 760 | static int __init arch_timer_of_init(struct device_node *np) |
753 | { | 761 | { |
754 | int i; | 762 | int i; |
755 | 763 | ||
756 | if (arch_timers_present & ARCH_CP15_TIMER) { | 764 | if (arch_timers_present & ARCH_CP15_TIMER) { |
757 | pr_warn("arch_timer: multiple nodes in dt, skipping\n"); | 765 | pr_warn("arch_timer: multiple nodes in dt, skipping\n"); |
758 | return; | 766 | return 0; |
759 | } | 767 | } |
760 | 768 | ||
761 | arch_timers_present |= ARCH_CP15_TIMER; | 769 | arch_timers_present |= ARCH_CP15_TIMER; |
@@ -774,23 +782,23 @@ static void __init arch_timer_of_init(struct device_node *np) | |||
774 | of_property_read_bool(np, "arm,cpu-registers-not-fw-configured")) | 782 | of_property_read_bool(np, "arm,cpu-registers-not-fw-configured")) |
775 | arch_timer_uses_ppi = PHYS_SECURE_PPI; | 783 | arch_timer_uses_ppi = PHYS_SECURE_PPI; |
776 | 784 | ||
777 | arch_timer_init(); | 785 | return arch_timer_init(); |
778 | } | 786 | } |
779 | CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init); | 787 | CLOCKSOURCE_OF_DECLARE_RET(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init); |
780 | CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_of_init); | 788 | CLOCKSOURCE_OF_DECLARE_RET(armv8_arch_timer, "arm,armv8-timer", arch_timer_of_init); |
781 | 789 | ||
782 | static void __init arch_timer_mem_init(struct device_node *np) | 790 | static int __init arch_timer_mem_init(struct device_node *np) |
783 | { | 791 | { |
784 | struct device_node *frame, *best_frame = NULL; | 792 | struct device_node *frame, *best_frame = NULL; |
785 | void __iomem *cntctlbase, *base; | 793 | void __iomem *cntctlbase, *base; |
786 | unsigned int irq; | 794 | unsigned int irq, ret = -EINVAL; |
787 | u32 cnttidr; | 795 | u32 cnttidr; |
788 | 796 | ||
789 | arch_timers_present |= ARCH_MEM_TIMER; | 797 | arch_timers_present |= ARCH_MEM_TIMER; |
790 | cntctlbase = of_iomap(np, 0); | 798 | cntctlbase = of_iomap(np, 0); |
791 | if (!cntctlbase) { | 799 | if (!cntctlbase) { |
792 | pr_err("arch_timer: Can't find CNTCTLBase\n"); | 800 | pr_err("arch_timer: Can't find CNTCTLBase\n"); |
793 | return; | 801 | return -ENXIO; |
794 | } | 802 | } |
795 | 803 | ||
796 | cnttidr = readl_relaxed(cntctlbase + CNTTIDR); | 804 | cnttidr = readl_relaxed(cntctlbase + CNTTIDR); |
@@ -830,6 +838,7 @@ static void __init arch_timer_mem_init(struct device_node *np) | |||
830 | best_frame = of_node_get(frame); | 838 | best_frame = of_node_get(frame); |
831 | } | 839 | } |
832 | 840 | ||
841 | ret= -ENXIO; | ||
833 | base = arch_counter_base = of_iomap(best_frame, 0); | 842 | base = arch_counter_base = of_iomap(best_frame, 0); |
834 | if (!base) { | 843 | if (!base) { |
835 | pr_err("arch_timer: Can't map frame's registers\n"); | 844 | pr_err("arch_timer: Can't map frame's registers\n"); |
@@ -841,6 +850,7 @@ static void __init arch_timer_mem_init(struct device_node *np) | |||
841 | else | 850 | else |
842 | irq = irq_of_parse_and_map(best_frame, 0); | 851 | irq = irq_of_parse_and_map(best_frame, 0); |
843 | 852 | ||
853 | ret = -EINVAL; | ||
844 | if (!irq) { | 854 | if (!irq) { |
845 | pr_err("arch_timer: Frame missing %s irq", | 855 | pr_err("arch_timer: Frame missing %s irq", |
846 | arch_timer_mem_use_virtual ? "virt" : "phys"); | 856 | arch_timer_mem_use_virtual ? "virt" : "phys"); |
@@ -848,13 +858,17 @@ static void __init arch_timer_mem_init(struct device_node *np) | |||
848 | } | 858 | } |
849 | 859 | ||
850 | arch_timer_detect_rate(base, np); | 860 | arch_timer_detect_rate(base, np); |
851 | arch_timer_mem_register(base, irq); | 861 | ret = arch_timer_mem_register(base, irq); |
852 | arch_timer_common_init(); | 862 | if (ret) |
863 | goto out; | ||
864 | |||
865 | return arch_timer_common_init(); | ||
853 | out: | 866 | out: |
854 | iounmap(cntctlbase); | 867 | iounmap(cntctlbase); |
855 | of_node_put(best_frame); | 868 | of_node_put(best_frame); |
869 | return ret; | ||
856 | } | 870 | } |
857 | CLOCKSOURCE_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem", | 871 | CLOCKSOURCE_OF_DECLARE_RET(armv7_arch_timer_mem, "arm,armv7-timer-mem", |
858 | arch_timer_mem_init); | 872 | arch_timer_mem_init); |
859 | 873 | ||
860 | #ifdef CONFIG_ACPI | 874 | #ifdef CONFIG_ACPI |