|
@@ -1480,9 +1480,13 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq
|
|
ioapic_write_entry(apic_id, pin, entry);
|
|
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)
|
|
static void __init setup_IO_APIC_irqs(void)
|
|
{
|
|
{
|
|
- int apic_id, pin, idx, irq;
|
|
|
|
|
|
+ int apic_id = 0, pin, idx, irq;
|
|
int notcon = 0;
|
|
int notcon = 0;
|
|
struct irq_desc *desc;
|
|
struct irq_desc *desc;
|
|
struct irq_cfg *cfg;
|
|
struct irq_cfg *cfg;
|
|
@@ -1490,48 +1494,53 @@ static void __init setup_IO_APIC_irqs(void)
|
|
|
|
|
|
apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
|
|
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++) {
|
|
|
|
-
|
|
|
|
- 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) {
|
|
|
|
- apic_printk(APIC_VERBOSE,
|
|
|
|
- " (apicid-pin) not connected\n");
|
|
|
|
- notcon = 0;
|
|
|
|
- }
|
|
|
|
|
|
+#ifdef CONFIG_ACPI
|
|
|
|
+ if (!acpi_disabled && acpi_ioapic) {
|
|
|
|
+ apic_id = mp_find_ioapic(0);
|
|
|
|
+ if (apic_id < 0)
|
|
|
|
+ apic_id = 0;
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
|
|
- irq = pin_2_irq(idx, apic_id, pin);
|
|
|
|
|
|
+ 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) {
|
|
|
|
+ apic_printk(APIC_VERBOSE,
|
|
|
|
+ " (apicid-pin) not connected\n");
|
|
|
|
+ notcon = 0;
|
|
|
|
+ }
|
|
|
|
|
|
- /*
|
|
|
|
- * 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;
|
|
|
|
|
|
+ irq = pin_2_irq(idx, apic_id, pin);
|
|
|
|
|
|
- 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)
|
|
if (notcon)
|
|
@@ -3876,10 +3885,6 @@ static int __io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, in
|
|
return 0;
|
|
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 io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, int irq,
|
|
int triggering, int polarity)
|
|
int triggering, int polarity)
|
|
{
|
|
{
|
|
@@ -4023,51 +4028,44 @@ int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
|
|
#ifdef CONFIG_SMP
|
|
#ifdef CONFIG_SMP
|
|
void __init setup_ioapic_dest(void)
|
|
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_desc *desc;
|
|
- struct irq_cfg *cfg;
|
|
|
|
const struct cpumask *mask;
|
|
const struct cpumask *mask;
|
|
|
|
|
|
if (skip_ioapic_setup == 1)
|
|
if (skip_ioapic_setup == 1)
|
|
return;
|
|
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
|
|
#endif
|
|
|
|
|