clocksource/drivers/arm_arch_timer: Fix DEFINE_PER_CPU expansion
[platform/kernel/linux-exynos.git] / drivers / clocksource / arm_arch_timer.c
index fd4b7f6..a328d2c 100644 (file)
@@ -78,6 +78,7 @@ static bool arch_counter_suspend_stop;
 static bool vdso_default = true;
 
 static bool evtstrm_enable = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM);
+static bool mct_enable = IS_ENABLED(CONFIG_CLKSRC_EXYNOS_MCT);
 
 static int __init early_evtstrm_cfg(char *buf)
 {
@@ -299,8 +300,7 @@ static u64 notrace arm64_858921_read_cntvct_el0(void)
 #endif
 
 #ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
-DEFINE_PER_CPU(const struct arch_timer_erratum_workaround *,
-              timer_unstable_counter_workaround);
+DEFINE_PER_CPU(const struct arch_timer_erratum_workaround *, timer_unstable_counter_workaround);
 EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround);
 
 DEFINE_STATIC_KEY_FALSE(arch_timer_read_ool_enabled);
@@ -892,7 +892,7 @@ static void __init arch_counter_register(unsigned type)
        if (type & ARCH_TIMER_TYPE_CP15) {
                if (IS_ENABLED(CONFIG_ARM64) ||
                    arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI)
-                       arch_timer_read_counter = arch_counter_get_cntvct;
+                       arch_timer_read_counter = arch_counter_get_cntpct;
                else
                        arch_timer_read_counter = arch_counter_get_cntpct;
 
@@ -1018,12 +1018,25 @@ static int __init arch_timer_register(void)
                goto out_unreg_notify;
 
 
-       /* Register and immediately configure the timer on the boot CPU */
-       err = cpuhp_setup_state(CPUHP_AP_ARM_ARCH_TIMER_STARTING,
-                               "clockevents/arm/arch_timer:starting",
-                               arch_timer_starting_cpu, arch_timer_dying_cpu);
-       if (err)
-               goto out_unreg_cpupm;
+       if (mct_enable) {
+               /*
+                * FIXME: The arm64 architecture enables the arm_arch_timer always
+                * even if arm_arch_timer is not stable. When Exynos5433 uses the
+                * arm_arch_timer, it fails to enable/disble the secondary cpu.
+                * To fix the hotplug issue of secondary cpu, if Exynos's MCT timer
+                * is enabled, arm_arch_timer doesn't register the clockevent
+                * for Per-CPU.
+                */
+               return 0;
+       } else {
+               /* Register and immediately configure the timer on the boot CPU */
+               err = cpuhp_setup_state(CPUHP_AP_ARM_ARCH_TIMER_STARTING,
+                                       "clockevents/arm/arch_timer:starting",
+                                       arch_timer_starting_cpu, arch_timer_dying_cpu);
+               if (err)
+                       goto out_unreg_cpupm;
+       }
+
        return 0;
 
 out_unreg_cpupm:
@@ -1268,10 +1281,6 @@ arch_timer_mem_find_best_frame(struct arch_timer_mem *timer_mem)
 
        iounmap(cntctlbase);
 
-       if (!best_frame)
-               pr_err("Unable to find a suitable frame in timer @ %pa\n",
-                       &timer_mem->cntctlbase);
-
        return best_frame;
 }
 
@@ -1372,6 +1381,8 @@ static int __init arch_timer_mem_of_init(struct device_node *np)
 
        frame = arch_timer_mem_find_best_frame(timer_mem);
        if (!frame) {
+               pr_err("Unable to find a suitable frame in timer @ %pa\n",
+                       &timer_mem->cntctlbase);
                ret = -EINVAL;
                goto out;
        }
@@ -1420,7 +1431,7 @@ arch_timer_mem_verify_cntfrq(struct arch_timer_mem *timer_mem)
 static int __init arch_timer_mem_acpi_init(int platform_timer_count)
 {
        struct arch_timer_mem *timers, *timer;
-       struct arch_timer_mem_frame *frame;
+       struct arch_timer_mem_frame *frame, *best_frame = NULL;
        int timer_count, i, ret = 0;
 
        timers = kcalloc(platform_timer_count, sizeof(*timers),
@@ -1432,14 +1443,6 @@ static int __init arch_timer_mem_acpi_init(int platform_timer_count)
        if (ret || !timer_count)
                goto out;
 
-       for (i = 0; i < timer_count; i++) {
-               ret = arch_timer_mem_verify_cntfrq(&timers[i]);
-               if (ret) {
-                       pr_err("Disabling MMIO timers due to CNTFRQ mismatch\n");
-                       goto out;
-               }
-       }
-
        /*
         * While unlikely, it's theoretically possible that none of the frames
         * in a timer expose the combination of feature we want.
@@ -1448,12 +1451,26 @@ static int __init arch_timer_mem_acpi_init(int platform_timer_count)
                timer = &timers[i];
 
                frame = arch_timer_mem_find_best_frame(timer);
-               if (frame)
-                       break;
+               if (!best_frame)
+                       best_frame = frame;
+
+               ret = arch_timer_mem_verify_cntfrq(timer);
+               if (ret) {
+                       pr_err("Disabling MMIO timers due to CNTFRQ mismatch\n");
+                       goto out;
+               }
+
+               if (!best_frame) /* implies !frame */
+                       /*
+                        * Only complain about missing suitable frames if we
+                        * haven't already found one in a previous iteration.
+                        */
+                       pr_err("Unable to find a suitable frame in timer @ %pa\n",
+                               &timer->cntctlbase);
        }
 
-       if (frame)
-               ret = arch_timer_mem_frame_register(frame);
+       if (best_frame)
+               ret = arch_timer_mem_frame_register(best_frame);
 out:
        kfree(timers);
        return ret;