aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time/tick-broadcast.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2015-04-02 20:05:15 -0400
committerIngo Molnar <mingo@kernel.org>2015-04-03 02:44:33 -0400
commit1fe5d5c3c9ba0c4ade18e3325cba0ffe35127941 (patch)
treeb07d74d6468aa0bf1e2b107bb82d62b9fe6638d4 /kernel/time/tick-broadcast.c
parent89feddbfe7023ccfb4a6d7f5e3f5161d91b28b18 (diff)
clockevents: Provide explicit broadcast oneshot control functions
clockevents_notify() is a leftover from the early design of the clockevents facility. It's really not a notification mechanism, it's a multiplex call. We are way better off to have explicit calls instead of this monstrosity. Split out the broadcast oneshot control into a separate function and provide inline helpers. Switch clockevents_notify() over. This will go away once all callers are converted. This also gets rid of the nested locking of clockevents_lock and broadcast_lock. The broadcast oneshot control functions do not require clockevents_lock. Only the managing functions (setup/shutdown/suspend/resume of the broadcast device require clockevents_lock. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Cc: Alexandre Courbot <gnurou@gmail.com> Cc: Daniel Lezcano <daniel.lezcano@linaro.org> Cc: Len Brown <lenb@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephen Warren <swarren@wwwdotorg.org> Cc: Thierry Reding <thierry.reding@gmail.com> Cc: Tony Lindgren <tony@atomide.com> Link: http://lkml.kernel.org/r/13000649.8qZuEDV0OA@vostro.rjw.lan Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/time/tick-broadcast.c')
-rw-r--r--kernel/time/tick-broadcast.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index 1a0bee04ef8c..55e43f20987a 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -687,18 +687,23 @@ void hotplug_cpu__broadcast_tick_pull(int deadcpu)
687 raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); 687 raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
688} 688}
689 689
690/* 690/**
691 * Powerstate information: The system enters/leaves a state, where 691 * tick_broadcast_oneshot_control - Enter/exit broadcast oneshot mode
692 * affected devices might stop 692 * @state: The target state (enter/exit)
693 *
694 * The system enters/leaves a state, where affected devices might stop
693 * Returns 0 on success, -EBUSY if the cpu is used to broadcast wakeups. 695 * Returns 0 on success, -EBUSY if the cpu is used to broadcast wakeups.
696 *
697 * Called with interrupts disabled, so clockevents_lock is not
698 * required here because the local clock event device cannot go away
699 * under us.
694 */ 700 */
695int tick_broadcast_oneshot_control(unsigned long reason) 701int tick_broadcast_oneshot_control(enum tick_broadcast_state state)
696{ 702{
697 struct clock_event_device *bc, *dev; 703 struct clock_event_device *bc, *dev;
698 struct tick_device *td; 704 struct tick_device *td;
699 unsigned long flags;
700 ktime_t now;
701 int cpu, ret = 0; 705 int cpu, ret = 0;
706 ktime_t now;
702 707
703 /* 708 /*
704 * Periodic mode does not care about the enter/exit of power 709 * Periodic mode does not care about the enter/exit of power
@@ -711,17 +716,17 @@ int tick_broadcast_oneshot_control(unsigned long reason)
711 * We are called with preemtion disabled from the depth of the 716 * We are called with preemtion disabled from the depth of the
712 * idle code, so we can't be moved away. 717 * idle code, so we can't be moved away.
713 */ 718 */
714 cpu = smp_processor_id(); 719 td = this_cpu_ptr(&tick_cpu_device);
715 td = &per_cpu(tick_cpu_device, cpu);
716 dev = td->evtdev; 720 dev = td->evtdev;
717 721
718 if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) 722 if (!(dev->features & CLOCK_EVT_FEAT_C3STOP))
719 return 0; 723 return 0;
720 724
725 raw_spin_lock(&tick_broadcast_lock);
721 bc = tick_broadcast_device.evtdev; 726 bc = tick_broadcast_device.evtdev;
727 cpu = smp_processor_id();
722 728
723 raw_spin_lock_irqsave(&tick_broadcast_lock, flags); 729 if (state == TICK_BROADCAST_ENTER) {
724 if (reason == CLOCK_EVT_NOTIFY_BROADCAST_ENTER) {
725 if (!cpumask_test_and_set_cpu(cpu, tick_broadcast_oneshot_mask)) { 730 if (!cpumask_test_and_set_cpu(cpu, tick_broadcast_oneshot_mask)) {
726 WARN_ON_ONCE(cpumask_test_cpu(cpu, tick_broadcast_pending_mask)); 731 WARN_ON_ONCE(cpumask_test_cpu(cpu, tick_broadcast_pending_mask));
727 broadcast_shutdown_local(bc, dev); 732 broadcast_shutdown_local(bc, dev);
@@ -813,9 +818,10 @@ int tick_broadcast_oneshot_control(unsigned long reason)
813 } 818 }
814 } 819 }
815out: 820out:
816 raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); 821 raw_spin_unlock(&tick_broadcast_lock);
817 return ret; 822 return ret;
818} 823}
824EXPORT_SYMBOL_GPL(tick_broadcast_oneshot_control);
819 825
820/* 826/*
821 * Reset the one shot broadcast for a cpu 827 * Reset the one shot broadcast for a cpu