Skip to contentSkip to conversation

acpi: add support for extended IRQ to PCI link

PATCH Superseded Sinan Kaya 2 participants 4 messages Nov 24, 2015 – Nov 25, 2015

Subsystems (2)

v5 of 6 Superseded Latest is v6 →

lore
Share & tools
lore

Sinan Kaya

author
#0 lore raw

PATCH v5 1/1 acpi: add support for extended IRQ to PCI link

The ACPI compiler uses the extended format when used interrupt numbers are greater than 256. The extended IRQ numbers use 32 bits for storing interrupts. The code already supports parsing extended IRQ type but is limited by 256 due to used data structure type (u8). This patch changes the interrupt number type to 32 bits and places an upper limit of 1020 as possible interrupt id. 1020 is the maximum interrupt ID that can be assigned to an ARM SPI interrupt according to ARM architecture.

Additional checks have been placed to return an error when ACPI_MAX_IRQS is exceeded.

---
 drivers/acpi/pci_link.c | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)
drivers/acpi/pci_link.c +22 -5
index 7c8408b..8fe4e6f 100644
@@ -1,6 +1,7 @@
 /*
  *  pci_link.c - ACPI PCI Interrupt Link Device Driver ($Revision: 34 $)
  *
+ *  Copyright (c) 2015, The Linux Foundation. All rights reserved.
  *  Copyright (C) 2001, 2002 Andy Grover <[email protected]>
  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <[email protected]>
  *  Copyright (C) 2002       Dominik Brodowski <[email protected]>
@@ -47,6 +48,14 @@ ACPI_MODULE_NAME("pci_link");
 #define ACPI_PCI_LINK_FILE_STATUS	"state"
 #define ACPI_PCI_LINK_MAX_POSSIBLE	16
 
+/*
+ * 1020 is the maximum interrupt ID that can be assigned to
+ * an ARM SPI interrupt according to ARM architecture.
+ */
+#define ACPI_MAX_IRQS		1020
+#define ACPI_MAX_ISA_IRQ	16
+
+
 static int acpi_pci_link_add(struct acpi_device *device,
 			     const struct acpi_device_id *not_used);
 static void acpi_pci_link_remove(struct acpi_device *device);
@@ -67,12 +76,12 @@ static struct acpi_scan_handler pci_link_handler = {
  * later even the link is disable. Instead, we just repick the active irq
  */
 struct acpi_pci_link_irq {
-	u8 active;		/* Current IRQ */
+	u32 active;		/* Current IRQ */
 	u8 triggering;		/* All IRQs */
 	u8 polarity;		/* All IRQs */
 	u8 resource_type;
 	u8 possible_count;
-	u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
+	u32 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
 	u8 initialized:1;
 	u8 reserved:7;
 };
@@ -147,6 +156,12 @@ static acpi_status acpi_pci_link_check_possible(struct acpi_resource *resource,
 					       p->interrupts[i]);
 					continue;
 				}
+				if (p->interrupts[i] > ACPI_MAX_IRQS) {
+					pr_warn("IRQ %d exceeds max (%d)\n",
+						p->interrupts[i],
+						ACPI_MAX_IRQS);
+					continue;
+				}
 				link->irq.possible[i] = p->interrupts[i];
 				link->irq.possible_count++;
 			}
@@ -279,6 +294,11 @@ static int acpi_pci_link_get_current(struct acpi_pci_link *link)
 		result = -ENODEV;
 	}
 
+	if (irq > ACPI_MAX_IRQS) {
+		pr_err("IRQ %d number exceed max IRQ (%d)\n", irq,
+			ACPI_MAX_IRQS);
+		result = -ENODEV;
+	}
 	link->irq.active = irq;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link at IRQ %d \n", link->irq.active));
@@ -437,9 +457,6 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
  * enabled system.
  */
 
-#define ACPI_MAX_IRQS		256
-#define ACPI_MAX_ISA_IRQ	16
-
 #define PIRQ_PENALTY_PCI_AVAILABLE	(0)
 #define PIRQ_PENALTY_PCI_POSSIBLE	(16*16)
 #define PIRQ_PENALTY_PCI_USING		(16*16*16)
Signature · 2 lines
Qualcomm Technologies, Inc. on behalf of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
author
#1 lore raw
Quoted 59 lines · Sinan Kaya

The ACPI compiler uses the extended format when used interrupt numbers are greater than 256. The extended IRQ numbers use 32 bits for storing interrupts. The code already supports parsing extended IRQ type but is limited by 256 due to used data structure type (u8). This patch changes the interrupt number type to 32 bits and places an upper limit of 1020 as possible interrupt id. 1020 is the maximum interrupt ID that can be assigned to an ARM SPI interrupt according to ARM architecture.

Additional checks have been placed to return an error when ACPI_MAX_IRQS is exceeded.

---
 drivers/acpi/pci_link.c | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)
drivers/acpi/pci_link.c +11 -2
index 7c8408b..8fe4e6f 100644
@@ -1,6 +1,7 @@
 /*
  *  pci_link.c - ACPI PCI Interrupt Link Device Driver ($Revision: 34 $)
  *
+ *  Copyright (c) 2015, The Linux Foundation. All rights reserved.
  *  Copyright (C) 2001, 2002 Andy Grover <[email protected]>
  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <[email protected]>
  *  Copyright (C) 2002       Dominik Brodowski <[email protected]>
@@ -47,6 +48,14 @@ ACPI_MODULE_NAME("pci_link");
 #define ACPI_PCI_LINK_FILE_STATUS	"state"
 #define ACPI_PCI_LINK_MAX_POSSIBLE	16
 
+/*
+ * 1020 is the maximum interrupt ID that can be assigned to
+ * an ARM SPI interrupt according to ARM architecture.
+ */
+#define ACPI_MAX_IRQS		1020
+#define ACPI_MAX_ISA_IRQ	16
+
+
 static int acpi_pci_link_add(struct acpi_device *device,
 			     const struct acpi_device_id *not_used);
 static void acpi_pci_link_remove(struct acpi_device *device);
@@ -67,12 +76,12 @@ static struct acpi_scan_handler pci_link_handler = {
  * later even the link is disable. Instead, we just repick the active irq
  */
 struct acpi_pci_link_irq {
-	u8 active;		/* Current IRQ */
+	u32 active;		/* Current IRQ */
 	u8 triggering;		/* All IRQs */
 	u8 polarity;		/* All IRQs */
 	u8 resource_type;
 	u8 possible_count;
-	u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
+	u32 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
 	u8 initialized:1;
 	u8 reserved:7;
 };

drivers/acpi/pci_link.c static acpi_status acpi_pci_link_check_possible(struct acpi_resource *resource, · line 159

Quoted 4 lines
drivers/acpi/pci_link.c +1 -0
@@ -147,6 +156,12 @@ static acpi_status acpi_pci_link_check_possible(struct acpi_resource *resource,
 					       p->interrupts[i]);
 					continue;
 				}
+				if (p->interrupts[i] > ACPI_MAX_IRQS) {

this should have been >=

drivers/acpi/pci_link.c static int acpi_pci_link_get_current(struct acpi_pci_link *link) · line 296

Quoted 12 lines
drivers/acpi/pci_link.c +5 -0
+					pr_warn("IRQ %d exceeds max (%d)\n",
+						p->interrupts[i],
+						ACPI_MAX_IRQS);
+					continue;
+				}
 				link->irq.possible[i] = p->interrupts[i];
 				link->irq.possible_count++;
 			}
@@ -279,6 +294,11 @@ static int acpi_pci_link_get_current(struct acpi_pci_link *link)
 		result = -ENODEV;
 	}
 

this should have been >=

Quoted 10 lines
drivers/acpi/pci_link.c +5 -0
+	if (irq > ACPI_MAX_IRQS) {
+		pr_err("IRQ %d number exceed max IRQ (%d)\n", irq,
+			ACPI_MAX_IRQS);
+		result = -ENODEV;
+	}
 	link->irq.active = irq;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link at IRQ %d \n", link->irq.active));

drivers/acpi/pci_link.c static int acpi_pci_link_set(struct acpi_pci_link *link, int irq) · line 462

Quoted 9 lines
drivers/acpi/pci_link.c +0 -3
@@ -437,9 +457,6 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
  * enabled system.
  */
 
-#define ACPI_MAX_IRQS		256
-#define ACPI_MAX_ISA_IRQ	16
-
 #define PIRQ_PENALTY_PCI_AVAILABLE	(0)
 #define PIRQ_PENALTY_PCI_POSSIBLE	(16*16)
 #define PIRQ_PENALTY_PCI_USING		(16*16*16)

Bjorn,
Does this look like what you were thinking?
Sinan

Signature · 4 lines
Sinan Kaya
Qualcomm Technologies, Inc. on behalf of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a
Linux Foundation Collaborative Project
#2 lore raw

Hi Sinan,

Quoted 93 lines · Sinan Kaya
Quoted 59 lines · Sinan Kaya

The ACPI compiler uses the extended format when used interrupt numbers are greater than 256. The extended IRQ numbers use 32 bits for storing interrupts. The code already supports parsing extended IRQ type but is limited by 256 due to used data structure type (u8). This patch changes the interrupt number type to 32 bits and places an upper limit of 1020 as possible interrupt id. 1020 is the maximum interrupt ID that can be assigned to an ARM SPI interrupt according to ARM architecture.

Additional checks have been placed to return an error when ACPI_MAX_IRQS is exceeded.

---
 drivers/acpi/pci_link.c | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)
drivers/acpi/pci_link.c +11 -2
index 7c8408b..8fe4e6f 100644
@@ -1,6 +1,7 @@
 /*
  *  pci_link.c - ACPI PCI Interrupt Link Device Driver ($Revision: 34 $)
  *
+ *  Copyright (c) 2015, The Linux Foundation. All rights reserved.
  *  Copyright (C) 2001, 2002 Andy Grover <[email protected]>
  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <[email protected]>
  *  Copyright (C) 2002       Dominik Brodowski <[email protected]>
@@ -47,6 +48,14 @@ ACPI_MODULE_NAME("pci_link");
 #define ACPI_PCI_LINK_FILE_STATUS	"state"
 #define ACPI_PCI_LINK_MAX_POSSIBLE	16
 
+/*
+ * 1020 is the maximum interrupt ID that can be assigned to
+ * an ARM SPI interrupt according to ARM architecture.
+ */
+#define ACPI_MAX_IRQS		1020
+#define ACPI_MAX_ISA_IRQ	16
+
+
 static int acpi_pci_link_add(struct acpi_device *device,
 			     const struct acpi_device_id *not_used);
 static void acpi_pci_link_remove(struct acpi_device *device);
@@ -67,12 +76,12 @@ static struct acpi_scan_handler pci_link_handler = {
  * later even the link is disable. Instead, we just repick the active irq
  */
 struct acpi_pci_link_irq {
-	u8 active;		/* Current IRQ */
+	u32 active;		/* Current IRQ */
 	u8 triggering;		/* All IRQs */
 	u8 polarity;		/* All IRQs */
 	u8 resource_type;
 	u8 possible_count;
-	u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
+	u32 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
 	u8 initialized:1;
 	u8 reserved:7;
 };

drivers/acpi/pci_link.c static acpi_status acpi_pci_link_check_possible(struct acpi_resource *resource, · line 159

Quoted 4 lines
drivers/acpi/pci_link.c +1 -0
@@ -147,6 +156,12 @@ static acpi_status acpi_pci_link_check_possible(struct acpi_resource *resource,
 					       p->interrupts[i]);
 					continue;
 				}
+				if (p->interrupts[i] > ACPI_MAX_IRQS) {

this should have been >=

drivers/acpi/pci_link.c static int acpi_pci_link_get_current(struct acpi_pci_link *link) · line 296

Quoted 12 lines
drivers/acpi/pci_link.c +5 -0
+					pr_warn("IRQ %d exceeds max (%d)\n",
+						p->interrupts[i],
+						ACPI_MAX_IRQS);
+					continue;
+				}
 				link->irq.possible[i] = p->interrupts[i];
 				link->irq.possible_count++;
 			}
@@ -279,6 +294,11 @@ static int acpi_pci_link_get_current(struct acpi_pci_link *link)
 		result = -ENODEV;
 	}
 

this should have been >=

Quoted 12 lines
drivers/acpi/pci_link.c +5 -0
+	if (irq > ACPI_MAX_IRQS) {
+		pr_err("IRQ %d number exceed max IRQ (%d)\n", irq,
+			ACPI_MAX_IRQS);
+		result = -ENODEV;
+	}
 	link->irq.active = irq;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link at IRQ %d \n", link->irq.active));
@@ -437,9 +457,6 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
  * enabled system.
  */
 
Quoted 10 lines

drivers/acpi/pci_link.c static int acpi_pci_link_set(struct acpi_pci_link *link, int irq) · line 462

Quoted 7 lines
drivers/acpi/pci_link.c +0 -3
-#define ACPI_MAX_IRQS		256
-#define ACPI_MAX_ISA_IRQ	16
-
 #define PIRQ_PENALTY_PCI_AVAILABLE	(0)
 #define PIRQ_PENALTY_PCI_POSSIBLE	(16*16)
 #define PIRQ_PENALTY_PCI_USING		(16*16*16)

Bjorn,
Does this look like what you were thinking?

Yes, exactly. I think it's much nicer if we can avoid putting invalid data into the list in the first place.

Maybe reword the diagnostic to make it clear that we're ignoring this IRQ information. It'd really be nice if the message had a clue about what it applies to, i.e., the ACPI device path or something, but I don't know how hard that is, and none of the other messages from that driver include that information either.

Bjorn

author
#3 lore raw
Quoted 3 lines · Bjorn Helgaas

Maybe reword the diagnostic to make it clear that we're ignoring this IRQ information. It'd really be nice if the message had a clue about what it applies to, i.e., the ACPI device path or something,

Are we OK with print strings exceeding 80 characters to include detailed information? Chris Covington pointed out to me that there are exceptions to 80 characters when it comes to print format strings.

"The limit on the length of lines is 80 columns and this is a strongly preferred limit. ... However, never break user-visible strings such as printk messages, because that breaks the ability to grep for them."

Signature · 4 lines
Sinan Kaya
Qualcomm Technologies, Inc. on behalf of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a
Linux Foundation Collaborative Project