Commit 710dcda6 authored by Thomas Gleixner's avatar Thomas Gleixner

x86: ioapic: Implement and use io_apic_setup_irq_pin_once()

io_apic_set_pci_routing() and mp_save_irq() check the pin_programmed
bit before calling io_apic_setup_irq_pin() and set the bit when the
pin was setup.

Move that duplicated code into a separate function and use it.
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent b77cf6a8
...@@ -128,6 +128,9 @@ static int __init parse_noapic(char *str) ...@@ -128,6 +128,9 @@ static int __init parse_noapic(char *str)
} }
early_param("noapic", parse_noapic); early_param("noapic", parse_noapic);
static int io_apic_setup_irq_pin_once(unsigned int irq, int node,
struct io_apic_irq_attr *attr);
/* Will be called in mpparse/acpi/sfi codes for saving IRQ info */ /* Will be called in mpparse/acpi/sfi codes for saving IRQ info */
void mp_save_irq(struct mpc_intsrc *m) void mp_save_irq(struct mpc_intsrc *m)
{ {
...@@ -1457,17 +1460,10 @@ void setup_IO_APIC_irq_extra(u32 gsi) ...@@ -1457,17 +1460,10 @@ void setup_IO_APIC_irq_extra(u32 gsi)
if (apic_id == 0 || irq < NR_IRQS_LEGACY) if (apic_id == 0 || irq < NR_IRQS_LEGACY)
return; return;
if (test_bit(pin, mp_ioapic_routing[apic_id].pin_programmed)) {
pr_debug("Pin %d-%d already programmed\n",
mp_ioapics[apic_id].apicid, pin);
return;
}
set_io_apic_irq_attr(&attr, apic_id, pin, irq_trigger(idx), set_io_apic_irq_attr(&attr, apic_id, pin, irq_trigger(idx),
irq_polarity(idx)); irq_polarity(idx));
if (!io_apic_setup_irq_pin(irq, node, &attr)) io_apic_setup_irq_pin_once(irq, node, &attr);
set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed);
} }
/* /*
...@@ -3601,6 +3597,24 @@ io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr) ...@@ -3601,6 +3597,24 @@ io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr)
return ret; return ret;
} }
static int io_apic_setup_irq_pin_once(unsigned int irq, int node,
struct io_apic_irq_attr *attr)
{
unsigned int id = attr->ioapic, pin = attr->ioapic_pin;
int ret;
/* Avoid redundant programming */
if (test_bit(pin, mp_ioapic_routing[id].pin_programmed)) {
pr_debug("Pin %d-%d already programmed\n",
mp_ioapics[id].apicid, pin);
return 0;
}
ret = io_apic_setup_irq_pin(irq, node, attr);
if (!ret)
set_bit(pin, mp_ioapic_routing[id].pin_programmed);
return ret;
}
static int __init io_apic_get_redir_entries(int ioapic) static int __init io_apic_get_redir_entries(int ioapic)
{ {
union IO_APIC_reg_01 reg_01; union IO_APIC_reg_01 reg_01;
...@@ -3655,8 +3669,8 @@ int __init arch_probe_nr_irqs(void) ...@@ -3655,8 +3669,8 @@ int __init arch_probe_nr_irqs(void)
} }
#endif #endif
static int __io_apic_set_pci_routing(struct device *dev, int irq, int io_apic_set_pci_routing(struct device *dev, int irq,
struct io_apic_irq_attr *irq_attr) struct io_apic_irq_attr *irq_attr)
{ {
int node; int node;
...@@ -3668,28 +3682,7 @@ static int __io_apic_set_pci_routing(struct device *dev, int irq, ...@@ -3668,28 +3682,7 @@ static int __io_apic_set_pci_routing(struct device *dev, int irq,
node = dev ? dev_to_node(dev) : cpu_to_node(0); node = dev ? dev_to_node(dev) : cpu_to_node(0);
return io_apic_setup_irq_pin(irq, node, irq_attr); return io_apic_setup_irq_pin_once(irq, node, irq_attr);
}
int io_apic_set_pci_routing(struct device *dev, int irq,
struct io_apic_irq_attr *irq_attr)
{
int ioapic, pin;
/*
* Avoid pin reprogramming. PRTs typically include entries
* with redundant pin->gsi mappings (but unique PCI devices);
* we only program the IOAPIC on the first.
*/
ioapic = irq_attr->ioapic;
pin = irq_attr->ioapic_pin;
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, irq, irq_attr);
} }
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment