diff mbox

[Bugfix] x86, irq: Fix bug in setting IOAPIC pin attributes

Message ID 1409118795-17046-1-git-send-email-jiang.liu@linux.intel.com
State Not Applicable
Headers show

Commit Message

Jiang Liu Aug. 27, 2014, 5:53 a.m. UTC
Commit 15a3c7cc9154321fc3 "x86, irq: Introduce two helper functions
to support irqdomain map operation" breaks LPSS ACPI enumerated
devices.

On startup, IOAPIC driver preallocates IRQ descriptors and programs
IOAPIC pins with default level and polarity attributes for all legacy
IRQs. Later legacy IRQ users may fail to set IOAPIC pin attributes
if the requested attributes conflicts with the default IOAPIC pin
attributes. So change mp_irqdomain_map() to allow the first legacy IRQ
user to reprogram IOAPIC pin with different attributes.

Reported-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
Hi Mika,
	We have a plan to kill function mp_set_gsi_attr() later, so
I have slightly modified your changes. Could you please help to test
it again?
Regards!
Gerry
---
 arch/x86/kernel/apic/io_apic.c |   15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

Comments

Mika Westerberg Aug. 27, 2014, 8:04 a.m. UTC | #1
On Wed, Aug 27, 2014 at 01:53:11PM +0800, Jiang Liu wrote:
> Commit 15a3c7cc9154321fc3 "x86, irq: Introduce two helper functions
> to support irqdomain map operation" breaks LPSS ACPI enumerated
> devices.
> 
> On startup, IOAPIC driver preallocates IRQ descriptors and programs
> IOAPIC pins with default level and polarity attributes for all legacy
> IRQs. Later legacy IRQ users may fail to set IOAPIC pin attributes
> if the requested attributes conflicts with the default IOAPIC pin
> attributes. So change mp_irqdomain_map() to allow the first legacy IRQ
> user to reprogram IOAPIC pin with different attributes.
> 
> Reported-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
> ---
> Hi Mika,
> 	We have a plan to kill function mp_set_gsi_attr() later, so
> I have slightly modified your changes. Could you please help to test
> it again?

Works fine here, thanks!

Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 29290f554e79..40a4aa3f4061 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1070,6 +1070,11 @@  static int mp_map_pin_to_irq(u32 gsi, int idx, int ioapic, int pin,
 	}
 
 	if (flags & IOAPIC_MAP_ALLOC) {
+		/* special handling for legacy IRQs */
+		if (irq < nr_legacy_irqs() && info->count == 1 &&
+		    mp_irqdomain_map(domain, irq, pin) != 0)
+			irq = -1;
+
 		if (irq > 0)
 			info->count++;
 		else if (info->count == 0)
@@ -3896,7 +3901,15 @@  int mp_irqdomain_map(struct irq_domain *domain, unsigned int virq,
 			info->polarity = 1;
 		}
 		info->node = NUMA_NO_NODE;
-		info->set = 1;
+
+		/*
+		 * setup_IO_APIC_irqs() programs all legacy IRQs with default
+		 * trigger and polarity attributes. Don't set the flag for that
+		 * case so the first legacy IRQ user could reprogram the pin
+		 * with real trigger and polarity attributes.
+		 */
+		if (virq >= nr_legacy_irqs() || info->count)
+			info->set = 1;
 	}
 	set_io_apic_irq_attr(&attr, ioapic, hwirq, info->trigger,
 			     info->polarity);