diff options
Diffstat (limited to 'kernel/irq/chip.c')
-rw-r--r-- | kernel/irq/chip.c | 300 |
1 files changed, 209 insertions, 91 deletions
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index b7091d5ca2f8..3405761d6224 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c | |||
@@ -31,19 +31,19 @@ static void dynamic_irq_init_x(unsigned int irq, bool keep_chip_data) | |||
31 | 31 | ||
32 | /* Ensure we don't have left over values from a previous use of this irq */ | 32 | /* Ensure we don't have left over values from a previous use of this irq */ |
33 | raw_spin_lock_irqsave(&desc->lock, flags); | 33 | raw_spin_lock_irqsave(&desc->lock, flags); |
34 | desc->status = IRQ_DISABLED; | 34 | desc->status = IRQ_DEFAULT_INIT_FLAGS; |
35 | desc->chip = &no_irq_chip; | 35 | desc->irq_data.chip = &no_irq_chip; |
36 | desc->handle_irq = handle_bad_irq; | 36 | desc->handle_irq = handle_bad_irq; |
37 | desc->depth = 1; | 37 | desc->depth = 1; |
38 | desc->msi_desc = NULL; | 38 | desc->irq_data.msi_desc = NULL; |
39 | desc->handler_data = NULL; | 39 | desc->irq_data.handler_data = NULL; |
40 | if (!keep_chip_data) | 40 | if (!keep_chip_data) |
41 | desc->chip_data = NULL; | 41 | desc->irq_data.chip_data = NULL; |
42 | desc->action = NULL; | 42 | desc->action = NULL; |
43 | desc->irq_count = 0; | 43 | desc->irq_count = 0; |
44 | desc->irqs_unhandled = 0; | 44 | desc->irqs_unhandled = 0; |
45 | #ifdef CONFIG_SMP | 45 | #ifdef CONFIG_SMP |
46 | cpumask_setall(desc->affinity); | 46 | cpumask_setall(desc->irq_data.affinity); |
47 | #ifdef CONFIG_GENERIC_PENDING_IRQ | 47 | #ifdef CONFIG_GENERIC_PENDING_IRQ |
48 | cpumask_clear(desc->pending_mask); | 48 | cpumask_clear(desc->pending_mask); |
49 | #endif | 49 | #endif |
@@ -64,7 +64,7 @@ void dynamic_irq_init(unsigned int irq) | |||
64 | * dynamic_irq_init_keep_chip_data - initialize a dynamically allocated irq | 64 | * dynamic_irq_init_keep_chip_data - initialize a dynamically allocated irq |
65 | * @irq: irq number to initialize | 65 | * @irq: irq number to initialize |
66 | * | 66 | * |
67 | * does not set irq_to_desc(irq)->chip_data to NULL | 67 | * does not set irq_to_desc(irq)->irq_data.chip_data to NULL |
68 | */ | 68 | */ |
69 | void dynamic_irq_init_keep_chip_data(unsigned int irq) | 69 | void dynamic_irq_init_keep_chip_data(unsigned int irq) |
70 | { | 70 | { |
@@ -88,12 +88,12 @@ static void dynamic_irq_cleanup_x(unsigned int irq, bool keep_chip_data) | |||
88 | irq); | 88 | irq); |
89 | return; | 89 | return; |
90 | } | 90 | } |
91 | desc->msi_desc = NULL; | 91 | desc->irq_data.msi_desc = NULL; |
92 | desc->handler_data = NULL; | 92 | desc->irq_data.handler_data = NULL; |
93 | if (!keep_chip_data) | 93 | if (!keep_chip_data) |
94 | desc->chip_data = NULL; | 94 | desc->irq_data.chip_data = NULL; |
95 | desc->handle_irq = handle_bad_irq; | 95 | desc->handle_irq = handle_bad_irq; |
96 | desc->chip = &no_irq_chip; | 96 | desc->irq_data.chip = &no_irq_chip; |
97 | desc->name = NULL; | 97 | desc->name = NULL; |
98 | clear_kstat_irqs(desc); | 98 | clear_kstat_irqs(desc); |
99 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 99 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
@@ -112,7 +112,7 @@ void dynamic_irq_cleanup(unsigned int irq) | |||
112 | * dynamic_irq_cleanup_keep_chip_data - cleanup a dynamically allocated irq | 112 | * dynamic_irq_cleanup_keep_chip_data - cleanup a dynamically allocated irq |
113 | * @irq: irq number to initialize | 113 | * @irq: irq number to initialize |
114 | * | 114 | * |
115 | * does not set irq_to_desc(irq)->chip_data to NULL | 115 | * does not set irq_to_desc(irq)->irq_data.chip_data to NULL |
116 | */ | 116 | */ |
117 | void dynamic_irq_cleanup_keep_chip_data(unsigned int irq) | 117 | void dynamic_irq_cleanup_keep_chip_data(unsigned int irq) |
118 | { | 118 | { |
@@ -140,7 +140,7 @@ int set_irq_chip(unsigned int irq, struct irq_chip *chip) | |||
140 | 140 | ||
141 | raw_spin_lock_irqsave(&desc->lock, flags); | 141 | raw_spin_lock_irqsave(&desc->lock, flags); |
142 | irq_chip_set_defaults(chip); | 142 | irq_chip_set_defaults(chip); |
143 | desc->chip = chip; | 143 | desc->irq_data.chip = chip; |
144 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 144 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
145 | 145 | ||
146 | return 0; | 146 | return 0; |
@@ -193,7 +193,7 @@ int set_irq_data(unsigned int irq, void *data) | |||
193 | } | 193 | } |
194 | 194 | ||
195 | raw_spin_lock_irqsave(&desc->lock, flags); | 195 | raw_spin_lock_irqsave(&desc->lock, flags); |
196 | desc->handler_data = data; | 196 | desc->irq_data.handler_data = data; |
197 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 197 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
198 | return 0; | 198 | return 0; |
199 | } | 199 | } |
@@ -218,7 +218,7 @@ int set_irq_msi(unsigned int irq, struct msi_desc *entry) | |||
218 | } | 218 | } |
219 | 219 | ||
220 | raw_spin_lock_irqsave(&desc->lock, flags); | 220 | raw_spin_lock_irqsave(&desc->lock, flags); |
221 | desc->msi_desc = entry; | 221 | desc->irq_data.msi_desc = entry; |
222 | if (entry) | 222 | if (entry) |
223 | entry->irq = irq; | 223 | entry->irq = irq; |
224 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 224 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
@@ -243,19 +243,27 @@ int set_irq_chip_data(unsigned int irq, void *data) | |||
243 | return -EINVAL; | 243 | return -EINVAL; |
244 | } | 244 | } |
245 | 245 | ||
246 | if (!desc->chip) { | 246 | if (!desc->irq_data.chip) { |
247 | printk(KERN_ERR "BUG: bad set_irq_chip_data(IRQ#%d)\n", irq); | 247 | printk(KERN_ERR "BUG: bad set_irq_chip_data(IRQ#%d)\n", irq); |
248 | return -EINVAL; | 248 | return -EINVAL; |
249 | } | 249 | } |
250 | 250 | ||
251 | raw_spin_lock_irqsave(&desc->lock, flags); | 251 | raw_spin_lock_irqsave(&desc->lock, flags); |
252 | desc->chip_data = data; | 252 | desc->irq_data.chip_data = data; |
253 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 253 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
254 | 254 | ||
255 | return 0; | 255 | return 0; |
256 | } | 256 | } |
257 | EXPORT_SYMBOL(set_irq_chip_data); | 257 | EXPORT_SYMBOL(set_irq_chip_data); |
258 | 258 | ||
259 | struct irq_data *irq_get_irq_data(unsigned int irq) | ||
260 | { | ||
261 | struct irq_desc *desc = irq_to_desc(irq); | ||
262 | |||
263 | return desc ? &desc->irq_data : NULL; | ||
264 | } | ||
265 | EXPORT_SYMBOL_GPL(irq_get_irq_data); | ||
266 | |||
259 | /** | 267 | /** |
260 | * set_irq_nested_thread - Set/Reset the IRQ_NESTED_THREAD flag of an irq | 268 | * set_irq_nested_thread - Set/Reset the IRQ_NESTED_THREAD flag of an irq |
261 | * | 269 | * |
@@ -287,93 +295,216 @@ EXPORT_SYMBOL_GPL(set_irq_nested_thread); | |||
287 | /* | 295 | /* |
288 | * default enable function | 296 | * default enable function |
289 | */ | 297 | */ |
290 | static void default_enable(unsigned int irq) | 298 | static void default_enable(struct irq_data *data) |
291 | { | 299 | { |
292 | struct irq_desc *desc = irq_to_desc(irq); | 300 | struct irq_desc *desc = irq_data_to_desc(data); |
293 | 301 | ||
294 | desc->chip->unmask(irq); | 302 | desc->irq_data.chip->irq_unmask(&desc->irq_data); |
295 | desc->status &= ~IRQ_MASKED; | 303 | desc->status &= ~IRQ_MASKED; |
296 | } | 304 | } |
297 | 305 | ||
298 | /* | 306 | /* |
299 | * default disable function | 307 | * default disable function |
300 | */ | 308 | */ |
301 | static void default_disable(unsigned int irq) | 309 | static void default_disable(struct irq_data *data) |
302 | { | 310 | { |
303 | } | 311 | } |
304 | 312 | ||
305 | /* | 313 | /* |
306 | * default startup function | 314 | * default startup function |
307 | */ | 315 | */ |
308 | static unsigned int default_startup(unsigned int irq) | 316 | static unsigned int default_startup(struct irq_data *data) |
309 | { | 317 | { |
310 | struct irq_desc *desc = irq_to_desc(irq); | 318 | struct irq_desc *desc = irq_data_to_desc(data); |
311 | 319 | ||
312 | desc->chip->enable(irq); | 320 | desc->irq_data.chip->irq_enable(data); |
313 | return 0; | 321 | return 0; |
314 | } | 322 | } |
315 | 323 | ||
316 | /* | 324 | /* |
317 | * default shutdown function | 325 | * default shutdown function |
318 | */ | 326 | */ |
319 | static void default_shutdown(unsigned int irq) | 327 | static void default_shutdown(struct irq_data *data) |
320 | { | 328 | { |
321 | struct irq_desc *desc = irq_to_desc(irq); | 329 | struct irq_desc *desc = irq_data_to_desc(data); |
322 | 330 | ||
323 | desc->chip->mask(irq); | 331 | desc->irq_data.chip->irq_mask(&desc->irq_data); |
324 | desc->status |= IRQ_MASKED; | 332 | desc->status |= IRQ_MASKED; |
325 | } | 333 | } |
326 | 334 | ||
335 | #ifndef CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED | ||
336 | /* Temporary migration helpers */ | ||
337 | static void compat_irq_mask(struct irq_data *data) | ||
338 | { | ||
339 | data->chip->mask(data->irq); | ||
340 | } | ||
341 | |||
342 | static void compat_irq_unmask(struct irq_data *data) | ||
343 | { | ||
344 | data->chip->unmask(data->irq); | ||
345 | } | ||
346 | |||
347 | static void compat_irq_ack(struct irq_data *data) | ||
348 | { | ||
349 | data->chip->ack(data->irq); | ||
350 | } | ||
351 | |||
352 | static void compat_irq_mask_ack(struct irq_data *data) | ||
353 | { | ||
354 | data->chip->mask_ack(data->irq); | ||
355 | } | ||
356 | |||
357 | static void compat_irq_eoi(struct irq_data *data) | ||
358 | { | ||
359 | data->chip->eoi(data->irq); | ||
360 | } | ||
361 | |||
362 | static void compat_irq_enable(struct irq_data *data) | ||
363 | { | ||
364 | data->chip->enable(data->irq); | ||
365 | } | ||
366 | |||
367 | static void compat_irq_disable(struct irq_data *data) | ||
368 | { | ||
369 | data->chip->disable(data->irq); | ||
370 | } | ||
371 | |||
372 | static void compat_irq_shutdown(struct irq_data *data) | ||
373 | { | ||
374 | data->chip->shutdown(data->irq); | ||
375 | } | ||
376 | |||
377 | static unsigned int compat_irq_startup(struct irq_data *data) | ||
378 | { | ||
379 | return data->chip->startup(data->irq); | ||
380 | } | ||
381 | |||
382 | static int compat_irq_set_affinity(struct irq_data *data, | ||
383 | const struct cpumask *dest, bool force) | ||
384 | { | ||
385 | return data->chip->set_affinity(data->irq, dest); | ||
386 | } | ||
387 | |||
388 | static int compat_irq_set_type(struct irq_data *data, unsigned int type) | ||
389 | { | ||
390 | return data->chip->set_type(data->irq, type); | ||
391 | } | ||
392 | |||
393 | static int compat_irq_set_wake(struct irq_data *data, unsigned int on) | ||
394 | { | ||
395 | return data->chip->set_wake(data->irq, on); | ||
396 | } | ||
397 | |||
398 | static int compat_irq_retrigger(struct irq_data *data) | ||
399 | { | ||
400 | return data->chip->retrigger(data->irq); | ||
401 | } | ||
402 | |||
403 | static void compat_bus_lock(struct irq_data *data) | ||
404 | { | ||
405 | data->chip->bus_lock(data->irq); | ||
406 | } | ||
407 | |||
408 | static void compat_bus_sync_unlock(struct irq_data *data) | ||
409 | { | ||
410 | data->chip->bus_sync_unlock(data->irq); | ||
411 | } | ||
412 | #endif | ||
413 | |||
327 | /* | 414 | /* |
328 | * Fixup enable/disable function pointers | 415 | * Fixup enable/disable function pointers |
329 | */ | 416 | */ |
330 | void irq_chip_set_defaults(struct irq_chip *chip) | 417 | void irq_chip_set_defaults(struct irq_chip *chip) |
331 | { | 418 | { |
332 | if (!chip->enable) | 419 | #ifndef CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED |
333 | chip->enable = default_enable; | 420 | /* |
334 | if (!chip->disable) | 421 | * Compat fixup functions need to be before we set the |
335 | chip->disable = default_disable; | 422 | * defaults for enable/disable/startup/shutdown |
336 | if (!chip->startup) | 423 | */ |
337 | chip->startup = default_startup; | 424 | if (chip->enable) |
425 | chip->irq_enable = compat_irq_enable; | ||
426 | if (chip->disable) | ||
427 | chip->irq_disable = compat_irq_disable; | ||
428 | if (chip->shutdown) | ||
429 | chip->irq_shutdown = compat_irq_shutdown; | ||
430 | if (chip->startup) | ||
431 | chip->irq_startup = compat_irq_startup; | ||
432 | #endif | ||
433 | /* | ||
434 | * The real defaults | ||
435 | */ | ||
436 | if (!chip->irq_enable) | ||
437 | chip->irq_enable = default_enable; | ||
438 | if (!chip->irq_disable) | ||
439 | chip->irq_disable = default_disable; | ||
440 | if (!chip->irq_startup) | ||
441 | chip->irq_startup = default_startup; | ||
338 | /* | 442 | /* |
339 | * We use chip->disable, when the user provided its own. When | 443 | * We use chip->irq_disable, when the user provided its own. When |
340 | * we have default_disable set for chip->disable, then we need | 444 | * we have default_disable set for chip->irq_disable, then we need |
341 | * to use default_shutdown, otherwise the irq line is not | 445 | * to use default_shutdown, otherwise the irq line is not |
342 | * disabled on free_irq(): | 446 | * disabled on free_irq(): |
343 | */ | 447 | */ |
344 | if (!chip->shutdown) | 448 | if (!chip->irq_shutdown) |
345 | chip->shutdown = chip->disable != default_disable ? | 449 | chip->irq_shutdown = chip->irq_disable != default_disable ? |
346 | chip->disable : default_shutdown; | 450 | chip->irq_disable : default_shutdown; |
347 | if (!chip->name) | 451 | |
348 | chip->name = chip->typename; | 452 | #ifndef CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED |
349 | if (!chip->end) | 453 | if (!chip->end) |
350 | chip->end = dummy_irq_chip.end; | 454 | chip->end = dummy_irq_chip.end; |
455 | |||
456 | /* | ||
457 | * Now fix up the remaining compat handlers | ||
458 | */ | ||
459 | if (chip->bus_lock) | ||
460 | chip->irq_bus_lock = compat_bus_lock; | ||
461 | if (chip->bus_sync_unlock) | ||
462 | chip->irq_bus_sync_unlock = compat_bus_sync_unlock; | ||
463 | if (chip->mask) | ||
464 | chip->irq_mask = compat_irq_mask; | ||
465 | if (chip->unmask) | ||
466 | chip->irq_unmask = compat_irq_unmask; | ||
467 | if (chip->ack) | ||
468 | chip->irq_ack = compat_irq_ack; | ||
469 | if (chip->mask_ack) | ||
470 | chip->irq_mask_ack = compat_irq_mask_ack; | ||
471 | if (chip->eoi) | ||
472 | chip->irq_eoi = compat_irq_eoi; | ||
473 | if (chip->set_affinity) | ||
474 | chip->irq_set_affinity = compat_irq_set_affinity; | ||
475 | if (chip->set_type) | ||
476 | chip->irq_set_type = compat_irq_set_type; | ||
477 | if (chip->set_wake) | ||
478 | chip->irq_set_wake = compat_irq_set_wake; | ||
479 | if (chip->retrigger) | ||
480 | chip->irq_retrigger = compat_irq_retrigger; | ||
481 | #endif | ||
351 | } | 482 | } |
352 | 483 | ||
353 | static inline void mask_ack_irq(struct irq_desc *desc, int irq) | 484 | static inline void mask_ack_irq(struct irq_desc *desc) |
354 | { | 485 | { |
355 | if (desc->chip->mask_ack) | 486 | if (desc->irq_data.chip->irq_mask_ack) |
356 | desc->chip->mask_ack(irq); | 487 | desc->irq_data.chip->irq_mask_ack(&desc->irq_data); |
357 | else { | 488 | else { |
358 | desc->chip->mask(irq); | 489 | desc->irq_data.chip->irq_mask(&desc->irq_data); |
359 | if (desc->chip->ack) | 490 | if (desc->irq_data.chip->irq_ack) |
360 | desc->chip->ack(irq); | 491 | desc->irq_data.chip->irq_ack(&desc->irq_data); |
361 | } | 492 | } |
362 | desc->status |= IRQ_MASKED; | 493 | desc->status |= IRQ_MASKED; |
363 | } | 494 | } |
364 | 495 | ||
365 | static inline void mask_irq(struct irq_desc *desc, int irq) | 496 | static inline void mask_irq(struct irq_desc *desc) |
366 | { | 497 | { |
367 | if (desc->chip->mask) { | 498 | if (desc->irq_data.chip->irq_mask) { |
368 | desc->chip->mask(irq); | 499 | desc->irq_data.chip->irq_mask(&desc->irq_data); |
369 | desc->status |= IRQ_MASKED; | 500 | desc->status |= IRQ_MASKED; |
370 | } | 501 | } |
371 | } | 502 | } |
372 | 503 | ||
373 | static inline void unmask_irq(struct irq_desc *desc, int irq) | 504 | static inline void unmask_irq(struct irq_desc *desc) |
374 | { | 505 | { |
375 | if (desc->chip->unmask) { | 506 | if (desc->irq_data.chip->irq_unmask) { |
376 | desc->chip->unmask(irq); | 507 | desc->irq_data.chip->irq_unmask(&desc->irq_data); |
377 | desc->status &= ~IRQ_MASKED; | 508 | desc->status &= ~IRQ_MASKED; |
378 | } | 509 | } |
379 | } | 510 | } |
@@ -476,7 +607,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc) | |||
476 | irqreturn_t action_ret; | 607 | irqreturn_t action_ret; |
477 | 608 | ||
478 | raw_spin_lock(&desc->lock); | 609 | raw_spin_lock(&desc->lock); |
479 | mask_ack_irq(desc, irq); | 610 | mask_ack_irq(desc); |
480 | 611 | ||
481 | if (unlikely(desc->status & IRQ_INPROGRESS)) | 612 | if (unlikely(desc->status & IRQ_INPROGRESS)) |
482 | goto out_unlock; | 613 | goto out_unlock; |
@@ -502,7 +633,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc) | |||
502 | desc->status &= ~IRQ_INPROGRESS; | 633 | desc->status &= ~IRQ_INPROGRESS; |
503 | 634 | ||
504 | if (!(desc->status & (IRQ_DISABLED | IRQ_ONESHOT))) | 635 | if (!(desc->status & (IRQ_DISABLED | IRQ_ONESHOT))) |
505 | unmask_irq(desc, irq); | 636 | unmask_irq(desc); |
506 | out_unlock: | 637 | out_unlock: |
507 | raw_spin_unlock(&desc->lock); | 638 | raw_spin_unlock(&desc->lock); |
508 | } | 639 | } |
@@ -539,7 +670,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc) | |||
539 | action = desc->action; | 670 | action = desc->action; |
540 | if (unlikely(!action || (desc->status & IRQ_DISABLED))) { | 671 | if (unlikely(!action || (desc->status & IRQ_DISABLED))) { |
541 | desc->status |= IRQ_PENDING; | 672 | desc->status |= IRQ_PENDING; |
542 | mask_irq(desc, irq); | 673 | mask_irq(desc); |
543 | goto out; | 674 | goto out; |
544 | } | 675 | } |
545 | 676 | ||
@@ -554,7 +685,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc) | |||
554 | raw_spin_lock(&desc->lock); | 685 | raw_spin_lock(&desc->lock); |
555 | desc->status &= ~IRQ_INPROGRESS; | 686 | desc->status &= ~IRQ_INPROGRESS; |
556 | out: | 687 | out: |
557 | desc->chip->eoi(irq); | 688 | desc->irq_data.chip->irq_eoi(&desc->irq_data); |
558 | 689 | ||
559 | raw_spin_unlock(&desc->lock); | 690 | raw_spin_unlock(&desc->lock); |
560 | } | 691 | } |
@@ -590,14 +721,13 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc) | |||
590 | if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) || | 721 | if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) || |
591 | !desc->action)) { | 722 | !desc->action)) { |
592 | desc->status |= (IRQ_PENDING | IRQ_MASKED); | 723 | desc->status |= (IRQ_PENDING | IRQ_MASKED); |
593 | mask_ack_irq(desc, irq); | 724 | mask_ack_irq(desc); |
594 | goto out_unlock; | 725 | goto out_unlock; |
595 | } | 726 | } |
596 | kstat_incr_irqs_this_cpu(irq, desc); | 727 | kstat_incr_irqs_this_cpu(irq, desc); |
597 | 728 | ||
598 | /* Start handling the irq */ | 729 | /* Start handling the irq */ |
599 | if (desc->chip->ack) | 730 | desc->irq_data.chip->irq_ack(&desc->irq_data); |
600 | desc->chip->ack(irq); | ||
601 | 731 | ||
602 | /* Mark the IRQ currently in progress.*/ | 732 | /* Mark the IRQ currently in progress.*/ |
603 | desc->status |= IRQ_INPROGRESS; | 733 | desc->status |= IRQ_INPROGRESS; |
@@ -607,7 +737,7 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc) | |||
607 | irqreturn_t action_ret; | 737 | irqreturn_t action_ret; |
608 | 738 | ||
609 | if (unlikely(!action)) { | 739 | if (unlikely(!action)) { |
610 | mask_irq(desc, irq); | 740 | mask_irq(desc); |
611 | goto out_unlock; | 741 | goto out_unlock; |
612 | } | 742 | } |
613 | 743 | ||
@@ -619,7 +749,7 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc) | |||
619 | if (unlikely((desc->status & | 749 | if (unlikely((desc->status & |
620 | (IRQ_PENDING | IRQ_MASKED | IRQ_DISABLED)) == | 750 | (IRQ_PENDING | IRQ_MASKED | IRQ_DISABLED)) == |
621 | (IRQ_PENDING | IRQ_MASKED))) { | 751 | (IRQ_PENDING | IRQ_MASKED))) { |
622 | unmask_irq(desc, irq); | 752 | unmask_irq(desc); |
623 | } | 753 | } |
624 | 754 | ||
625 | desc->status &= ~IRQ_PENDING; | 755 | desc->status &= ~IRQ_PENDING; |
@@ -650,15 +780,15 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc) | |||
650 | 780 | ||
651 | kstat_incr_irqs_this_cpu(irq, desc); | 781 | kstat_incr_irqs_this_cpu(irq, desc); |
652 | 782 | ||
653 | if (desc->chip->ack) | 783 | if (desc->irq_data.chip->irq_ack) |
654 | desc->chip->ack(irq); | 784 | desc->irq_data.chip->irq_ack(&desc->irq_data); |
655 | 785 | ||
656 | action_ret = handle_IRQ_event(irq, desc->action); | 786 | action_ret = handle_IRQ_event(irq, desc->action); |
657 | if (!noirqdebug) | 787 | if (!noirqdebug) |
658 | note_interrupt(irq, desc, action_ret); | 788 | note_interrupt(irq, desc, action_ret); |
659 | 789 | ||
660 | if (desc->chip->eoi) | 790 | if (desc->irq_data.chip->irq_eoi) |
661 | desc->chip->eoi(irq); | 791 | desc->irq_data.chip->irq_eoi(&desc->irq_data); |
662 | } | 792 | } |
663 | 793 | ||
664 | void | 794 | void |
@@ -676,7 +806,7 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, | |||
676 | 806 | ||
677 | if (!handle) | 807 | if (!handle) |
678 | handle = handle_bad_irq; | 808 | handle = handle_bad_irq; |
679 | else if (desc->chip == &no_irq_chip) { | 809 | else if (desc->irq_data.chip == &no_irq_chip) { |
680 | printk(KERN_WARNING "Trying to install %sinterrupt handler " | 810 | printk(KERN_WARNING "Trying to install %sinterrupt handler " |
681 | "for IRQ%d\n", is_chained ? "chained " : "", irq); | 811 | "for IRQ%d\n", is_chained ? "chained " : "", irq); |
682 | /* | 812 | /* |
@@ -686,16 +816,16 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, | |||
686 | * prevent us to setup the interrupt at all. Switch it to | 816 | * prevent us to setup the interrupt at all. Switch it to |
687 | * dummy_irq_chip for easy transition. | 817 | * dummy_irq_chip for easy transition. |
688 | */ | 818 | */ |
689 | desc->chip = &dummy_irq_chip; | 819 | desc->irq_data.chip = &dummy_irq_chip; |
690 | } | 820 | } |
691 | 821 | ||
692 | chip_bus_lock(irq, desc); | 822 | chip_bus_lock(desc); |
693 | raw_spin_lock_irqsave(&desc->lock, flags); | 823 | raw_spin_lock_irqsave(&desc->lock, flags); |
694 | 824 | ||
695 | /* Uninstall? */ | 825 | /* Uninstall? */ |
696 | if (handle == handle_bad_irq) { | 826 | if (handle == handle_bad_irq) { |
697 | if (desc->chip != &no_irq_chip) | 827 | if (desc->irq_data.chip != &no_irq_chip) |
698 | mask_ack_irq(desc, irq); | 828 | mask_ack_irq(desc); |
699 | desc->status |= IRQ_DISABLED; | 829 | desc->status |= IRQ_DISABLED; |
700 | desc->depth = 1; | 830 | desc->depth = 1; |
701 | } | 831 | } |
@@ -706,10 +836,10 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, | |||
706 | desc->status &= ~IRQ_DISABLED; | 836 | desc->status &= ~IRQ_DISABLED; |
707 | desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE; | 837 | desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE; |
708 | desc->depth = 0; | 838 | desc->depth = 0; |
709 | desc->chip->startup(irq); | 839 | desc->irq_data.chip->irq_startup(&desc->irq_data); |
710 | } | 840 | } |
711 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 841 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
712 | chip_bus_sync_unlock(irq, desc); | 842 | chip_bus_sync_unlock(desc); |
713 | } | 843 | } |
714 | EXPORT_SYMBOL_GPL(__set_irq_handler); | 844 | EXPORT_SYMBOL_GPL(__set_irq_handler); |
715 | 845 | ||
@@ -729,32 +859,20 @@ set_irq_chip_and_handler_name(unsigned int irq, struct irq_chip *chip, | |||
729 | __set_irq_handler(irq, handle, 0, name); | 859 | __set_irq_handler(irq, handle, 0, name); |
730 | } | 860 | } |
731 | 861 | ||
732 | void set_irq_noprobe(unsigned int irq) | 862 | void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set) |
733 | { | 863 | { |
734 | struct irq_desc *desc = irq_to_desc(irq); | 864 | struct irq_desc *desc = irq_to_desc(irq); |
735 | unsigned long flags; | 865 | unsigned long flags; |
736 | 866 | ||
737 | if (!desc) { | 867 | if (!desc) |
738 | printk(KERN_ERR "Trying to mark IRQ%d non-probeable\n", irq); | ||
739 | return; | 868 | return; |
740 | } | ||
741 | 869 | ||
742 | raw_spin_lock_irqsave(&desc->lock, flags); | 870 | /* Sanitize flags */ |
743 | desc->status |= IRQ_NOPROBE; | 871 | set &= IRQF_MODIFY_MASK; |
744 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 872 | clr &= IRQF_MODIFY_MASK; |
745 | } | ||
746 | |||
747 | void set_irq_probe(unsigned int irq) | ||
748 | { | ||
749 | struct irq_desc *desc = irq_to_desc(irq); | ||
750 | unsigned long flags; | ||
751 | |||
752 | if (!desc) { | ||
753 | printk(KERN_ERR "Trying to mark IRQ%d probeable\n", irq); | ||
754 | return; | ||
755 | } | ||
756 | 873 | ||
757 | raw_spin_lock_irqsave(&desc->lock, flags); | 874 | raw_spin_lock_irqsave(&desc->lock, flags); |
758 | desc->status &= ~IRQ_NOPROBE; | 875 | desc->status &= ~clr; |
876 | desc->status |= set; | ||
759 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 877 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
760 | } | 878 | } |