@@ -326,3 +326,10 @@ static int __init pnpacpi_setup(char *str)
}
__setup("pnpacpi=", pnpacpi_setup);
+
+void pnpacpi_reconfigure_irq(struct pnp_dev *dev, unsigned int index, struct resource *res)
+{
+ if (has_acpi_companion(&dev->dev))
+ acpi_irq_get(ACPI_HANDLE(&dev->dev), index, res);
+}
+EXPORT_SYMBOL(pnpacpi_reconfigure_irq);
@@ -26,6 +26,7 @@ struct pnp_dev;
#ifdef CONFIG_PNP
struct resource *pnp_get_resource(struct pnp_dev *dev, unsigned long type,
unsigned int num);
+
#else
static inline struct resource *pnp_get_resource(struct pnp_dev *dev,
unsigned long type, unsigned int num)
@@ -146,13 +147,22 @@ static inline resource_size_t pnp_mem_len(struct pnp_dev *dev,
return 0;
}
+#ifdef CONFIG_PNPACPI
+void pnpacpi_reconfigure_irq(struct pnp_dev *dev, unsigned int index, struct resource *res);
+#endif
-static inline resource_size_t pnp_irq(struct pnp_dev *dev, unsigned int bar)
+static inline int pnp_irq(struct pnp_dev *dev, unsigned int bar)
{
struct resource *res = pnp_get_resource(dev, IORESOURCE_IRQ, bar);
- if (pnp_resource_valid(res))
+ if (pnp_resource_valid(res)) {
+#ifdef CONFIG_PNPACPI
+ if (!pnp_resource_enabled(res))
+ pnpacpi_reconfigure_irq(dev, bar, res);
+#endif
return res->start;
+ }
+
return -1;
}
PNP devices add the IRQ resources to PNP data structure early during boot from ACPI resource structure. As part of this, the Interrupt resource (GSI) are registered and appropriate linux IRQ is saved directly in PNP data structure while creating PNP devices. But at this time, the interrupt controller for the GSI (either via GSI vector mapping or via ResourceSource in Interrupt()) may not be probed and initialized. Hence, the IRQ number in PNP data structure may not be the linux IRQ number. When the actual driver for the PNP device get probed, it will get incorrect linux IRQ number. Fix this issue similar to how platform devices handle this. Basically, while creating PNP devices, the hwirq number is saved in PNP device and marked as disabled since acpi_register_gsi() would have failed. When the actual driver calls pnp_irq(), get the linux IRQ number again if the IRQ is disabled. Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> --- drivers/pnp/pnpacpi/core.c | 7 +++++++ include/linux/pnp.h | 14 ++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-)