arm/bL_switcher: Kill tick suspend hackery
authorThomas Gleixner <tglx@linutronix.de>
Wed, 25 Mar 2015 12:11:52 +0000 (13:11 +0100)
committerIngo Molnar <mingo@kernel.org>
Wed, 1 Apr 2015 12:23:00 +0000 (14:23 +0200)
Use the new tick_suspend/resume_local() and get rid of the
homebrewn implementation of these in the ARM bL switcher.  The
check for the cpumask is completely pointless.  There is no harm
to suspend a per cpu tick device unconditionally.  If that's a
real issue then we fix it proper at the core level and not with
some completely undocumented hacks in some random core code.

Move the tick internals to the core code, now that this nuisance
is gone.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
[ rjw: Rebase, changelog ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Nicolas Pitre <nicolas.pitre@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Link: http://lkml.kernel.org/r/1655112.Ws17YsMfN7@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/arm/common/bL_switcher.c
include/linux/clockchips.h
include/linux/tick.h
kernel/time/tick-common.c
kernel/time/tick-internal.h
kernel/time/tick-sched.h

index d4f970a4d255acebedef4bd39e6b2121651db8e1..37dc0fe1093fb24bb26b1c852c568bd8fcd3f6d2 100644 (file)
@@ -151,8 +151,6 @@ static int bL_switch_to(unsigned int new_cluster_id)
        unsigned int mpidr, this_cpu, that_cpu;
        unsigned int ob_mpidr, ob_cpu, ob_cluster, ib_mpidr, ib_cpu, ib_cluster;
        struct completion inbound_alive;
-       struct tick_device *tdev;
-       enum clock_event_state tdev_state;
        long volatile *handshake_ptr;
        int ipi_nr, ret;
 
@@ -219,13 +217,7 @@ static int bL_switch_to(unsigned int new_cluster_id)
        /* redirect GIC's SGIs to our counterpart */
        gic_migrate_target(bL_gic_id[ib_cpu][ib_cluster]);
 
-       tdev = tick_get_device(this_cpu);
-       if (tdev && !cpumask_equal(tdev->evtdev->cpumask, cpumask_of(this_cpu)))
-               tdev = NULL;
-       if (tdev) {
-               tdev_state = tdev->evtdev->state;
-               clockevents_set_state(tdev->evtdev, CLOCK_EVT_STATE_SHUTDOWN);
-       }
+       tick_suspend_local();
 
        ret = cpu_pm_enter();
 
@@ -251,11 +243,7 @@ static int bL_switch_to(unsigned int new_cluster_id)
 
        ret = cpu_pm_exit();
 
-       if (tdev) {
-               clockevents_set_state(tdev->evtdev, tdev_state);
-               clockevents_program_event(tdev->evtdev,
-                                         tdev->evtdev->next_event, 1);
-       }
+       tick_resume_local();
 
        trace_cpu_migrate_finish(ktime_get_real_ns(), ib_mpidr);
        local_fiq_enable();
index 50ce9750754f42608a7f886c8ff12300c8322399..3ac7e2d90374fd5f88f8a4130fa2aa7b827c20c4 100644 (file)
@@ -198,12 +198,6 @@ clockevents_calc_mult_shift(struct clock_event_device *ce, u32 freq, u32 minsec)
                                      freq, minsec);
 }
 
-/* Should be core only, but is abused by arm bl_switcher */
-extern void clockevents_set_state(struct clock_event_device *dev,
-                                enum clock_event_state state);
-extern int clockevents_program_event(struct clock_event_device *dev,
-                                    ktime_t expires, bool force);
-
 extern void clockevents_suspend(void);
 extern void clockevents_resume(void);
 
index a3d4d2840e7fa9160b739f10dede9fcd981ff777..589868b09affb53be3b366a04902c95064c0fe32 100644 (file)
 #include <linux/cpumask.h>
 #include <linux/sched.h>
 
-/* ARM BL switcher abuse support */
-#ifdef CONFIG_GENERIC_CLOCKEVENTS
-enum tick_device_mode {
-       TICKDEV_MODE_PERIODIC,
-       TICKDEV_MODE_ONESHOT,
-};
-
-struct tick_device {
-       struct clock_event_device *evtdev;
-       enum tick_device_mode mode;
-};
-extern struct tick_device *tick_get_device(int cpu);
-#endif
-
 #ifdef CONFIG_GENERIC_CLOCKEVENTS
 extern void __init tick_init(void);
 extern void tick_freeze(void);
 extern void tick_unfreeze(void);
-/* Should be core only, but XEN resume magic requires this */
+/* Should be core only, but ARM BL switcher requires it */
+extern void tick_suspend_local(void);
+/* Should be core only, but XEN resume magic and ARM BL switcher require it */
 extern void tick_resume_local(void);
 #else /* CONFIG_GENERIC_CLOCKEVENTS */
 static inline void tick_init(void) { }
 static inline void tick_freeze(void) { }
 static inline void tick_unfreeze(void) { }
+static inline void tick_suspend_local(void) { }
 static inline void tick_resume_local(void) { }
 #endif /* !CONFIG_GENERIC_CLOCKEVENTS */
 
index da796d65d1fb5356e66c5b90bf0622920c4ba807..e28ba5c044c51fafa9142cf3d2c9ae9179b5f8c2 100644 (file)
@@ -380,7 +380,7 @@ void tick_shutdown(unsigned int *cpup)
  *
  * No locks required. Nothing can change the per cpu device.
  */
-static void tick_suspend_local(void)
+void tick_suspend_local(void)
 {
        struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
 
index 6ba7bce732f250b6f3b347c1e59d2901e365d98e..5fc2dafabd58914e3bfe5d1be753068af2b78d1c 100644 (file)
@@ -28,6 +28,7 @@ extern bool tick_check_replacement(struct clock_event_device *curdev,
                                   struct clock_event_device *newdev);
 extern void tick_install_replacement(struct clock_event_device *dev);
 extern int tick_is_oneshot_available(void);
+extern struct tick_device *tick_get_device(int cpu);
 
 extern int clockevents_tick_resume(struct clock_event_device *dev);
 /* Check, if the device is functional or a dummy for broadcast */
@@ -39,6 +40,10 @@ static inline int tick_device_is_functional(struct clock_event_device *dev)
 extern void clockevents_shutdown(struct clock_event_device *dev);
 extern void clockevents_exchange_device(struct clock_event_device *old,
                                        struct clock_event_device *new);
+extern void clockevents_set_state(struct clock_event_device *dev,
+                                enum clock_event_state state);
+extern int clockevents_program_event(struct clock_event_device *dev,
+                                    ktime_t expires, bool force);
 extern void clockevents_handle_noop(struct clock_event_device *dev);
 extern int __clockevents_update_freq(struct clock_event_device *dev, u32 freq);
 extern ssize_t sysfs_get_uname(const char *buf, char *dst, size_t cnt);
index 930743249127ca0dec4695182e906ca98667f73e..28b5da3e1a176e62c081e965fbfc32090d3f1e74 100644 (file)
@@ -3,6 +3,16 @@
 
 #include <linux/hrtimer.h>
 
+enum tick_device_mode {
+       TICKDEV_MODE_PERIODIC,
+       TICKDEV_MODE_ONESHOT,
+};
+
+struct tick_device {
+       struct clock_event_device *evtdev;
+       enum tick_device_mode mode;
+};
+
 enum tick_nohz_mode {
        NOHZ_MODE_INACTIVE,
        NOHZ_MODE_LOWRES,