aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apic/io_apic.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2011-02-23 11:47:41 -0500
committerThomas Gleixner <tglx@linutronix.de>2011-02-23 12:58:09 -0500
commit710dcda64369e3f3704a0eee502ce27dbf9fedc1 (patch)
tree42f74f2bef2e6b05da7f58163fcb787d267f34e5 /arch/x86/kernel/apic/io_apic.c
parentb77cf6a8609a8450786c572bc8af6ad068022dbe (diff)
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: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/apic/io_apic.c')
-rw-r--r--arch/x86/kernel/apic/io_apic.c57
1 files changed, 25 insertions, 32 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 2d49e4b41c2..46913ef88ea 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -128,6 +128,9 @@ static int __init parse_noapic(char *str)
128} 128}
129early_param("noapic", parse_noapic); 129early_param("noapic", parse_noapic);
130 130
131static int io_apic_setup_irq_pin_once(unsigned int irq, int node,
132 struct io_apic_irq_attr *attr);
133
131/* Will be called in mpparse/acpi/sfi codes for saving IRQ info */ 134/* Will be called in mpparse/acpi/sfi codes for saving IRQ info */
132void mp_save_irq(struct mpc_intsrc *m) 135void mp_save_irq(struct mpc_intsrc *m)
133{ 136{
@@ -1457,17 +1460,10 @@ void setup_IO_APIC_irq_extra(u32 gsi)
1457 if (apic_id == 0 || irq < NR_IRQS_LEGACY) 1460 if (apic_id == 0 || irq < NR_IRQS_LEGACY)
1458 return; 1461 return;
1459 1462
1460 if (test_bit(pin, mp_ioapic_routing[apic_id].pin_programmed)) {
1461 pr_debug("Pin %d-%d already programmed\n",
1462 mp_ioapics[apic_id].apicid, pin);
1463 return;
1464 }
1465
1466 set_io_apic_irq_attr(&attr, apic_id, pin, irq_trigger(idx), 1463 set_io_apic_irq_attr(&attr, apic_id, pin, irq_trigger(idx),
1467 irq_polarity(idx)); 1464 irq_polarity(idx));
1468 1465
1469 if (!io_apic_setup_irq_pin(irq, node, &attr)) 1466 io_apic_setup_irq_pin_once(irq, node, &attr);
1470 set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed);
1471} 1467}
1472 1468
1473/* 1469/*
@@ -3601,6 +3597,24 @@ io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr)
3601 return ret; 3597 return ret;
3602} 3598}
3603 3599
3600static int io_apic_setup_irq_pin_once(unsigned int irq, int node,
3601 struct io_apic_irq_attr *attr)
3602{
3603 unsigned int id = attr->ioapic, pin = attr->ioapic_pin;
3604 int ret;
3605
3606 /* Avoid redundant programming */
3607 if (test_bit(pin, mp_ioapic_routing[id].pin_programmed)) {
3608 pr_debug("Pin %d-%d already programmed\n",
3609 mp_ioapics[id].apicid, pin);
3610 return 0;
3611 }
3612 ret = io_apic_setup_irq_pin(irq, node, attr);
3613 if (!ret)
3614 set_bit(pin, mp_ioapic_routing[id].pin_programmed);
3615 return ret;
3616}
3617
3604static int __init io_apic_get_redir_entries(int ioapic) 3618static int __init io_apic_get_redir_entries(int ioapic)
3605{ 3619{
3606 union IO_APIC_reg_01 reg_01; 3620 union IO_APIC_reg_01 reg_01;
@@ -3655,8 +3669,8 @@ int __init arch_probe_nr_irqs(void)
3655} 3669}
3656#endif 3670#endif
3657 3671
3658static int __io_apic_set_pci_routing(struct device *dev, int irq, 3672int io_apic_set_pci_routing(struct device *dev, int irq,
3659 struct io_apic_irq_attr *irq_attr) 3673 struct io_apic_irq_attr *irq_attr)
3660{ 3674{
3661 int node; 3675 int node;
3662 3676
@@ -3668,28 +3682,7 @@ static int __io_apic_set_pci_routing(struct device *dev, int irq,
3668 3682
3669 node = dev ? dev_to_node(dev) : cpu_to_node(0); 3683 node = dev ? dev_to_node(dev) : cpu_to_node(0);
3670 3684
3671 return io_apic_setup_irq_pin(irq, node, irq_attr); 3685 return io_apic_setup_irq_pin_once(irq, node, irq_attr);
3672}
3673
3674int io_apic_set_pci_routing(struct device *dev, int irq,
3675 struct io_apic_irq_attr *irq_attr)
3676{
3677 int ioapic, pin;
3678 /*
3679 * Avoid pin reprogramming. PRTs typically include entries
3680 * with redundant pin->gsi mappings (but unique PCI devices);
3681 * we only program the IOAPIC on the first.
3682 */
3683 ioapic = irq_attr->ioapic;
3684 pin = irq_attr->ioapic_pin;
3685 if (test_bit(pin, mp_ioapic_routing[ioapic].pin_programmed)) {
3686 pr_debug("Pin %d-%d already programmed\n",
3687 mp_ioapics[ioapic].apicid, pin);
3688 return 0;
3689 }
3690 set_bit(pin, mp_ioapic_routing[ioapic].pin_programmed);
3691
3692 return __io_apic_set_pci_routing(dev, irq, irq_attr);
3693} 3686}
3694 3687
3695#ifdef CONFIG_X86_32 3688#ifdef CONFIG_X86_32