Commit-ID:  b23d8e527815954768861bb20d2b224009fff7cd
Gitweb:     http://git.kernel.org/tip/b23d8e527815954768861bb20d2b224009fff7cd
Author:     Viresh Kumar <viresh.ku...@linaro.org>
AuthorDate: Thu, 16 Jul 2015 16:28:44 +0530
Committer:  Thomas Gleixner <t...@linutronix.de>
CommitDate: Thu, 30 Jul 2015 00:51:47 +0200

x86/apic: Migrate apic timer to new set_state interface

Migrate apic driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

We weren't doing anything while switching to resume mode and so that
callback isn't implemented.

Signed-off-by: Viresh Kumar <viresh.ku...@linaro.org>
Cc: linaro-ker...@lists.linaro.org
Cc: Jiang Liu <jiang....@linux.intel.com>
Cc: Borislav Petkov <b...@alien8.de>
Cc: David Rientjes <rient...@google.com>
Cc: Bandan Das <b...@redhat.com>
Link: 
http://lkml.kernel.org/r/1896ac5989d27f2ac37f4786af9bd537e1921b83.1437042675.git.viresh.ku...@linaro.org
Signed-off-by: Thomas Gleixner <t...@linutronix.de>
---
 arch/x86/kernel/apic/apic.c | 86 +++++++++++++++++++++++++++------------------
 1 file changed, 51 insertions(+), 35 deletions(-)

diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index dcb5285..ecd6705 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -462,40 +462,53 @@ static int lapic_next_deadline(unsigned long delta,
        return 0;
 }
 
-/*
- * Setup the lapic timer in periodic or oneshot mode
- */
-static void lapic_timer_setup(enum clock_event_mode mode,
-                             struct clock_event_device *evt)
+static int lapic_timer_shutdown(struct clock_event_device *evt)
 {
        unsigned long flags;
        unsigned int v;
 
        /* Lapic used as dummy for broadcast ? */
        if (evt->features & CLOCK_EVT_FEAT_DUMMY)
-               return;
+               return 0;
 
        local_irq_save(flags);
 
-       switch (mode) {
-       case CLOCK_EVT_MODE_PERIODIC:
-       case CLOCK_EVT_MODE_ONESHOT:
-               __setup_APIC_LVTT(lapic_timer_frequency,
-                                 mode != CLOCK_EVT_MODE_PERIODIC, 1);
-               break;
-       case CLOCK_EVT_MODE_UNUSED:
-       case CLOCK_EVT_MODE_SHUTDOWN:
-               v = apic_read(APIC_LVTT);
-               v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
-               apic_write(APIC_LVTT, v);
-               apic_write(APIC_TMICT, 0);
-               break;
-       case CLOCK_EVT_MODE_RESUME:
-               /* Nothing to do here */
-               break;
-       }
+       v = apic_read(APIC_LVTT);
+       v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
+       apic_write(APIC_LVTT, v);
+       apic_write(APIC_TMICT, 0);
+
+       local_irq_restore(flags);
+
+       return 0;
+}
+
+static inline int
+lapic_timer_set_periodic_oneshot(struct clock_event_device *evt, bool oneshot)
+{
+       unsigned long flags;
+
+       /* Lapic used as dummy for broadcast ? */
+       if (evt->features & CLOCK_EVT_FEAT_DUMMY)
+               return 0;
+
+       local_irq_save(flags);
+
+       __setup_APIC_LVTT(lapic_timer_frequency, oneshot, 1);
 
        local_irq_restore(flags);
+
+       return 0;
+}
+
+static int lapic_timer_set_periodic(struct clock_event_device *evt)
+{
+       return lapic_timer_set_periodic_oneshot(evt, false);
+}
+
+static int lapic_timer_set_oneshot(struct clock_event_device *evt)
+{
+       return lapic_timer_set_periodic_oneshot(evt, true);
 }
 
 /*
@@ -513,15 +526,18 @@ static void lapic_timer_broadcast(const struct cpumask 
*mask)
  * The local apic timer can be used for any function which is CPU local.
  */
 static struct clock_event_device lapic_clockevent = {
-       .name           = "lapic",
-       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT
-                       | CLOCK_EVT_FEAT_C3STOP | CLOCK_EVT_FEAT_DUMMY,
-       .shift          = 32,
-       .set_mode       = lapic_timer_setup,
-       .set_next_event = lapic_next_event,
-       .broadcast      = lapic_timer_broadcast,
-       .rating         = 100,
-       .irq            = -1,
+       .name                   = "lapic",
+       .features               = CLOCK_EVT_FEAT_PERIODIC |
+                                 CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP
+                                 | CLOCK_EVT_FEAT_DUMMY,
+       .shift                  = 32,
+       .set_state_shutdown     = lapic_timer_shutdown,
+       .set_state_periodic     = lapic_timer_set_periodic,
+       .set_state_oneshot      = lapic_timer_set_oneshot,
+       .set_next_event         = lapic_next_event,
+       .broadcast              = lapic_timer_broadcast,
+       .rating                 = 100,
+       .irq                    = -1,
 };
 static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
 
@@ -778,7 +794,7 @@ static int __init calibrate_APIC_clock(void)
                 * Setup the apic timer manually
                 */
                levt->event_handler = lapic_cal_handler;
-               lapic_timer_setup(CLOCK_EVT_MODE_PERIODIC, levt);
+               lapic_timer_set_periodic(levt);
                lapic_cal_loops = -1;
 
                /* Let the interrupts run */
@@ -788,7 +804,7 @@ static int __init calibrate_APIC_clock(void)
                        cpu_relax();
 
                /* Stop the lapic timer */
-               lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, levt);
+               lapic_timer_shutdown(levt);
 
                /* Jiffies delta */
                deltaj = lapic_cal_j2 - lapic_cal_j1;
@@ -878,7 +894,7 @@ static void local_apic_timer_interrupt(void)
        if (!evt->event_handler) {
                pr_warning("Spurious LAPIC timer interrupt on cpu %d\n", cpu);
                /* Switch it off */
-               lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, evt);
+               lapic_timer_shutdown(evt);
                return;
        }
 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to