aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorJiang Liu <jiang.liu@linux.intel.com>2014-06-10 02:13:25 -0400
committerThomas Gleixner <tglx@linutronix.de>2014-06-21 17:05:42 -0400
commit6b9fb7082409cd4a2c7caf43e3c023ad82dad0d4 (patch)
tree0e6fa36575e9b41bde22b2e8414ae0d157105051 /arch/x86
parent4b92b4f754939e4ac6bb53355abbe48a5054b573 (diff)
x86, ACPI, irq: Consolidate algorithm of mapping (ioapic, pin) to IRQ number
Currently ACPI and ioapic both implement algorithms to map (ioapic, pin) to IRQ number. So consolidate the common part into one place, which is also preparing for irqdomain support. It introduces mp_map_gsi_to_irq(), which will be used to allocate IRQ number IOAPIC pins when irqdomain is enabled. Also rename gsi_to_irq() to map_gsi_to_irq(), later we will introduce unmap_gsi_to_irq() when enabling 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> Cc: Len Brown <len.brown@intel.com> Cc: Pavel Machek <pavel@ucw.cz> Link: http://lkml.kernel.org/r/1402380812-32446-1-git-send-email-jiang.liu@linux.intel.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/include/asm/io_apic.h2
-rw-r--r--arch/x86/kernel/acpi/boot.c45
-rw-r--r--arch/x86/kernel/apic/io_apic.c27
3 files changed, 38 insertions, 36 deletions
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index b775cf3622c3..978e51fdcb59 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -172,6 +172,7 @@ extern u32 gsi_top;
172extern int mp_find_ioapic(u32 gsi); 172extern int mp_find_ioapic(u32 gsi);
173extern int mp_find_ioapic_pin(int ioapic, u32 gsi); 173extern int mp_find_ioapic_pin(int ioapic, u32 gsi);
174extern u32 mp_pin_to_gsi(int ioapic, int pin); 174extern u32 mp_pin_to_gsi(int ioapic, int pin);
175extern int mp_map_gsi_to_irq(u32 gsi);
175extern void __init mp_register_ioapic(int id, u32 address, u32 gsi_base); 176extern void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
176extern void __init pre_init_apic_IRQ0(void); 177extern void __init pre_init_apic_IRQ0(void);
177 178
@@ -214,6 +215,7 @@ static inline void ioapic_insert_resources(void) { }
214#define gsi_top (NR_IRQS_LEGACY) 215#define gsi_top (NR_IRQS_LEGACY)
215static inline int mp_find_ioapic(u32 gsi) { return 0; } 216static inline int mp_find_ioapic(u32 gsi) { return 0; }
216static inline u32 mp_pin_to_gsi(int ioapic, int pin) { return UINT_MAX; } 217static inline u32 mp_pin_to_gsi(int ioapic, int pin) { return UINT_MAX; }
218static inline int mp_map_gsi_to_irq(u32 gsi) { return gsi; }
217 219
218struct io_apic_irq_attr; 220struct io_apic_irq_attr;
219static inline int io_apic_set_pci_routing(struct device *dev, int irq, 221static inline int io_apic_set_pci_routing(struct device *dev, int irq,
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index b12976590a72..9965afbd71ca 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -100,27 +100,15 @@ static u32 isa_irq_to_gsi[NR_IRQS_LEGACY] __read_mostly = {
100 100
101#define ACPI_INVALID_GSI INT_MIN 101#define ACPI_INVALID_GSI INT_MIN
102 102
103static unsigned int gsi_to_irq(unsigned int gsi) 103static int map_gsi_to_irq(unsigned int gsi)
104{ 104{
105 unsigned int irq = gsi + nr_legacy_irqs(); 105 int i;
106 unsigned int i;
107 106
108 for (i = 0; i < nr_legacy_irqs(); i++) { 107 for (i = 0; i < nr_legacy_irqs(); i++)
109 if (isa_irq_to_gsi[i] == gsi) { 108 if (isa_irq_to_gsi[i] == gsi)
110 return i; 109 return i;
111 }
112 }
113
114 /* Provide an identity mapping of gsi == irq
115 * except on truly weird platforms that have
116 * non isa irqs in the first 16 gsis.
117 */
118 if (gsi >= nr_legacy_irqs())
119 irq = gsi;
120 else
121 irq = gsi_top + gsi;
122 110
123 return irq; 111 return mp_map_gsi_to_irq(gsi);
124} 112}
125 113
126/* 114/*
@@ -416,6 +404,7 @@ static int mp_config_acpi_gsi(struct device *dev, u32 gsi, int trigger,
416static int mp_register_gsi(struct device *dev, u32 gsi, int trigger, 404static int mp_register_gsi(struct device *dev, u32 gsi, int trigger,
417 int polarity) 405 int polarity)
418{ 406{
407 int irq;
419 int ioapic; 408 int ioapic;
420 int ioapic_pin; 409 int ioapic_pin;
421 struct io_apic_irq_attr irq_attr; 410 struct io_apic_irq_attr irq_attr;
@@ -428,6 +417,10 @@ static int mp_register_gsi(struct device *dev, u32 gsi, int trigger,
428 if (acpi_gbl_FADT.sci_interrupt == gsi) 417 if (acpi_gbl_FADT.sci_interrupt == gsi)
429 return gsi; 418 return gsi;
430 419
420 irq = map_gsi_to_irq(gsi);
421 if (irq < 0)
422 return ACPI_INVALID_GSI;
423
431 ioapic = mp_find_ioapic(gsi); 424 ioapic = mp_find_ioapic(gsi);
432 if (ioapic < 0) { 425 if (ioapic < 0) {
433 printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi); 426 printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi);
@@ -449,7 +442,7 @@ static int mp_register_gsi(struct device *dev, u32 gsi, int trigger,
449 set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin, 442 set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin,
450 trigger == ACPI_EDGE_SENSITIVE ? 0 : 1, 443 trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,
451 polarity == ACPI_ACTIVE_HIGH ? 0 : 1); 444 polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
452 ret = io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr); 445 ret = io_apic_set_pci_routing(dev, irq, &irq_attr);
453 if (ret < 0) 446 if (ret < 0)
454 gsi = ACPI_INVALID_GSI; 447 gsi = ACPI_INVALID_GSI;
455 448
@@ -614,16 +607,20 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
614 outb(new >> 8, 0x4d1); 607 outb(new >> 8, 0x4d1);
615} 608}
616 609
617int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) 610int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp)
618{ 611{
619 *irq = gsi_to_irq(gsi); 612 int irq = map_gsi_to_irq(gsi);
620 613
614 if (irq >= 0) {
621#ifdef CONFIG_X86_IO_APIC 615#ifdef CONFIG_X86_IO_APIC
622 if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) 616 if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
623 setup_IO_APIC_irq_extra(gsi); 617 setup_IO_APIC_irq_extra(gsi);
624#endif 618#endif
619 *irqp = irq;
620 return 0;
621 }
625 622
626 return 0; 623 return -1;
627} 624}
628EXPORT_SYMBOL_GPL(acpi_gsi_to_irq); 625EXPORT_SYMBOL_GPL(acpi_gsi_to_irq);
629 626
@@ -681,7 +678,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
681 678
682 plat_gsi = __acpi_register_gsi(dev, gsi, trigger, polarity); 679 plat_gsi = __acpi_register_gsi(dev, gsi, trigger, polarity);
683 if (plat_gsi != ACPI_INVALID_GSI) 680 if (plat_gsi != ACPI_INVALID_GSI)
684 return gsi_to_irq(plat_gsi); 681 return map_gsi_to_irq(plat_gsi);
685 682
686 return -1; 683 return -1;
687} 684}
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index e25e7e315d4f..7fd9f1befe0b 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -959,11 +959,19 @@ static int irq_trigger(int idx)
959 return trigger; 959 return trigger;
960} 960}
961 961
962int mp_map_gsi_to_irq(u32 gsi)
963{
964 /*
965 * Provide an identity mapping of gsi == irq except on truly weird
966 * platforms that have non isa irqs in the first 16 gsis.
967 */
968 return gsi >= nr_legacy_irqs() ? gsi : gsi_top + gsi;
969}
970
962static int pin_2_irq(int idx, int apic, int pin) 971static int pin_2_irq(int idx, int apic, int pin)
963{ 972{
964 int irq; 973 int irq;
965 int bus = mp_irqs[idx].srcbus; 974 int bus = mp_irqs[idx].srcbus;
966 struct mp_ioapic_gsi *gsi_cfg = mp_ioapic_gsi_routing(apic);
967 975
968 /* 976 /*
969 * Debugging check, we are in big trouble if this message pops up! 977 * Debugging check, we are in big trouble if this message pops up!
@@ -971,17 +979,6 @@ static int pin_2_irq(int idx, int apic, int pin)
971 if (mp_irqs[idx].dstirq != pin) 979 if (mp_irqs[idx].dstirq != pin)
972 pr_err("broken BIOS or MPTABLE parser, ayiee!!\n"); 980 pr_err("broken BIOS or MPTABLE parser, ayiee!!\n");
973 981
974 if (test_bit(bus, mp_bus_not_pci)) {
975 irq = mp_irqs[idx].srcbusirq;
976 } else {
977 u32 gsi = gsi_cfg->gsi_base + pin;
978
979 if (gsi >= nr_legacy_irqs())
980 irq = gsi;
981 else
982 irq = gsi_top + gsi;
983 }
984
985#ifdef CONFIG_X86_32 982#ifdef CONFIG_X86_32
986 /* 983 /*
987 * PCI IRQ command line redirection. Yes, limits are hardcoded. 984 * PCI IRQ command line redirection. Yes, limits are hardcoded.
@@ -996,11 +993,17 @@ static int pin_2_irq(int idx, int apic, int pin)
996 apic_printk(APIC_VERBOSE, KERN_DEBUG 993 apic_printk(APIC_VERBOSE, KERN_DEBUG
997 "using PIRQ%d -> IRQ %d\n", 994 "using PIRQ%d -> IRQ %d\n",
998 pin-16, irq); 995 pin-16, irq);
996 return irq;
999 } 997 }
1000 } 998 }
1001 } 999 }
1002#endif 1000#endif
1003 1001
1002 if (test_bit(bus, mp_bus_not_pci))
1003 irq = mp_irqs[idx].srcbusirq;
1004 else
1005 irq = mp_map_gsi_to_irq(mp_pin_to_gsi(apic, pin));
1006
1004 return irq; 1007 return irq;
1005} 1008}
1006 1009