Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=667984d9e481e43a930a478c588dced98cb61fea
Commit:     667984d9e481e43a930a478c588dced98cb61fea
Parent:     889c94a14e38e749c8060f597ee7825ea0764229
Author:     Jordan Crouse <[EMAIL PROTECTED]>
AuthorDate: Tue Jan 22 23:30:16 2008 +0100
Committer:  Ingo Molnar <[EMAIL PROTECTED]>
CommitDate: Tue Jan 22 23:30:16 2008 +0100

    x86: GEODE fix a race condition in the MFGPT timer tick
    
    When we set the MFGPT timer tick, there is a chance that we'll
    immediately assert an event.  If for some reason the IRQ routing
    for this clock has been setup for some other purpose, then we
    could end up firing an interrupt into the SMM handler or worse.
    
    This rearranges the timer tick init function to initalize the handler
    before we set up the MFGPT clock to make sure that even if we get
    an event, it will go to the handler.
    
    Furthermore, in the handler we need to make sure that we clear the
    event, even if the timer isn't running.
    
    Signed-off-by: Jordan Crouse <[EMAIL PROTECTED]>
    Signed-off-by: Thomas Gleixner <[EMAIL PROTECTED]>
    Acked-by: Ingo Molnar <[EMAIL PROTECTED]>
    Tested-by: Arnd Hannemann <[EMAIL PROTECTED]>
---
 arch/x86/kernel/mfgpt_32.c |   15 ++++++++-------
 1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kernel/mfgpt_32.c b/arch/x86/kernel/mfgpt_32.c
index 0ab680f..3960ab7 100644
--- a/arch/x86/kernel/mfgpt_32.c
+++ b/arch/x86/kernel/mfgpt_32.c
@@ -278,12 +278,12 @@ static int mfgpt_next_event(unsigned long delta, struct 
clock_event_device *evt)
 
 static irqreturn_t mfgpt_tick(int irq, void *dev_id)
 {
+       /* Turn off the clock (and clear the event) */
+       mfgpt_disable_timer(mfgpt_event_clock);
+
        if (mfgpt_tick_mode == CLOCK_EVT_MODE_SHUTDOWN)
                return IRQ_HANDLED;
 
-       /* Turn off the clock */
-       mfgpt_disable_timer(mfgpt_event_clock);
-
        /* Clear the counter */
        geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_COUNTER, 0);
 
@@ -319,10 +319,6 @@ static int __init mfgpt_timer_setup(void)
        }
 
        mfgpt_event_clock = timer;
-       /* Set the clock scale and enable the event mode for CMP2 */
-       val = MFGPT_SCALE | (3 << 8);
-
-       geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_SETUP, val);
 
        /* Set up the IRQ on the MFGPT side */
        if (geode_mfgpt_setup_irq(mfgpt_event_clock, MFGPT_CMP2, irq)) {
@@ -339,6 +335,11 @@ static int __init mfgpt_timer_setup(void)
                goto err;
        }
 
+       /* Set the clock scale and enable the event mode for CMP2 */
+       val = MFGPT_SCALE | (3 << 8);
+
+       geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_SETUP, val);
+
        /* Set up the clock event */
        mfgpt_clockevent.mult = div_sc(MFGPT_HZ, NSEC_PER_SEC, 32);
        mfgpt_clockevent.min_delta_ns = clockevent_delta2ns(0xF,
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to