diff options
Diffstat (limited to 'kernel/irq/autoprobe.c')
| -rw-r--r-- | kernel/irq/autoprobe.c | 54 |
1 files changed, 22 insertions, 32 deletions
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c index 505798f86c3..394784c5706 100644 --- a/kernel/irq/autoprobe.c +++ b/kernel/irq/autoprobe.c | |||
| @@ -17,7 +17,7 @@ | |||
| 17 | /* | 17 | /* |
| 18 | * Autodetection depends on the fact that any interrupt that | 18 | * Autodetection depends on the fact that any interrupt that |
| 19 | * comes in on to an unassigned handler will get stuck with | 19 | * comes in on to an unassigned handler will get stuck with |
| 20 | * "IRQ_WAITING" cleared and the interrupt disabled. | 20 | * "IRQS_WAITING" cleared and the interrupt disabled. |
| 21 | */ | 21 | */ |
| 22 | static DEFINE_MUTEX(probing_active); | 22 | static DEFINE_MUTEX(probing_active); |
| 23 | 23 | ||
| @@ -32,7 +32,6 @@ unsigned long probe_irq_on(void) | |||
| 32 | { | 32 | { |
| 33 | struct irq_desc *desc; | 33 | struct irq_desc *desc; |
| 34 | unsigned long mask = 0; | 34 | unsigned long mask = 0; |
| 35 | unsigned int status; | ||
| 36 | int i; | 35 | int i; |
| 37 | 36 | ||
| 38 | /* | 37 | /* |
| @@ -46,13 +45,7 @@ unsigned long probe_irq_on(void) | |||
| 46 | */ | 45 | */ |
| 47 | for_each_irq_desc_reverse(i, desc) { | 46 | for_each_irq_desc_reverse(i, desc) { |
| 48 | raw_spin_lock_irq(&desc->lock); | 47 | raw_spin_lock_irq(&desc->lock); |
| 49 | if (!desc->action && !(desc->status & IRQ_NOPROBE)) { | 48 | if (!desc->action && irq_settings_can_probe(desc)) { |
| 50 | /* | ||
| 51 | * An old-style architecture might still have | ||
| 52 | * the handle_bad_irq handler there: | ||
| 53 | */ | ||
| 54 | compat_irq_chip_set_default_handler(desc); | ||
| 55 | |||
| 56 | /* | 49 | /* |
| 57 | * Some chips need to know about probing in | 50 | * Some chips need to know about probing in |
| 58 | * progress: | 51 | * progress: |
| @@ -60,7 +53,7 @@ unsigned long probe_irq_on(void) | |||
| 60 | if (desc->irq_data.chip->irq_set_type) | 53 | if (desc->irq_data.chip->irq_set_type) |
| 61 | desc->irq_data.chip->irq_set_type(&desc->irq_data, | 54 | desc->irq_data.chip->irq_set_type(&desc->irq_data, |
| 62 | IRQ_TYPE_PROBE); | 55 | IRQ_TYPE_PROBE); |
| 63 | desc->irq_data.chip->irq_startup(&desc->irq_data); | 56 | irq_startup(desc); |
| 64 | } | 57 | } |
| 65 | raw_spin_unlock_irq(&desc->lock); | 58 | raw_spin_unlock_irq(&desc->lock); |
| 66 | } | 59 | } |
| @@ -75,10 +68,12 @@ unsigned long probe_irq_on(void) | |||
| 75 | */ | 68 | */ |
| 76 | for_each_irq_desc_reverse(i, desc) { | 69 | for_each_irq_desc_reverse(i, desc) { |
| 77 | raw_spin_lock_irq(&desc->lock); | 70 | raw_spin_lock_irq(&desc->lock); |
| 78 | if (!desc->action && !(desc->status & IRQ_NOPROBE)) { | 71 | if (!desc->action && irq_settings_can_probe(desc)) { |
| 79 | desc->status |= IRQ_AUTODETECT | IRQ_WAITING; | 72 | desc->istate |= IRQS_AUTODETECT | IRQS_WAITING; |
| 80 | if (desc->irq_data.chip->irq_startup(&desc->irq_data)) | 73 | if (irq_startup(desc)) { |
| 81 | desc->status |= IRQ_PENDING; | 74 | irq_compat_set_pending(desc); |
| 75 | desc->istate |= IRQS_PENDING; | ||
| 76 | } | ||
| 82 | } | 77 | } |
| 83 | raw_spin_unlock_irq(&desc->lock); | 78 | raw_spin_unlock_irq(&desc->lock); |
| 84 | } | 79 | } |
| @@ -93,13 +88,12 @@ unsigned long probe_irq_on(void) | |||
| 93 | */ | 88 | */ |
| 94 | for_each_irq_desc(i, desc) { | 89 | for_each_irq_desc(i, desc) { |
| 95 | raw_spin_lock_irq(&desc->lock); | 90 | raw_spin_lock_irq(&desc->lock); |
| 96 | status = desc->status; | ||
| 97 | 91 | ||
| 98 | if (status & IRQ_AUTODETECT) { | 92 | if (desc->istate & IRQS_AUTODETECT) { |
| 99 | /* It triggered already - consider it spurious. */ | 93 | /* It triggered already - consider it spurious. */ |
| 100 | if (!(status & IRQ_WAITING)) { | 94 | if (!(desc->istate & IRQS_WAITING)) { |
| 101 | desc->status = status & ~IRQ_AUTODETECT; | 95 | desc->istate &= ~IRQS_AUTODETECT; |
| 102 | desc->irq_data.chip->irq_shutdown(&desc->irq_data); | 96 | irq_shutdown(desc); |
| 103 | } else | 97 | } else |
| 104 | if (i < 32) | 98 | if (i < 32) |
| 105 | mask |= 1 << i; | 99 | mask |= 1 << i; |
| @@ -125,20 +119,18 @@ EXPORT_SYMBOL(probe_irq_on); | |||
| 125 | */ | 119 | */ |
| 126 | unsigned int probe_irq_mask(unsigned long val) | 120 | unsigned int probe_irq_mask(unsigned long val) |
| 127 | { | 121 | { |
| 128 | unsigned int status, mask = 0; | 122 | unsigned int mask = 0; |
| 129 | struct irq_desc *desc; | 123 | struct irq_desc *desc; |
| 130 | int i; | 124 | int i; |
| 131 | 125 | ||
| 132 | for_each_irq_desc(i, desc) { | 126 | for_each_irq_desc(i, desc) { |
| 133 | raw_spin_lock_irq(&desc->lock); | 127 | raw_spin_lock_irq(&desc->lock); |
| 134 | status = desc->status; | 128 | if (desc->istate & IRQS_AUTODETECT) { |
| 135 | 129 | if (i < 16 && !(desc->istate & IRQS_WAITING)) | |
| 136 | if (status & IRQ_AUTODETECT) { | ||
| 137 | if (i < 16 && !(status & IRQ_WAITING)) | ||
| 138 | mask |= 1 << i; | 130 | mask |= 1 << i; |
| 139 | 131 | ||
| 140 | desc->status = status & ~IRQ_AUTODETECT; | 132 | desc->istate &= ~IRQS_AUTODETECT; |
| 141 | desc->irq_data.chip->irq_shutdown(&desc->irq_data); | 133 | irq_shutdown(desc); |
| 142 | } | 134 | } |
| 143 | raw_spin_unlock_irq(&desc->lock); | 135 | raw_spin_unlock_irq(&desc->lock); |
| 144 | } | 136 | } |
| @@ -169,20 +161,18 @@ int probe_irq_off(unsigned long val) | |||
| 169 | { | 161 | { |
| 170 | int i, irq_found = 0, nr_of_irqs = 0; | 162 | int i, irq_found = 0, nr_of_irqs = 0; |
| 171 | struct irq_desc *desc; | 163 | struct irq_desc *desc; |
| 172 | unsigned int status; | ||
| 173 | 164 | ||
| 174 | for_each_irq_desc(i, desc) { | 165 | for_each_irq_desc(i, desc) { |
| 175 | raw_spin_lock_irq(&desc->lock); | 166 | raw_spin_lock_irq(&desc->lock); |
| 176 | status = desc->status; | ||
| 177 | 167 | ||
| 178 | if (status & IRQ_AUTODETECT) { | 168 | if (desc->istate & IRQS_AUTODETECT) { |
| 179 | if (!(status & IRQ_WAITING)) { | 169 | if (!(desc->istate & IRQS_WAITING)) { |
| 180 | if (!nr_of_irqs) | 170 | if (!nr_of_irqs) |
| 181 | irq_found = i; | 171 | irq_found = i; |
| 182 | nr_of_irqs++; | 172 | nr_of_irqs++; |
| 183 | } | 173 | } |
| 184 | desc->status = status & ~IRQ_AUTODETECT; | 174 | desc->istate &= ~IRQS_AUTODETECT; |
| 185 | desc->irq_data.chip->irq_shutdown(&desc->irq_data); | 175 | irq_shutdown(desc); |
| 186 | } | 176 | } |
| 187 | raw_spin_unlock_irq(&desc->lock); | 177 | raw_spin_unlock_irq(&desc->lock); |
| 188 | } | 178 | } |
