x86: don't print strange not connect ioapic
PATCH 1/1 x86: don't print strange not connect ioapic
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 ]
--- arch/x86/kernel/apic/io_apic.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
arch/x86/kernel/apic/io_apic.c +18 -1
@@ -1477,10 +1477,27 @@ static void __init setup_IO_APIC_irqs(vostruct 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);
PATCH 1/4 x86/acpi: move pin_programmed bit map to io_apic.c
prepare to call setup_io_apic_routing in pcibios_irq_enable also remove not needed member apic_id.
--- arch/x86/kernel/acpi/boot.c | 18 ++---------------- arch/x86/kernel/apic/io_apic.c | 25 ++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 17 deletions(-)
arch/x86/kernel/acpi/boot.c +2 -16
@@ -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 );
arch/x86/kernel/apic/io_apic.c +24 -1
@@ -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 devicreturn 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) {
PATCH 2/4 x86/pci: add 4 more return param in IO_APIC_get_PCI_irq_vector
In reply to Yinghai Luso prepare those params for pcibios_irq_enable to call setup_io_apic_routing
--- 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(-)
arch/x86/kernel/apic/io_apic.c +59 -48
@@ -874,54 +874,6 @@ static int __init find_isa_irq_apic(intreturn -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
arch/x86/include/asm/hw_irq.h +3 -1
@@ -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 );
drivers/pci/hotplug/ibmphp_core.c +28 -24
73 lines not on this page · raw message
arch/x86/pci/irq.c +20 -4
@@ -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_deif (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",
PATCH 3/4 x86/acpi: move setup io apic routing out of ACPI macro scope
In reply to Yinghai Luso we could set io apic routing when ACPI is not set
--- arch/x86/include/asm/io_apic.h | 4 - arch/x86/kernel/apic/io_apic.c | 122 ++++++++++++++++++++--------------------- 2 files changed, 63 insertions(+), 63 deletions(-)
arch/x86/kernel/apic/io_apic.c +61 -61
@@ -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;
arch/x86/include/asm/io_apic.h +2 -2
@@ -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 );
PATCH 4/4 x86/pci: update pirq_enable_irq to setup io apic routing
In reply to Yinghai Luso 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 ]
--- arch/x86/kernel/apic/io_apic.c | 157 ++++++++++++++++++----------------------- arch/x86/pci/irq.c | 92 ++++++++---------------- 2 files changed, 103 insertions(+), 146 deletions(-)
arch/x86/kernel/apic/io_apic.c +69 -88
@@ -1481,75 +1481,67 @@ static void setup_IO_APIC_irq(int apic_iioapic_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(strreturn 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
arch/x86/pci/irq.c +34 -58
143 lines not on this page · raw message
PATCH 4/4 x86/pci: update pirq_enable_irq to setup io apic routing -v2
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 ]
--- arch/x86/kernel/apic/io_apic.c | 148 ++++++++++++++++++++--------------------- arch/x86/pci/irq.c | 84 ++++++++--------------- 2 files changed, 103 insertions(+), 129 deletions(-)
arch/x86/kernel/apic/io_apic.c +73 -75
@@ -1481,9 +1481,13 @@ static void setup_IO_APIC_irq(int apic_iioapic_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(voapic_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(strreturn 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
arch/x86/pci/irq.c +30 -54
130 lines not on this page · raw message
Re: [PATCH 4/4] x86/pci: update pirq_enable_irq to setup io apic routing -v2
Quoted 8 lines · Yinghai Lu
so we could set io apic routing only when enable device irq.
also could make
setup_IO_APIC_irqsandsetup_ioapic_destonly handle first ioapic...v2: remove one one not needed style change.
merge the patch only setupio_apicfor acpi on insetup_IO_APIC_irqs
Quoted 8 lines
[ Impact: make mptable irq enable more like acpi is used, and
numa_irq_desccould get correct node when acpi=off ]Signed-off-by Yinghai Lu <[email protected]>--- 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:
arch/x86/kernel/apic/io_apic.c static void __init setup_IO_APIC_irqs(vo · line 1504
Quoted 7 lines
arch/x86/kernel/apic/io_apic.c +7
-0+#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.
Quoted 65 lines
arch/x86/kernel/apic/io_apic.c +26
-34- 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);
arch/x86/kernel/apic/io_apic.c static void __init setup_IO_APIC_irqs(vo · line 1545
Quoted 10 lines
arch/x86/kernel/apic/io_apic.c +8
-0+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?
arch/x86/kernel/apic/io_apic.c int acpi_get_override_irq(int bus_irq, i · line 4045
Quoted 7 lines
arch/x86/kernel/apic/io_apic.c +7
-0+#ifdef CONFIG_ACPI +if (!acpi_disabled && acpi_ioapic) { + ioapic =mp_find_ioapic (0 ); +if (ioapic <0 ) + ioapic =0 ; + } +#endif
Needs a helper too?
Quoted 68 lines
Index:
linux-2.6/arch/x86/pci/irq.c
===================================================================arch/x86/pci/irq.c +6
-41@@ -889,6 +889,9 @@ static int pcibios_lookup_irq(struct pcireturn 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);
arch/x86/pci/irq.c static void __init pcibios_fixup_irqs(vo · line 1098
Quoted 10 lines
arch/x86/pci/irq.c +0
-10- } -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!
Quoted 51 lines
arch/x86/pci/irq.c +23
-2/* * 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, istatic 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;
arch/x86/pci/irq.c static int pirq_enable_irq(struct pci_de · line 1248
Quoted 10 lines
arch/x86/pci/irq.c +1
-1dev_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
Re: [PATCH 4/4] x86/pci: update pirq_enable_irq to setup io apic routing -v2
Quoted 23 lines · On Wed, 6 May 2009 14:45:58 +0200 Ingo Molnar <[email protected]> wrote:
Quoted 12 lines · Yinghai Lu
so we could set io apic routing only when enable device irq.
also could make
setup_IO_APIC_irqsandsetup_ioapic_destonly handle first ioapic...v2: remove one one not needed style change.
merge the patch only setupio_apicfor acpi on insetup_IO_APIC_irqs[ Impact: make mptable irq enable more like acpi is used, and
numa_irq_desccould get correct node when acpi=off ]Quoted 7 lines
Signed-off-by Yinghai Lu <[email protected]>--- arch/x86/kernel/apic/io_apic.c | 148++++++++++++++++++++---------------------
arch/x86/pci/irq.c| 84 ++++++++--------------- 2
files changed, 103 insertions(+), 129 deletions(-)
Quoted 6 lines
Ok, i guess this makes sense with acpi-less bootup modes.
There's hefty impact on
io_apic.candpci/irq.cas well. The io-apic code already has a fair amount of changes queued up. Jesse: do you havepci/irq.cchanges 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.
Signature · 1 line
Jesse Barnes, Intel Open Source Technology Center