* [PATCH] x86: don't print strange not connect ioapic
@ 2009-04-29 20:04 Yinghai Lu
2009-04-30 8:19 ` [PATCH 1/4] x86/acpi: move pin_programmed bit map to io_apic.c Yinghai Lu
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Yinghai Lu @ 2009-04-29 20:04 UTC (permalink / raw)
To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Len Brown
Cc: linux-kernel, ACPI Devel Maling List
in setup_IO_APIC_irqs(), we only need to go with ioapic that handle legacy irqs,
because at that points we only have those irq in mp_irqs[]
will not print out those strange not connected pin warning.
[ Impact: don't go with not used ioapic yet ]
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
arch/x86/kernel/apic/io_apic.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
Index: linux-2.6/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6/arch/x86/kernel/apic/io_apic.c
@@ -1477,10 +1477,27 @@ static void __init setup_IO_APIC_irqs(vo
struct irq_desc *desc;
struct irq_cfg *cfg;
int node = cpu_to_node(boot_cpu_id);
+ int ioapic_start = 0, ioapic_end = nr_ioapics;
apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
- for (apic_id = 0; apic_id < nr_ioapics; apic_id++) {
+#ifdef CONFIG_ACPI
+ /*
+ * when acpi is used, at this point, we only have legacy entries
+ * in mp_irqs[] by mp_config_acpi_legacy_irqs/mp_override_legacy_irq
+ * so only setup for that ioapic, and will not print out those strange
+ * not connected on other ioapic
+ */
+ if (!acpi_disabled && acpi_ioapic) {
+ ioapic_start = mp_find_ioapic(0);
+ if (ioapic_start < 0)
+ ioapic_start = 0;
+ else
+ ioapic_end = ioapic_start + 1;
+ }
+#endif
+
+ for (apic_id = ioapic_start; apic_id < ioapic_end; apic_id++) {
for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) {
idx = find_irq_entry(apic_id, pin, mp_INT);
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/4] x86/acpi: move pin_programmed bit map to io_apic.c
2009-04-29 20:04 [PATCH] x86: don't print strange not connect ioapic Yinghai Lu
@ 2009-04-30 8:19 ` Yinghai Lu
2009-04-30 8:21 ` [PATCH 2/4] x86/pci: add 4 more return param in IO_APIC_get_PCI_irq_vector Yinghai Lu
` (2 subsequent siblings)
3 siblings, 0 replies; 8+ messages in thread
From: Yinghai Lu @ 2009-04-30 8:19 UTC (permalink / raw)
To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Len Brown
Cc: linux-kernel, ACPI Devel Maling List
prepare to call setup_io_apic_routing in pcibios_irq_enable
also remove not needed member apic_id.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
arch/x86/kernel/acpi/boot.c | 18 ++----------------
arch/x86/kernel/apic/io_apic.c | 25 ++++++++++++++++++++++++-
2 files changed, 26 insertions(+), 17 deletions(-)
Index: linux-2.6/arch/x86/kernel/acpi/boot.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/acpi/boot.c
+++ linux-2.6/arch/x86/kernel/acpi/boot.c
@@ -904,10 +904,8 @@ extern int es7000_plat;
#endif
static struct {
- int apic_id;
int gsi_base;
int gsi_end;
- DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
} mp_ioapic_routing[MAX_IO_APICS];
int mp_find_ioapic(int gsi)
@@ -996,7 +994,6 @@ void __init mp_register_ioapic(int id, u
* Build basic GSI lookup table to facilitate gsi->io_apic lookups
* and to prevent reprogramming of IOAPIC pins (PCI GSIs).
*/
- mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].apicid;
mp_ioapic_routing[idx].gsi_base = gsi_base;
mp_ioapic_routing[idx].gsi_end = gsi_base +
io_apic_get_redir_entries(idx);
@@ -1189,7 +1186,7 @@ static int mp_config_acpi_gsi(struct dev
mp_irq.srcbus = number;
mp_irq.srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3);
ioapic = mp_find_ioapic(gsi);
- mp_irq.dstapic = mp_ioapic_routing[ioapic].apic_id;
+ mp_irq.dstapic = mp_ioapics[ioapic].apicid;
mp_irq.dstirq = mp_find_ioapic_pin(ioapic, gsi);
save_mp_irq(&mp_irq);
@@ -1224,23 +1221,12 @@ int mp_register_gsi(struct device *dev,
if (ioapic_pin > MP_MAX_IOAPIC_PIN) {
printk(KERN_ERR "Invalid reference to IOAPIC pin "
- "%d-%d\n", mp_ioapic_routing[ioapic].apic_id,
+ "%d-%d\n", mp_ioapics[ioapic].apicid,
ioapic_pin);
return gsi;
}
mp_config_acpi_gsi(dev, gsi, triggering, polarity);
- /*
- * Avoid pin reprogramming. PRTs typically include entries
- * with redundant pin->gsi mappings (but unique PCI devices);
- * we only program the IOAPIC on the first.
- */
- if (test_bit(ioapic_pin, mp_ioapic_routing[ioapic].pin_programmed)) {
- pr_debug("Pin %d-%d already programmed\n",
- mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
- return gsi;
- }
- set_bit(ioapic_pin, mp_ioapic_routing[ioapic].pin_programmed);
io_apic_set_pci_routing(dev, ioapic, ioapic_pin, gsi,
triggering == ACPI_EDGE_SENSITIVE ? 0 : 1,
polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
Index: linux-2.6/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6/arch/x86/kernel/apic/io_apic.c
@@ -3938,7 +3938,7 @@ int __init io_apic_get_version(int ioapi
}
#endif
-int io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, int irq,
+static int __io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, int irq,
int triggering, int polarity)
{
struct irq_desc *desc;
@@ -3975,6 +3975,29 @@ int io_apic_set_pci_routing(struct devic
return 0;
}
+static struct {
+ DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
+} mp_ioapic_routing[MAX_IO_APICS];
+
+int io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, int irq,
+ int triggering, int polarity)
+{
+
+ /*
+ * Avoid pin reprogramming. PRTs typically include entries
+ * with redundant pin->gsi mappings (but unique PCI devices);
+ * we only program the IOAPIC on the first.
+ */
+ if (test_bit(pin, mp_ioapic_routing[ioapic].pin_programmed)) {
+ pr_debug("Pin %d-%d already programmed\n",
+ mp_ioapics[ioapic].apicid, pin);
+ return 0;
+ }
+ set_bit(pin, mp_ioapic_routing[ioapic].pin_programmed);
+
+ return __io_apic_set_pci_routing(dev, ioapic, pin, irq,
+ triggering, polarity);
+}
int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
{
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/4] x86/pci: add 4 more return param in IO_APIC_get_PCI_irq_vector
2009-04-29 20:04 [PATCH] x86: don't print strange not connect ioapic Yinghai Lu
2009-04-30 8:19 ` [PATCH 1/4] x86/acpi: move pin_programmed bit map to io_apic.c Yinghai Lu
@ 2009-04-30 8:21 ` Yinghai Lu
2009-04-30 8:22 ` [PATCH 3/4] x86/acpi: move setup io apic routing out of ACPI macro scope Yinghai Lu
2009-04-30 8:23 ` [PATCH 4/4] x86/pci: update pirq_enable_irq to setup io apic routing Yinghai Lu
3 siblings, 0 replies; 8+ messages in thread
From: Yinghai Lu @ 2009-04-30 8:21 UTC (permalink / raw)
To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin
Cc: linux-kernel, Jesse Barnes, linux-pci
so prepare those params for pcibios_irq_enable to call setup_io_apic_routing
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
arch/x86/include/asm/hw_irq.h | 4 +
arch/x86/kernel/apic/io_apic.c | 107 ++++++++++++++++++++------------------
arch/x86/pci/irq.c | 24 +++++++-
drivers/pci/hotplug/ibmphp_core.c | 52 +++++++++---------
4 files changed, 110 insertions(+), 77 deletions(-)
Index: linux-2.6/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6/arch/x86/kernel/apic/io_apic.c
@@ -874,54 +874,6 @@ static int __init find_isa_irq_apic(int
return -1;
}
-/*
- * Find a specific PCI IRQ entry.
- * Not an __init, possibly needed by modules
- */
-static int pin_2_irq(int idx, int apic, int pin);
-
-int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
-{
- int apic, i, best_guess = -1;
-
- apic_printk(APIC_DEBUG, "querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n",
- bus, slot, pin);
- if (test_bit(bus, mp_bus_not_pci)) {
- apic_printk(APIC_VERBOSE, "PCI BIOS passed nonexistent PCI bus %d!\n", bus);
- return -1;
- }
- for (i = 0; i < mp_irq_entries; i++) {
- int lbus = mp_irqs[i].srcbus;
-
- for (apic = 0; apic < nr_ioapics; apic++)
- if (mp_ioapics[apic].apicid == mp_irqs[i].dstapic ||
- mp_irqs[i].dstapic == MP_APIC_ALL)
- break;
-
- if (!test_bit(lbus, mp_bus_not_pci) &&
- !mp_irqs[i].irqtype &&
- (bus == lbus) &&
- (slot == ((mp_irqs[i].srcbusirq >> 2) & 0x1f))) {
- int irq = pin_2_irq(i, apic, mp_irqs[i].dstirq);
-
- if (!(apic || IO_APIC_IRQ(irq)))
- continue;
-
- if (pin == (mp_irqs[i].srcbusirq & 3))
- return irq;
- /*
- * Use the first all-but-pin matching entry as a
- * best-guess fuzzy result for broken mptables.
- */
- if (best_guess < 0)
- best_guess = irq;
- }
- }
- return best_guess;
-}
-
-EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
-
#if defined(CONFIG_EISA) || defined(CONFIG_MCA)
/*
* EISA Edge/Level control register, ELCR
@@ -1140,6 +1092,65 @@ static int pin_2_irq(int idx, int apic,
return irq;
}
+/*
+ * Find a specific PCI IRQ entry.
+ * Not an __init, possibly needed by modules
+ */
+int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,
+ int *ioapic, int *ioapic_pin,
+ int *trigger, int *polarity)
+{
+ int apic, i, best_guess = -1;
+
+ apic_printk(APIC_DEBUG,
+ "querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n",
+ bus, slot, pin);
+ if (test_bit(bus, mp_bus_not_pci)) {
+ apic_printk(APIC_VERBOSE,
+ "PCI BIOS passed nonexistent PCI bus %d!\n", bus);
+ return -1;
+ }
+ for (i = 0; i < mp_irq_entries; i++) {
+ int lbus = mp_irqs[i].srcbus;
+
+ for (apic = 0; apic < nr_ioapics; apic++)
+ if (mp_ioapics[apic].apicid == mp_irqs[i].dstapic ||
+ mp_irqs[i].dstapic == MP_APIC_ALL)
+ break;
+
+ if (!test_bit(lbus, mp_bus_not_pci) &&
+ !mp_irqs[i].irqtype &&
+ (bus == lbus) &&
+ (slot == ((mp_irqs[i].srcbusirq >> 2) & 0x1f))) {
+ int irq = pin_2_irq(i, apic, mp_irqs[i].dstirq);
+
+ if (!(apic || IO_APIC_IRQ(irq)))
+ continue;
+
+ if (pin == (mp_irqs[i].srcbusirq & 3)) {
+ *ioapic = apic;
+ *ioapic_pin = mp_irqs[i].dstirq;
+ *trigger = irq_trigger(i);
+ *polarity = irq_polarity(i);
+ return irq;
+ }
+ /*
+ * Use the first all-but-pin matching entry as a
+ * best-guess fuzzy result for broken mptables.
+ */
+ if (best_guess < 0) {
+ *ioapic = apic;
+ *ioapic_pin = mp_irqs[i].dstirq;
+ *trigger = irq_trigger(i);
+ *polarity = irq_polarity(i);
+ best_guess = irq;
+ }
+ }
+ }
+ return best_guess;
+}
+EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
+
void lock_vector_lock(void)
{
/* Used to the online set of cpus does not change
Index: linux-2.6/arch/x86/include/asm/hw_irq.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/hw_irq.h
+++ linux-2.6/arch/x86/include/asm/hw_irq.h
@@ -66,7 +66,9 @@ extern unsigned long io_apic_irqs;
extern void init_VISWS_APIC_irqs(void);
extern void setup_IO_APIC(void);
extern void disable_IO_APIC(void);
-extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
+extern int IO_APIC_get_PCI_irq_vector(int bus, int devfn, int pin,
+ int *ioapic, int *ioapic_pin,
+ int *trigger, int *polarity);
extern void setup_ioapic_dest(void);
extern void enable_IO_APIC(void);
Index: linux-2.6/drivers/pci/hotplug/ibmphp_core.c
===================================================================
--- linux-2.6.orig/drivers/pci/hotplug/ibmphp_core.c
+++ linux-2.6/drivers/pci/hotplug/ibmphp_core.c
@@ -153,45 +153,49 @@ int ibmphp_init_devno(struct slot **cur_
return -1;
}
for (loop = 0; loop < len; loop++) {
- if ((*cur_slot)->number == rtable->slots[loop].slot) {
- if ((*cur_slot)->bus == rtable->slots[loop].bus) {
+ if ((*cur_slot)->number == rtable->slots[loop].slot &&
+ (*cur_slot)->bus == rtable->slots[loop].bus) {
+ int ioapic = -1, ioapic_pin = -1;
+ int triggering, polarity;
+
(*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn);
for (i = 0; i < 4; i++)
(*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector((int) (*cur_slot)->bus,
- (int) (*cur_slot)->device, i);
+ (int) (*cur_slot)->device, i.
+ &ioapic, &ioapic_pin,
+ &triggering, &polarity);
- debug("(*cur_slot)->irq[0] = %x\n",
- (*cur_slot)->irq[0]);
- debug("(*cur_slot)->irq[1] = %x\n",
- (*cur_slot)->irq[1]);
- debug("(*cur_slot)->irq[2] = %x\n",
- (*cur_slot)->irq[2]);
- debug("(*cur_slot)->irq[3] = %x\n",
- (*cur_slot)->irq[3]);
+ debug("(*cur_slot)->irq[0] = %x\n",
+ (*cur_slot)->irq[0]);
+ debug("(*cur_slot)->irq[1] = %x\n",
+ (*cur_slot)->irq[1]);
+ debug("(*cur_slot)->irq[2] = %x\n",
+ (*cur_slot)->irq[2]);
+ debug("(*cur_slot)->irq[3] = %x\n",
+ (*cur_slot)->irq[3]);
- debug("rtable->exlusive_irqs = %x\n",
+ debug("rtable->exlusive_irqs = %x\n",
rtable->exclusive_irqs);
- debug("rtable->slots[loop].irq[0].bitmap = %x\n",
+ debug("rtable->slots[loop].irq[0].bitmap = %x\n",
rtable->slots[loop].irq[0].bitmap);
- debug("rtable->slots[loop].irq[1].bitmap = %x\n",
+ debug("rtable->slots[loop].irq[1].bitmap = %x\n",
rtable->slots[loop].irq[1].bitmap);
- debug("rtable->slots[loop].irq[2].bitmap = %x\n",
+ debug("rtable->slots[loop].irq[2].bitmap = %x\n",
rtable->slots[loop].irq[2].bitmap);
- debug("rtable->slots[loop].irq[3].bitmap = %x\n",
+ debug("rtable->slots[loop].irq[3].bitmap = %x\n",
rtable->slots[loop].irq[3].bitmap);
- debug("rtable->slots[loop].irq[0].link = %x\n",
+ debug("rtable->slots[loop].irq[0].link = %x\n",
rtable->slots[loop].irq[0].link);
- debug("rtable->slots[loop].irq[1].link = %x\n",
+ debug("rtable->slots[loop].irq[1].link = %x\n",
rtable->slots[loop].irq[1].link);
- debug("rtable->slots[loop].irq[2].link = %x\n",
+ debug("rtable->slots[loop].irq[2].link = %x\n",
rtable->slots[loop].irq[2].link);
- debug("rtable->slots[loop].irq[3].link = %x\n",
+ debug("rtable->slots[loop].irq[3].link = %x\n",
rtable->slots[loop].irq[3].link);
- debug("end of init_devno\n");
- kfree(rtable);
- return 0;
- }
+ debug("end of init_devno\n");
+ kfree(rtable);
+ return 0;
}
}
Index: linux-2.6/arch/x86/pci/irq.c
===================================================================
--- linux-2.6.orig/arch/x86/pci/irq.c
+++ linux-2.6/arch/x86/pci/irq.c
@@ -1051,12 +1051,16 @@ static void __init pcibios_fixup_irqs(vo
*/
if (io_apic_assign_pci_irqs) {
int irq;
+ int ioapic = -1, ioapic_pin = -1;
+ int triggering, polarity;
/*
* interrupt pins are numbered starting from 1
*/
irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
- PCI_SLOT(dev->devfn), pin - 1);
+ PCI_SLOT(dev->devfn), pin - 1,
+ &ioapic, &ioapic_pin,
+ &triggering, &polarity);
/*
* Busses behind bridges are typically not listed in the
* MP-table. In this case we have to look up the IRQ
@@ -1072,7 +1076,10 @@ static void __init pcibios_fixup_irqs(vo
pin = pci_swizzle_interrupt_pin(dev, pin);
bus = bridge->bus->number;
irq = IO_APIC_get_PCI_irq_vector(bus,
- PCI_SLOT(bridge->devfn), pin - 1);
+ PCI_SLOT(bridge->devfn),
+ pin - 1,
+ &ioapic, &ioapic_pin,
+ &triggering, &polarity);
if (irq >= 0)
dev_warn(&dev->dev,
"using bridge %s INT %c to "
@@ -1221,8 +1228,14 @@ static int pirq_enable_irq(struct pci_de
if (io_apic_assign_pci_irqs) {
int irq;
+ int ioapic = -1, ioapic_pin = -1;
+ int triggering, polarity;
- irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin - 1);
+ irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
+ PCI_SLOT(dev->devfn),
+ pin - 1,
+ &ioapic, &ioapic_pin,
+ &triggering, &polarity);
/*
* Busses behind bridges are typically not listed in the MP-table.
* In this case we have to look up the IRQ based on the parent bus,
@@ -1235,7 +1248,10 @@ static int pirq_enable_irq(struct pci_de
pin = pci_swizzle_interrupt_pin(dev, pin);
irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number,
- PCI_SLOT(bridge->devfn), pin - 1);
+ PCI_SLOT(bridge->devfn),
+ pin - 1,
+ &ioapic, &ioapic_pin,
+ &triggering, &polarity);
if (irq >= 0)
dev_warn(&dev->dev, "using bridge %s "
"INT %c to get IRQ %d\n",
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/4] x86/acpi: move setup io apic routing out of ACPI macro scope
2009-04-29 20:04 [PATCH] x86: don't print strange not connect ioapic Yinghai Lu
2009-04-30 8:19 ` [PATCH 1/4] x86/acpi: move pin_programmed bit map to io_apic.c Yinghai Lu
2009-04-30 8:21 ` [PATCH 2/4] x86/pci: add 4 more return param in IO_APIC_get_PCI_irq_vector Yinghai Lu
@ 2009-04-30 8:22 ` Yinghai Lu
2009-04-30 8:23 ` [PATCH 4/4] x86/pci: update pirq_enable_irq to setup io apic routing Yinghai Lu
3 siblings, 0 replies; 8+ messages in thread
From: Yinghai Lu @ 2009-04-30 8:22 UTC (permalink / raw)
To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Len Brown
Cc: linux-kernel, ACPI Devel Maling List
so we could set io apic routing when ACPI is not set
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
arch/x86/include/asm/io_apic.h | 4 -
arch/x86/kernel/apic/io_apic.c | 122 ++++++++++++++++++++---------------------
2 files changed, 63 insertions(+), 63 deletions(-)
Index: linux-2.6/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6/arch/x86/kernel/apic/io_apic.c
@@ -3855,6 +3855,67 @@ int __init arch_probe_nr_irqs(void)
}
#endif
+static int __io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, int irq,
+ int triggering, int polarity)
+{
+ struct irq_desc *desc;
+ struct irq_cfg *cfg;
+ int node;
+
+ if (!IO_APIC_IRQ(irq)) {
+ apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n",
+ ioapic);
+ return -EINVAL;
+ }
+
+ if (dev)
+ node = dev_to_node(dev);
+ else
+ node = cpu_to_node(boot_cpu_id);
+
+ desc = irq_to_desc_alloc_node(irq, node);
+ if (!desc) {
+ printk(KERN_INFO "can not get irq_desc %d\n", irq);
+ return 0;
+ }
+
+ /*
+ * IRQs < 16 are already in the irq_2_pin[] map
+ */
+ if (irq >= NR_IRQS_LEGACY) {
+ cfg = desc->chip_data;
+ add_pin_to_irq_node(cfg, node, ioapic, pin);
+ }
+
+ setup_IO_APIC_irq(ioapic, pin, irq, desc, triggering, polarity);
+
+ return 0;
+}
+
+static struct {
+ DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
+} mp_ioapic_routing[MAX_IO_APICS];
+
+int io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, int irq,
+ int triggering, int polarity)
+{
+
+ /*
+ * Avoid pin reprogramming. PRTs typically include entries
+ * with redundant pin->gsi mappings (but unique PCI devices);
+ * we only program the IOAPIC on the first.
+ */
+ if (test_bit(pin, mp_ioapic_routing[ioapic].pin_programmed)) {
+ pr_debug("Pin %d-%d already programmed\n",
+ mp_ioapics[ioapic].apicid, pin);
+ return 0;
+ }
+ set_bit(pin, mp_ioapic_routing[ioapic].pin_programmed);
+
+ return __io_apic_set_pci_routing(dev, ioapic, pin, irq,
+ triggering, polarity);
+}
+
/* --------------------------------------------------------------------------
ACPI-based IOAPIC Configuration
-------------------------------------------------------------------------- */
@@ -3949,67 +4010,6 @@ int __init io_apic_get_version(int ioapi
}
#endif
-static int __io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, int irq,
- int triggering, int polarity)
-{
- struct irq_desc *desc;
- struct irq_cfg *cfg;
- int node;
-
- if (!IO_APIC_IRQ(irq)) {
- apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n",
- ioapic);
- return -EINVAL;
- }
-
- if (dev)
- node = dev_to_node(dev);
- else
- node = cpu_to_node(boot_cpu_id);
-
- desc = irq_to_desc_alloc_node(irq, node);
- if (!desc) {
- printk(KERN_INFO "can not get irq_desc %d\n", irq);
- return 0;
- }
-
- /*
- * IRQs < 16 are already in the irq_2_pin[] map
- */
- if (irq >= NR_IRQS_LEGACY) {
- cfg = desc->chip_data;
- add_pin_to_irq_node(cfg, node, ioapic, pin);
- }
-
- setup_IO_APIC_irq(ioapic, pin, irq, desc, triggering, polarity);
-
- return 0;
-}
-
-static struct {
- DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
-} mp_ioapic_routing[MAX_IO_APICS];
-
-int io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, int irq,
- int triggering, int polarity)
-{
-
- /*
- * Avoid pin reprogramming. PRTs typically include entries
- * with redundant pin->gsi mappings (but unique PCI devices);
- * we only program the IOAPIC on the first.
- */
- if (test_bit(pin, mp_ioapic_routing[ioapic].pin_programmed)) {
- pr_debug("Pin %d-%d already programmed\n",
- mp_ioapics[ioapic].apicid, pin);
- return 0;
- }
- set_bit(pin, mp_ioapic_routing[ioapic].pin_programmed);
-
- return __io_apic_set_pci_routing(dev, ioapic, pin, irq,
- triggering, polarity);
-}
-
int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
{
int i;
Index: linux-2.6/arch/x86/include/asm/io_apic.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/io_apic.h
+++ linux-2.6/arch/x86/include/asm/io_apic.h
@@ -154,10 +154,10 @@ extern int timer_through_8259;
extern int io_apic_get_unique_id(int ioapic, int apic_id);
extern int io_apic_get_version(int ioapic);
extern int io_apic_get_redir_entries(int ioapic);
-extern int io_apic_set_pci_routing(struct device *dev, int ioapic, int pin,
- int irq, int edge_level, int active_high_low);
#endif /* CONFIG_ACPI */
+extern int io_apic_set_pci_routing(struct device *dev, int ioapic, int pin,
+ int irq, int edge_level, int active_high_low);
extern int (*ioapic_renumber_irq)(int ioapic, int irq);
extern void ioapic_init_mappings(void);
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 4/4] x86/pci: update pirq_enable_irq to setup io apic routing
2009-04-29 20:04 [PATCH] x86: don't print strange not connect ioapic Yinghai Lu
` (2 preceding siblings ...)
2009-04-30 8:22 ` [PATCH 3/4] x86/acpi: move setup io apic routing out of ACPI macro scope Yinghai Lu
@ 2009-04-30 8:23 ` Yinghai Lu
2009-05-02 17:44 ` [PATCH 4/4] x86/pci: update pirq_enable_irq to setup io apic routing -v2 Yinghai Lu
3 siblings, 1 reply; 8+ messages in thread
From: Yinghai Lu @ 2009-04-30 8:23 UTC (permalink / raw)
To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Jesse Barnes
Cc: linux-kernel, linux-pci
so we could set io apic routing only when enable device irq.
also could make setup_IO_APIC_irqs and setup_ioapic_dest only handle
first ioapic...
[ make mptable irq enable more like acpi is used ]
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
arch/x86/kernel/apic/io_apic.c | 157 ++++++++++++++++++-----------------------
arch/x86/pci/irq.c | 92 ++++++++----------------
2 files changed, 103 insertions(+), 146 deletions(-)
Index: linux-2.6/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6/arch/x86/kernel/apic/io_apic.c
@@ -1481,75 +1481,67 @@ static void setup_IO_APIC_irq(int apic_i
ioapic_write_entry(apic_id, pin, entry);
}
+static struct {
+ DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
+} mp_ioapic_routing[MAX_IO_APICS];
+
static void __init setup_IO_APIC_irqs(void)
{
- int apic_id, pin, idx, irq;
+ int apic_id = 0, pin, idx, irq;
int notcon = 0;
struct irq_desc *desc;
struct irq_cfg *cfg;
int node = cpu_to_node(boot_cpu_id);
- int ioapic_start = 0, ioapic_end = nr_ioapics;
apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
#ifdef CONFIG_ACPI
- /*
- * when acpi is used, at this point, we only have legacy entries
- * in mp_irqs[] by mp_config_acpi_legacy_irqs/mp_override_legacy_irq
- * so only setup for that ioapic, and will not print out those strange
- * not connected on other ioapic
- */
if (!acpi_disabled && acpi_ioapic) {
- ioapic_start = mp_find_ioapic(0);
- if (ioapic_start < 0)
- ioapic_start = 0;
- else
- ioapic_end = ioapic_start + 1;
+ apic_id = mp_find_ioapic(0);
+ if (apic_id < 0)
+ apic_id = 0;
}
#endif
- for (apic_id = ioapic_start; apic_id < ioapic_end; apic_id++) {
- for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) {
-
- idx = find_irq_entry(apic_id, pin, mp_INT);
- if (idx == -1) {
- if (!notcon) {
- notcon = 1;
- apic_printk(APIC_VERBOSE,
- KERN_DEBUG " %d-%d",
- mp_ioapics[apic_id].apicid, pin);
- } else
- apic_printk(APIC_VERBOSE, " %d-%d",
- mp_ioapics[apic_id].apicid, pin);
- continue;
- }
- if (notcon) {
+ for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) {
+ idx = find_irq_entry(apic_id, pin, mp_INT);
+ if (idx == -1) {
+ if (!notcon) {
+ notcon = 1;
apic_printk(APIC_VERBOSE,
- " (apicid-pin) not connected\n");
- notcon = 0;
- }
+ KERN_DEBUG " %d-%d",
+ mp_ioapics[apic_id].apicid, pin);
+ } else
+ apic_printk(APIC_VERBOSE, " %d-%d",
+ mp_ioapics[apic_id].apicid, pin);
+ continue;
+ }
+ if (notcon) {
+ apic_printk(APIC_VERBOSE,
+ " (apicid-pin) not connected\n");
+ notcon = 0;
+ }
- irq = pin_2_irq(idx, apic_id, pin);
+ irq = pin_2_irq(idx, apic_id, pin);
- /*
- * Skip the timer IRQ if there's a quirk handler
- * installed and if it returns 1:
- */
- if (apic->multi_timer_check &&
- apic->multi_timer_check(apic_id, irq))
- continue;
-
- desc = irq_to_desc_alloc_node(irq, node);
- if (!desc) {
- printk(KERN_INFO "can not get irq_desc for %d\n", irq);
- continue;
- }
- cfg = desc->chip_data;
- add_pin_to_irq_node(cfg, node, apic_id, pin);
+ /*
+ * Skip the timer IRQ if there's a quirk handler
+ * installed and if it returns 1:
+ */
+ if (apic->multi_timer_check &&
+ apic->multi_timer_check(apic_id, irq))
+ continue;
- setup_IO_APIC_irq(apic_id, pin, irq, desc,
- irq_trigger(idx), irq_polarity(idx));
+ desc = irq_to_desc_alloc_node(irq, node);
+ if (!desc) {
+ printk(KERN_INFO "can not get irq_desc for %d\n", irq);
+ continue;
}
+ cfg = desc->chip_data;
+ add_pin_to_irq_node(cfg, node, apic_id, pin);
+ set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed);
+ setup_IO_APIC_irq(apic_id, pin, irq, desc,
+ irq_trigger(idx), irq_polarity(idx));
}
if (notcon)
@@ -3892,10 +3884,6 @@ static int __io_apic_set_pci_routing(str
return 0;
}
-static struct {
- DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
-} mp_ioapic_routing[MAX_IO_APICS];
-
int io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, int irq,
int triggering, int polarity)
{
@@ -4039,51 +4027,44 @@ int acpi_get_override_irq(int bus_irq, i
#ifdef CONFIG_SMP
void __init setup_ioapic_dest(void)
{
- int pin, ioapic, irq, irq_entry;
+ int pin, ioapic = 0, irq, irq_entry;
struct irq_desc *desc;
- struct irq_cfg *cfg;
const struct cpumask *mask;
if (skip_ioapic_setup == 1)
return;
- for (ioapic = 0; ioapic < nr_ioapics; ioapic++) {
- for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
- irq_entry = find_irq_entry(ioapic, pin, mp_INT);
- if (irq_entry == -1)
- continue;
- irq = pin_2_irq(irq_entry, ioapic, pin);
-
- /* setup_IO_APIC_irqs could fail to get vector for some device
- * when you have too many devices, because at that time only boot
- * cpu is online.
- */
- desc = irq_to_desc(irq);
- cfg = desc->chip_data;
- if (!cfg->vector) {
- setup_IO_APIC_irq(ioapic, pin, irq, desc,
- irq_trigger(irq_entry),
- irq_polarity(irq_entry));
- continue;
+#ifdef CONFIG_ACPI
+ if (!acpi_disabled && acpi_ioapic) {
+ ioapic = mp_find_ioapic(0);
+ if (ioapic < 0)
+ ioapic = 0;
+ }
+#endif
- }
+ for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
+ irq_entry = find_irq_entry(ioapic, pin, mp_INT);
+ if (irq_entry == -1)
+ continue;
+ irq = pin_2_irq(irq_entry, ioapic, pin);
- /*
- * Honour affinities which have been set in early boot
- */
- if (desc->status &
- (IRQ_NO_BALANCING | IRQ_AFFINITY_SET))
- mask = desc->affinity;
- else
- mask = apic->target_cpus();
+ desc = irq_to_desc(irq);
- if (intr_remapping_enabled)
- set_ir_ioapic_affinity_irq_desc(desc, mask);
- else
- set_ioapic_affinity_irq_desc(desc, mask);
- }
+ /*
+ * Honour affinities which have been set in early boot
+ */
+ if (desc->status &
+ (IRQ_NO_BALANCING | IRQ_AFFINITY_SET))
+ mask = desc->affinity;
+ else
+ mask = apic->target_cpus();
+ if (intr_remapping_enabled)
+ set_ir_ioapic_affinity_irq_desc(desc, mask);
+ else
+ set_ioapic_affinity_irq_desc(desc, mask);
}
+
}
#endif
Index: linux-2.6/arch/x86/pci/irq.c
===================================================================
--- linux-2.6.orig/arch/x86/pci/irq.c
+++ linux-2.6/arch/x86/pci/irq.c
@@ -889,6 +889,9 @@ static int pcibios_lookup_irq(struct pci
return 0;
}
+ if (io_apic_assign_pci_irqs)
+ return 0;
+
/* Find IRQ routing entry */
if (!pirq_table)
@@ -1039,63 +1042,15 @@ static void __init pcibios_fixup_irqs(vo
pirq_penalty[dev->irq]++;
}
+ if (io_apic_assign_pci_irqs)
+ return;
+
dev = NULL;
while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
if (!pin)
continue;
-#ifdef CONFIG_X86_IO_APIC
- /*
- * Recalculate IRQ numbers if we use the I/O APIC.
- */
- if (io_apic_assign_pci_irqs) {
- int irq;
- int ioapic = -1, ioapic_pin = -1;
- int triggering, polarity;
-
- /*
- * interrupt pins are numbered starting from 1
- */
- irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
- PCI_SLOT(dev->devfn), pin - 1,
- &ioapic, &ioapic_pin,
- &triggering, &polarity);
- /*
- * Busses behind bridges are typically not listed in the
- * MP-table. In this case we have to look up the IRQ
- * based on the parent bus, parent slot, and pin number.
- * The SMP code detects such bridged busses itself so we
- * should get into this branch reliably.
- */
- if (irq < 0 && dev->bus->parent) {
- /* go back to the bridge */
- struct pci_dev *bridge = dev->bus->self;
- int bus;
-
- pin = pci_swizzle_interrupt_pin(dev, pin);
- bus = bridge->bus->number;
- irq = IO_APIC_get_PCI_irq_vector(bus,
- PCI_SLOT(bridge->devfn),
- pin - 1,
- &ioapic, &ioapic_pin,
- &triggering, &polarity);
- if (irq >= 0)
- dev_warn(&dev->dev,
- "using bridge %s INT %c to "
- "get IRQ %d\n",
- pci_name(bridge),
- 'A' + pin - 1, irq);
- }
- if (irq >= 0) {
- dev_info(&dev->dev,
- "PCI->APIC IRQ transform: INT %c "
- "-> IRQ %d\n",
- 'A' + pin - 1, irq);
- dev->irq = irq;
- }
- }
-#endif
/*
* Still no IRQ? Try to lookup one...
*/
@@ -1190,6 +1145,19 @@ int __init pcibios_irq_init(void)
pcibios_enable_irq = pirq_enable_irq;
pcibios_fixup_irqs();
+
+ if (io_apic_assign_pci_irqs && pci_routeirq) {
+ struct pci_dev *dev = NULL;
+ /*
+ * PCI IRQ routing is set up by pci_enable_device(), but we
+ * also do it here in case there are still broken drivers that
+ * don't use pci_enable_device().
+ */
+ printk(KERN_INFO "PCI: Routing PCI interrupts for all devices because \"pci=routeirq\" specified\n");
+ for_each_pci_dev(dev)
+ pirq_enable_irq(dev);
+ }
+
return 0;
}
@@ -1220,22 +1188,25 @@ void pcibios_penalize_isa_irq(int irq, i
static int pirq_enable_irq(struct pci_dev *dev)
{
u8 pin;
- struct pci_dev *temp_dev;
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
- if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) {
+ if (pin && !pcibios_lookup_irq(dev, 1)) {
char *msg = "";
+ if (!io_apic_assign_pci_irqs && dev->irq)
+ return 0;
+
if (io_apic_assign_pci_irqs) {
+#ifdef CONFIG_X86_IO_APIC
+ struct pci_dev *temp_dev;
int irq;
int ioapic = -1, ioapic_pin = -1;
int triggering, polarity;
irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
- PCI_SLOT(dev->devfn),
- pin - 1,
- &ioapic, &ioapic_pin,
- &triggering, &polarity);
+ PCI_SLOT(dev->devfn), pin - 1,
+ &ioapic, &ioapic_pin,
+ &triggering, &polarity);
/*
* Busses behind bridges are typically not listed in the MP-table.
* In this case we have to look up the IRQ based on the parent bus,
@@ -1261,12 +1232,17 @@ static int pirq_enable_irq(struct pci_de
}
dev = temp_dev;
if (irq >= 0) {
+ dev->irq = irq;
+ io_apic_set_pci_routing(&dev->dev, ioapic,
+ ioapic_pin, irq,
+ triggering, polarity);
+
dev_info(&dev->dev, "PCI->APIC IRQ transform: "
"INT %c -> IRQ %d\n", 'A' + pin - 1, irq);
- dev->irq = irq;
return 0;
} else
msg = "; probably buggy MP table";
+#endif
} else if (pci_probe & PCI_BIOS_IRQ_SCAN)
msg = "";
else
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 4/4] x86/pci: update pirq_enable_irq to setup io apic routing -v2
2009-04-30 8:23 ` [PATCH 4/4] x86/pci: update pirq_enable_irq to setup io apic routing Yinghai Lu
@ 2009-05-02 17:44 ` Yinghai Lu
2009-05-06 12:45 ` Ingo Molnar
0 siblings, 1 reply; 8+ messages in thread
From: Yinghai Lu @ 2009-05-02 17:44 UTC (permalink / raw)
To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Jesse Barnes
Cc: linux-kernel, linux-pci
so we could set io apic routing only when enable device irq.
also could make setup_IO_APIC_irqs and setup_ioapic_dest only handle
first ioapic...
v2: remove one one not needed style change.
merge the patch only setup io_apic for acpi on in setup_IO_APIC_irqs
[ Impact: make mptable irq enable more like acpi is used, and numa_irq_desc could get correct node when acpi=off ]
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
arch/x86/kernel/apic/io_apic.c | 148 ++++++++++++++++++++---------------------
arch/x86/pci/irq.c | 84 ++++++++---------------
2 files changed, 103 insertions(+), 129 deletions(-)
Index: linux-2.6/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6/arch/x86/kernel/apic/io_apic.c
@@ -1481,9 +1481,13 @@ static void setup_IO_APIC_irq(int apic_i
ioapic_write_entry(apic_id, pin, entry);
}
+static struct {
+ DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
+} mp_ioapic_routing[MAX_IO_APICS];
+
static void __init setup_IO_APIC_irqs(void)
{
- int apic_id, pin, idx, irq;
+ int apic_id = 0, pin, idx, irq;
int notcon = 0;
struct irq_desc *desc;
struct irq_cfg *cfg;
@@ -1491,48 +1495,53 @@ static void __init setup_IO_APIC_irqs(vo
apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
- for (apic_id = 0; apic_id < nr_ioapics; apic_id++) {
- for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) {
+#ifdef CONFIG_ACPI
+ if (!acpi_disabled && acpi_ioapic) {
+ apic_id = mp_find_ioapic(0);
+ if (apic_id < 0)
+ apic_id = 0;
+ }
+#endif
- idx = find_irq_entry(apic_id, pin, mp_INT);
- if (idx == -1) {
- if (!notcon) {
- notcon = 1;
- apic_printk(APIC_VERBOSE,
- KERN_DEBUG " %d-%d",
- mp_ioapics[apic_id].apicid, pin);
- } else
- apic_printk(APIC_VERBOSE, " %d-%d",
- mp_ioapics[apic_id].apicid, pin);
- continue;
- }
- if (notcon) {
+ for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) {
+ idx = find_irq_entry(apic_id, pin, mp_INT);
+ if (idx == -1) {
+ if (!notcon) {
+ notcon = 1;
apic_printk(APIC_VERBOSE,
- " (apicid-pin) not connected\n");
- notcon = 0;
- }
+ KERN_DEBUG " %d-%d",
+ mp_ioapics[apic_id].apicid, pin);
+ } else
+ apic_printk(APIC_VERBOSE, " %d-%d",
+ mp_ioapics[apic_id].apicid, pin);
+ continue;
+ }
+ if (notcon) {
+ apic_printk(APIC_VERBOSE,
+ " (apicid-pin) not connected\n");
+ notcon = 0;
+ }
- irq = pin_2_irq(idx, apic_id, pin);
+ irq = pin_2_irq(idx, apic_id, pin);
- /*
- * Skip the timer IRQ if there's a quirk handler
- * installed and if it returns 1:
- */
- if (apic->multi_timer_check &&
- apic->multi_timer_check(apic_id, irq))
- continue;
-
- desc = irq_to_desc_alloc_node(irq, node);
- if (!desc) {
- printk(KERN_INFO "can not get irq_desc for %d\n", irq);
- continue;
- }
- cfg = desc->chip_data;
- add_pin_to_irq_node(cfg, node, apic_id, pin);
+ /*
+ * Skip the timer IRQ if there's a quirk handler
+ * installed and if it returns 1:
+ */
+ if (apic->multi_timer_check &&
+ apic->multi_timer_check(apic_id, irq))
+ continue;
- setup_IO_APIC_irq(apic_id, pin, irq, desc,
- irq_trigger(idx), irq_polarity(idx));
+ desc = irq_to_desc_alloc_node(irq, node);
+ if (!desc) {
+ printk(KERN_INFO "can not get irq_desc for %d\n", irq);
+ continue;
}
+ cfg = desc->chip_data;
+ add_pin_to_irq_node(cfg, node, apic_id, pin);
+ set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed);
+ setup_IO_APIC_irq(apic_id, pin, irq, desc,
+ irq_trigger(idx), irq_polarity(idx));
}
if (notcon)
@@ -3877,10 +3886,6 @@ static int __io_apic_set_pci_routing(str
return 0;
}
-static struct {
- DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
-} mp_ioapic_routing[MAX_IO_APICS];
-
int io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, int irq,
int triggering, int polarity)
{
@@ -4024,51 +4029,44 @@ int acpi_get_override_irq(int bus_irq, i
#ifdef CONFIG_SMP
void __init setup_ioapic_dest(void)
{
- int pin, ioapic, irq, irq_entry;
+ int pin, ioapic = 0, irq, irq_entry;
struct irq_desc *desc;
- struct irq_cfg *cfg;
const struct cpumask *mask;
if (skip_ioapic_setup == 1)
return;
- for (ioapic = 0; ioapic < nr_ioapics; ioapic++) {
- for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
- irq_entry = find_irq_entry(ioapic, pin, mp_INT);
- if (irq_entry == -1)
- continue;
- irq = pin_2_irq(irq_entry, ioapic, pin);
-
- /* setup_IO_APIC_irqs could fail to get vector for some device
- * when you have too many devices, because at that time only boot
- * cpu is online.
- */
- desc = irq_to_desc(irq);
- cfg = desc->chip_data;
- if (!cfg->vector) {
- setup_IO_APIC_irq(ioapic, pin, irq, desc,
- irq_trigger(irq_entry),
- irq_polarity(irq_entry));
- continue;
+#ifdef CONFIG_ACPI
+ if (!acpi_disabled && acpi_ioapic) {
+ ioapic = mp_find_ioapic(0);
+ if (ioapic < 0)
+ ioapic = 0;
+ }
+#endif
- }
+ for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
+ irq_entry = find_irq_entry(ioapic, pin, mp_INT);
+ if (irq_entry == -1)
+ continue;
+ irq = pin_2_irq(irq_entry, ioapic, pin);
- /*
- * Honour affinities which have been set in early boot
- */
- if (desc->status &
- (IRQ_NO_BALANCING | IRQ_AFFINITY_SET))
- mask = desc->affinity;
- else
- mask = apic->target_cpus();
+ desc = irq_to_desc(irq);
- if (intr_remapping_enabled)
- set_ir_ioapic_affinity_irq_desc(desc, mask);
- else
- set_ioapic_affinity_irq_desc(desc, mask);
- }
+ /*
+ * Honour affinities which have been set in early boot
+ */
+ if (desc->status &
+ (IRQ_NO_BALANCING | IRQ_AFFINITY_SET))
+ mask = desc->affinity;
+ else
+ mask = apic->target_cpus();
+ if (intr_remapping_enabled)
+ set_ir_ioapic_affinity_irq_desc(desc, mask);
+ else
+ set_ioapic_affinity_irq_desc(desc, mask);
}
+
}
#endif
Index: linux-2.6/arch/x86/pci/irq.c
===================================================================
--- linux-2.6.orig/arch/x86/pci/irq.c
+++ linux-2.6/arch/x86/pci/irq.c
@@ -889,6 +889,9 @@ static int pcibios_lookup_irq(struct pci
return 0;
}
+ if (io_apic_assign_pci_irqs)
+ return 0;
+
/* Find IRQ routing entry */
if (!pirq_table)
@@ -1039,63 +1042,15 @@ static void __init pcibios_fixup_irqs(vo
pirq_penalty[dev->irq]++;
}
+ if (io_apic_assign_pci_irqs)
+ return;
+
dev = NULL;
while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
if (!pin)
continue;
-#ifdef CONFIG_X86_IO_APIC
- /*
- * Recalculate IRQ numbers if we use the I/O APIC.
- */
- if (io_apic_assign_pci_irqs) {
- int irq;
- int ioapic = -1, ioapic_pin = -1;
- int triggering, polarity;
-
- /*
- * interrupt pins are numbered starting from 1
- */
- irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
- PCI_SLOT(dev->devfn), pin - 1,
- &ioapic, &ioapic_pin,
- &triggering, &polarity);
- /*
- * Busses behind bridges are typically not listed in the
- * MP-table. In this case we have to look up the IRQ
- * based on the parent bus, parent slot, and pin number.
- * The SMP code detects such bridged busses itself so we
- * should get into this branch reliably.
- */
- if (irq < 0 && dev->bus->parent) {
- /* go back to the bridge */
- struct pci_dev *bridge = dev->bus->self;
- int bus;
-
- pin = pci_swizzle_interrupt_pin(dev, pin);
- bus = bridge->bus->number;
- irq = IO_APIC_get_PCI_irq_vector(bus,
- PCI_SLOT(bridge->devfn),
- pin - 1,
- &ioapic, &ioapic_pin,
- &triggering, &polarity);
- if (irq >= 0)
- dev_warn(&dev->dev,
- "using bridge %s INT %c to "
- "get IRQ %d\n",
- pci_name(bridge),
- 'A' + pin - 1, irq);
- }
- if (irq >= 0) {
- dev_info(&dev->dev,
- "PCI->APIC IRQ transform: INT %c "
- "-> IRQ %d\n",
- 'A' + pin - 1, irq);
- dev->irq = irq;
- }
- }
-#endif
/*
* Still no IRQ? Try to lookup one...
*/
@@ -1190,6 +1145,19 @@ int __init pcibios_irq_init(void)
pcibios_enable_irq = pirq_enable_irq;
pcibios_fixup_irqs();
+
+ if (io_apic_assign_pci_irqs && pci_routeirq) {
+ struct pci_dev *dev = NULL;
+ /*
+ * PCI IRQ routing is set up by pci_enable_device(), but we
+ * also do it here in case there are still broken drivers that
+ * don't use pci_enable_device().
+ */
+ printk(KERN_INFO "PCI: Routing PCI interrupts for all devices because \"pci=routeirq\" specified\n");
+ for_each_pci_dev(dev)
+ pirq_enable_irq(dev);
+ }
+
return 0;
}
@@ -1220,13 +1188,17 @@ void pcibios_penalize_isa_irq(int irq, i
static int pirq_enable_irq(struct pci_dev *dev)
{
u8 pin;
- struct pci_dev *temp_dev;
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
- if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) {
+ if (pin && !pcibios_lookup_irq(dev, 1)) {
char *msg = "";
+ if (!io_apic_assign_pci_irqs && dev->irq)
+ return 0;
+
if (io_apic_assign_pci_irqs) {
+#ifdef CONFIG_X86_IO_APIC
+ struct pci_dev *temp_dev;
int irq;
int ioapic = -1, ioapic_pin = -1;
int triggering, polarity;
@@ -1261,12 +1233,16 @@ static int pirq_enable_irq(struct pci_de
}
dev = temp_dev;
if (irq >= 0) {
+ io_apic_set_pci_routing(&dev->dev, ioapic,
+ ioapic_pin, irq,
+ triggering, polarity);
+ dev->irq = irq;
dev_info(&dev->dev, "PCI->APIC IRQ transform: "
"INT %c -> IRQ %d\n", 'A' + pin - 1, irq);
- dev->irq = irq;
return 0;
} else
msg = "; probably buggy MP table";
+#endif
} else if (pci_probe & PCI_BIOS_IRQ_SCAN)
msg = "";
else
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 4/4] x86/pci: update pirq_enable_irq to setup io apic routing -v2
2009-05-02 17:44 ` [PATCH 4/4] x86/pci: update pirq_enable_irq to setup io apic routing -v2 Yinghai Lu
@ 2009-05-06 12:45 ` Ingo Molnar
2009-05-06 15:48 ` Jesse Barnes
0 siblings, 1 reply; 8+ messages in thread
From: Ingo Molnar @ 2009-05-06 12:45 UTC (permalink / raw)
To: Yinghai Lu, Jesse Barnes
Cc: Thomas Gleixner, H. Peter Anvin, linux-kernel, linux-pci
* Yinghai Lu <yinghai@kernel.org> wrote:
> so we could set io apic routing only when enable device irq.
>
> also could make setup_IO_APIC_irqs and setup_ioapic_dest only handle
> first ioapic...
>
> v2: remove one one not needed style change.
> merge the patch only setup io_apic for acpi on in setup_IO_APIC_irqs
>
> [ Impact: make mptable irq enable more like acpi is used, and numa_irq_desc could get correct node when acpi=off ]
>
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
>
> ---
> arch/x86/kernel/apic/io_apic.c | 148 ++++++++++++++++++++---------------------
> arch/x86/pci/irq.c | 84 ++++++++---------------
> 2 files changed, 103 insertions(+), 129 deletions(-)
Ok, i guess this makes sense with acpi-less bootup modes.
There's hefty impact on io_apic.c and pci/irq.c as well. The io-apic
code already has a fair amount of changes queued up. Jesse: do you
have pci/irq.c changes queued up? If you agree with the patch, how
should we handle this?
A few mostly cosmetic comments:
> +#ifdef CONFIG_ACPI
> + if (!acpi_disabled && acpi_ioapic) {
> + apic_id = mp_find_ioapic(0);
> + if (apic_id < 0)
> + apic_id = 0;
> + }
> +#endif
that should go into a helper. I suspect.
>
> - idx = find_irq_entry(apic_id, pin, mp_INT);
> - if (idx == -1) {
> - if (!notcon) {
> - notcon = 1;
> - apic_printk(APIC_VERBOSE,
> - KERN_DEBUG " %d-%d",
> - mp_ioapics[apic_id].apicid, pin);
> - } else
> - apic_printk(APIC_VERBOSE, " %d-%d",
> - mp_ioapics[apic_id].apicid, pin);
> - continue;
> - }
> - if (notcon) {
> + for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) {
> + idx = find_irq_entry(apic_id, pin, mp_INT);
> + if (idx == -1) {
> + if (!notcon) {
> + notcon = 1;
> apic_printk(APIC_VERBOSE,
> - " (apicid-pin) not connected\n");
> - notcon = 0;
> - }
> + KERN_DEBUG " %d-%d",
> + mp_ioapics[apic_id].apicid, pin);
> + } else
> + apic_printk(APIC_VERBOSE, " %d-%d",
> + mp_ioapics[apic_id].apicid, pin);
> + continue;
> + }
> + if (notcon) {
> + apic_printk(APIC_VERBOSE,
> + " (apicid-pin) not connected\n");
> + notcon = 0;
> + }
>
> - irq = pin_2_irq(idx, apic_id, pin);
> + irq = pin_2_irq(idx, apic_id, pin);
>
> - /*
> - * Skip the timer IRQ if there's a quirk handler
> - * installed and if it returns 1:
> - */
> - if (apic->multi_timer_check &&
> - apic->multi_timer_check(apic_id, irq))
> - continue;
> -
> - desc = irq_to_desc_alloc_node(irq, node);
> - if (!desc) {
> - printk(KERN_INFO "can not get irq_desc for %d\n", irq);
> - continue;
> - }
> - cfg = desc->chip_data;
> - add_pin_to_irq_node(cfg, node, apic_id, pin);
> + /*
> + * Skip the timer IRQ if there's a quirk handler
> + * installed and if it returns 1:
> + */
> + if (apic->multi_timer_check &&
> + apic->multi_timer_check(apic_id, irq))
> + continue;
>
> - setup_IO_APIC_irq(apic_id, pin, irq, desc,
> - irq_trigger(idx), irq_polarity(idx));
> + desc = irq_to_desc_alloc_node(irq, node);
> + if (!desc) {
> + printk(KERN_INFO "can not get irq_desc for %d\n", irq);
> + continue;
> }
> + cfg = desc->chip_data;
> + add_pin_to_irq_node(cfg, node, apic_id, pin);
> + set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed);
> + setup_IO_APIC_irq(apic_id, pin, irq, desc,
> + irq_trigger(idx), irq_polarity(idx));
> }
this loop has become quite large now - could its body be moved into
a helper inline function?
> +#ifdef CONFIG_ACPI
> + if (!acpi_disabled && acpi_ioapic) {
> + ioapic = mp_find_ioapic(0);
> + if (ioapic < 0)
> + ioapic = 0;
> + }
> +#endif
Needs a helper too?
> Index: linux-2.6/arch/x86/pci/irq.c
> ===================================================================
> --- linux-2.6.orig/arch/x86/pci/irq.c
> +++ linux-2.6/arch/x86/pci/irq.c
> @@ -889,6 +889,9 @@ static int pcibios_lookup_irq(struct pci
> return 0;
> }
>
> + if (io_apic_assign_pci_irqs)
> + return 0;
> +
> /* Find IRQ routing entry */
>
> if (!pirq_table)
> @@ -1039,63 +1042,15 @@ static void __init pcibios_fixup_irqs(vo
> pirq_penalty[dev->irq]++;
> }
>
> + if (io_apic_assign_pci_irqs)
> + return;
> +
> dev = NULL;
> while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
> pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
> if (!pin)
> continue;
>
> -#ifdef CONFIG_X86_IO_APIC
> - /*
> - * Recalculate IRQ numbers if we use the I/O APIC.
> - */
> - if (io_apic_assign_pci_irqs) {
> - int irq;
> - int ioapic = -1, ioapic_pin = -1;
> - int triggering, polarity;
> -
> - /*
> - * interrupt pins are numbered starting from 1
> - */
> - irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
> - PCI_SLOT(dev->devfn), pin - 1,
> - &ioapic, &ioapic_pin,
> - &triggering, &polarity);
> - /*
> - * Busses behind bridges are typically not listed in the
> - * MP-table. In this case we have to look up the IRQ
> - * based on the parent bus, parent slot, and pin number.
> - * The SMP code detects such bridged busses itself so we
> - * should get into this branch reliably.
> - */
> - if (irq < 0 && dev->bus->parent) {
> - /* go back to the bridge */
> - struct pci_dev *bridge = dev->bus->self;
> - int bus;
> -
> - pin = pci_swizzle_interrupt_pin(dev, pin);
> - bus = bridge->bus->number;
> - irq = IO_APIC_get_PCI_irq_vector(bus,
> - PCI_SLOT(bridge->devfn),
> - pin - 1,
> - &ioapic, &ioapic_pin,
> - &triggering, &polarity);
> - if (irq >= 0)
> - dev_warn(&dev->dev,
> - "using bridge %s INT %c to "
> - "get IRQ %d\n",
> - pci_name(bridge),
> - 'A' + pin - 1, irq);
> - }
> - if (irq >= 0) {
> - dev_info(&dev->dev,
> - "PCI->APIC IRQ transform: INT %c "
> - "-> IRQ %d\n",
> - 'A' + pin - 1, irq);
> - dev->irq = irq;
> - }
> - }
> -#endif
nice!
> /*
> * Still no IRQ? Try to lookup one...
> */
> @@ -1190,6 +1145,19 @@ int __init pcibios_irq_init(void)
> pcibios_enable_irq = pirq_enable_irq;
>
> pcibios_fixup_irqs();
> +
> + if (io_apic_assign_pci_irqs && pci_routeirq) {
> + struct pci_dev *dev = NULL;
> + /*
> + * PCI IRQ routing is set up by pci_enable_device(), but we
> + * also do it here in case there are still broken drivers that
> + * don't use pci_enable_device().
> + */
> + printk(KERN_INFO "PCI: Routing PCI interrupts for all devices because \"pci=routeirq\" specified\n");
> + for_each_pci_dev(dev)
> + pirq_enable_irq(dev);
> + }
> +
> return 0;
> }
>
> @@ -1220,13 +1188,17 @@ void pcibios_penalize_isa_irq(int irq, i
> static int pirq_enable_irq(struct pci_dev *dev)
> {
> u8 pin;
> - struct pci_dev *temp_dev;
>
> pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
> - if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) {
> + if (pin && !pcibios_lookup_irq(dev, 1)) {
> char *msg = "";
>
> + if (!io_apic_assign_pci_irqs && dev->irq)
> + return 0;
> +
> if (io_apic_assign_pci_irqs) {
> +#ifdef CONFIG_X86_IO_APIC
> + struct pci_dev *temp_dev;
> int irq;
> int ioapic = -1, ioapic_pin = -1;
> int triggering, polarity;
> @@ -1261,12 +1233,16 @@ static int pirq_enable_irq(struct pci_de
> }
> dev = temp_dev;
> if (irq >= 0) {
> + io_apic_set_pci_routing(&dev->dev, ioapic,
> + ioapic_pin, irq,
> + triggering, polarity);
> + dev->irq = irq;
> dev_info(&dev->dev, "PCI->APIC IRQ transform: "
> "INT %c -> IRQ %d\n", 'A' + pin - 1, irq);
> - dev->irq = irq;
> return 0;
> } else
> msg = "; probably buggy MP table";
> +#endif
> } else if (pci_probe & PCI_BIOS_IRQ_SCAN)
> msg = "";
> else
What a [pre-existing] maze of if else if else. Now also burdened
with an #ifdef. New helper(s) needed?
Ingo
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 4/4] x86/pci: update pirq_enable_irq to setup io apic routing -v2
2009-05-06 12:45 ` Ingo Molnar
@ 2009-05-06 15:48 ` Jesse Barnes
0 siblings, 0 replies; 8+ messages in thread
From: Jesse Barnes @ 2009-05-06 15:48 UTC (permalink / raw)
To: Ingo Molnar
Cc: Yinghai Lu, Thomas Gleixner, H. Peter Anvin, linux-kernel, linux-pci
On Wed, 6 May 2009 14:45:58 +0200
Ingo Molnar <mingo@elte.hu> wrote:
>
> * Yinghai Lu <yinghai@kernel.org> wrote:
>
> > so we could set io apic routing only when enable device irq.
> >
> > also could make setup_IO_APIC_irqs and setup_ioapic_dest only handle
> > first ioapic...
> >
> > v2: remove one one not needed style change.
> > merge the patch only setup io_apic for acpi on in
> > setup_IO_APIC_irqs
> >
> > [ Impact: make mptable irq enable more like acpi is used, and
> > numa_irq_desc could get correct node when acpi=off ]
> >
> > Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> >
> > ---
> > arch/x86/kernel/apic/io_apic.c | 148
> > ++++++++++++++++++++---------------------
> > arch/x86/pci/irq.c | 84 ++++++++--------------- 2
> > files changed, 103 insertions(+), 129 deletions(-)
>
> Ok, i guess this makes sense with acpi-less bootup modes.
>
> There's hefty impact on io_apic.c and pci/irq.c as well. The io-apic
> code already has a fair amount of changes queued up. Jesse: do you
> have pci/irq.c changes queued up? If you agree with the patch, how
> should we handle this?
No I don't have anything recent... and since this stuff is intertwined
with the io_apic changes I'm fine with it going through you guys.
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-05-06 15:49 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-29 20:04 [PATCH] x86: don't print strange not connect ioapic Yinghai Lu
2009-04-30 8:19 ` [PATCH 1/4] x86/acpi: move pin_programmed bit map to io_apic.c Yinghai Lu
2009-04-30 8:21 ` [PATCH 2/4] x86/pci: add 4 more return param in IO_APIC_get_PCI_irq_vector Yinghai Lu
2009-04-30 8:22 ` [PATCH 3/4] x86/acpi: move setup io apic routing out of ACPI macro scope Yinghai Lu
2009-04-30 8:23 ` [PATCH 4/4] x86/pci: update pirq_enable_irq to setup io apic routing Yinghai Lu
2009-05-02 17:44 ` [PATCH 4/4] x86/pci: update pirq_enable_irq to setup io apic routing -v2 Yinghai Lu
2009-05-06 12:45 ` Ingo Molnar
2009-05-06 15:48 ` Jesse Barnes
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).