aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJiang Liu <jiang.liu@linux.intel.com>2014-06-09 04:19:42 -0400
committerThomas Gleixner <tglx@linutronix.de>2014-06-21 17:05:41 -0400
commitf44d16929638a6dc34bdd51e7422e7e3c1d0b904 (patch)
tree1f24467cfb3b862d2ea28ab8e4a5132bda677cc1 /arch
parent518b2c63fcdde0723d2719bbe5b14086bdc8ec80 (diff)
x86, ioapic: Introduce helper utilities to walk ioapics and pins
Introduce helper utilities for_each_ioapic(), for_each_ioapic_reverse(), for_each_pin() and for_each_ioapic_pin() to walk ioapics and pins. They will be rewritten e will rewrite later to support IOAPIC hotplug. Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com> Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Cc: Tony Luck <tony.luck@intel.com> Cc: Joerg Roedel <joro@8bytes.org> Cc: Paul Gortmaker <paul.gortmaker@windriver.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Grant Likely <grant.likely@linaro.org> Cc: Rafael J. Wysocki <rjw@rjwysocki.net> Cc: Bjorn Helgaas <bhelgaas@google.com> Cc: Randy Dunlap <rdunlap@infradead.org> Cc: Yinghai Lu <yinghai@kernel.org> Link: http://lkml.kernel.org/r/1402302011-23642-14-git-send-email-jiang.liu@linux.intel.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/apic/io_apic.c120
1 files changed, 62 insertions, 58 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 46d09eac1777..16b0247392a5 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -62,6 +62,16 @@
62 62
63#define __apicdebuginit(type) static type __init 63#define __apicdebuginit(type) static type __init
64 64
65#define for_each_ioapic(idx) \
66 for ((idx) = 0; (idx) < nr_ioapics; (idx)++)
67#define for_each_ioapic_reverse(idx) \
68 for ((idx) = nr_ioapics - 1; (idx) >= 0; (idx)--)
69#define for_each_pin(idx, pin) \
70 for ((pin) = 0; (pin) < ioapics[(idx)].nr_registers; (pin)++)
71#define for_each_ioapic_pin(idx, pin) \
72 for_each_ioapic((idx)) \
73 for_each_pin((idx), (pin))
74
65#define for_each_irq_pin(entry, head) \ 75#define for_each_irq_pin(entry, head) \
66 for (entry = head; entry; entry = entry->next) 76 for (entry = head; entry; entry = entry->next)
67 77
@@ -191,7 +201,7 @@ int __init arch_early_irq_init(void)
191 if (!legacy_pic->nr_legacy_irqs) 201 if (!legacy_pic->nr_legacy_irqs)
192 io_apic_irqs = ~0UL; 202 io_apic_irqs = ~0UL;
193 203
194 for (i = 0; i < nr_ioapics; i++) { 204 for_each_ioapic(i) {
195 ioapics[i].saved_registers = 205 ioapics[i].saved_registers =
196 kzalloc(sizeof(struct IO_APIC_route_entry) * 206 kzalloc(sizeof(struct IO_APIC_route_entry) *
197 ioapics[i].nr_registers, GFP_KERNEL); 207 ioapics[i].nr_registers, GFP_KERNEL);
@@ -624,9 +634,8 @@ static void clear_IO_APIC (void)
624{ 634{
625 int apic, pin; 635 int apic, pin;
626 636
627 for (apic = 0; apic < nr_ioapics; apic++) 637 for_each_ioapic_pin(apic, pin)
628 for (pin = 0; pin < ioapics[apic].nr_registers; pin++) 638 clear_IO_APIC_pin(apic, pin);
629 clear_IO_APIC_pin(apic, pin);
630} 639}
631 640
632#ifdef CONFIG_X86_32 641#ifdef CONFIG_X86_32
@@ -675,13 +684,13 @@ int save_ioapic_entries(void)
675 int apic, pin; 684 int apic, pin;
676 int err = 0; 685 int err = 0;
677 686
678 for (apic = 0; apic < nr_ioapics; apic++) { 687 for_each_ioapic(apic) {
679 if (!ioapics[apic].saved_registers) { 688 if (!ioapics[apic].saved_registers) {
680 err = -ENOMEM; 689 err = -ENOMEM;
681 continue; 690 continue;
682 } 691 }
683 692
684 for (pin = 0; pin < ioapics[apic].nr_registers; pin++) 693 for_each_pin(apic, pin)
685 ioapics[apic].saved_registers[pin] = 694 ioapics[apic].saved_registers[pin] =
686 ioapic_read_entry(apic, pin); 695 ioapic_read_entry(apic, pin);
687 } 696 }
@@ -696,11 +705,11 @@ void mask_ioapic_entries(void)
696{ 705{
697 int apic, pin; 706 int apic, pin;
698 707
699 for (apic = 0; apic < nr_ioapics; apic++) { 708 for_each_ioapic(apic) {
700 if (!ioapics[apic].saved_registers) 709 if (!ioapics[apic].saved_registers)
701 continue; 710 continue;
702 711
703 for (pin = 0; pin < ioapics[apic].nr_registers; pin++) { 712 for_each_pin(apic, pin) {
704 struct IO_APIC_route_entry entry; 713 struct IO_APIC_route_entry entry;
705 714
706 entry = ioapics[apic].saved_registers[pin]; 715 entry = ioapics[apic].saved_registers[pin];
@@ -719,11 +728,11 @@ int restore_ioapic_entries(void)
719{ 728{
720 int apic, pin; 729 int apic, pin;
721 730
722 for (apic = 0; apic < nr_ioapics; apic++) { 731 for_each_ioapic(apic) {
723 if (!ioapics[apic].saved_registers) 732 if (!ioapics[apic].saved_registers)
724 continue; 733 continue;
725 734
726 for (pin = 0; pin < ioapics[apic].nr_registers; pin++) 735 for_each_pin(apic, pin)
727 ioapic_write_entry(apic, pin, 736 ioapic_write_entry(apic, pin,
728 ioapics[apic].saved_registers[pin]); 737 ioapics[apic].saved_registers[pin]);
729 } 738 }
@@ -782,7 +791,7 @@ static int __init find_isa_irq_apic(int irq, int type)
782 if (i < mp_irq_entries) { 791 if (i < mp_irq_entries) {
783 int ioapic_idx; 792 int ioapic_idx;
784 793
785 for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++) 794 for_each_ioapic(ioapic_idx)
786 if (mpc_ioapic_id(ioapic_idx) == mp_irqs[i].dstapic) 795 if (mpc_ioapic_id(ioapic_idx) == mp_irqs[i].dstapic)
787 return ioapic_idx; 796 return ioapic_idx;
788 } 797 }
@@ -1001,7 +1010,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,
1001 for (i = 0; i < mp_irq_entries; i++) { 1010 for (i = 0; i < mp_irq_entries; i++) {
1002 int lbus = mp_irqs[i].srcbus; 1011 int lbus = mp_irqs[i].srcbus;
1003 1012
1004 for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++) 1013 for_each_ioapic(ioapic_idx)
1005 if (mpc_ioapic_id(ioapic_idx) == mp_irqs[i].dstapic || 1014 if (mpc_ioapic_id(ioapic_idx) == mp_irqs[i].dstapic ||
1006 mp_irqs[i].dstapic == MP_APIC_ALL) 1015 mp_irqs[i].dstapic == MP_APIC_ALL)
1007 break; 1016 break;
@@ -1224,12 +1233,10 @@ static inline int IO_APIC_irq_trigger(int irq)
1224{ 1233{
1225 int apic, idx, pin; 1234 int apic, idx, pin;
1226 1235
1227 for (apic = 0; apic < nr_ioapics; apic++) { 1236 for_each_ioapic_pin(apic, pin) {
1228 for (pin = 0; pin < ioapics[apic].nr_registers; pin++) { 1237 idx = find_irq_entry(apic, pin, mp_INT);
1229 idx = find_irq_entry(apic, pin, mp_INT); 1238 if ((idx != -1) && (irq == pin_2_irq(idx, apic, pin)))
1230 if ((idx != -1) && (irq == pin_2_irq(idx, apic, pin))) 1239 return irq_trigger(idx);
1231 return irq_trigger(idx);
1232 }
1233 } 1240 }
1234 /* 1241 /*
1235 * nonexistent IRQs are edge default 1242 * nonexistent IRQs are edge default
@@ -1349,7 +1356,7 @@ static void __init __io_apic_setup_irqs(unsigned int ioapic_idx)
1349 struct io_apic_irq_attr attr; 1356 struct io_apic_irq_attr attr;
1350 unsigned int pin, irq; 1357 unsigned int pin, irq;
1351 1358
1352 for (pin = 0; pin < ioapics[ioapic_idx].nr_registers; pin++) { 1359 for_each_pin(ioapic_idx, pin) {
1353 idx = find_irq_entry(ioapic_idx, pin, mp_INT); 1360 idx = find_irq_entry(ioapic_idx, pin, mp_INT);
1354 if (io_apic_pin_not_connected(idx, ioapic_idx, pin)) 1361 if (io_apic_pin_not_connected(idx, ioapic_idx, pin))
1355 continue; 1362 continue;
@@ -1380,7 +1387,7 @@ static void __init setup_IO_APIC_irqs(void)
1380 1387
1381 apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); 1388 apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
1382 1389
1383 for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++) 1390 for_each_ioapic(ioapic_idx)
1384 __io_apic_setup_irqs(ioapic_idx); 1391 __io_apic_setup_irqs(ioapic_idx);
1385} 1392}
1386 1393
@@ -1583,7 +1590,7 @@ __apicdebuginit(void) print_IO_APICs(void)
1583 struct irq_chip *chip; 1590 struct irq_chip *chip;
1584 1591
1585 printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries); 1592 printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
1586 for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++) 1593 for_each_ioapic(ioapic_idx)
1587 printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n", 1594 printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n",
1588 mpc_ioapic_id(ioapic_idx), 1595 mpc_ioapic_id(ioapic_idx),
1589 ioapics[ioapic_idx].nr_registers); 1596 ioapics[ioapic_idx].nr_registers);
@@ -1594,7 +1601,7 @@ __apicdebuginit(void) print_IO_APICs(void)
1594 */ 1601 */
1595 printk(KERN_INFO "testing the IO APIC.......................\n"); 1602 printk(KERN_INFO "testing the IO APIC.......................\n");
1596 1603
1597 for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++) 1604 for_each_ioapic(ioapic_idx)
1598 print_IO_APIC(ioapic_idx); 1605 print_IO_APIC(ioapic_idx);
1599 1606
1600 printk(KERN_DEBUG "IRQ to pin mappings:\n"); 1607 printk(KERN_DEBUG "IRQ to pin mappings:\n");
@@ -1825,26 +1832,22 @@ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
1825void __init enable_IO_APIC(void) 1832void __init enable_IO_APIC(void)
1826{ 1833{
1827 int i8259_apic, i8259_pin; 1834 int i8259_apic, i8259_pin;
1828 int apic; 1835 int apic, pin;
1829 1836
1830 if (!legacy_pic->nr_legacy_irqs) 1837 if (!legacy_pic->nr_legacy_irqs)
1831 return; 1838 return;
1832 1839
1833 for(apic = 0; apic < nr_ioapics; apic++) { 1840 for_each_ioapic_pin(apic, pin) {
1834 int pin;
1835 /* See if any of the pins is in ExtINT mode */ 1841 /* See if any of the pins is in ExtINT mode */
1836 for (pin = 0; pin < ioapics[apic].nr_registers; pin++) { 1842 struct IO_APIC_route_entry entry = ioapic_read_entry(apic, pin);
1837 struct IO_APIC_route_entry entry;
1838 entry = ioapic_read_entry(apic, pin);
1839 1843
1840 /* If the interrupt line is enabled and in ExtInt mode 1844 /* If the interrupt line is enabled and in ExtInt mode
1841 * I have found the pin where the i8259 is connected. 1845 * I have found the pin where the i8259 is connected.
1842 */ 1846 */
1843 if ((entry.mask == 0) && (entry.delivery_mode == dest_ExtINT)) { 1847 if ((entry.mask == 0) && (entry.delivery_mode == dest_ExtINT)) {
1844 ioapic_i8259.apic = apic; 1848 ioapic_i8259.apic = apic;
1845 ioapic_i8259.pin = pin; 1849 ioapic_i8259.pin = pin;
1846 goto found_i8259; 1850 goto found_i8259;
1847 }
1848 } 1851 }
1849 } 1852 }
1850 found_i8259: 1853 found_i8259:
@@ -1947,7 +1950,7 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void)
1947 /* 1950 /*
1948 * Set the IOAPIC ID to the value stored in the MPC table. 1951 * Set the IOAPIC ID to the value stored in the MPC table.
1949 */ 1952 */
1950 for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++) { 1953 for_each_ioapic(ioapic_idx) {
1951 /* Read the register 0 value */ 1954 /* Read the register 0 value */
1952 raw_spin_lock_irqsave(&ioapic_lock, flags); 1955 raw_spin_lock_irqsave(&ioapic_lock, flags);
1953 reg_00.raw = io_apic_read(ioapic_idx, 0); 1956 reg_00.raw = io_apic_read(ioapic_idx, 0);
@@ -2863,7 +2866,7 @@ static void ioapic_resume(void)
2863{ 2866{
2864 int ioapic_idx; 2867 int ioapic_idx;
2865 2868
2866 for (ioapic_idx = nr_ioapics - 1; ioapic_idx >= 0; ioapic_idx--) 2869 for_each_ioapic_reverse(ioapic_idx)
2867 resume_ioapic_id(ioapic_idx); 2870 resume_ioapic_id(ioapic_idx);
2868 2871
2869 restore_ioapic_entries(); 2872 restore_ioapic_entries();
@@ -3457,9 +3460,8 @@ static u8 __init io_apic_unique_id(u8 id)
3457 DECLARE_BITMAP(used, 256); 3460 DECLARE_BITMAP(used, 256);
3458 3461
3459 bitmap_zero(used, 256); 3462 bitmap_zero(used, 256);
3460 for (i = 0; i < nr_ioapics; i++) { 3463 for_each_ioapic(i)
3461 __set_bit(mpc_ioapic_id(i), used); 3464 __set_bit(mpc_ioapic_id(i), used);
3462 }
3463 if (!test_bit(id, used)) 3465 if (!test_bit(id, used))
3464 return id; 3466 return id;
3465 return find_first_zero_bit(used, 256); 3467 return find_first_zero_bit(used, 256);
@@ -3517,8 +3519,7 @@ void __init setup_ioapic_dest(void)
3517 if (skip_ioapic_setup == 1) 3519 if (skip_ioapic_setup == 1)
3518 return; 3520 return;
3519 3521
3520 for (ioapic = 0; ioapic < nr_ioapics; ioapic++) 3522 for_each_ioapic_pin(ioapic, pin) {
3521 for (pin = 0; pin < ioapics[ioapic].nr_registers; pin++) {
3522 irq_entry = find_irq_entry(ioapic, pin, mp_INT); 3523 irq_entry = find_irq_entry(ioapic, pin, mp_INT);
3523 if (irq_entry == -1) 3524 if (irq_entry == -1)
3524 continue; 3525 continue;
@@ -3547,29 +3548,33 @@ void __init setup_ioapic_dest(void)
3547 3548
3548static struct resource *ioapic_resources; 3549static struct resource *ioapic_resources;
3549 3550
3550static struct resource * __init ioapic_setup_resources(int nr_ioapics) 3551static struct resource * __init ioapic_setup_resources(void)
3551{ 3552{
3552 unsigned long n; 3553 unsigned long n;
3553 struct resource *res; 3554 struct resource *res;
3554 char *mem; 3555 char *mem;
3555 int i; 3556 int i, num = 0;
3556 3557
3557 if (nr_ioapics <= 0) 3558 for_each_ioapic(i)
3559 num++;
3560 if (num == 0)
3558 return NULL; 3561 return NULL;
3559 3562
3560 n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource); 3563 n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource);
3561 n *= nr_ioapics; 3564 n *= num;
3562 3565
3563 mem = alloc_bootmem(n); 3566 mem = alloc_bootmem(n);
3564 res = (void *)mem; 3567 res = (void *)mem;
3565 3568
3566 mem += sizeof(struct resource) * nr_ioapics; 3569 mem += sizeof(struct resource) * num;
3567 3570
3568 for (i = 0; i < nr_ioapics; i++) { 3571 num = 0;
3569 res[i].name = mem; 3572 for_each_ioapic(i) {
3570 res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY; 3573 res[num].name = mem;
3574 res[num].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
3571 snprintf(mem, IOAPIC_RESOURCE_NAME_SIZE, "IOAPIC %u", i); 3575 snprintf(mem, IOAPIC_RESOURCE_NAME_SIZE, "IOAPIC %u", i);
3572 mem += IOAPIC_RESOURCE_NAME_SIZE; 3576 mem += IOAPIC_RESOURCE_NAME_SIZE;
3577 num++;
3573 } 3578 }
3574 3579
3575 ioapic_resources = res; 3580 ioapic_resources = res;
@@ -3583,8 +3588,8 @@ void __init native_io_apic_init_mappings(void)
3583 struct resource *ioapic_res; 3588 struct resource *ioapic_res;
3584 int i; 3589 int i;
3585 3590
3586 ioapic_res = ioapic_setup_resources(nr_ioapics); 3591 ioapic_res = ioapic_setup_resources();
3587 for (i = 0; i < nr_ioapics; i++) { 3592 for_each_ioapic(i) {
3588 if (smp_found_config) { 3593 if (smp_found_config) {
3589 ioapic_phys = mpc_ioapic_addr(i); 3594 ioapic_phys = mpc_ioapic_addr(i);
3590#ifdef CONFIG_X86_32 3595#ifdef CONFIG_X86_32
@@ -3629,7 +3634,7 @@ void __init ioapic_insert_resources(void)
3629 return; 3634 return;
3630 } 3635 }
3631 3636
3632 for (i = 0; i < nr_ioapics; i++) { 3637 for_each_ioapic(i) {
3633 insert_resource(&iomem_resource, r); 3638 insert_resource(&iomem_resource, r);
3634 r++; 3639 r++;
3635 } 3640 }
@@ -3637,16 +3642,15 @@ void __init ioapic_insert_resources(void)
3637 3642
3638int mp_find_ioapic(u32 gsi) 3643int mp_find_ioapic(u32 gsi)
3639{ 3644{
3640 int i = 0; 3645 int i;
3641 3646
3642 if (nr_ioapics == 0) 3647 if (nr_ioapics == 0)
3643 return -1; 3648 return -1;
3644 3649
3645 /* Find the IOAPIC that manages this GSI. */ 3650 /* Find the IOAPIC that manages this GSI. */
3646 for (i = 0; i < nr_ioapics; i++) { 3651 for_each_ioapic(i) {
3647 struct mp_ioapic_gsi *gsi_cfg = mp_ioapic_gsi_routing(i); 3652 struct mp_ioapic_gsi *gsi_cfg = mp_ioapic_gsi_routing(i);
3648 if ((gsi >= gsi_cfg->gsi_base) 3653 if (gsi >= gsi_cfg->gsi_base && gsi <= gsi_cfg->gsi_end)
3649 && (gsi <= gsi_cfg->gsi_end))
3650 return i; 3654 return i;
3651 } 3655 }
3652 3656
@@ -3658,7 +3662,7 @@ int mp_find_ioapic_pin(int ioapic, u32 gsi)
3658{ 3662{
3659 struct mp_ioapic_gsi *gsi_cfg; 3663 struct mp_ioapic_gsi *gsi_cfg;
3660 3664
3661 if (WARN_ON(ioapic == -1)) 3665 if (WARN_ON(ioapic < 0))
3662 return -1; 3666 return -1;
3663 3667
3664 gsi_cfg = mp_ioapic_gsi_routing(ioapic); 3668 gsi_cfg = mp_ioapic_gsi_routing(ioapic);