Commit 8df2e02c5c4de9e65ee60153dd9c442356534ad9

Authored by Thomas Gleixner
Committed by Rafael J. Wysocki
1 parent 068765ba79

genirq: Move suspend/resume logic into irq/pm code

No functional change. Preparatory patch for cleaning up the suspend
abort functionality. Update the comments while at it.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Showing 3 changed files with 45 additions and 31 deletions Side-by-side Diff

kernel/irq/internals.h
... ... @@ -63,8 +63,8 @@
63 63  
64 64 extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
65 65 unsigned long flags);
66   -extern void __disable_irq(struct irq_desc *desc, unsigned int irq, bool susp);
67   -extern void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume);
  66 +extern void __disable_irq(struct irq_desc *desc, unsigned int irq);
  67 +extern void __enable_irq(struct irq_desc *desc, unsigned int irq);
68 68  
69 69 extern int irq_startup(struct irq_desc *desc, bool resend);
70 70 extern void irq_shutdown(struct irq_desc *desc);
... ... @@ -382,14 +382,8 @@
382 382 }
383 383 #endif
384 384  
385   -void __disable_irq(struct irq_desc *desc, unsigned int irq, bool suspend)
  385 +void __disable_irq(struct irq_desc *desc, unsigned int irq)
386 386 {
387   - if (suspend) {
388   - if (!desc->action || (desc->action->flags & IRQF_NO_SUSPEND))
389   - return;
390   - desc->istate |= IRQS_SUSPENDED;
391   - }
392   -
393 387 if (!desc->depth++)
394 388 irq_disable(desc);
395 389 }
... ... @@ -401,7 +395,7 @@
401 395  
402 396 if (!desc)
403 397 return -EINVAL;
404   - __disable_irq(desc, irq, false);
  398 + __disable_irq(desc, irq);
405 399 irq_put_desc_busunlock(desc, flags);
406 400 return 0;
407 401 }
408 402  
... ... @@ -442,20 +436,8 @@
442 436 }
443 437 EXPORT_SYMBOL(disable_irq);
444 438  
445   -void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume)
  439 +void __enable_irq(struct irq_desc *desc, unsigned int irq)
446 440 {
447   - if (resume) {
448   - if (!(desc->istate & IRQS_SUSPENDED)) {
449   - if (!desc->action)
450   - return;
451   - if (!(desc->action->flags & IRQF_FORCE_RESUME))
452   - return;
453   - /* Pretend that it got disabled ! */
454   - desc->depth++;
455   - }
456   - desc->istate &= ~IRQS_SUSPENDED;
457   - }
458   -
459 441 switch (desc->depth) {
460 442 case 0:
461 443 err_out:
... ... @@ -497,7 +479,7 @@
497 479 KERN_ERR "enable_irq before setup/request_irq: irq %u\n", irq))
498 480 goto out;
499 481  
500   - __enable_irq(desc, irq, false);
  482 + __enable_irq(desc, irq);
501 483 out:
502 484 irq_put_desc_busunlock(desc, flags);
503 485 }
... ... @@ -1228,7 +1210,7 @@
1228 1210 */
1229 1211 if (shared && (desc->istate & IRQS_SPURIOUS_DISABLED)) {
1230 1212 desc->istate &= ~IRQS_SPURIOUS_DISABLED;
1231   - __enable_irq(desc, irq, false);
  1213 + __enable_irq(desc, irq);
1232 1214 }
1233 1215  
1234 1216 raw_spin_unlock_irqrestore(&desc->lock, flags);
... ... @@ -13,13 +13,26 @@
13 13  
14 14 #include "internals.h"
15 15  
  16 +static void suspend_device_irq(struct irq_desc *desc, int irq)
  17 +{
  18 + if (!desc->action || (desc->action->flags & IRQF_NO_SUSPEND))
  19 + return;
  20 +
  21 + desc->istate |= IRQS_SUSPENDED;
  22 + __disable_irq(desc, irq);
  23 +}
  24 +
16 25 /**
17 26 * suspend_device_irqs - disable all currently enabled interrupt lines
18 27 *
19   - * During system-wide suspend or hibernation device drivers need to be prevented
20   - * from receiving interrupts and this function is provided for this purpose.
21   - * It marks all interrupt lines in use, except for the timer ones, as disabled
22   - * and sets the IRQS_SUSPENDED flag for each of them.
  28 + * During system-wide suspend or hibernation device drivers need to be
  29 + * prevented from receiving interrupts and this function is provided
  30 + * for this purpose.
  31 + *
  32 + * So we disable all interrupts and mark them IRQS_SUSPENDED except
  33 + * for those which are unused and those which are marked as not
  34 + * suspendable via an interrupt request with the flag IRQF_NO_SUSPEND
  35 + * set.
23 36 */
24 37 void suspend_device_irqs(void)
25 38 {
... ... @@ -30,7 +43,7 @@
30 43 unsigned long flags;
31 44  
32 45 raw_spin_lock_irqsave(&desc->lock, flags);
33   - __disable_irq(desc, irq, true);
  46 + suspend_device_irq(desc, irq);
34 47 raw_spin_unlock_irqrestore(&desc->lock, flags);
35 48 }
36 49  
... ... @@ -40,6 +53,25 @@
40 53 }
41 54 EXPORT_SYMBOL_GPL(suspend_device_irqs);
42 55  
  56 +static void resume_irq(struct irq_desc *desc, int irq)
  57 +{
  58 + if (desc->istate & IRQS_SUSPENDED)
  59 + goto resume;
  60 +
  61 + if (!desc->action)
  62 + return;
  63 +
  64 + /* Interrupts marked with that flag are force reenabled */
  65 + if (!(desc->action->flags & IRQF_FORCE_RESUME))
  66 + return;
  67 +
  68 + /* Pretend that it got disabled ! */
  69 + desc->depth++;
  70 +resume:
  71 + desc->istate &= ~IRQS_SUSPENDED;
  72 + __enable_irq(desc, irq);
  73 +}
  74 +
43 75 static void resume_irqs(bool want_early)
44 76 {
45 77 struct irq_desc *desc;
... ... @@ -54,7 +86,7 @@
54 86 continue;
55 87  
56 88 raw_spin_lock_irqsave(&desc->lock, flags);
57   - __enable_irq(desc, irq, true);
  89 + resume_irq(desc, irq);
58 90 raw_spin_unlock_irqrestore(&desc->lock, flags);
59 91 }
60 92 }