diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2014-08-28 05:49:28 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-09-01 07:47:57 -0400 |
commit | 8df2e02c5c4de9e65ee60153dd9c442356534ad9 (patch) | |
tree | b4080a4efddd018fac2bd4aa57c8c6ced8b6f0b4 /kernel/irq | |
parent | 068765ba7987e73d4381edfe47b70aa121c7155c (diff) |
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>
Diffstat (limited to 'kernel/irq')
-rw-r--r-- | kernel/irq/internals.h | 4 | ||||
-rw-r--r-- | kernel/irq/manage.c | 28 | ||||
-rw-r--r-- | kernel/irq/pm.c | 44 |
3 files changed, 45 insertions, 31 deletions
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h index 099ea2e0eb88..af2821178900 100644 --- a/kernel/irq/internals.h +++ b/kernel/irq/internals.h | |||
@@ -63,8 +63,8 @@ enum { | |||
63 | 63 | ||
64 | extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, | 64 | extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, |
65 | unsigned long flags); | 65 | unsigned long flags); |
66 | extern void __disable_irq(struct irq_desc *desc, unsigned int irq, bool susp); | 66 | extern void __disable_irq(struct irq_desc *desc, unsigned int irq); |
67 | extern void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume); | 67 | extern void __enable_irq(struct irq_desc *desc, unsigned int irq); |
68 | 68 | ||
69 | extern int irq_startup(struct irq_desc *desc, bool resend); | 69 | extern int irq_startup(struct irq_desc *desc, bool resend); |
70 | extern void irq_shutdown(struct irq_desc *desc); | 70 | extern void irq_shutdown(struct irq_desc *desc); |
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 3dc6a61bf06a..fa564e8db996 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -382,14 +382,8 @@ setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask) | |||
382 | } | 382 | } |
383 | #endif | 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 | if (!desc->depth++) | 387 | if (!desc->depth++) |
394 | irq_disable(desc); | 388 | irq_disable(desc); |
395 | } | 389 | } |
@@ -401,7 +395,7 @@ static int __disable_irq_nosync(unsigned int irq) | |||
401 | 395 | ||
402 | if (!desc) | 396 | if (!desc) |
403 | return -EINVAL; | 397 | return -EINVAL; |
404 | __disable_irq(desc, irq, false); | 398 | __disable_irq(desc, irq); |
405 | irq_put_desc_busunlock(desc, flags); | 399 | irq_put_desc_busunlock(desc, flags); |
406 | return 0; | 400 | return 0; |
407 | } | 401 | } |
@@ -442,20 +436,8 @@ void disable_irq(unsigned int irq) | |||
442 | } | 436 | } |
443 | EXPORT_SYMBOL(disable_irq); | 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 | switch (desc->depth) { | 441 | switch (desc->depth) { |
460 | case 0: | 442 | case 0: |
461 | err_out: | 443 | err_out: |
@@ -497,7 +479,7 @@ void enable_irq(unsigned int irq) | |||
497 | KERN_ERR "enable_irq before setup/request_irq: irq %u\n", irq)) | 479 | KERN_ERR "enable_irq before setup/request_irq: irq %u\n", irq)) |
498 | goto out; | 480 | goto out; |
499 | 481 | ||
500 | __enable_irq(desc, irq, false); | 482 | __enable_irq(desc, irq); |
501 | out: | 483 | out: |
502 | irq_put_desc_busunlock(desc, flags); | 484 | irq_put_desc_busunlock(desc, flags); |
503 | } | 485 | } |
@@ -1228,7 +1210,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
1228 | */ | 1210 | */ |
1229 | if (shared && (desc->istate & IRQS_SPURIOUS_DISABLED)) { | 1211 | if (shared && (desc->istate & IRQS_SPURIOUS_DISABLED)) { |
1230 | desc->istate &= ~IRQS_SPURIOUS_DISABLED; | 1212 | desc->istate &= ~IRQS_SPURIOUS_DISABLED; |
1231 | __enable_irq(desc, irq, false); | 1213 | __enable_irq(desc, irq); |
1232 | } | 1214 | } |
1233 | 1215 | ||
1234 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 1216 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
diff --git a/kernel/irq/pm.c b/kernel/irq/pm.c index abcd6ca86cb7..b84141dcee5e 100644 --- a/kernel/irq/pm.c +++ b/kernel/irq/pm.c | |||
@@ -13,13 +13,26 @@ | |||
13 | 13 | ||
14 | #include "internals.h" | 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 | * suspend_device_irqs - disable all currently enabled interrupt lines | 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 | 28 | * During system-wide suspend or hibernation device drivers need to be |
20 | * from receiving interrupts and this function is provided for this purpose. | 29 | * prevented from receiving interrupts and this function is provided |
21 | * It marks all interrupt lines in use, except for the timer ones, as disabled | 30 | * for this purpose. |
22 | * and sets the IRQS_SUSPENDED flag for each of them. | 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 | void suspend_device_irqs(void) | 37 | void suspend_device_irqs(void) |
25 | { | 38 | { |
@@ -30,7 +43,7 @@ void suspend_device_irqs(void) | |||
30 | unsigned long flags; | 43 | unsigned long flags; |
31 | 44 | ||
32 | raw_spin_lock_irqsave(&desc->lock, flags); | 45 | raw_spin_lock_irqsave(&desc->lock, flags); |
33 | __disable_irq(desc, irq, true); | 46 | suspend_device_irq(desc, irq); |
34 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 47 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
35 | } | 48 | } |
36 | 49 | ||
@@ -40,6 +53,25 @@ void suspend_device_irqs(void) | |||
40 | } | 53 | } |
41 | EXPORT_SYMBOL_GPL(suspend_device_irqs); | 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 | static void resume_irqs(bool want_early) | 75 | static void resume_irqs(bool want_early) |
44 | { | 76 | { |
45 | struct irq_desc *desc; | 77 | struct irq_desc *desc; |
@@ -54,7 +86,7 @@ static void resume_irqs(bool want_early) | |||
54 | continue; | 86 | continue; |
55 | 87 | ||
56 | raw_spin_lock_irqsave(&desc->lock, flags); | 88 | raw_spin_lock_irqsave(&desc->lock, flags); |
57 | __enable_irq(desc, irq, true); | 89 | resume_irq(desc, irq); |
58 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 90 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
59 | } | 91 | } |
60 | } | 92 | } |