Skip to contentSkip to conversation

ACPI: PCI: simplify _PRT handling

PATCH In review Bjorn Helgaas 2 participants 23 messages Dec 9, 2008 – Dec 31, 2008

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover ACPI: PCI: simplify _PRT handling

This series simplifies the code that handles ACPI _PRTs (PCI routing tables). My goal is to make this look more like the corresponding code in other architectures, especially in terms of swizzling, e.g., the various implementations of common_swizzle() and simple_swizzle(), and the x86 non-ACPI code in pirq_enable_irq().

There should be no functional changes in this series.

Comments welcome.

Bjorn

---

Bjorn Helgaas (20):
ACPI: PCI: add HP copyright
ACPI: PCI: whitespace and useless initialization cleanup
ACPI: PCI: expand acpi_pci_allocate_irq() and acpi_pci_free_irq() inline
ACPI: PCI: simplify struct acpi_prt_entry
ACPI: PCI: simplify list of _PRT entries
ACPI: PCI: combine lookup and derive
ACPI: PCI: follow typical PCI INTx swizzling pattern
ACPI: PCI: use positive logic to simplify code
ACPI: PCI: remove callback from acpi_pci_irq_lookup & acpi_pci_irq_derive
ACPI: PCI: tweak _PRT lookup debug
ACPI: PCI: lookup _PRT entry by PCI dev and pin, not segment/bus/dev/pin
ACPI: PCI: use 1-based encoding for _PRT quirks
ACPI: PCI: always use the PCI INTx pin values, not the _PRT ones
ACPI: PCI: add a helper to convert _PRT INTx pin number to name
ACPI: PCI: move struct acpi_prt_entry declaration out of public header file
ACPI: PCI: fix GSI/IRQ naming confusion
ACPI: PCI: ignore _PRT function information
ACPI: PCI: simplify buffer management for evaluating _PRT
ACPI: PCI: remove unnecessary null pointer checks
ACPI: PCI: use conventional PCI address format

 drivers/acpi/pci_bind.c |   12 +
 drivers/acpi/pci_irq.c  |  416 +++++++++++++++--------------------------------
 include/linux/acpi.h    |   16 --
 3 files changed, 136 insertions(+), 308 deletions(-)
#1 lore raw

PATCH 1/20 ACPI: PCI: use conventional PCI address format

Use the conventional format for PCI addresses (%04x:%02x:%02x.%d).

---
 drivers/acpi/pci_bind.c |   12 ++++++------
 drivers/acpi/pci_irq.c  |   10 +++++-----
 2 files changed, 11 insertions(+), 11 deletions(-)
drivers/acpi/pci_bind.c +6 -6
index 676d0a4..cd9780c 100644
@@ -101,7 +101,7 @@ acpi_status acpi_get_pci_id(acpi_handle handle, struct acpi_pci_id *id)
 	 */
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			  "Device %s has PCI address %02x:%02x:%02x.%02x\n",
+			  "Device %s has PCI address %04x:%02x:%02x.%d\n",
 			  acpi_device_bid(device), id->segment, id->bus,
 			  id->device, id->function));
 
@@ -168,7 +168,7 @@ int acpi_pci_bind(struct acpi_device *device)
 	data->id.device = device->pnp.bus_address >> 16;
 	data->id.function = device->pnp.bus_address & 0xFFFF;
 
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "...to %02x:%02x:%02x.%02x\n",
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "...to %04x:%02x:%02x.%d\n",
 			  data->id.segment, data->id.bus, data->id.device,
 			  data->id.function));
 
@@ -198,7 +198,7 @@ int acpi_pci_bind(struct acpi_device *device)
 	}
 	if (!data->dev) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Device %02x:%02x:%02x.%02x not present in PCI namespace\n",
+				  "Device %04x:%02x:%02x.%d not present in PCI namespace\n",
 				  data->id.segment, data->id.bus,
 				  data->id.device, data->id.function));
 		result = -ENODEV;
@@ -206,7 +206,7 @@ int acpi_pci_bind(struct acpi_device *device)
 	}
 	if (!data->dev->bus) {
 		printk(KERN_ERR PREFIX
-			    "Device %02x:%02x:%02x.%02x has invalid 'bus' field\n",
+			    "Device %04x:%02x:%02x.%d has invalid 'bus' field\n",
 			    data->id.segment, data->id.bus,
 			    data->id.device, data->id.function);
 		result = -ENODEV;
@@ -221,7 +221,7 @@ int acpi_pci_bind(struct acpi_device *device)
 	 */
 	if (data->dev->subordinate) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Device %02x:%02x:%02x.%02x is a PCI bridge\n",
+				  "Device %04x:%02x:%02x.%d is a PCI bridge\n",
 				  data->id.segment, data->id.bus,
 				  data->id.device, data->id.function));
 		data->bus = data->dev->subordinate;
@@ -355,7 +355,7 @@ acpi_pci_bind_root(struct acpi_device *device,
 	acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI root bridge [%s] to "
-			  "%02x:%02x\n", pathname, id->segment, id->bus));
+			  "%04x:%02x\n", pathname, id->segment, id->bus));
 
 	status = acpi_attach_data(device->handle, acpi_pci_data_handler, data);
 	if (ACPI_FAILURE(status)) {
drivers/acpi/pci_irq.c +5 -5
index a5ba18c..6666f74 100644
@@ -224,7 +224,7 @@ acpi_pci_irq_add_entry(acpi_handle handle,
 		entry->link.index = prt->source_index;
 
 	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO,
-			      "      %02X:%02X:%02X[%c] -> %s[%d]\n",
+			      "      %04x:%02x:%02x[%c] -> %s[%d]\n",
 			      entry->id.segment, entry->id.bus,
 			      entry->id.device, ('A' + entry->pin), prt->source,
 			      entry->link.index));
@@ -330,8 +330,8 @@ void acpi_pci_irq_del_prt(int segment, int bus)
 	}
 
 	printk(KERN_DEBUG
-	       "ACPI: Delete PCI Interrupt Routing Table for %x:%x\n", segment,
-	       bus);
+	       "ACPI: Delete PCI Interrupt Routing Table for %04x:%02x\n",
+	       segment, bus);
 	spin_lock(&acpi_prt_lock);
 	list_for_each_safe(node, n, &acpi_prt.entries) {
 		entry = list_entry(node, struct acpi_prt_entry, node);
@@ -405,12 +405,12 @@ acpi_pci_irq_lookup(struct pci_bus *bus,
 
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			  "Searching for PRT entry for %02x:%02x:%02x[%c]\n",
+			  "Searching for _PRT entry for %04x:%02x:%02x[%c]\n",
 			  segment, bus_nr, device, ('A' + pin)));
 
 	entry = acpi_pci_irq_find_prt_entry(segment, bus_nr, device, pin);
 	if (!entry) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "PRT entry not found\n"));
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_PRT entry not found\n"));
 		return -1;
 	}
 
#2 lore raw

PATCH 2/20 ACPI: PCI: remove unnecessary null pointer checks

In reply to Bjorn Helgaas

Better to oops and learn about a bug than to silently cover it up.

---
 drivers/acpi/pci_irq.c |   18 ------------------
 1 files changed, 0 insertions(+), 18 deletions(-)
drivers/acpi/pci_irq.c +0 -18
index 6666f74..8250c55 100644
@@ -180,10 +180,6 @@ acpi_pci_irq_add_entry(acpi_handle handle,
 {
 	struct acpi_prt_entry *entry = NULL;
 
-
-	if (!prt)
-		return -EINVAL;
-
 	entry = kzalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL);
 	if (!entry)
 		return -ENOMEM;
@@ -434,9 +430,6 @@ acpi_pci_irq_derive(struct pci_dev *dev,
 	u8 bridge_pin = 0, orig_pin = pin;
 
 
-	if (!dev)
-		return -EINVAL;
-
 	/* 
 	 * Attempt to derive an IRQ for this device from a parent bridge's
 	 * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge).
@@ -493,9 +486,6 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
 	int rc;
 
 
-	if (!dev)
-		return -EINVAL;
-
 	pin = dev->pin;
 	if (!pin) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -505,11 +495,6 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
 	}
 	pin--;
 
-	if (!dev->bus) {
-		dev_err(&dev->dev, "invalid (NULL) 'bus' field\n");
-		return -ENODEV;
-	}
-
 	/* 
 	 * First we check the PCI IRQ routing table (PRT) for an IRQ.  PRT
 	 * values override any BIOS-assigned IRQs set during boot.
@@ -588,9 +573,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
 	int polarity = ACPI_ACTIVE_LOW;
 
 
-	if (!dev || !dev->bus)
-		return;
-
 	pin = dev->pin;
 	if (!pin)
 		return;
#3 lore raw

PATCH 3/20 ACPI: PCI: simplify buffer management for evaluating _PRT

In reply to Bjorn Helgaas

Previously, acpi_pci_irq_add_prt() did all its own buffer management. But now that we have ACPI_ALLOCATE_BUFFER, we no longer need to do that management. And we don't have to call acpi_get_irq_routing_table() twice (once to learn the size of the buffer needed, and again to actually get the table).

---
 drivers/acpi/pci_irq.c |   52 +++++++++++-------------------------------------
 1 files changed, 12 insertions(+), 40 deletions(-)
drivers/acpi/pci_irq.c +12 -40
index 8250c55..0a31527 100644
@@ -245,55 +245,29 @@ acpi_pci_irq_del_entry(int segment, int bus, struct acpi_prt_entry *entry)
 
 int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus)
 {
-	acpi_status status = AE_OK;
-	char *pathname = NULL;
-	struct acpi_buffer buffer = { 0, NULL };
-	struct acpi_pci_routing_table *prt = NULL;
-	struct acpi_pci_routing_table *entry = NULL;
+	acpi_status status;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	struct acpi_pci_routing_table *entry;
 	static int first_time = 1;
 
-
-	pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
-	if (!pathname)
-		return -ENOMEM;
-
 	if (first_time) {
 		acpi_prt.count = 0;
 		INIT_LIST_HEAD(&acpi_prt.entries);
 		first_time = 0;
 	}
 
-	/* 
-	 * NOTE: We're given a 'handle' to the _PRT object's parent device
-	 *       (either a PCI root bridge or PCI-PCI bridge).
-	 */
-
-	buffer.length = ACPI_PATHNAME_MAX;
-	buffer.pointer = pathname;
-	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+	/* 'handle' is the _PRT's parent (root bridge or PCI-PCI bridge) */
+	status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
 
 	printk(KERN_DEBUG "ACPI: PCI Interrupt Routing Table [%s._PRT]\n",
-	       pathname);
+	       (char *) buffer.pointer);
 
-	/* 
-	 * Evaluate this _PRT and add its entries to our global list (acpi_prt).
-	 */
+	kfree(buffer.pointer);
 
-	buffer.length = 0;
+	buffer.length = ACPI_ALLOCATE_BUFFER;
 	buffer.pointer = NULL;
-	kfree(pathname);
-	status = acpi_get_irq_routing_table(handle, &buffer);
-	if (status != AE_BUFFER_OVERFLOW) {
-		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRT [%s]",
-				acpi_format_exception(status)));
-		return -ENODEV;
-	}
-
-	prt = kzalloc(buffer.length, GFP_KERNEL);
-	if (!prt) {
-		return -ENOMEM;
-	}
-	buffer.pointer = prt;
 
 	status = acpi_get_irq_routing_table(handle, &buffer);
 	if (ACPI_FAILURE(status)) {
@@ -303,16 +277,14 @@ int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus)
 		return -ENODEV;
 	}
 
-	entry = prt;
-
+	entry = buffer.pointer;
 	while (entry && (entry->length > 0)) {
 		acpi_pci_irq_add_entry(handle, segment, bus, entry);
 		entry = (struct acpi_pci_routing_table *)
 		    ((unsigned long)entry + entry->length);
 	}
 
-	kfree(prt);
-
+	kfree(buffer.pointer);
 	return 0;
 }
 
reviewer
#4 lore raw

PATCH 1/1 ACPI: simplify buffer management for acpi_pci_bind() etc.

From: Len Brown <[email protected]>
Date: Tue, 30 Dec 2008 22:44:33 -0500

use ACPI_ALLOCATE_BUFFER to remove the allocations
within acpi_pci_bind(), acpi_pci_unbind() and acpi_pci_bind_root(). While there, delete some unnecessary param inits from those routines.

Delete concept of ACPI_PATHNAME_MAX, since this was the last use.

---

Bjorn,
That patch was such a good idea, I just had to do the same thing over in pci_bind.c:-)

cheers,
-Len

 drivers/acpi/pci_bind.c         |   80 ++++++++++++++++-----------------------
 include/acpi/platform/aclinux.h |    3 -
 2 files changed, 33 insertions(+), 50 deletions(-)
drivers/acpi/pci_bind.c +33 -47
index 53f502d..95650f8 100644
@@ -111,12 +111,11 @@ EXPORT_SYMBOL(acpi_get_pci_id);
 int acpi_pci_bind(struct acpi_device *device)
 {
 	int result = 0;
-	acpi_status status = AE_OK;
-	struct acpi_pci_data *data = NULL;
-	struct acpi_pci_data *pdata = NULL;
-	char *pathname = NULL;
-	struct acpi_buffer buffer = { 0, NULL };
-	acpi_handle handle = NULL;
+	acpi_status status;
+	struct acpi_pci_data *data;
+	struct acpi_pci_data *pdata;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	acpi_handle handle;
 	struct pci_dev *dev;
 	struct pci_bus *bus;
 
@@ -124,21 +123,18 @@ int acpi_pci_bind(struct acpi_device *device)
 	if (!device || !device->parent)
 		return -EINVAL;
 
-	pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
-	if (!pathname)
-		return -ENOMEM;
-	buffer.length = ACPI_PATHNAME_MAX;
-	buffer.pointer = pathname;
-
 	data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
-	if (!data) {
-		kfree(pathname);
+	if (!data)
 		return -ENOMEM;
+
+	status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
+	if (ACPI_FAILURE(status)) {
+		kfree(data);
+		return -ENODEV;
 	}
 
-	acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI device [%s]...\n",
-			  pathname));
+			  (char *)buffer.pointer));
 
 	/* 
 	 * Segment & Bus
@@ -262,7 +258,7 @@ int acpi_pci_bind(struct acpi_device *device)
 	}
 
       end:
-	kfree(pathname);
+	kfree(buffer.pointer);
 	if (result)
 		kfree(data);
 
@@ -272,25 +268,21 @@ int acpi_pci_bind(struct acpi_device *device)
 static int acpi_pci_unbind(struct acpi_device *device)
 {
 	int result = 0;
-	acpi_status status = AE_OK;
-	struct acpi_pci_data *data = NULL;
-	char *pathname = NULL;
-	struct acpi_buffer buffer = { 0, NULL };
+	acpi_status status;
+	struct acpi_pci_data *data;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 
 
 	if (!device || !device->parent)
 		return -EINVAL;
 
-	pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
-	if (!pathname)
-		return -ENOMEM;
+	status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
 
-	buffer.length = ACPI_PATHNAME_MAX;
-	buffer.pointer = pathname;
-	acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unbinding PCI device [%s]...\n",
-			  pathname));
-	kfree(pathname);
+			  (char *) buffer.pointer));
+	kfree(buffer.pointer);
 
 	status =
 	    acpi_get_data(device->handle, acpi_pci_data_handler,
@@ -322,50 +314,44 @@ acpi_pci_bind_root(struct acpi_device *device,
 		   struct acpi_pci_id *id, struct pci_bus *bus)
 {
 	int result = 0;
-	acpi_status status = AE_OK;
+	acpi_status status;
 	struct acpi_pci_data *data = NULL;
-	char *pathname = NULL;
-	struct acpi_buffer buffer = { 0, NULL };
-
-	pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
-	if (!pathname)
-		return -ENOMEM;
-
-	buffer.length = ACPI_PATHNAME_MAX;
-	buffer.pointer = pathname;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 
 	if (!device || !id || !bus) {
-		kfree(pathname);
 		return -EINVAL;
 	}
 
 	data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
-	if (!data) {
-		kfree(pathname);
+	if (!data)
 		return -ENOMEM;
-	}
 
 	data->id = *id;
 	data->bus = bus;
 	device->ops.bind = acpi_pci_bind;
 	device->ops.unbind = acpi_pci_unbind;
 
-	acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
+	status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
+	if (ACPI_FAILURE(status)) {
+		kfree (data);
+		return -ENODEV;
+	}
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI root bridge [%s] to "
-			  "%04x:%02x\n", pathname, id->segment, id->bus));
+			"%04x:%02x\n", (char *)buffer.pointer,
+			id->segment, id->bus));
 
 	status = acpi_attach_data(device->handle, acpi_pci_data_handler, data);
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status,
 				"Unable to attach ACPI-PCI context to device %s",
-				pathname));
+				(char *)buffer.pointer));
 		result = -ENODEV;
 		goto end;
 	}
 
       end:
-	kfree(pathname);
+	kfree(buffer.pointer);
 	if (result != 0)
 		kfree(data);
 
include/acpi/platform/aclinux.h +0 -3
index 0515e75..9116c98 100644
@@ -70,9 +70,6 @@
 #define ACPI_EXPORT_SYMBOL(symbol)  EXPORT_SYMBOL(symbol);
 #define strtoul                     simple_strtoul
 
-/* Full namespace pathname length limit - arbitrary */
-#define ACPI_PATHNAME_MAX              256
-
 #else				/* !__KERNEL__ */
 
 #include <stdarg.h>
Signature · 1 line
1.6.1.28.gc32f76
#5 lore raw

PATCH 4/20 ACPI: PCI: ignore _PRT function information

In reply to Bjorn Helgaas

_PRT entries don't contain any useful PCI function information (the function part of the PCI address is supposed to be 0xffff), and we don't ever look at it, so this patch just removes the reference to it.

---
 drivers/acpi/pci_irq.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)
drivers/acpi/pci_irq.c +0 -1
index 0a31527..579bf17 100644
@@ -187,7 +187,6 @@ acpi_pci_irq_add_entry(acpi_handle handle,
 	entry->id.segment = segment;
 	entry->id.bus = bus;
 	entry->id.device = (prt->address >> 16) & 0xFFFF;
-	entry->id.function = prt->address & 0xFFFF;
 	entry->pin = prt->pin;
 
 	do_prt_fixups(entry, prt);
#6 lore raw

PATCH 5/20 ACPI: PCI: fix GSI/IRQ naming confusion

In reply to Bjorn Helgaas

The interrupt numbers from _PRT entries are GSIs, not Linux IRQs.

---
 drivers/acpi/pci_irq.c |   20 ++++++++++----------
 1 files changed, 10 insertions(+), 10 deletions(-)
drivers/acpi/pci_irq.c +10 -10
index 579bf17..f80b8a2 100644
@@ -335,7 +335,7 @@ acpi_pci_allocate_irq(struct acpi_prt_entry *entry,
 		*polarity = ACPI_ACTIVE_LOW;
 	}
 
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", irq));
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found GSI %d\n", irq));
 	return irq;
 }
 
@@ -434,7 +434,7 @@ acpi_pci_irq_derive(struct pci_dev *dev,
 		return -1;
 	}
 
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derive IRQ %d for device %s from %s\n",
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derive GSI %d for device %s from %s\n",
 			  irq, pci_name(dev), pci_name(bridge)));
 
 	return irq;
@@ -448,7 +448,7 @@ acpi_pci_irq_derive(struct pci_dev *dev,
 
 int acpi_pci_irq_enable(struct pci_dev *dev)
 {
-	int irq = 0;
+	int gsi = 0;
 	u8 pin = 0;
 	int triggering = ACPI_LEVEL_SENSITIVE;
 	int polarity = ACPI_ACTIVE_LOW;
@@ -470,7 +470,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
 	 * First we check the PCI IRQ routing table (PRT) for an IRQ.  PRT
 	 * values override any BIOS-assigned IRQs set during boot.
 	 */
-	irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
+	gsi = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
 				  &triggering, &polarity, &link,
 				  acpi_pci_allocate_irq);
 
@@ -478,12 +478,12 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
 	 * If no PRT entry was found, we'll try to derive an IRQ from the
 	 * device's parent bridge.
 	 */
-	if (irq < 0)
-		irq = acpi_pci_irq_derive(dev, pin, &triggering,
+	if (gsi < 0)
+		gsi = acpi_pci_irq_derive(dev, pin, &triggering,
 					  &polarity, &link,
 					  acpi_pci_allocate_irq);
 
-	if (irq < 0) {
+	if (gsi < 0) {
 		/*
 		 * IDE legacy mode controller IRQs are magic. Why do compat
 		 * extensions always make such a nasty mess.
@@ -496,7 +496,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
 	 * No IRQ known to the ACPI subsystem - maybe the BIOS / 
 	 * driver reported one, then use it. Exit in any case.
 	 */
-	if (irq < 0) {
+	if (gsi < 0) {
 		dev_warn(&dev->dev, "PCI INT %c: no GSI", 'A' + pin);
 		/* Interrupt Line values above 0xF are forbidden */
 		if (dev->irq > 0 && (dev->irq <= 0xF)) {
@@ -510,7 +510,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
 		}
 	}
 
-	rc = acpi_register_gsi(irq, triggering, polarity);
+	rc = acpi_register_gsi(gsi, triggering, polarity);
 	if (rc < 0) {
 		dev_warn(&dev->dev, "PCI INT %c: failed to register GSI\n",
 			 'A' + pin);
@@ -524,7 +524,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
 		link_desc[0] = '\0';
 
 	dev_info(&dev->dev, "PCI INT %c%s -> GSI %u (%s, %s) -> IRQ %d\n",
-		 'A' + pin, link_desc, irq,
+		 'A' + pin, link_desc, gsi,
 		 (triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
 		 (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq);
 
#7 lore raw

PATCH 6/20 ACPI: PCI: move struct acpi_prt_entry declaration out of public header file

In reply to Bjorn Helgaas

The struct acpi_prt_entry is used only in pci_irq.c, so there's no need for the declaration to be public. This patch moves it into pci_irq.c.

---
 drivers/acpi/pci_irq.c |   16 ++++++++++++++++
 include/linux/acpi.h   |   16 ----------------
 2 files changed, 16 insertions(+), 16 deletions(-)
drivers/acpi/pci_irq.c +16 -0
index f80b8a2..04b9df4 100644
@@ -43,6 +43,22 @@
 #define _COMPONENT		ACPI_PCI_COMPONENT
 ACPI_MODULE_NAME("pci_irq");
 
+struct acpi_prt_entry {
+	struct list_head	node;
+	struct acpi_pci_id	id;
+	u8			pin;
+	struct {
+		acpi_handle		handle;
+		u32			index;
+	}			link;
+	u32			irq;
+};
+
+struct acpi_prt_list {
+	int			count;
+	struct list_head	entries;
+};
+
 static struct acpi_prt_list acpi_prt;
 static DEFINE_SPINLOCK(acpi_prt_lock);
 
include/linux/acpi.h +0 -16
index fba8051..813f937 100644
@@ -131,22 +131,6 @@ extern int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity);
  */
 void acpi_unregister_gsi (u32 gsi);
 
-struct acpi_prt_entry {
-	struct list_head	node;
-	struct acpi_pci_id	id;
-	u8			pin;
-	struct {
-		acpi_handle		handle;
-		u32			index;
-	}			link;
-	u32			irq;
-};
-
-struct acpi_prt_list {
-	int			count;
-	struct list_head	entries;
-};
-
 struct pci_dev;
 
 int acpi_pci_irq_enable (struct pci_dev *dev);
#8 lore raw

PATCH 7/20 ACPI: PCI: add a helper to convert _PRT INTx pin number to name

In reply to Bjorn Helgaas

This adds a helper function to convert INTx pin numbers from the _PRT (0, 1, 2, 3) to the pin name ('A', 'B', 'C', 'D').

---
 drivers/acpi/pci_irq.c |   25 +++++++++++++++----------
 1 files changed, 15 insertions(+), 10 deletions(-)
drivers/acpi/pci_irq.c +15 -10
index 04b9df4..ccbb163 100644
@@ -62,6 +62,11 @@ struct acpi_prt_list {
 static struct acpi_prt_list acpi_prt;
 static DEFINE_SPINLOCK(acpi_prt_lock);
 
+static inline char pin_name(int pin)
+{
+	return 'A' + pin;
+}
+
 /* --------------------------------------------------------------------------
                          PCI IRQ Routing Table (PRT) Support
    -------------------------------------------------------------------------- */
@@ -176,14 +181,14 @@ do_prt_fixups(struct acpi_prt_entry *entry, struct acpi_pci_routing_table *prt)
 		    entry->id.segment == quirk->segment &&
 		    entry->id.bus == quirk->bus &&
 		    entry->id.device == quirk->device &&
-		    entry->pin + 'A' == quirk->pin &&
+		    pin_name(entry->pin) == quirk->pin &&
 		    !strcmp(prt->source, quirk->source) &&
 		    strlen(prt->source) >= strlen(quirk->actual_source)) {
 			printk(KERN_WARNING PREFIX "firmware reports "
 				"%04x:%02x:%02x PCI INT %c connected to %s; "
 				"changing to %s\n",
 				entry->id.segment, entry->id.bus,
-				entry->id.device, 'A' + entry->pin,
+				entry->id.device, pin_name(entry->pin),
 				prt->source, quirk->actual_source);
 			strcpy(prt->source, quirk->actual_source);
 		}
@@ -237,8 +242,8 @@ acpi_pci_irq_add_entry(acpi_handle handle,
 	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO,
 			      "      %04x:%02x:%02x[%c] -> %s[%d]\n",
 			      entry->id.segment, entry->id.bus,
-			      entry->id.device, ('A' + entry->pin), prt->source,
-			      entry->link.index));
+			      entry->id.device, pin_name(entry->pin),
+			      prt->source, entry->link.index));
 
 	spin_lock(&acpi_prt_lock);
 	list_add_tail(&entry->node, &acpi_prt.entries);
@@ -389,7 +394,7 @@ acpi_pci_irq_lookup(struct pci_bus *bus,
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 			  "Searching for _PRT entry for %04x:%02x:%02x[%c]\n",
-			  segment, bus_nr, device, ('A' + pin)));
+			  segment, bus_nr, device, pin_name(pin)));
 
 	entry = acpi_pci_irq_find_prt_entry(segment, bus_nr, device, pin);
 	if (!entry) {
@@ -446,7 +451,7 @@ acpi_pci_irq_derive(struct pci_dev *dev,
 
 	if (irq < 0) {
 		dev_warn(&dev->dev, "can't derive routing for PCI INT %c\n",
-			 'A' + orig_pin);
+			 pin_name(orig_pin));
 		return -1;
 	}
 
@@ -513,7 +518,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
 	 * driver reported one, then use it. Exit in any case.
 	 */
 	if (gsi < 0) {
-		dev_warn(&dev->dev, "PCI INT %c: no GSI", 'A' + pin);
+		dev_warn(&dev->dev, "PCI INT %c: no GSI", pin_name(pin));
 		/* Interrupt Line values above 0xF are forbidden */
 		if (dev->irq > 0 && (dev->irq <= 0xF)) {
 			printk(" - using IRQ %d\n", dev->irq);
@@ -529,7 +534,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
 	rc = acpi_register_gsi(gsi, triggering, polarity);
 	if (rc < 0) {
 		dev_warn(&dev->dev, "PCI INT %c: failed to register GSI\n",
-			 'A' + pin);
+			 pin_name(pin));
 		return rc;
 	}
 	dev->irq = rc;
@@ -540,7 +545,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
 		link_desc[0] = '\0';
 
 	dev_info(&dev->dev, "PCI INT %c%s -> GSI %u (%s, %s) -> IRQ %d\n",
-		 'A' + pin, link_desc, gsi,
+		 pin_name(pin), link_desc, gsi,
 		 (triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
 		 (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq);
 
@@ -587,6 +592,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
 	 * (e.g. PCI_UNDEFINED_IRQ).
 	 */
 
-	dev_info(&dev->dev, "PCI INT %c disabled\n", 'A' + pin);
+	dev_info(&dev->dev, "PCI INT %c disabled\n", pin_name(pin));
 	acpi_unregister_gsi(gsi);
 }
#9 lore raw

PATCH 8/20 ACPI: PCI: always use the PCI INTx pin values, not the _PRT ones

In reply to Bjorn Helgaas

This patch changes pci_irq.c to always use PCI INTx pin encodings instead of a mix of PCI and _PRT encodings.

The PCI INTx pin numbers from the PCI_INTERRUPT_PIN config register are 0=device doesn't use interrupts, 1=INTA, ..., 4=INTD. But the _PRT table uses 0=INTA, ..., 3=INTD.

This patch converts the _PRT encoding to the PCI encoding immediately when we add a _PRT entry to the global list. All the rest of the code can then use the PCI encoding consistently.

The point of this is to make the interrupt swizzling look the same as on other architectures, so someday we can unify them.

---
 drivers/acpi/pci_irq.c |   15 ++++++++-------
 1 files changed, 8 insertions(+), 7 deletions(-)
drivers/acpi/pci_irq.c +8 -7
index ccbb163..0036055 100644
@@ -64,7 +64,7 @@ static DEFINE_SPINLOCK(acpi_prt_lock);
 
 static inline char pin_name(int pin)
 {
-	return 'A' + pin;
+	return 'A' + pin - 1;
 }
 
 /* --------------------------------------------------------------------------
@@ -205,10 +205,15 @@ acpi_pci_irq_add_entry(acpi_handle handle,
 	if (!entry)
 		return -ENOMEM;
 
+	/*
+	 * Note that the _PRT uses 0=INTA, 1=INTB, etc, while PCI uses
+	 * 1=INTA, 2=INTB.  We use the PCI encoding throughout, so convert
+	 * it here.
+	 */
 	entry->id.segment = segment;
 	entry->id.bus = bus;
 	entry->id.device = (prt->address >> 16) & 0xFFFF;
-	entry->pin = prt->pin;
+	entry->pin = prt->pin + 1;
 
 	do_prt_fixups(entry, prt);
 
@@ -427,7 +432,7 @@ acpi_pci_irq_derive(struct pci_dev *dev,
 	 * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge).
 	 */
 	while (irq < 0 && bridge->bus->self) {
-		pin = (pin + PCI_SLOT(bridge->devfn)) % 4;
+		pin = (((pin - 1) + PCI_SLOT(bridge->devfn)) % 4) + 1;
 		bridge = bridge->bus->self;
 
 		if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) {
@@ -439,8 +444,6 @@ acpi_pci_irq_derive(struct pci_dev *dev,
 						  pci_name(bridge)));
 				return -1;
 			}
-			/* Pin is from 0 to 3 */
-			bridge_pin--;
 			pin = bridge_pin;
 		}
 
@@ -485,7 +488,6 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
 				  pci_name(dev)));
 		return 0;
 	}
-	pin--;
 
 	/* 
 	 * First we check the PCI IRQ routing table (PRT) for an IRQ.  PRT
@@ -568,7 +570,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
 	pin = dev->pin;
 	if (!pin)
 		return;
-	pin--;
 
 	/*
 	 * First we check the PCI IRQ routing table (PRT) for an IRQ.
#10 lore raw

PATCH 9/20 ACPI: PCI: use 1-based encoding for _PRT quirks

In reply to Bjorn Helgaas

Use the PCI INTx pin encoding (1=INTA, 2=INTB, etc) for _PRT quirks. Then we can simply compare "entry->pin == quirk->pin".

---
 drivers/acpi/pci_irq.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)
drivers/acpi/pci_irq.c +6 -4
index 0036055..eea15fd 100644
@@ -147,19 +147,21 @@ struct prt_quirk {
 	char			*actual_source;
 };
 
+#define PCI_INTX_PIN(c)		(c - 'A' + 1)
+
 /*
  * These systems have incorrect _PRT entries.  The BIOS claims the PCI
  * interrupt at the listed segment/bus/device/pin is connected to the first
  * link device, but it is actually connected to the second.
  */
 static struct prt_quirk prt_quirks[] = {
-	{ medion_md9580, 0, 0, 9, 'A',
+	{ medion_md9580, 0, 0, 9, PCI_INTX_PIN('A'),
 		"\\_SB_.PCI0.ISA_.LNKA",
 		"\\_SB_.PCI0.ISA_.LNKB"},
-	{ dell_optiplex, 0, 0, 0xd, 'A',
+	{ dell_optiplex, 0, 0, 0xd, PCI_INTX_PIN('A'),
 		"\\_SB_.LNKB",
 		"\\_SB_.LNKA"},
-	{ hp_t5710, 0, 0, 1, 'A',
+	{ hp_t5710, 0, 0, 1, PCI_INTX_PIN('A'),
 		"\\_SB_.PCI0.LNK1",
 		"\\_SB_.PCI0.LNK3"},
 };
@@ -181,7 +183,7 @@ do_prt_fixups(struct acpi_prt_entry *entry, struct acpi_pci_routing_table *prt)
 		    entry->id.segment == quirk->segment &&
 		    entry->id.bus == quirk->bus &&
 		    entry->id.device == quirk->device &&
-		    pin_name(entry->pin) == quirk->pin &&
+		    entry->pin == quirk->pin &&
 		    !strcmp(prt->source, quirk->source) &&
 		    strlen(prt->source) >= strlen(quirk->actual_source)) {
 			printk(KERN_WARNING PREFIX "firmware reports "
#11 lore raw

PATCH 10/20 ACPI: PCI: lookup _PRT entry by PCI dev and pin, not segment/bus/dev/pin

In reply to Bjorn Helgaas

There's no reason to pass around segment, bus, and device independently when we can just pass the pci_dev pointer, which carries all those already.

The pci_dev contains an interrupt pin, too, but we still have to pass both the pci_dev and the pin because when we use a bridge to derive an IRQ, we need the pin from the downstream device, not the bridge.

---
 drivers/acpi/pci_irq.c |   27 ++++++++++++---------------
 1 files changed, 12 insertions(+), 15 deletions(-)
drivers/acpi/pci_irq.c +12 -15
index eea15fd..6f4c5f3 100644
@@ -71,11 +71,13 @@ static inline char pin_name(int pin)
                          PCI IRQ Routing Table (PRT) Support
    -------------------------------------------------------------------------- */
 
-static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(int segment,
-							  int bus,
-							  int device, int pin)
+static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(struct pci_dev *dev,
+							  int pin)
 {
 	struct acpi_prt_entry *entry = NULL;
+	int segment = pci_domain_nr(dev->bus);
+	int bus = dev->bus->number;
+	int device = PCI_SLOT(dev->devfn);
 
 	if (!acpi_prt.count)
 		return NULL;
@@ -387,23 +389,18 @@ acpi_pci_free_irq(struct acpi_prt_entry *entry,
  * failure: return -1
  */
 static int
-acpi_pci_irq_lookup(struct pci_bus *bus,
-		    int device,
-		    int pin,
+acpi_pci_irq_lookup(struct pci_dev *dev, int pin,
 		    int *triggering,
 		    int *polarity, char **link, irq_lookup_func func)
 {
 	struct acpi_prt_entry *entry = NULL;
-	int segment = pci_domain_nr(bus);
-	int bus_nr = bus->number;
 	int ret;
 
 
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			  "Searching for _PRT entry for %04x:%02x:%02x[%c]\n",
-			  segment, bus_nr, device, pin_name(pin)));
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Searching for _PRT entry for %s[%c]\n",
+			  pci_name(dev), pin_name(pin)));
 
-	entry = acpi_pci_irq_find_prt_entry(segment, bus_nr, device, pin);
+	entry = acpi_pci_irq_find_prt_entry(dev, pin);
 	if (!entry) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_PRT entry not found\n"));
 		return -1;
@@ -449,7 +446,7 @@ acpi_pci_irq_derive(struct pci_dev *dev,
 			pin = bridge_pin;
 		}
 
-		irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn),
+		irq = acpi_pci_irq_lookup(bridge,
 					  pin, triggering, polarity,
 					  link, func);
 	}
@@ -495,7 +492,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
 	 * First we check the PCI IRQ routing table (PRT) for an IRQ.  PRT
 	 * values override any BIOS-assigned IRQs set during boot.
 	 */
-	gsi = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
+	gsi = acpi_pci_irq_lookup(dev, pin,
 				  &triggering, &polarity, &link,
 				  acpi_pci_allocate_irq);
 
@@ -576,7 +573,7 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
 	/*
 	 * First we check the PCI IRQ routing table (PRT) for an IRQ.
 	 */
-	gsi = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
+	gsi = acpi_pci_irq_lookup(dev, pin,
 				  &triggering, &polarity, NULL,
 				  acpi_pci_free_irq);
 	/*
#12 lore raw

PATCH 11/20 ACPI: PCI: tweak _PRT lookup debug

In reply to Bjorn Helgaas

Print one message (either "found" or "not found") for every _PRT search. And add pin information to the INTx swizzling debug.

---
 drivers/acpi/pci_irq.c |   13 +++++++------
 1 files changed, 7 insertions(+), 6 deletions(-)
drivers/acpi/pci_irq.c +7 -6
index 6f4c5f3..c8246c2 100644
@@ -397,15 +397,16 @@ acpi_pci_irq_lookup(struct pci_dev *dev, int pin,
 	int ret;
 
 
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Searching for _PRT entry for %s[%c]\n",
-			  pci_name(dev), pin_name(pin)));
-
 	entry = acpi_pci_irq_find_prt_entry(dev, pin);
 	if (!entry) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_PRT entry not found\n"));
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No %s[%c] _PRT entry\n",
+				  pci_name(dev), pin_name(pin)));
 		return -1;
 	}
 
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %s[%c] _PRT entry\n",
+			  pci_name(dev), pin_name(pin)));
+
 	ret = func(entry, triggering, polarity, link);
 	return ret;
 }
@@ -457,8 +458,8 @@ acpi_pci_irq_derive(struct pci_dev *dev,
 		return -1;
 	}
 
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derive GSI %d for device %s from %s\n",
-			  irq, pci_name(dev), pci_name(bridge)));
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derived GSI %d for %s INT %c from %s\n",
+			  irq, pci_name(dev), pin_name(orig_pin), pci_name(bridge)));
 
 	return irq;
 }
#13 lore raw

PATCH 12/20 ACPI: PCI: remove callback from acpi_pci_irq_lookup & acpi_pci_irq_derive

In reply to Bjorn Helgaas

We currently pass a callback function (either acpi_pci_allocate_irq() or acpi_pci_free_irq()) to acpi_pci_irq_lookup() and acpi_pci_irq_derive().

I think it's simpler to remove the callback and just have the enable/ disable functions make the calls directly.

---
 drivers/acpi/pci_irq.c |   93 +++++++++++++++++++-----------------------------
 1 files changed, 36 insertions(+), 57 deletions(-)
drivers/acpi/pci_irq.c +36 -57
index c8246c2..ef65c6d 100644
@@ -341,8 +341,6 @@ void acpi_pci_irq_del_prt(int segment, int bus)
 /* --------------------------------------------------------------------------
                           PCI Interrupt Routing Support
    -------------------------------------------------------------------------- */
-typedef int (*irq_lookup_func) (struct acpi_prt_entry *, int *, int *, char **);
-
 static int
 acpi_pci_allocate_irq(struct acpi_prt_entry *entry,
 		      int *triggering, int *polarity, char **link)
@@ -370,8 +368,7 @@ acpi_pci_allocate_irq(struct acpi_prt_entry *entry,
 }
 
 static int
-acpi_pci_free_irq(struct acpi_prt_entry *entry,
-		  int *triggering, int *polarity, char **link)
+acpi_pci_free_irq(struct acpi_prt_entry *entry)
 {
 	int irq;
 
@@ -383,47 +380,29 @@ acpi_pci_free_irq(struct acpi_prt_entry *entry,
 	return irq;
 }
 
-/*
- * acpi_pci_irq_lookup
- * success: return IRQ >= 0
- * failure: return -1
- */
-static int
-acpi_pci_irq_lookup(struct pci_dev *dev, int pin,
-		    int *triggering,
-		    int *polarity, char **link, irq_lookup_func func)
+static struct acpi_prt_entry *
+acpi_pci_irq_lookup(struct pci_dev *dev, int pin)
 {
-	struct acpi_prt_entry *entry = NULL;
-	int ret;
-
+	struct acpi_prt_entry *entry;
 
 	entry = acpi_pci_irq_find_prt_entry(dev, pin);
 	if (!entry) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No %s[%c] _PRT entry\n",
 				  pci_name(dev), pin_name(pin)));
-		return -1;
+		return NULL;
 	}
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %s[%c] _PRT entry\n",
 			  pci_name(dev), pin_name(pin)));
 
-	ret = func(entry, triggering, polarity, link);
-	return ret;
+	return entry;
 }
 
-/*
- * acpi_pci_irq_derive
- * success: return IRQ >= 0
- * failure: return < 0
- */
-static int
-acpi_pci_irq_derive(struct pci_dev *dev,
-		    int pin,
-		    int *triggering,
-		    int *polarity, char **link, irq_lookup_func func)
+static struct acpi_prt_entry *
+acpi_pci_irq_derive(struct pci_dev *dev, int pin)
 {
+	struct acpi_prt_entry *entry = NULL;
 	struct pci_dev *bridge = dev;
-	int irq = -1;
 	u8 bridge_pin = 0, orig_pin = pin;
 
 
@@ -431,7 +410,7 @@ acpi_pci_irq_derive(struct pci_dev *dev,
 	 * Attempt to derive an IRQ for this device from a parent bridge's
 	 * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge).
 	 */
-	while (irq < 0 && bridge->bus->self) {
+	while (!entry && bridge->bus->self) {
 		pin = (((pin - 1) + PCI_SLOT(bridge->devfn)) % 4) + 1;
 		bridge = bridge->bus->self;
 
@@ -442,26 +421,24 @@ acpi_pci_irq_derive(struct pci_dev *dev,
 				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 						  "No interrupt pin configured for device %s\n",
 						  pci_name(bridge)));
-				return -1;
+				return NULL;
 			}
 			pin = bridge_pin;
 		}
 
-		irq = acpi_pci_irq_lookup(bridge,
-					  pin, triggering, polarity,
-					  link, func);
+		entry = acpi_pci_irq_lookup(bridge, pin);
 	}
 
-	if (irq < 0) {
+	if (!entry) {
 		dev_warn(&dev->dev, "can't derive routing for PCI INT %c\n",
 			 pin_name(orig_pin));
-		return -1;
+		return NULL;
 	}
 
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derived GSI %d for %s INT %c from %s\n",
-			  irq, pci_name(dev), pin_name(orig_pin), pci_name(bridge)));
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derived GSI for %s INT %c from %s\n",
+			  pci_name(dev), pin_name(orig_pin), pci_name(bridge)));
 
-	return irq;
+	return entry;
 }
 
 /*
@@ -472,6 +449,7 @@ acpi_pci_irq_derive(struct pci_dev *dev,
 
 int acpi_pci_irq_enable(struct pci_dev *dev)
 {
+	struct acpi_prt_entry *entry;
 	int gsi = 0;
 	u8 pin = 0;
 	int triggering = ACPI_LEVEL_SENSITIVE;
@@ -493,18 +471,20 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
 	 * First we check the PCI IRQ routing table (PRT) for an IRQ.  PRT
 	 * values override any BIOS-assigned IRQs set during boot.
 	 */
-	gsi = acpi_pci_irq_lookup(dev, pin,
-				  &triggering, &polarity, &link,
-				  acpi_pci_allocate_irq);
+	entry = acpi_pci_irq_lookup(dev, pin);
 
 	/*
 	 * If no PRT entry was found, we'll try to derive an IRQ from the
 	 * device's parent bridge.
 	 */
-	if (gsi < 0)
-		gsi = acpi_pci_irq_derive(dev, pin, &triggering,
-					  &polarity, &link,
-					  acpi_pci_allocate_irq);
+	if (!entry)
+		entry = acpi_pci_irq_derive(dev, pin);
+
+	if (entry)
+		gsi = acpi_pci_allocate_irq(entry, &triggering, &polarity,
+					    &link);
+	else
+		gsi = -1;
 
 	if (gsi < 0) {
 		/*
@@ -561,10 +541,9 @@ void __attribute__ ((weak)) acpi_unregister_gsi(u32 i)
 
 void acpi_pci_irq_disable(struct pci_dev *dev)
 {
+	struct acpi_prt_entry *entry;
 	int gsi = 0;
 	u8 pin = 0;
-	int triggering = ACPI_LEVEL_SENSITIVE;
-	int polarity = ACPI_ACTIVE_LOW;
 
 
 	pin = dev->pin;
@@ -574,20 +553,20 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
 	/*
 	 * First we check the PCI IRQ routing table (PRT) for an IRQ.
 	 */
-	gsi = acpi_pci_irq_lookup(dev, pin,
-				  &triggering, &polarity, NULL,
-				  acpi_pci_free_irq);
+	entry = acpi_pci_irq_lookup(dev, pin);
+
 	/*
 	 * If no PRT entry was found, we'll try to derive an IRQ from the
 	 * device's parent bridge.
 	 */
-	if (gsi < 0)
-		gsi = acpi_pci_irq_derive(dev, pin,
-					  &triggering, &polarity, NULL,
-					  acpi_pci_free_irq);
-	if (gsi < 0)
+	if (!entry)
+		entry = acpi_pci_irq_derive(dev, pin);
+
+	if (!entry)
 		return;
 
+	gsi = acpi_pci_free_irq(entry);
+
 	/*
 	 * TBD: It might be worth clearing dev->irq by magic constant
 	 * (e.g. PCI_UNDEFINED_IRQ).
#14 lore raw

PATCH 13/20 ACPI: PCI: use positive logic to simplify code

In reply to Bjorn Helgaas

This doesn't change anything functionally; it just changes tests so we test for success instead of failure. This makes the code read more easily and allows us to remove the "!entry" in the while loop condition.

---
 drivers/acpi/pci_irq.c |   33 ++++++++++++++++-----------------
 1 files changed, 16 insertions(+), 17 deletions(-)
drivers/acpi/pci_irq.c +16 -17
index ef65c6d..6f54c3a 100644
@@ -386,16 +386,15 @@ acpi_pci_irq_lookup(struct pci_dev *dev, int pin)
 	struct acpi_prt_entry *entry;
 
 	entry = acpi_pci_irq_find_prt_entry(dev, pin);
-	if (!entry) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No %s[%c] _PRT entry\n",
+	if (entry) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %s[%c] _PRT entry\n",
 				  pci_name(dev), pin_name(pin)));
-		return NULL;
+		return entry;
 	}
 
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %s[%c] _PRT entry\n",
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No %s[%c] _PRT entry\n",
 			  pci_name(dev), pin_name(pin)));
-
-	return entry;
+	return NULL;
 }
 
 static struct acpi_prt_entry *
@@ -410,7 +409,7 @@ acpi_pci_irq_derive(struct pci_dev *dev, int pin)
 	 * Attempt to derive an IRQ for this device from a parent bridge's
 	 * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge).
 	 */
-	while (!entry && bridge->bus->self) {
+	while (bridge->bus->self) {
 		pin = (((pin - 1) + PCI_SLOT(bridge->devfn)) % 4) + 1;
 		bridge = bridge->bus->self;
 
@@ -427,18 +426,18 @@ acpi_pci_irq_derive(struct pci_dev *dev, int pin)
 		}
 
 		entry = acpi_pci_irq_lookup(bridge, pin);
+		if (entry) {
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+					 "Derived GSI for %s INT %c from %s\n",
+					 pci_name(dev), pin_name(orig_pin),
+					 pci_name(bridge)));
+			return entry;
+		}
 	}
 
-	if (!entry) {
-		dev_warn(&dev->dev, "can't derive routing for PCI INT %c\n",
-			 pin_name(orig_pin));
-		return NULL;
-	}
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derived GSI for %s INT %c from %s\n",
-			  pci_name(dev), pin_name(orig_pin), pci_name(bridge)));
-
-	return entry;
+	dev_warn(&dev->dev, "can't derive routing for PCI INT %c\n",
+		 pin_name(orig_pin));
+	return NULL;
 }
 
 /*
#15 lore raw

PATCH 14/20 ACPI: PCI: follow typical PCI INTx swizzling pattern

In reply to Bjorn Helgaas

No functional change; this just uses the typical pattern of PCI INTx swizzling done on other architectures.

---
 drivers/acpi/pci_irq.c |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)
drivers/acpi/pci_irq.c +7 -4
index 6f54c3a..b2885ce 100644
@@ -401,7 +401,7 @@ static struct acpi_prt_entry *
 acpi_pci_irq_derive(struct pci_dev *dev, int pin)
 {
 	struct acpi_prt_entry *entry = NULL;
-	struct pci_dev *bridge = dev;
+	struct pci_dev *bridge;
 	u8 bridge_pin = 0, orig_pin = pin;
 
 
@@ -409,9 +409,9 @@ acpi_pci_irq_derive(struct pci_dev *dev, int pin)
 	 * Attempt to derive an IRQ for this device from a parent bridge's
 	 * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge).
 	 */
-	while (bridge->bus->self) {
-		pin = (((pin - 1) + PCI_SLOT(bridge->devfn)) % 4) + 1;
-		bridge = bridge->bus->self;
+	bridge = dev->bus->self;
+	while (bridge) {
+		pin = (((pin - 1) + PCI_SLOT(dev->devfn)) % 4) + 1;
 
 		if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) {
 			/* PC card has the same IRQ as its cardbridge */
@@ -433,6 +433,9 @@ acpi_pci_irq_derive(struct pci_dev *dev, int pin)
 					 pci_name(bridge)));
 			return entry;
 		}
+
+		dev = bridge;
+		bridge = dev->bus->self;
 	}
 
 	dev_warn(&dev->dev, "can't derive routing for PCI INT %c\n",
#16 lore raw

PATCH 15/20 ACPI: PCI: combine lookup and derive

In reply to Bjorn Helgaas

This folds acpi_pci_irq_derive() into acpi_pci_irq_lookup() so it can be easily used by both acpi_pci_irq_enable() and acpi_pci_irq_disable().

---
 drivers/acpi/pci_irq.c |   55 ++++++++++--------------------------------------
 1 files changed, 11 insertions(+), 44 deletions(-)
drivers/acpi/pci_irq.c +11 -44
index b2885ce..431d00b 100644
@@ -384,6 +384,8 @@ static struct acpi_prt_entry *
 acpi_pci_irq_lookup(struct pci_dev *dev, int pin)
 {
 	struct acpi_prt_entry *entry;
+	struct pci_dev *bridge;
+	u8 bridge_pin, orig_pin = pin;
 
 	entry = acpi_pci_irq_find_prt_entry(dev, pin);
 	if (entry) {
@@ -392,19 +394,6 @@ acpi_pci_irq_lookup(struct pci_dev *dev, int pin)
 		return entry;
 	}
 
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No %s[%c] _PRT entry\n",
-			  pci_name(dev), pin_name(pin)));
-	return NULL;
-}
-
-static struct acpi_prt_entry *
-acpi_pci_irq_derive(struct pci_dev *dev, int pin)
-{
-	struct acpi_prt_entry *entry = NULL;
-	struct pci_dev *bridge;
-	u8 bridge_pin = 0, orig_pin = pin;
-
-
 	/* 
 	 * Attempt to derive an IRQ for this device from a parent bridge's
 	 * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge).
@@ -425,7 +414,7 @@ acpi_pci_irq_derive(struct pci_dev *dev, int pin)
 			pin = bridge_pin;
 		}
 
-		entry = acpi_pci_irq_lookup(bridge, pin);
+		entry = acpi_pci_irq_find_prt_entry(bridge, pin);
 		if (entry) {
 			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 					 "Derived GSI for %s INT %c from %s\n",
@@ -469,26 +458,8 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
 		return 0;
 	}
 
-	/* 
-	 * First we check the PCI IRQ routing table (PRT) for an IRQ.  PRT
-	 * values override any BIOS-assigned IRQs set during boot.
-	 */
 	entry = acpi_pci_irq_lookup(dev, pin);
-
-	/*
-	 * If no PRT entry was found, we'll try to derive an IRQ from the
-	 * device's parent bridge.
-	 */
-	if (!entry)
-		entry = acpi_pci_irq_derive(dev, pin);
-
-	if (entry)
-		gsi = acpi_pci_allocate_irq(entry, &triggering, &polarity,
-					    &link);
-	else
-		gsi = -1;
-
-	if (gsi < 0) {
+	if (!entry) {
 		/*
 		 * IDE legacy mode controller IRQs are magic. Why do compat
 		 * extensions always make such a nasty mess.
@@ -497,6 +468,13 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
 				(dev->class & 0x05) == 0)
 			return 0;
 	}
+
+	if (entry)
+		gsi = acpi_pci_allocate_irq(entry, &triggering, &polarity,
+					    &link);
+	else
+		gsi = -1;
+
 	/*
 	 * No IRQ known to the ACPI subsystem - maybe the BIOS / 
 	 * driver reported one, then use it. Exit in any case.
@@ -552,18 +530,7 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
 	if (!pin)
 		return;
 
-	/*
-	 * First we check the PCI IRQ routing table (PRT) for an IRQ.
-	 */
 	entry = acpi_pci_irq_lookup(dev, pin);
-
-	/*
-	 * If no PRT entry was found, we'll try to derive an IRQ from the
-	 * device's parent bridge.
-	 */
-	if (!entry)
-		entry = acpi_pci_irq_derive(dev, pin);
-
 	if (!entry)
 		return;
 
#17 lore raw

PATCH 16/20 ACPI: PCI: simplify list of _PRT entries

In reply to Bjorn Helgaas

We don't need a struct containing a count and a list_head; a simple list_head is sufficient. The list iterators handle empty lists fine.

---
 drivers/acpi/pci_irq.c |   60 ++++++++++--------------------------------------
 1 files changed, 12 insertions(+), 48 deletions(-)
drivers/acpi/pci_irq.c +12 -48
index 431d00b..b1cfd39 100644
@@ -44,7 +44,7 @@
 ACPI_MODULE_NAME("pci_irq");
 
 struct acpi_prt_entry {
-	struct list_head	node;
+	struct list_head	list;
 	struct acpi_pci_id	id;
 	u8			pin;
 	struct {
@@ -54,12 +54,7 @@ struct acpi_prt_entry {
 	u32			irq;
 };
 
-struct acpi_prt_list {
-	int			count;
-	struct list_head	entries;
-};
-
-static struct acpi_prt_list acpi_prt;
+static LIST_HEAD(acpi_prt_list);
 static DEFINE_SPINLOCK(acpi_prt_lock);
 
 static inline char pin_name(int pin)
@@ -74,21 +69,13 @@ static inline char pin_name(int pin)
 static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(struct pci_dev *dev,
 							  int pin)
 {
-	struct acpi_prt_entry *entry = NULL;
+	struct acpi_prt_entry *entry;
 	int segment = pci_domain_nr(dev->bus);
 	int bus = dev->bus->number;
 	int device = PCI_SLOT(dev->devfn);
 
-	if (!acpi_prt.count)
-		return NULL;
-
-	/*
-	 * Parse through all PRT entries looking for a match on the specified
-	 * PCI device's segment, bus, device, and pin (don't care about func).
-	 *
-	 */
 	spin_lock(&acpi_prt_lock);
-	list_for_each_entry(entry, &acpi_prt.entries, node) {
+	list_for_each_entry(entry, &acpi_prt_list, list) {
 		if ((segment == entry->id.segment)
 		    && (bus == entry->id.bus)
 		    && (device == entry->id.device)
@@ -97,7 +84,6 @@ static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(struct pci_dev *dev,
 			return entry;
 		}
 	}
-
 	spin_unlock(&acpi_prt_lock);
 	return NULL;
 }
@@ -203,7 +189,7 @@ static int
 acpi_pci_irq_add_entry(acpi_handle handle,
 		       int segment, int bus, struct acpi_pci_routing_table *prt)
 {
-	struct acpi_prt_entry *entry = NULL;
+	struct acpi_prt_entry *entry;
 
 	entry = kzalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL);
 	if (!entry)
@@ -255,35 +241,17 @@ acpi_pci_irq_add_entry(acpi_handle handle,
 			      prt->source, entry->link.index));
 
 	spin_lock(&acpi_prt_lock);
-	list_add_tail(&entry->node, &acpi_prt.entries);
-	acpi_prt.count++;
+	list_add_tail(&entry->list, &acpi_prt_list);
 	spin_unlock(&acpi_prt_lock);
 
 	return 0;
 }
 
-static void
-acpi_pci_irq_del_entry(int segment, int bus, struct acpi_prt_entry *entry)
-{
-	if (segment == entry->id.segment && bus == entry->id.bus) {
-		acpi_prt.count--;
-		list_del(&entry->node);
-		kfree(entry);
-	}
-}
-
 int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus)
 {
 	acpi_status status;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 	struct acpi_pci_routing_table *entry;
-	static int first_time = 1;
-
-	if (first_time) {
-		acpi_prt.count = 0;
-		INIT_LIST_HEAD(&acpi_prt.entries);
-		first_time = 0;
-	}
 
 	/* 'handle' is the _PRT's parent (root bridge or PCI-PCI bridge) */
 	status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
@@ -319,21 +287,17 @@ int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus)
 
 void acpi_pci_irq_del_prt(int segment, int bus)
 {
-	struct list_head *node = NULL, *n = NULL;
-	struct acpi_prt_entry *entry = NULL;
-
-	if (!acpi_prt.count) {
-		return;
-	}
+	struct acpi_prt_entry *entry, *tmp;
 
 	printk(KERN_DEBUG
 	       "ACPI: Delete PCI Interrupt Routing Table for %04x:%02x\n",
 	       segment, bus);
 	spin_lock(&acpi_prt_lock);
-	list_for_each_safe(node, n, &acpi_prt.entries) {
-		entry = list_entry(node, struct acpi_prt_entry, node);
-
-		acpi_pci_irq_del_entry(segment, bus, entry);
+	list_for_each_entry_safe(entry, tmp, &acpi_prt_list, list) {
+		if (segment == entry->id.segment && bus == entry->id.bus) {
+			list_del(&entry->list);
+			kfree(entry);
+		}
 	}
 	spin_unlock(&acpi_prt_lock);
 }
#18 lore raw

PATCH 17/20 ACPI: PCI: simplify struct acpi_prt_entry

In reply to Bjorn Helgaas

Remove unused "irq" field, remove unnecessary struct, rename "handle" to "link".

---
 drivers/acpi/pci_irq.c |   35 +++++++++++++++--------------------
 1 files changed, 15 insertions(+), 20 deletions(-)
drivers/acpi/pci_irq.c +15 -20
index b1cfd39..288583b 100644
@@ -47,11 +47,8 @@ struct acpi_prt_entry {
 	struct list_head	list;
 	struct acpi_pci_id	id;
 	u8			pin;
-	struct {
-		acpi_handle		handle;
-		u32			index;
-	}			link;
-	u32			irq;
+	acpi_handle		link;
+	u32			index;		/* GSI, or link _CRS index */
 };
 
 static LIST_HEAD(acpi_prt_list);
@@ -207,6 +204,8 @@ acpi_pci_irq_add_entry(acpi_handle handle,
 
 	do_prt_fixups(entry, prt);
 
+	entry->index = prt->source_index;
+
 	/*
 	 * Type 1: Dynamic
 	 * ---------------
@@ -220,10 +219,9 @@ acpi_pci_irq_add_entry(acpi_handle handle,
 	 *       (e.g. exists somewhere 'below' this _PRT entry in the ACPI
 	 *       namespace).
 	 */
-	if (prt->source[0]) {
-		acpi_get_handle(handle, prt->source, &entry->link.handle);
-		entry->link.index = prt->source_index;
-	}
+	if (prt->source[0])
+		acpi_get_handle(handle, prt->source, &entry->link);
+
 	/*
 	 * Type 2: Static
 	 * --------------
@@ -231,14 +229,12 @@ acpi_pci_irq_add_entry(acpi_handle handle,
 	 * the IRQ value, which is hardwired to specific interrupt inputs on
 	 * the interrupt controller.
 	 */
-	else
-		entry->link.index = prt->source_index;
 
 	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO,
 			      "      %04x:%02x:%02x[%c] -> %s[%d]\n",
 			      entry->id.segment, entry->id.bus,
 			      entry->id.device, pin_name(entry->pin),
-			      prt->source, entry->link.index));
+			      prt->source, entry->index));
 
 	spin_lock(&acpi_prt_lock);
 	list_add_tail(&entry->list, &acpi_prt_list);
@@ -312,17 +308,16 @@ acpi_pci_allocate_irq(struct acpi_prt_entry *entry,
 	int irq;
 
 
-	if (entry->link.handle) {
-		irq = acpi_pci_link_allocate_irq(entry->link.handle,
-						 entry->link.index, triggering,
-						 polarity, link);
+	if (entry->link) {
+		irq = acpi_pci_link_allocate_irq(entry->link, entry->index,
+						 triggering, polarity, link);
 		if (irq < 0) {
 			printk(KERN_WARNING PREFIX
 				      "Invalid IRQ link routing entry\n");
 			return -1;
 		}
 	} else {
-		irq = entry->link.index;
+		irq = entry->index;
 		*triggering = ACPI_LEVEL_SENSITIVE;
 		*polarity = ACPI_ACTIVE_LOW;
 	}
@@ -336,10 +331,10 @@ acpi_pci_free_irq(struct acpi_prt_entry *entry)
 {
 	int irq;
 
-	if (entry->link.handle) {
-		irq = acpi_pci_link_free_irq(entry->link.handle);
+	if (entry->link) {
+		irq = acpi_pci_link_free_irq(entry->link);
 	} else {
-		irq = entry->link.index;
+		irq = entry->index;
 	}
 	return irq;
 }
#19 lore raw

PATCH 18/20 ACPI: PCI: expand acpi_pci_allocate_irq() and acpi_pci_free_irq() inline

In reply to Bjorn Helgaas

acpi_pci_allocate_irq() and acpi_pci_free_irq() are trivial and only used once, so just open-code them.

---
 drivers/acpi/pci_irq.c |   56 +++++++++++-------------------------------------
 1 files changed, 13 insertions(+), 43 deletions(-)
drivers/acpi/pci_irq.c +13 -43
index 288583b..5a07d48 100644
@@ -301,44 +301,6 @@ void acpi_pci_irq_del_prt(int segment, int bus)
 /* --------------------------------------------------------------------------
                           PCI Interrupt Routing Support
    -------------------------------------------------------------------------- */
-static int
-acpi_pci_allocate_irq(struct acpi_prt_entry *entry,
-		      int *triggering, int *polarity, char **link)
-{
-	int irq;
-
-
-	if (entry->link) {
-		irq = acpi_pci_link_allocate_irq(entry->link, entry->index,
-						 triggering, polarity, link);
-		if (irq < 0) {
-			printk(KERN_WARNING PREFIX
-				      "Invalid IRQ link routing entry\n");
-			return -1;
-		}
-	} else {
-		irq = entry->index;
-		*triggering = ACPI_LEVEL_SENSITIVE;
-		*polarity = ACPI_ACTIVE_LOW;
-	}
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found GSI %d\n", irq));
-	return irq;
-}
-
-static int
-acpi_pci_free_irq(struct acpi_prt_entry *entry)
-{
-	int irq;
-
-	if (entry->link) {
-		irq = acpi_pci_link_free_irq(entry->link);
-	} else {
-		irq = entry->index;
-	}
-	return irq;
-}
-
 static struct acpi_prt_entry *
 acpi_pci_irq_lookup(struct pci_dev *dev, int pin)
 {
@@ -428,10 +390,15 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
 			return 0;
 	}
 
-	if (entry)
-		gsi = acpi_pci_allocate_irq(entry, &triggering, &polarity,
-					    &link);
-	else
+	if (entry) {
+		if (entry->link)
+			gsi = acpi_pci_link_allocate_irq(entry->link,
+							 entry->index,
+							 &triggering, &polarity,
+							 &link);
+		else
+			gsi = entry->index;
+	} else
 		gsi = -1;
 
 	/*
@@ -493,7 +460,10 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
 	if (!entry)
 		return;
 
-	gsi = acpi_pci_free_irq(entry);
+	if (entry->link)
+		gsi = acpi_pci_link_free_irq(entry->link);
+	else
+		gsi = entry->index;
 
 	/*
 	 * TBD: It might be worth clearing dev->irq by magic constant
#20 lore raw

PATCH 19/20 ACPI: PCI: whitespace and useless initialization cleanup

In reply to Bjorn Helgaas

This patch makes function declarations consistent throughout the file and removes some unnecessary initializations.

---
 drivers/acpi/pci_irq.c |   28 +++++++++-------------------
 1 files changed, 9 insertions(+), 19 deletions(-)
drivers/acpi/pci_irq.c +9 -19
index 5a07d48..30aa0a0 100644
@@ -151,8 +151,8 @@ static struct prt_quirk prt_quirks[] = {
 		"\\_SB_.PCI0.LNK3"},
 };
 
-static void
-do_prt_fixups(struct acpi_prt_entry *entry, struct acpi_pci_routing_table *prt)
+static void do_prt_fixups(struct acpi_prt_entry *entry,
+			  struct acpi_pci_routing_table *prt)
 {
 	int i;
 	struct prt_quirk *quirk;
@@ -182,9 +182,8 @@ do_prt_fixups(struct acpi_prt_entry *entry, struct acpi_pci_routing_table *prt)
 	}
 }
 
-static int
-acpi_pci_irq_add_entry(acpi_handle handle,
-		       int segment, int bus, struct acpi_pci_routing_table *prt)
+static int acpi_pci_irq_add_entry(acpi_handle handle, int segment, int bus,
+				  struct acpi_pci_routing_table *prt)
 {
 	struct acpi_prt_entry *entry;
 
@@ -301,8 +300,7 @@ void acpi_pci_irq_del_prt(int segment, int bus)
 /* --------------------------------------------------------------------------
                           PCI Interrupt Routing Support
    -------------------------------------------------------------------------- */
-static struct acpi_prt_entry *
-acpi_pci_irq_lookup(struct pci_dev *dev, int pin)
+static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin)
 {
 	struct acpi_prt_entry *entry;
 	struct pci_dev *bridge;
@@ -353,24 +351,17 @@ acpi_pci_irq_lookup(struct pci_dev *dev, int pin)
 	return NULL;
 }
 
-/*
- * acpi_pci_irq_enable
- * success: return 0
- * failure: return < 0
- */
-
 int acpi_pci_irq_enable(struct pci_dev *dev)
 {
 	struct acpi_prt_entry *entry;
-	int gsi = 0;
-	u8 pin = 0;
+	int gsi;
+	u8 pin;
 	int triggering = ACPI_LEVEL_SENSITIVE;
 	int polarity = ACPI_ACTIVE_LOW;
 	char *link = NULL;
 	char link_desc[16];
 	int rc;
 
-
 	pin = dev->pin;
 	if (!pin) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -448,9 +439,8 @@ void __attribute__ ((weak)) acpi_unregister_gsi(u32 i)
 void acpi_pci_irq_disable(struct pci_dev *dev)
 {
 	struct acpi_prt_entry *entry;
-	int gsi = 0;
-	u8 pin = 0;
-
+	int gsi;
+	u8 pin;
 
 	pin = dev->pin;
 	if (!pin)
#21 lore raw

PATCH 20/20 ACPI: PCI: add HP copyright

In reply to Bjorn Helgaas

Add HP copyright to pci_irq.c.

---
 drivers/acpi/pci_irq.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
drivers/acpi/pci_irq.c +2 -0
index 30aa0a0..2c579a5 100644
@@ -4,6 +4,8 @@
  *  Copyright (C) 2001, 2002 Andy Grover <[email protected]>
  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <[email protected]>
  *  Copyright (C) 2002       Dominik Brodowski <[email protected]>
+ *  (c) Copyright 2008 Hewlett-Packard Development Company, L.P.
+ *	Bjorn Helgaas <[email protected]>
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *
reviewer
#22 lore raw
In reply to Bjorn Helgaas

series looks good -- applied all 20.

thanks,
-- Len Brown, Intel Open Source Technology Center

Quoted 42 lines · Bjorn Helgaas

This series simplifies the code that handles ACPI _PRTs (PCI routing tables). My goal is to make this look more like the corresponding code in other architectures, especially in terms of swizzling, e.g., the various implementations of common_swizzle() and simple_swizzle(), and the x86 non-ACPI code in pirq_enable_irq().

There should be no functional changes in this series.

Comments welcome.

Bjorn

---

Bjorn Helgaas (20):
ACPI: PCI: add HP copyright
ACPI: PCI: whitespace and useless initialization cleanup
ACPI: PCI: expand acpi_pci_allocate_irq() and acpi_pci_free_irq() inline
ACPI: PCI: simplify struct acpi_prt_entry
ACPI: PCI: simplify list of _PRT entries
ACPI: PCI: combine lookup and derive
ACPI: PCI: follow typical PCI INTx swizzling pattern
ACPI: PCI: use positive logic to simplify code
ACPI: PCI: remove callback from acpi_pci_irq_lookup & acpi_pci_irq_derive
ACPI: PCI: tweak _PRT lookup debug
ACPI: PCI: lookup _PRT entry by PCI dev and pin, not segment/bus/dev/pin
ACPI: PCI: use 1-based encoding for _PRT quirks
ACPI: PCI: always use the PCI INTx pin values, not the _PRT ones
ACPI: PCI: add a helper to convert _PRT INTx pin number to name
ACPI: PCI: move struct acpi_prt_entry declaration out of public header file
ACPI: PCI: fix GSI/IRQ naming confusion
ACPI: PCI: ignore _PRT function information
ACPI: PCI: simplify buffer management for evaluating _PRT
ACPI: PCI: remove unnecessary null pointer checks
ACPI: PCI: use conventional PCI address format

 drivers/acpi/pci_bind.c |   12 +
 drivers/acpi/pci_irq.c  |  416 +++++++++++++++--------------------------------
 include/linux/acpi.h    |   16 --
 3 files changed, 136 insertions(+), 308 deletions(-)