Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] HPET: handle multiple ACPI EXTENDED_IRQ resources

When the _CRS for a single HPET contains multiple EXTENDED_IRQ resources,
we overwrote hdp->hd_nirqs every time we found one.

So the driver worked when all the IRQs were described in a single
EXTENDED_IRQ resource, but failed when multiple resources were used.
(Strictly speaking, I think the latter is actually more correct, but both
styles have been used.)

Someday we should remove all the ACPI stuff from hpet.c and use PNP driver
registration instead. But currently PNP_MAX_IRQ is 2, and HPETs often have
more IRQs. Hint, hint, Adam :-)

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Bob Picco <robert.picco@hp.com>
Cc: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Cc: Len Brown <len.brown@intel.com>
Cc: Adam Belay <ambx1@neo.rr.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Bjorn Helgaas and committed by
Linus Torvalds
be5efffb da965822

+8 -12
+8 -12
drivers/char/hpet.c
··· 956 956 } 957 957 } else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) { 958 958 struct acpi_resource_extended_irq *irqp; 959 - int i; 959 + int i, irq; 960 960 961 961 irqp = &res->data.extended_irq; 962 962 963 - if (irqp->interrupt_count > 0) { 964 - hdp->hd_nirqs = irqp->interrupt_count; 963 + for (i = 0; i < irqp->interrupt_count; i++) { 964 + irq = acpi_register_gsi(irqp->interrupts[i], 965 + irqp->triggering, irqp->polarity); 966 + if (irq < 0) 967 + return AE_ERROR; 965 968 966 - for (i = 0; i < hdp->hd_nirqs; i++) { 967 - int rc = 968 - acpi_register_gsi(irqp->interrupts[i], 969 - irqp->triggering, 970 - irqp->polarity); 971 - if (rc < 0) 972 - return AE_ERROR; 973 - hdp->hd_irq[i] = rc; 974 - } 969 + hdp->hd_irq[hdp->hd_nirqs] = irq; 970 + hdp->hd_nirqs++; 975 971 } 976 972 } 977 973