aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pnp
diff options
context:
space:
mode:
authorBjorn Helgaas <bjorn.helgaas@hp.com>2008-06-09 19:52:04 -0400
committerLen Brown <len.brown@intel.com>2008-06-11 19:13:46 -0400
commite9fe9e188118a0a34c6200d9b10ea6247f53592d (patch)
tree151fb9549cefbcf7a8f7e1d591c99381d2c9802c /drivers/pnp
parent0638bc8dc037d844efe1d4abf44488c037705905 (diff)
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')
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c16
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)
56 return flags; 56 return flags;
57} 57}
58 58
59static void decode_irq_flags(int flag, int *triggering, int *polarity) 59static 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 case IORESOURCE_IRQ_LOWLEVEL: 64 case IORESOURCE_IRQ_LOWLEVEL:
63 *triggering = ACPI_LEVEL_SENSITIVE; 65 *triggering = ACPI_LEVEL_SENSITIVE;
64 *polarity = ACPI_ACTIVE_LOW; 66 *polarity = ACPI_ACTIVE_LOW;
@@ -75,6 +77,12 @@ static void decode_irq_flags(int flag, int *triggering, int *polarity)
75 *triggering = ACPI_EDGE_SENSITIVE; 77 *triggering = ACPI_EDGE_SENSITIVE;
76 *polarity = ACPI_ACTIVE_HIGH; 78 *polarity = ACPI_ACTIVE_HIGH;
77 break; 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 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev,
790 struct acpi_resource_irq *irq = &resource->data.irq; 798 struct acpi_resource_irq *irq = &resource->data.irq;
791 int triggering, polarity; 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 irq->triggering = triggering; 802 irq->triggering = triggering;
795 irq->polarity = polarity; 803 irq->polarity = polarity;
796 if (triggering == ACPI_EDGE_SENSITIVE) 804 if (triggering == ACPI_EDGE_SENSITIVE)
@@ -813,7 +821,7 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev,
813 struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq; 821 struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq;
814 int triggering, polarity; 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 extended_irq->producer_consumer = ACPI_CONSUMER; 825 extended_irq->producer_consumer = ACPI_CONSUMER;
818 extended_irq->triggering = triggering; 826 extended_irq->triggering = triggering;
819 extended_irq->polarity = polarity; 827 extended_irq->polarity = polarity;