~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to kernel/irq/spurious.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno, Martin Michlmayr
  • Date: 2011-04-06 13:53:30 UTC
  • mfrom: (43.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110406135330-wjufxhd0tvn3zx4z
Tags: 2.6.38-3
[ Ben Hutchings ]
* [ppc64] Add to linux-tools package architectures (Closes: #620124)
* [amd64] Save cr4 to mmu_cr4_features at boot time (Closes: #620284)
* appletalk: Fix bugs introduced when removing use of BKL
* ALSA: Fix yet another race in disconnection
* cciss: Fix lost command issue
* ath9k: Fix kernel panic in AR2427
* ses: Avoid kernel panic when lun 0 is not mapped
* PCI/ACPI: Report ASPM support to BIOS if not disabled from command line

[ Aurelien Jarno ]
* rtlwifi: fix build when PCI is not enabled.

[ Martin Michlmayr ]
* rtlwifi: Eliminate udelay calls with too large values (Closes: #620204)

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
#include <linux/moduleparam.h>
15
15
#include <linux/timer.h>
16
16
 
 
17
#include "internals.h"
 
18
 
17
19
static int irqfixup __read_mostly;
18
20
 
19
21
#define POLL_SPURIOUS_IRQ_INTERVAL (HZ/10)
28
30
        struct irqaction *action;
29
31
        int ok = 0, work = 0;
30
32
 
31
 
        spin_lock(&desc->lock);
 
33
        raw_spin_lock(&desc->lock);
32
34
        /* Already running on another processor */
33
35
        if (desc->status & IRQ_INPROGRESS) {
34
36
                /*
37
39
                 */
38
40
                if (desc->action && (desc->action->flags & IRQF_SHARED))
39
41
                        desc->status |= IRQ_PENDING;
40
 
                spin_unlock(&desc->lock);
 
42
                raw_spin_unlock(&desc->lock);
41
43
                return ok;
42
44
        }
43
45
        /* Honour the normal IRQ locking */
44
46
        desc->status |= IRQ_INPROGRESS;
45
47
        action = desc->action;
46
 
        spin_unlock(&desc->lock);
 
48
        raw_spin_unlock(&desc->lock);
47
49
 
48
50
        while (action) {
49
51
                /* Only shared IRQ handlers are safe to call */
56
58
        }
57
59
        local_irq_disable();
58
60
        /* Now clean up the flags */
59
 
        spin_lock(&desc->lock);
 
61
        raw_spin_lock(&desc->lock);
60
62
        action = desc->action;
61
63
 
62
64
        /*
68
70
                 * Perform real IRQ processing for the IRQ we deferred
69
71
                 */
70
72
                work = 1;
71
 
                spin_unlock(&desc->lock);
 
73
                raw_spin_unlock(&desc->lock);
72
74
                handle_IRQ_event(irq, action);
73
 
                spin_lock(&desc->lock);
 
75
                raw_spin_lock(&desc->lock);
74
76
                desc->status &= ~IRQ_PENDING;
75
77
        }
76
78
        desc->status &= ~IRQ_INPROGRESS;
78
80
         * If we did actual work for the real IRQ line we must let the
79
81
         * IRQ controller clean up too
80
82
         */
81
 
        if (work && desc->chip && desc->chip->end)
82
 
                desc->chip->end(irq);
83
 
        spin_unlock(&desc->lock);
 
83
        if (work)
 
84
                irq_end(irq, desc);
 
85
        raw_spin_unlock(&desc->lock);
84
86
 
85
87
        return ok;
86
88
}
104
106
        return ok;
105
107
}
106
108
 
107
 
static void poll_all_shared_irqs(void)
 
109
static void poll_spurious_irqs(unsigned long dummy)
108
110
{
109
111
        struct irq_desc *desc;
110
112
        int i;
125
127
                try_one_irq(i, desc);
126
128
                local_irq_enable();
127
129
        }
128
 
}
129
 
 
130
 
static void poll_spurious_irqs(unsigned long dummy)
131
 
{
132
 
        poll_all_shared_irqs();
133
130
 
134
131
        mod_timer(&poll_spurious_irq_timer,
135
132
                  jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
136
133
}
137
134
 
138
 
#ifdef CONFIG_DEBUG_SHIRQ
139
 
void debug_poll_all_shared_irqs(void)
140
 
{
141
 
        poll_all_shared_irqs();
142
 
}
143
 
#endif
144
 
 
145
135
/*
146
136
 * If 99,900 of the previous 100,000 interrupts have not been handled
147
137
 * then assume that the IRQ is stuck in some manner. Drop a diagnostic
232
222
                /*
233
223
                 * If we are seeing only the odd spurious IRQ caused by
234
224
                 * bus asynchronicity then don't eventually trigger an error,
235
 
                 * otherwise the couter becomes a doomsday timer for otherwise
 
225
                 * otherwise the counter becomes a doomsday timer for otherwise
236
226
                 * working systems
237
227
                 */
238
228
                if (time_after(jiffies, desc->last_unhandled + HZ/10))
266
256
                printk(KERN_EMERG "Disabling IRQ #%d\n", irq);
267
257
                desc->status |= IRQ_DISABLED | IRQ_SPURIOUS_DISABLED;
268
258
                desc->depth++;
269
 
                desc->chip->disable(irq);
 
259
                desc->irq_data.chip->irq_disable(&desc->irq_data);
270
260
 
271
261
                mod_timer(&poll_spurious_irq_timer,
272
262
                          jiffies + POLL_SPURIOUS_IRQ_INTERVAL);