Commit e9fe9e188118a0a34c6200d9b10ea6247f53592d
Committed by
Len Brown
1 parent
0638bc8dc0
Exists in
master
and in
4 other branches
pnpacpi: fix IRQ flag decoding
When decoding IRQ trigger mode and polarity, it is not enough to mask by IORESOURCE_BITS because there are now additional bits defined. For example, if IORESOURCE_IRQ_SHAREABLE was set, we failed to set *triggering and *polarity at all. I can't point to a failure that this patch fixes, but bugs in this area have caused problems when resuming after suspend, for example: http://bugzilla.kernel.org/show_bug.cgi?id=6316 http://bugzilla.kernel.org/show_bug.cgi?id=9487 https://bugs.launchpad.net/ubuntu/+source/linux-source-2.6.22/+bug/152187 This is based on a patch by Tom Jaeger: http://bugzilla.kernel.org/show_bug.cgi?id=9487#c32 [rene.herman@keyaccess.nl: fix comment] Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Len Brown <len.brown@intel.com>
Showing 2 changed files with 15 additions and 7 deletions Side-by-side Diff
drivers/pnp/pnpacpi/rsparser.c
... | ... | @@ -56,9 +56,11 @@ |
56 | 56 | return flags; |
57 | 57 | } |
58 | 58 | |
59 | -static void decode_irq_flags(int flag, int *triggering, int *polarity) | |
59 | +static void decode_irq_flags(struct pnp_dev *dev, int flags, int *triggering, | |
60 | + int *polarity) | |
60 | 61 | { |
61 | - switch (flag) { | |
62 | + switch (flags & (IORESOURCE_IRQ_LOWLEVEL | IORESOURCE_IRQ_HIGHLEVEL | | |
63 | + IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE)) { | |
62 | 64 | case IORESOURCE_IRQ_LOWLEVEL: |
63 | 65 | *triggering = ACPI_LEVEL_SENSITIVE; |
64 | 66 | *polarity = ACPI_ACTIVE_LOW; |
... | ... | @@ -75,6 +77,12 @@ |
75 | 77 | *triggering = ACPI_EDGE_SENSITIVE; |
76 | 78 | *polarity = ACPI_ACTIVE_HIGH; |
77 | 79 | break; |
80 | + default: | |
81 | + dev_err(&dev->dev, "can't encode invalid IRQ mode %#x\n", | |
82 | + flags); | |
83 | + *triggering = ACPI_EDGE_SENSITIVE; | |
84 | + *polarity = ACPI_ACTIVE_HIGH; | |
85 | + break; | |
78 | 86 | } |
79 | 87 | } |
80 | 88 | |
... | ... | @@ -790,7 +798,7 @@ |
790 | 798 | struct acpi_resource_irq *irq = &resource->data.irq; |
791 | 799 | int triggering, polarity; |
792 | 800 | |
793 | - decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity); | |
801 | + decode_irq_flags(dev, p->flags, &triggering, &polarity); | |
794 | 802 | irq->triggering = triggering; |
795 | 803 | irq->polarity = polarity; |
796 | 804 | if (triggering == ACPI_EDGE_SENSITIVE) |
... | ... | @@ -813,7 +821,7 @@ |
813 | 821 | struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq; |
814 | 822 | int triggering, polarity; |
815 | 823 | |
816 | - decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity); | |
824 | + decode_irq_flags(dev, p->flags, &triggering, &polarity); | |
817 | 825 | extended_irq->producer_consumer = ACPI_CONSUMER; |
818 | 826 | extended_irq->triggering = triggering; |
819 | 827 | extended_irq->polarity = polarity; |
include/linux/ioport.h
... | ... | @@ -53,14 +53,14 @@ |
53 | 53 | #define IORESOURCE_AUTO 0x40000000 |
54 | 54 | #define IORESOURCE_BUSY 0x80000000 /* Driver has marked this resource busy */ |
55 | 55 | |
56 | -/* ISA PnP IRQ specific bits (IORESOURCE_BITS) */ | |
56 | +/* PnP IRQ specific bits (IORESOURCE_BITS) */ | |
57 | 57 | #define IORESOURCE_IRQ_HIGHEDGE (1<<0) |
58 | 58 | #define IORESOURCE_IRQ_LOWEDGE (1<<1) |
59 | 59 | #define IORESOURCE_IRQ_HIGHLEVEL (1<<2) |
60 | 60 | #define IORESOURCE_IRQ_LOWLEVEL (1<<3) |
61 | 61 | #define IORESOURCE_IRQ_SHAREABLE (1<<4) |
62 | 62 | |
63 | -/* ISA PnP DMA specific bits (IORESOURCE_BITS) */ | |
63 | +/* PnP DMA specific bits (IORESOURCE_BITS) */ | |
64 | 64 | #define IORESOURCE_DMA_TYPE_MASK (3<<0) |
65 | 65 | #define IORESOURCE_DMA_8BIT (0<<0) |
66 | 66 | #define IORESOURCE_DMA_8AND16BIT (1<<0) |
... | ... | @@ -76,7 +76,7 @@ |
76 | 76 | #define IORESOURCE_DMA_TYPEB (2<<6) |
77 | 77 | #define IORESOURCE_DMA_TYPEF (3<<6) |
78 | 78 | |
79 | -/* ISA PnP memory I/O specific bits (IORESOURCE_BITS) */ | |
79 | +/* PnP memory I/O specific bits (IORESOURCE_BITS) */ | |
80 | 80 | #define IORESOURCE_MEM_WRITEABLE (1<<0) /* dup: IORESOURCE_READONLY */ |
81 | 81 | #define IORESOURCE_MEM_CACHEABLE (1<<1) /* dup: IORESOURCE_CACHEABLE */ |
82 | 82 | #define IORESOURCE_MEM_RANGELENGTH (1<<2) /* dup: IORESOURCE_RANGELENGTH */ |