diff options
author | Bjorn Helgaas <bjorn.helgaas@hp.com> | 2008-06-10 01:52:04 +0200 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2008-06-12 01:13:46 +0200 |
commit | e9fe9e188118a0a34c6200d9b10ea6247f53592d (patch) | |
tree | 151fb9549cefbcf7a8f7e1d591c99381d2c9802c /drivers/pnp/pnpacpi | |
parent | MAINTAINERS: update ACPI homepage (diff) | |
download | linux-e9fe9e188118a0a34c6200d9b10ea6247f53592d.tar.xz linux-e9fe9e188118a0a34c6200d9b10ea6247f53592d.zip |
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>
Diffstat (limited to 'drivers/pnp/pnpacpi')
-rw-r--r-- | drivers/pnp/pnpacpi/rsparser.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 0201c8adfda7..ab09fe6fe1e4 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -56,9 +56,11 @@ static int irq_flags(int triggering, int polarity, int shareable) return flags; } -static void decode_irq_flags(int flag, int *triggering, int *polarity) +static void decode_irq_flags(struct pnp_dev *dev, int flags, int *triggering, + int *polarity) { - switch (flag) { + switch (flags & (IORESOURCE_IRQ_LOWLEVEL | IORESOURCE_IRQ_HIGHLEVEL | + IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE)) { case IORESOURCE_IRQ_LOWLEVEL: *triggering = ACPI_LEVEL_SENSITIVE; *polarity = ACPI_ACTIVE_LOW; @@ -75,6 +77,12 @@ static void decode_irq_flags(int flag, int *triggering, int *polarity) *triggering = ACPI_EDGE_SENSITIVE; *polarity = ACPI_ACTIVE_HIGH; break; + default: + dev_err(&dev->dev, "can't encode invalid IRQ mode %#x\n", + flags); + *triggering = ACPI_EDGE_SENSITIVE; + *polarity = ACPI_ACTIVE_HIGH; + break; } } @@ -790,7 +798,7 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev, struct acpi_resource_irq *irq = &resource->data.irq; int triggering, polarity; - decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity); + decode_irq_flags(dev, p->flags, &triggering, &polarity); irq->triggering = triggering; irq->polarity = polarity; if (triggering == ACPI_EDGE_SENSITIVE) @@ -813,7 +821,7 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev, struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq; int triggering, polarity; - decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity); + decode_irq_flags(dev, p->flags, &triggering, &polarity); extended_irq->producer_consumer = ACPI_CONSUMER; extended_irq->triggering = triggering; extended_irq->polarity = polarity; |