linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC
@ 2014-05-19 16:22 Jiang Liu
  2014-05-19 16:22 ` [Patch Part1 V2 01/29] x86, irq: update high address field when updating affinity for MSI IRQ Jiang Liu
                   ` (28 more replies)
  0 siblings, 29 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:22 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu
  Cc: Jiang Liu, Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck,
	Joerg Roedel, Paul Gortmaker, Greg Kroah-Hartman, x86,
	linux-kernel, linux-pci, linux-acpi

On x86 platforms, IRQ number are statically allocated to IOAPIC pins at boot.
There are two issues with this design. First it causes trouble to IOAPIC
hotplug because we need to allocate a block of IRQ numbers for each IOAPIC.
Second it may waste IRQ nubmers even if some IOAPIC pins are not used because
IRQ numbers are statically assigned.

This patchset tries to enable dynamic IRQ number allocation for IOAPIC
by adopting the irqdomain framework, it solves the two issues mentioned
above. It also simplifies the IOAPIC driver by consolidating ways to
program IOAPIC pins with the irqdomain map interface.

We will enhance the IOAPIC driver core to support ACPI based IOAPIC hotplug
once the IOAPIC driver has been converted to irqdomain.

This patchset applies to tip/irq/core and has been tested on a two socket 64
bit Intel platforms with:
1) ACPI and mpparse enabled (boot successfully)
2) Mpparse enabled with ACPI disabled (boot successfully)
3) ACPI enabled with Mpparse disabled (boot successfully)

It also builds successfully (but without booting due to hardware resource
constraints) for 32 bit platforms with following configuraitons:
1) IOAPIC diabled
2) SFI enabled
3) devicetree (CE4100) enabled

TODO list:
1) check whether it affects Xen or not

Patch 1 is simple bugfix for MSI.

Patch 2-16 are trivial code improvements, bugfixes and preparation.

Patch 17-23 enable basic irqdomain support and IRQ number dynamic
allocation.

Patch 24-28 consoldate the way to program IOAPIC pins by using
irqdomain map() interface.

Patch 29 cleans up unused interfaces and functions in IOAPIC driver.

Tests and comments are warmly welcomed!

V1->V2
1) Rebase to tip/irq/core
2) reorder patches to put bugfixes at the head
3) fix bug in handling shared ISA IRQs
4) refine commit messages

Jiang Liu (29):
  x86, irq: update high address field when updating affinity for MSI
    IRQ
  genirq, trivial: improve documentation to match current
    implementation
  x86, mpparse: use pr_lvl() helper utilities to replace
    printk(KERN_LVL)
  x86, mpparse: simplify arch/x86/include/asm/mpspec.h
  x86, PCI, ACPI: use kmalloc_node() to optimize for performance
  x86, acpi, irq: kill static function irq_to_gsi()
  x86, ACPI, trivial: minor improvements to arch/x86/kernel/acpi/boot.c
  x86, ACPI, irq: enhance error handling in function
    acpi_register_gsi()
  x86, ACPI, irq: fix possible eror in GSI to IRQ mapping for legacy
    IRQ
  x86, irq, trivial: minor improvements of IRQ related code
  x86, ioapic: kill unused global variable timer_through_8259
  x86, ioapic: kill static variable nr_irqs_gsi
  x86, ioapic: introduce helper utilities to walk ioapics and pins
  x86, ioapic: use irq_cfg() instead of irq_get_chip_data() for better
    readability
  x86, irq: reorganize IO_APIC_get_PCI_irq_vector() to prepare for
    irqdomain
  x86, irq: introduce some helper utilities to improve readability
  x86, ACPI, irq: consolidate algorithm of mapping (ioapic, pin) to IRQ
    number
  x86, irq: introduce mechanisms to support dynamically allocate IRQ
    for IOAPIC
  x86, irq: enhance mp_register_ioapic() to support irqdomain
  x86, ACPI, irq: provide basic irqdomain support
  x86, mpparse, irq: provide basic irqdomain support
  x86, devicetree, irq: use common mechanism to support irqdomain
  x86, SFI, irq: provide basic irqdomain support
  x86, irq: introduce two helper functions to support irqdomain map
    operation
  x86, irq, ACPI: use common irqdomain map interface to program IOAPIC
    pins
  x86, irq, mpparse: use common irqdomain map interface to program
    IOAPIC pins
  x86, irq, SFI: use common irqdomain map interface to program IOAPIC
    pins
  x86, irq, devicetree: use common irqdomain map interface to program
    IOAPIC pins
  x86, irq: clean up unused IOAPIC interface

 Documentation/IRQ-domain.txt      |    3 +-
 arch/x86/include/asm/apic.h       |    4 +-
 arch/x86/include/asm/hardirq.h    |    3 -
 arch/x86/include/asm/io_apic.h    |   45 ++--
 arch/x86/include/asm/mpspec.h     |   13 -
 arch/x86/include/asm/prom.h       |    2 -
 arch/x86/kernel/acpi/boot.c       |  205 +++++++-------
 arch/x86/kernel/apic/apic.c       |    2 +-
 arch/x86/kernel/apic/io_apic.c    |  536 ++++++++++++++++++++++---------------
 arch/x86/kernel/devicetree.c      |   92 +------
 arch/x86/kernel/irqinit.c         |    6 -
 arch/x86/kernel/mpparse.c         |   97 +++----
 arch/x86/pci/acpi.c               |    6 +-
 arch/x86/pci/intel_mid_pci.c      |   17 +-
 arch/x86/pci/irq.c                |    2 -
 arch/x86/platform/intel-mid/sfi.c |   18 +-
 arch/x86/platform/sfi/sfi.c       |   12 +-
 kernel/irq/internals.h            |    2 +-
 kernel/irq/irqdomain.c            |    6 +-
 19 files changed, 550 insertions(+), 521 deletions(-)

-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 01/29] x86, irq: update high address field when updating affinity for MSI IRQ
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
@ 2014-05-19 16:22 ` Jiang Liu
  2014-05-19 16:22 ` [Patch Part1 V2 02/29] genirq, trivial: improve documentation to match current implementation Jiang Liu
                   ` (27 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:22 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, x86, Jiang Liu
  Cc: Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck, Joerg Roedel,
	Paul Gortmaker, Greg Kroah-Hartman, linux-kernel, linux-pci,
	linux-acpi, Ingo Molnar

If x2apic is enabled, the MSI high address field should also be aslo
updated when setting affinity for MSI IRQ, otherwise the MSI IRQ may
target wrong APIC IDs.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/kernel/apic/io_apic.c |    4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 9d0a9795a0f8..2de992501a1b 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3007,6 +3007,10 @@ msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force)
 
 	__get_cached_msi_msg(data->msi_desc, &msg);
 
+	msg.address_hi = MSI_ADDR_BASE_HI;
+	if (x2apic_enabled())
+		msg.address_hi |= MSI_ADDR_EXT_DEST_ID(dest);
+
 	msg.data &= ~MSI_DATA_VECTOR_MASK;
 	msg.data |= MSI_DATA_VECTOR(cfg->vector);
 	msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 02/29] genirq, trivial: improve documentation to match current implementation
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
  2014-05-19 16:22 ` [Patch Part1 V2 01/29] x86, irq: update high address field when updating affinity for MSI IRQ Jiang Liu
@ 2014-05-19 16:22 ` Jiang Liu
  2014-05-19 16:22 ` [Patch Part1 V2 03/29] x86, mpparse: use pr_lvl() helper utilities to replace printk(KERN_LVL) Jiang Liu
                   ` (26 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:22 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, Jiri Kosina
  Cc: Jiang Liu, Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck,
	Joerg Roedel, Paul Gortmaker, Greg Kroah-Hartman, x86,
	linux-kernel, linux-pci, linux-acpi, linux-doc

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 Documentation/IRQ-domain.txt |    3 +--
 kernel/irq/internals.h       |    2 +-
 kernel/irq/irqdomain.c       |    6 +++---
 3 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/Documentation/IRQ-domain.txt b/Documentation/IRQ-domain.txt
index 03df71aeb38c..8a8b82c9ca53 100644
--- a/Documentation/IRQ-domain.txt
+++ b/Documentation/IRQ-domain.txt
@@ -41,8 +41,7 @@ An interrupt controller driver creates and registers an irq_domain by
 calling one of the irq_domain_add_*() functions (each mapping method
 has a different allocator function, more on that later).  The function
 will return a pointer to the irq_domain on success.  The caller must
-provide the allocator function with an irq_domain_ops structure with
-the .map callback populated as a minimum.
+provide the allocator function with an irq_domain_ops structure.
 
 In most cases, the irq_domain will begin empty without any mappings
 between hwirq and IRQ numbers.  Mappings are added to the irq_domain
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index c4065e3edbc3..099ea2e0eb88 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -33,7 +33,7 @@ enum {
 };
 
 /*
- * Bit masks for desc->state
+ * Bit masks for desc->core_internal_state__do_not_mess_with_it
  *
  * IRQS_AUTODETECT		- autodetection in progress
  * IRQS_SPURIOUS_DISABLED	- was disabled due to spurious interrupt
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index f14033700c25..eb5e10e32e05 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -27,14 +27,14 @@ static struct irq_domain *irq_default_domain;
  * __irq_domain_add() - Allocate a new irq_domain data structure
  * @of_node: optional device-tree node of the interrupt controller
  * @size: Size of linear map; 0 for radix mapping only
+ * @hwirq_max: Maximum number of interrupts supported by controller
  * @direct_max: Maximum value of direct maps; Use ~0 for no limit; 0 for no
  *              direct mapping
  * @ops: map/unmap domain callbacks
  * @host_data: Controller private data pointer
  *
- * Allocates and initialize and irq_domain structure.  Caller is expected to
- * register allocated irq_domain with irq_domain_register().  Returns pointer
- * to IRQ domain, or NULL on failure.
+ * Allocates and initialize and irq_domain structure.
+ * Returns pointer to IRQ domain, or NULL on failure.
  */
 struct irq_domain *__irq_domain_add(struct device_node *of_node, int size,
 				    irq_hw_number_t hwirq_max, int direct_max,
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 03/29] x86, mpparse: use pr_lvl() helper utilities to replace printk(KERN_LVL)
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
  2014-05-19 16:22 ` [Patch Part1 V2 01/29] x86, irq: update high address field when updating affinity for MSI IRQ Jiang Liu
  2014-05-19 16:22 ` [Patch Part1 V2 02/29] genirq, trivial: improve documentation to match current implementation Jiang Liu
@ 2014-05-19 16:22 ` Jiang Liu
  2014-05-19 16:22 ` [Patch Part1 V2 04/29] x86, mpparse: simplify arch/x86/include/asm/mpspec.h Jiang Liu
                   ` (25 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:22 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, x86, Jiang Liu
  Cc: Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck, Joerg Roedel,
	Paul Gortmaker, Greg Kroah-Hartman, linux-kernel, linux-pci,
	linux-acpi

Use pr_lvl() helper utilities to replace printk(KERN_LVL) for readability,
no function changes.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/kernel/mpparse.c |   84 +++++++++++++++++++++------------------------
 1 file changed, 39 insertions(+), 45 deletions(-)

diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index d2b56489d70f..24da837389b7 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -67,7 +67,7 @@ static void __init MP_processor_info(struct mpc_cpu *m)
 		boot_cpu_physical_apicid = m->apicid;
 	}
 
-	printk(KERN_INFO "Processor #%d%s\n", m->apicid, bootup_cpu);
+	pr_info("Processor #%d%s\n", m->apicid, bootup_cpu);
 	generic_processor_info(apicid, m->apicver);
 }
 
@@ -87,9 +87,8 @@ static void __init MP_bus_info(struct mpc_bus *m)
 
 #if MAX_MP_BUSSES < 256
 	if (m->busid >= MAX_MP_BUSSES) {
-		printk(KERN_WARNING "MP table busid value (%d) for bustype %s "
-		       " is too large, max. supported is %d\n",
-		       m->busid, str, MAX_MP_BUSSES - 1);
+		pr_warn("MP table busid value (%d) for bustype %s is too large, max. supported is %d\n",
+			m->busid, str, MAX_MP_BUSSES - 1);
 		return;
 	}
 #endif
@@ -110,7 +109,7 @@ static void __init MP_bus_info(struct mpc_bus *m)
 		mp_bus_id_to_type[m->busid] = MP_BUS_EISA;
 #endif
 	} else
-		printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str);
+		pr_warn("Unknown bustype %s - ignoring\n", str);
 }
 
 static void __init MP_ioapic_info(struct mpc_ioapic *m)
@@ -148,34 +147,33 @@ static int __init smp_check_mpc(struct mpc_table *mpc, char *oem, char *str)
 {
 
 	if (memcmp(mpc->signature, MPC_SIGNATURE, 4)) {
-		printk(KERN_ERR "MPTABLE: bad signature [%c%c%c%c]!\n",
+		pr_err("MPTABLE: bad signature [%c%c%c%c]!\n",
 		       mpc->signature[0], mpc->signature[1],
 		       mpc->signature[2], mpc->signature[3]);
 		return 0;
 	}
 	if (mpf_checksum((unsigned char *)mpc, mpc->length)) {
-		printk(KERN_ERR "MPTABLE: checksum error!\n");
+		pr_err("MPTABLE: checksum error!\n");
 		return 0;
 	}
 	if (mpc->spec != 0x01 && mpc->spec != 0x04) {
-		printk(KERN_ERR "MPTABLE: bad table version (%d)!!\n",
-		       mpc->spec);
+		pr_err("MPTABLE: bad table version (%d)!!\n", mpc->spec);
 		return 0;
 	}
 	if (!mpc->lapic) {
-		printk(KERN_ERR "MPTABLE: null local APIC address!\n");
+		pr_err("MPTABLE: null local APIC address!\n");
 		return 0;
 	}
 	memcpy(oem, mpc->oem, 8);
 	oem[8] = 0;
-	printk(KERN_INFO "MPTABLE: OEM ID: %s\n", oem);
+	pr_info("MPTABLE: OEM ID: %s\n", oem);
 
 	memcpy(str, mpc->productid, 12);
 	str[12] = 0;
 
-	printk(KERN_INFO "MPTABLE: Product ID: %s\n", str);
+	pr_info("MPTABLE: Product ID: %s\n", str);
 
-	printk(KERN_INFO "MPTABLE: APIC at: 0x%X\n", mpc->lapic);
+	pr_info("MPTABLE: APIC at: 0x%X\n", mpc->lapic);
 
 	return 1;
 }
@@ -188,8 +186,8 @@ static void skip_entry(unsigned char **ptr, int *count, int size)
 
 static void __init smp_dump_mptable(struct mpc_table *mpc, unsigned char *mpt)
 {
-	printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n"
-		"type %x\n", *mpt);
+	pr_err("Your mptable is wrong, contact your HW vendor!\ntype %x\n",
+	       *mpt);
 	print_hex_dump(KERN_ERR, "  ", DUMP_PREFIX_ADDRESS, 16,
 			1, mpc, mpc->length, 1);
 }
@@ -259,7 +257,7 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
 	}
 
 	if (!num_processors)
-		printk(KERN_ERR "MPTABLE: no processors registered!\n");
+		pr_err("MPTABLE: no processors registered!\n");
 	return num_processors;
 }
 
@@ -295,16 +293,13 @@ static void __init construct_default_ioirq_mptable(int mpc_default_type)
 	 *  If it does, we assume it's valid.
 	 */
 	if (mpc_default_type == 5) {
-		printk(KERN_INFO "ISA/PCI bus type with no IRQ information... "
-		       "falling back to ELCR\n");
+		pr_info("ISA/PCI bus type with no IRQ information... falling back to ELCR\n");
 
 		if (ELCR_trigger(0) || ELCR_trigger(1) || ELCR_trigger(2) ||
 		    ELCR_trigger(13))
-			printk(KERN_ERR "ELCR contains invalid data... "
-			       "not using ELCR\n");
+			pr_err("ELCR contains invalid data... not using ELCR\n");
 		else {
-			printk(KERN_INFO
-			       "Using ELCR to identify PCI interrupts\n");
+			pr_info("Using ELCR to identify PCI interrupts\n");
 			ELCR_fallback = 1;
 		}
 	}
@@ -353,7 +348,7 @@ static void __init construct_ioapic_table(int mpc_default_type)
 	bus.busid = 0;
 	switch (mpc_default_type) {
 	default:
-		printk(KERN_ERR "???\nUnknown standard configuration %d\n",
+		pr_err("???\nUnknown standard configuration %d\n",
 		       mpc_default_type);
 		/* fall through */
 	case 1:
@@ -462,7 +457,7 @@ static int __init check_physptr(struct mpf_intel *mpf, unsigned int early)
 #ifdef CONFIG_X86_LOCAL_APIC
 		smp_found_config = 0;
 #endif
-		printk(KERN_ERR "BIOS bug, MP table errors detected!...\n"
+		pr_err("BIOS bug, MP table errors detected!...\n"
 			"... disabling SMP support. (tell your hw vendor)\n");
 		early_iounmap(mpc, size);
 		return -1;
@@ -481,7 +476,7 @@ static int __init check_physptr(struct mpf_intel *mpf, unsigned int early)
 	if (!mp_irq_entries) {
 		struct mpc_bus bus;
 
-		printk(KERN_ERR "BIOS bug, no explicit IRQ entries, "
+		pr_err("BIOS bug, no explicit IRQ entries, "
 		       "using default mptable. (tell your hw vendor)\n");
 
 		bus.type = MP_BUS;
@@ -516,14 +511,14 @@ void __init default_get_smp_config(unsigned int early)
 	if (acpi_lapic && acpi_ioapic)
 		return;
 
-	printk(KERN_INFO "Intel MultiProcessor Specification v1.%d\n",
-	       mpf->specification);
+	pr_info("Intel MultiProcessor Specification v1.%d\n",
+		mpf->specification);
 #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_32)
 	if (mpf->feature2 & (1 << 7)) {
-		printk(KERN_INFO "    IMCR and PIC compatibility mode.\n");
+		pr_info("    IMCR and PIC compatibility mode.\n");
 		pic_mode = 1;
 	} else {
-		printk(KERN_INFO "    Virtual Wire compatibility mode.\n");
+		pr_info("    Virtual Wire compatibility mode.\n");
 		pic_mode = 0;
 	}
 #endif
@@ -539,8 +534,7 @@ void __init default_get_smp_config(unsigned int early)
 			return;
 		}
 
-		printk(KERN_INFO "Default MP configuration #%d\n",
-		       mpf->feature1);
+		pr_info("Default MP configuration #%d\n", mpf->feature1);
 		construct_default_ISA_mptable(mpf->feature1);
 
 	} else if (mpf->physptr) {
@@ -550,7 +544,7 @@ void __init default_get_smp_config(unsigned int early)
 		BUG();
 
 	if (!early)
-		printk(KERN_INFO "Processors: %d\n", num_processors);
+		pr_info("Processors: %d\n", num_processors);
 	/*
 	 * Only use the first configuration found.
 	 */
@@ -583,10 +577,10 @@ static int __init smp_scan_config(unsigned long base, unsigned long length)
 #endif
 			mpf_found = mpf;
 
-			printk(KERN_INFO "found SMP MP-table at [mem %#010llx-%#010llx] mapped at [%p]\n",
-			       (unsigned long long) virt_to_phys(mpf),
-			       (unsigned long long) virt_to_phys(mpf) +
-			       sizeof(*mpf) - 1, mpf);
+			pr_info("found SMP MP-table at [mem %#010llx-%#010llx] mapped at [%p]\n",
+				(unsigned long long) virt_to_phys(mpf),
+				(unsigned long long) virt_to_phys(mpf) +
+				sizeof(*mpf) - 1, mpf);
 
 			mem = virt_to_phys(mpf);
 			memblock_reserve(mem, sizeof(*mpf));
@@ -735,7 +729,7 @@ static int  __init replace_intsrc_all(struct mpc_table *mpc,
 	int nr_m_spare = 0;
 	unsigned char *mpt = ((unsigned char *)mpc) + count;
 
-	printk(KERN_INFO "mpc_length %x\n", mpc->length);
+	pr_info("mpc_length %x\n", mpc->length);
 	while (count < mpc->length) {
 		switch (*mpt) {
 		case MP_PROCESSOR:
@@ -862,13 +856,13 @@ static int __init update_mp_table(void)
 	if (!smp_check_mpc(mpc, oem, str))
 		return 0;
 
-	printk(KERN_INFO "mpf: %llx\n", (u64)virt_to_phys(mpf));
-	printk(KERN_INFO "physptr: %x\n", mpf->physptr);
+	pr_info("mpf: %llx\n", (u64)virt_to_phys(mpf));
+	pr_info("physptr: %x\n", mpf->physptr);
 
 	if (mpc_new_phys && mpc->length > mpc_new_length) {
 		mpc_new_phys = 0;
-		printk(KERN_INFO "mpc_new_length is %ld, please use alloc_mptable=8k\n",
-			 mpc_new_length);
+		pr_info("mpc_new_length is %ld, please use alloc_mptable=8k\n",
+			mpc_new_length);
 	}
 
 	if (!mpc_new_phys) {
@@ -879,10 +873,10 @@ static int __init update_mp_table(void)
 		mpc->checksum = 0xff;
 		new = mpf_checksum((unsigned char *)mpc, mpc->length);
 		if (old == new) {
-			printk(KERN_INFO "mpc is readonly, please try alloc_mptable instead\n");
+			pr_info("mpc is readonly, please try alloc_mptable instead\n");
 			return 0;
 		}
-		printk(KERN_INFO "use in-position replacing\n");
+		pr_info("use in-position replacing\n");
 	} else {
 		mpf->physptr = mpc_new_phys;
 		mpc_new = phys_to_virt(mpc_new_phys);
@@ -892,7 +886,7 @@ static int __init update_mp_table(void)
 		if (mpc_new_phys - mpf->physptr) {
 			struct mpf_intel *mpf_new;
 			/* steal 16 bytes from [0, 1k) */
-			printk(KERN_INFO "mpf new: %x\n", 0x400 - 16);
+			pr_info("mpf new: %x\n", 0x400 - 16);
 			mpf_new = phys_to_virt(0x400 - 16);
 			memcpy(mpf_new, mpf, 16);
 			mpf = mpf_new;
@@ -900,7 +894,7 @@ static int __init update_mp_table(void)
 		}
 		mpf->checksum = 0;
 		mpf->checksum -= mpf_checksum((unsigned char *)mpf, 16);
-		printk(KERN_INFO "physptr new: %x\n", mpf->physptr);
+		pr_info("physptr new: %x\n", mpf->physptr);
 	}
 
 	/*
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 04/29] x86, mpparse: simplify arch/x86/include/asm/mpspec.h
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (2 preceding siblings ...)
  2014-05-19 16:22 ` [Patch Part1 V2 03/29] x86, mpparse: use pr_lvl() helper utilities to replace printk(KERN_LVL) Jiang Liu
@ 2014-05-19 16:22 ` Jiang Liu
  2014-05-19 16:22 ` [Patch Part1 V2 05/29] x86, PCI, ACPI: use kmalloc_node() to optimize for performance Jiang Liu
                   ` (24 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:22 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, x86, Len Brown, Pavel Machek,
	David Rientjes, Seiji Aguchi, Jiang Liu, HATAYAMA Daisuke,
	Paul Gortmaker, Richard Weinberger, Andi Kleen
  Cc: Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck, Joerg Roedel,
	Greg Kroah-Hartman, linux-kernel, linux-pci, linux-acpi,
	Ingo Molnar, H. Peter Anvin, linux-pm

Simplify arch/x86/include/asm/mpspec.h by
1) Change max_physical_apicid to static as it's only used in apic.c.
2) Kill declaration of mpc_default_type, it's never defined.
3) Delete default_acpi_madt_oem_check(), it has already been declared
   in apic.h.
4) Change mp_override_legacy_irq(), mp_config_acpi_legacy_irqs() and
   mp_register_gsi() as static because they are only used in acpi/boot.c.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/include/asm/apic.h    |    4 ++--
 arch/x86/include/asm/io_apic.h |    3 ---
 arch/x86/include/asm/mpspec.h  |   13 -------------
 arch/x86/kernel/acpi/boot.c    |   12 +++++++++---
 arch/x86/kernel/apic/apic.c    |    2 +-
 5 files changed, 12 insertions(+), 22 deletions(-)

diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 19b0ebafcd3e..69ed79aa9085 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -502,8 +502,6 @@ static inline unsigned default_get_apic_id(unsigned long x)
 #define DEFAULT_TRAMPOLINE_PHYS_HIGH		0x469
 
 #ifdef CONFIG_X86_64
-extern int default_acpi_madt_oem_check(char *, char *);
-
 extern void apic_send_IPI_self(int vector);
 
 DECLARE_PER_CPU(int, x2apic_extra_bits);
@@ -552,6 +550,8 @@ static inline int default_apic_id_valid(int apicid)
 	return (apicid < 255);
 }
 
+extern int default_acpi_madt_oem_check(char *, char *);
+
 extern void default_setup_apic_routing(void);
 
 extern struct apic apic_noop;
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 90f97b4b9347..9121abbc8c8f 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -118,9 +118,6 @@ extern int mp_irq_entries;
 /* MP IRQ source entries */
 extern struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];
 
-/* non-0 if default (table-less) MP configuration */
-extern int mpc_default_type;
-
 /* Older SiS APIC requires we rewrite the index register */
 extern int sis_apic_bug;
 
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index f5a617956735..7bef40a01a1d 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -40,8 +40,6 @@ extern int mp_bus_id_to_type[MAX_MP_BUSSES];
 extern DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);
 
 extern unsigned int boot_cpu_physical_apicid;
-extern unsigned int max_physical_apicid;
-extern int mpc_default_type;
 extern unsigned long mp_lapic_addr;
 
 #ifdef CONFIG_X86_LOCAL_APIC
@@ -88,15 +86,6 @@ static inline void early_reserve_e820_mpc_new(void) { }
 #endif
 
 int generic_processor_info(int apicid, int version);
-#ifdef CONFIG_ACPI
-extern void mp_register_ioapic(int id, u32 address, u32 gsi_base);
-extern void mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
-				   u32 gsi);
-extern void mp_config_acpi_legacy_irqs(void);
-struct device;
-extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
-				 int active_high_low);
-#endif /* CONFIG_ACPI */
 
 #define PHYSID_ARRAY_SIZE	BITS_TO_LONGS(MAX_LOCAL_APIC)
 
@@ -163,6 +152,4 @@ extern physid_mask_t phys_cpu_present_map;
 
 extern int generic_mps_oem_check(struct mpc_table *, char *, char *);
 
-extern int default_acpi_madt_oem_check(char *, char *);
-
 #endif /* _ASM_X86_MPSPEC_H */
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 86281ffb96d6..b41b47021f53 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -345,6 +345,10 @@ acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long e
 #endif				/*CONFIG_X86_LOCAL_APIC */
 
 #ifdef CONFIG_X86_IO_APIC
+static void  mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
+				    u32 gsi);
+static int mp_register_gsi(struct device *dev, u32 gsi, int trigger,
+			   int polarity);
 
 static int __init
 acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end)
@@ -903,7 +907,8 @@ static int __init acpi_parse_madt_lapic_entries(void)
 #ifdef	CONFIG_X86_IO_APIC
 #define MP_ISA_BUS		0
 
-void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
+static void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
+					  u32 gsi)
 {
 	int ioapic;
 	int pin;
@@ -938,7 +943,7 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
 	isa_irq_to_gsi[bus_irq] = gsi;
 }
 
-void __init mp_config_acpi_legacy_irqs(void)
+static void __init mp_config_acpi_legacy_irqs(void)
 {
 	int i;
 	struct mpc_intsrc mp_irq;
@@ -1040,7 +1045,8 @@ static int mp_config_acpi_gsi(struct device *dev, u32 gsi, int trigger,
 	return 0;
 }
 
-int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
+static int mp_register_gsi(struct device *dev, u32 gsi, int trigger,
+			   int polarity)
 {
 	int ioapic;
 	int ioapic_pin;
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index ad28db7e6bde..ca1bd75e3de2 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -67,7 +67,7 @@ EXPORT_SYMBOL_GPL(boot_cpu_physical_apicid);
 /*
  * The highest APIC ID seen during enumeration.
  */
-unsigned int max_physical_apicid;
+static unsigned int max_physical_apicid;
 
 /*
  * Bitmask of physically existing CPUs:
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 05/29] x86, PCI, ACPI: use kmalloc_node() to optimize for performance
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (3 preceding siblings ...)
  2014-05-19 16:22 ` [Patch Part1 V2 04/29] x86, mpparse: simplify arch/x86/include/asm/mpspec.h Jiang Liu
@ 2014-05-19 16:22 ` Jiang Liu
  2014-05-19 16:22 ` [Patch Part1 V2 06/29] x86, acpi, irq: kill static function irq_to_gsi() Jiang Liu
                   ` (23 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:22 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, x86
  Cc: Jiang Liu, Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck,
	Joerg Roedel, Paul Gortmaker, Greg Kroah-Hartman, linux-kernel,
	linux-pci, linux-acpi

Use kmalloc_node() instead of kmalloc() when possible to optimize
for performance on NUMA platforms.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/pci/acpi.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 01edac6c5e18..91bef49df228 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -448,7 +448,7 @@ static void probe_pci_root_info(struct pci_root_info *info,
 		return;
 
 	size = sizeof(*info->res) * info->res_num;
-	info->res = kzalloc(size, GFP_KERNEL);
+	info->res = kzalloc_node(size, GFP_KERNEL, info->sd.node);
 	if (!info->res) {
 		info->res_num = 0;
 		return;
@@ -456,7 +456,7 @@ static void probe_pci_root_info(struct pci_root_info *info,
 
 	size = sizeof(*info->res_offset) * info->res_num;
 	info->res_num = 0;
-	info->res_offset = kzalloc(size, GFP_KERNEL);
+	info->res_offset = kzalloc_node(size, GFP_KERNEL, info->sd.node);
 	if (!info->res_offset) {
 		kfree(info->res);
 		info->res = NULL;
@@ -495,7 +495,7 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
 	if (node != NUMA_NO_NODE && !node_online(node))
 		node = NUMA_NO_NODE;
 
-	info = kzalloc(sizeof(*info), GFP_KERNEL);
+	info = kzalloc_node(sizeof(*info), GFP_KERNEL, node);
 	if (!info) {
 		printk(KERN_WARNING "pci_bus %04x:%02x: "
 		       "ignored (out of memory)\n", domain, busnum);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 06/29] x86, acpi, irq: kill static function irq_to_gsi()
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (4 preceding siblings ...)
  2014-05-19 16:22 ` [Patch Part1 V2 05/29] x86, PCI, ACPI: use kmalloc_node() to optimize for performance Jiang Liu
@ 2014-05-19 16:22 ` Jiang Liu
  2014-05-19 16:22 ` [Patch Part1 V2 07/29] x86, ACPI, trivial: minor improvements to arch/x86/kernel/acpi/boot.c Jiang Liu
                   ` (22 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:22 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, Len Brown, Pavel Machek, x86
  Cc: Jiang Liu, Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck,
	Joerg Roedel, Paul Gortmaker, Greg Kroah-Hartman, linux-kernel,
	linux-pci, linux-acpi, linux-pm

Static function irq_to_gsi() is only called by acpi_isa_irq_to_gsi(),
so kill function irq_to_gsi() and simplify acpi_isa_irq_to_gsi().

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/kernel/acpi/boot.c |   26 ++++++--------------------
 1 file changed, 6 insertions(+), 20 deletions(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index b41b47021f53..8390db1f7a93 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -120,22 +120,6 @@ static unsigned int gsi_to_irq(unsigned int gsi)
 	return irq;
 }
 
-static u32 irq_to_gsi(int irq)
-{
-	unsigned int gsi;
-
-	if (irq < NR_IRQS_LEGACY)
-		gsi = isa_irq_to_gsi[irq];
-	else if (irq < gsi_top)
-		gsi = irq;
-	else if (irq < (gsi_top + NR_IRQS_LEGACY))
-		gsi = irq - gsi_top;
-	else
-		gsi = 0xffffffff;
-
-	return gsi;
-}
-
 /*
  * This is just a simple wrapper around early_ioremap(),
  * with sanity checks for phys == 0 and size == 0.
@@ -527,10 +511,12 @@ EXPORT_SYMBOL_GPL(acpi_gsi_to_irq);
 
 int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
 {
-	if (isa_irq >= 16)
-		return -1;
-	*gsi = irq_to_gsi(isa_irq);
-	return 0;
+	if (isa_irq < NR_IRQS_LEGACY) {
+		*gsi = isa_irq_to_gsi[isa_irq];
+		return 0;
+	}
+
+	return -1;
 }
 
 static int acpi_register_gsi_pic(struct device *dev, u32 gsi,
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 07/29] x86, ACPI, trivial: minor improvements to arch/x86/kernel/acpi/boot.c
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (5 preceding siblings ...)
  2014-05-19 16:22 ` [Patch Part1 V2 06/29] x86, acpi, irq: kill static function irq_to_gsi() Jiang Liu
@ 2014-05-19 16:22 ` Jiang Liu
  2014-05-19 16:22 ` [Patch Part1 V2 08/29] x86, ACPI, irq: enhance error handling in function acpi_register_gsi() Jiang Liu
                   ` (21 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:22 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, Len Brown, Pavel Machek, x86,
	Jiri Kosina
  Cc: Jiang Liu, Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck,
	Joerg Roedel, Paul Gortmaker, Greg Kroah-Hartman, linux-kernel,
	linux-pci, linux-acpi, linux-pm

1) Remove out-of-date comment
2) Kill unused function acpi_set_irq_model_pic()
3) Use NR_IRQS_LEGACY instead of hard-coded 16
4) Trivial syntax improvements

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/kernel/acpi/boot.c |   50 ++++++++++++++-----------------------------
 1 file changed, 16 insertions(+), 34 deletions(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 8390db1f7a93..6d65850f49e9 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -370,11 +370,6 @@ static void __init acpi_sci_ioapic_setup(u8 bus_irq, u16 polarity, u16 trigger,
 	if (acpi_sci_flags & ACPI_MADT_POLARITY_MASK)
 		polarity = acpi_sci_flags & ACPI_MADT_POLARITY_MASK;
 
-	/*
-	 * mp_config_acpi_legacy_irqs() already setup IRQs < 16
-	 * If GSI is < 16, this will update its flags,
-	 * else it will create a new mp_irqs[] entry.
-	 */
 	mp_override_legacy_irq(bus_irq, polarity, trigger, gsi);
 
 	/*
@@ -573,14 +568,7 @@ void acpi_unregister_gsi(u32 gsi)
 }
 EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
 
-void __init acpi_set_irq_model_pic(void)
-{
-	acpi_irq_model = ACPI_IRQ_MODEL_PIC;
-	__acpi_register_gsi = acpi_register_gsi_pic;
-	acpi_ioapic = 0;
-}
-
-void __init acpi_set_irq_model_ioapic(void)
+static void __init acpi_set_irq_model_ioapic(void)
 {
 	acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
 	__acpi_register_gsi = acpi_register_gsi_ioapic;
@@ -819,9 +807,8 @@ static int __init early_acpi_parse_madt_lapic_addr_ovr(void)
 	 * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value).
 	 */
 
-	count =
-	    acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE,
-				  acpi_parse_lapic_addr_ovr, 0);
+	count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE,
+				      acpi_parse_lapic_addr_ovr, 0);
 	if (count < 0) {
 		printk(KERN_ERR PREFIX
 		       "Error parsing LAPIC address override entry\n");
@@ -846,9 +833,8 @@ static int __init acpi_parse_madt_lapic_entries(void)
 	 * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value).
 	 */
 
-	count =
-	    acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE,
-				  acpi_parse_lapic_addr_ovr, 0);
+	count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE,
+				      acpi_parse_lapic_addr_ovr, 0);
 	if (count < 0) {
 		printk(KERN_ERR PREFIX
 		       "Error parsing LAPIC address override entry\n");
@@ -876,11 +862,10 @@ static int __init acpi_parse_madt_lapic_entries(void)
 		return count;
 	}
 
-	x2count =
-	    acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC_NMI,
-				  acpi_parse_x2apic_nmi, 0);
-	count =
-	    acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI, acpi_parse_lapic_nmi, 0);
+	x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC_NMI,
+					acpi_parse_x2apic_nmi, 0);
+	count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI,
+				      acpi_parse_lapic_nmi, 0);
 	if (count < 0 || x2count < 0) {
 		printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
 		/* TBD: Cleanup to allow fallback to MPS */
@@ -947,7 +932,7 @@ static void __init mp_config_acpi_legacy_irqs(void)
 	 * Use the default configuration for the IRQs 0-15.  Unless
 	 * overridden by (MADT) interrupt source override entries.
 	 */
-	for (i = 0; i < 16; i++) {
+	for (i = 0; i < NR_IRQS_LEGACY; i++) {
 		int ioapic, pin;
 		unsigned int dstapic;
 		int idx;
@@ -1103,9 +1088,8 @@ static int __init acpi_parse_madt_ioapic_entries(void)
 		return -ENODEV;
 	}
 
-	count =
-	    acpi_table_parse_madt(ACPI_MADT_TYPE_IO_APIC, acpi_parse_ioapic,
-				  MAX_IO_APICS);
+	count = acpi_table_parse_madt(ACPI_MADT_TYPE_IO_APIC, acpi_parse_ioapic,
+				      MAX_IO_APICS);
 	if (!count) {
 		printk(KERN_ERR PREFIX "No IOAPIC entries present\n");
 		return -ENODEV;
@@ -1114,9 +1098,8 @@ static int __init acpi_parse_madt_ioapic_entries(void)
 		return count;
 	}
 
-	count =
-	    acpi_table_parse_madt(ACPI_MADT_TYPE_INTERRUPT_OVERRIDE, acpi_parse_int_src_ovr,
-				  nr_irqs);
+	count = acpi_table_parse_madt(ACPI_MADT_TYPE_INTERRUPT_OVERRIDE,
+				      acpi_parse_int_src_ovr, nr_irqs);
 	if (count < 0) {
 		printk(KERN_ERR PREFIX
 		       "Error parsing interrupt source overrides entry\n");
@@ -1135,9 +1118,8 @@ static int __init acpi_parse_madt_ioapic_entries(void)
 	/* Fill in identity legacy mappings where no override */
 	mp_config_acpi_legacy_irqs();
 
-	count =
-	    acpi_table_parse_madt(ACPI_MADT_TYPE_NMI_SOURCE, acpi_parse_nmi_src,
-				  nr_irqs);
+	count = acpi_table_parse_madt(ACPI_MADT_TYPE_NMI_SOURCE,
+				      acpi_parse_nmi_src, nr_irqs);
 	if (count < 0) {
 		printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
 		/* TBD: Cleanup to allow fallback to MPS */
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 08/29] x86, ACPI, irq: enhance error handling in function acpi_register_gsi()
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (6 preceding siblings ...)
  2014-05-19 16:22 ` [Patch Part1 V2 07/29] x86, ACPI, trivial: minor improvements to arch/x86/kernel/acpi/boot.c Jiang Liu
@ 2014-05-19 16:22 ` Jiang Liu
  2014-05-19 16:22 ` [Patch Part1 V2 09/29] x86, ACPI, irq: fix possible eror in GSI to IRQ mapping for legacy IRQ Jiang Liu
                   ` (20 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:22 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, Len Brown, Pavel Machek, x86
  Cc: Jiang Liu, Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck,
	Joerg Roedel, Paul Gortmaker, Greg Kroah-Hartman, linux-kernel,
	linux-pci, linux-acpi, linux-pm

Function mp_register_gsi() may return invalid GSI if error happens,
so enhance acpi_register_gsi() to handle possible error cases.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/kernel/acpi/boot.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 6d65850f49e9..8b8ff786af12 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -97,6 +97,8 @@ static u32 isa_irq_to_gsi[NR_IRQS_LEGACY] __read_mostly = {
 	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
 };
 
+#define	ACPI_INVALID_GSI		INT_MIN
+
 static unsigned int gsi_to_irq(unsigned int gsi)
 {
 	unsigned int irq = gsi + NR_IRQS_LEGACY;
@@ -553,13 +555,13 @@ int (*acpi_suspend_lowlevel)(void);
  */
 int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
 {
-	unsigned int irq;
 	unsigned int plat_gsi = gsi;
 
 	plat_gsi = (*__acpi_register_gsi)(dev, gsi, trigger, polarity);
-	irq = gsi_to_irq(plat_gsi);
+	if (plat_gsi != ACPI_INVALID_GSI)
+		return gsi_to_irq(plat_gsi);
 
-	return irq;
+	return -1;
 }
 EXPORT_SYMBOL_GPL(acpi_register_gsi);
 
@@ -1054,7 +1056,7 @@ static int mp_register_gsi(struct device *dev, u32 gsi, int trigger,
 			     polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
 	ret = io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr);
 	if (ret < 0)
-		gsi = INT_MIN;
+		gsi = ACPI_INVALID_GSI;
 
 	return gsi;
 }
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 09/29] x86, ACPI, irq: fix possible eror in GSI to IRQ mapping for legacy IRQ
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (7 preceding siblings ...)
  2014-05-19 16:22 ` [Patch Part1 V2 08/29] x86, ACPI, irq: enhance error handling in function acpi_register_gsi() Jiang Liu
@ 2014-05-19 16:22 ` Jiang Liu
  2014-05-19 16:22 ` [Patch Part1 V2 10/29] x86, irq, trivial: minor improvements of IRQ related code Jiang Liu
                   ` (19 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:22 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, Len Brown, Pavel Machek, x86
  Cc: Jiang Liu, Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck,
	Joerg Roedel, Paul Gortmaker, Greg Kroah-Hartman, linux-kernel,
	linux-pci, linux-acpi, linux-pm

A default identity mapping between GSI and IRQ is built for legacy IRQs.
So when overriding the default identity mapping for legacy IRQs,
we should also invalidate isa_irq_to_gsi[gsi] when setting
isa_irq_to_gsi[irq] = gsi.  Otherwise there may be two entries with the
same GSI in the isa_irq_to_gsi array, and acpi_isa_irq_to_gsi() may give
wrong result.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/kernel/acpi/boot.c |   10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 8b8ff786af12..dccf9e88db30 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -508,7 +508,8 @@ EXPORT_SYMBOL_GPL(acpi_gsi_to_irq);
 
 int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
 {
-	if (isa_irq < NR_IRQS_LEGACY) {
+	if (isa_irq < NR_IRQS_LEGACY &&
+	    isa_irq_to_gsi[isa_irq] != ACPI_INVALID_GSI) {
 		*gsi = isa_irq_to_gsi[isa_irq];
 		return 0;
 	}
@@ -913,6 +914,13 @@ static void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
 
 	mp_save_irq(&mp_irq);
 
+	/*
+	 * Reset default identity mapping if gsi is also an legacy IRQ,
+	 * otherwise there will be more than one entry with the same GSI
+	 * and acpi_isa_irq_to_gsi() may give wrong result.
+	 */
+	if (gsi < NR_IRQS_LEGACY && isa_irq_to_gsi[gsi] == gsi)
+		isa_irq_to_gsi[gsi] = ACPI_INVALID_GSI;
 	isa_irq_to_gsi[bus_irq] = gsi;
 }
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 10/29] x86, irq, trivial: minor improvements of IRQ related code
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (8 preceding siblings ...)
  2014-05-19 16:22 ` [Patch Part1 V2 09/29] x86, ACPI, irq: fix possible eror in GSI to IRQ mapping for legacy IRQ Jiang Liu
@ 2014-05-19 16:22 ` Jiang Liu
  2014-05-19 16:22 ` [Patch Part1 V2 11/29] x86, ioapic: kill unused global variable timer_through_8259 Jiang Liu
                   ` (18 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:22 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, x86, Jiri Kosina, Jiang Liu
  Cc: Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck, Joerg Roedel,
	Paul Gortmaker, Greg Kroah-Hartman, linux-kernel, linux-pci,
	linux-acpi, Ingo Molnar

1) Kill unused MAX_HARDIRQS_PER_CPU.
2) Improve function prototype declararions.
3) simple typo fix, change "gsit" to "gsi".
4) use macro VECTOR_UNDEFINED instead of hard-coded -1.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/include/asm/hardirq.h |    3 ---
 arch/x86/include/asm/io_apic.h |   16 +++++++---------
 arch/x86/kernel/apic/io_apic.c |   10 +++++-----
 3 files changed, 12 insertions(+), 17 deletions(-)

diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index 230853da4ec0..0f5fb6b6567e 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -40,9 +40,6 @@ typedef struct {
 
 DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
 
-/* We can have at most NR_VECTORS irqs routed to a cpu at a time */
-#define MAX_HARDIRQS_PER_CPU NR_VECTORS
-
 #define __ARCH_IRQ_STAT
 
 #define inc_irq_stat(member)	this_cpu_inc(irq_stat.member)
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 9121abbc8c8f..8dd1e13f2989 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -144,22 +144,20 @@ struct io_apic_irq_attr;
 struct irq_cfg;
 extern int io_apic_set_pci_routing(struct device *dev, int irq,
 		 struct io_apic_irq_attr *irq_attr);
-void setup_IO_APIC_irq_extra(u32 gsi);
+extern void setup_IO_APIC_irq_extra(u32 gsi);
 extern void ioapic_insert_resources(void);
 
 extern int native_setup_ioapic_entry(int, struct IO_APIC_route_entry *,
 				     unsigned int, int,
 				     struct io_apic_irq_attr *);
-extern int native_setup_ioapic_entry(int, struct IO_APIC_route_entry *,
-				     unsigned int, int,
-				     struct io_apic_irq_attr *);
 extern void eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg);
 
 extern void native_compose_msi_msg(struct pci_dev *pdev,
 				   unsigned int irq, unsigned int dest,
 				   struct msi_msg *msg, u8 hpet_id);
 extern void native_eoi_ioapic_pin(int apic, int pin, int vector);
-int io_apic_setup_irq_pin_once(unsigned int irq, int node, struct io_apic_irq_attr *attr);
+extern int io_apic_setup_irq_pin_once(unsigned int irq, int node,
+				      struct io_apic_irq_attr *attr);
 
 extern int save_ioapic_entries(void);
 extern void mask_ioapic_entries(void);
@@ -172,11 +170,11 @@ struct mp_ioapic_gsi{
 	u32 gsi_base;
 	u32 gsi_end;
 };
-extern struct mp_ioapic_gsi  mp_gsi_routing[];
 extern u32 gsi_top;
-int mp_find_ioapic(u32 gsi);
-int mp_find_ioapic_pin(int ioapic, u32 gsi);
-void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
+
+extern int mp_find_ioapic(u32 gsi);
+extern int mp_find_ioapic_pin(int ioapic, u32 gsi);
+extern void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
 extern void __init pre_init_apic_IRQ0(void);
 
 extern void mp_save_irq(struct mpc_intsrc *m);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 2de992501a1b..4d7d46650faa 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1010,7 +1010,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,
 				break;
 
 		if (!test_bit(lbus, mp_bus_not_pci) &&
-		    !mp_irqs[i].irqtype &&
+		    mp_irqs[i].irqtype == mp_INT &&
 		    (bus == lbus) &&
 		    (slot == ((mp_irqs[i].srcbusirq >> 2) & 0x1f))) {
 			int irq = pin_2_irq(i, ioapic_idx, mp_irqs[i].dstirq);
@@ -1359,7 +1359,7 @@ static void __init __io_apic_setup_irqs(unsigned int ioapic_idx)
 
 		irq = pin_2_irq(idx, ioapic_idx, pin);
 
-		if ((ioapic_idx > 0) && (irq > 16))
+		if ((ioapic_idx > 0) && (irq > NR_IRQS_LEGACY))
 			continue;
 
 		/*
@@ -1388,7 +1388,7 @@ static void __init setup_IO_APIC_irqs(void)
 }
 
 /*
- * for the gsit that is not in first ioapic
+ * for the gsi that is not in first ioapic
  * but could not use acpi_register_gsi()
  * like some special sci in IBM x3330
  */
@@ -2225,7 +2225,7 @@ asmlinkage __visible void smp_irq_move_cleanup_interrupt(void)
 			apic->send_IPI_self(IRQ_MOVE_CLEANUP_VECTOR);
 			goto unlock;
 		}
-		__this_cpu_write(vector_irq[vector], -1);
+		__this_cpu_write(vector_irq[vector], VECTOR_UNDEFINED);
 unlock:
 		raw_spin_unlock(&desc->lock);
 	}
@@ -3546,7 +3546,7 @@ void __init setup_ioapic_dest(void)
 			continue;
 		irq = pin_2_irq(irq_entry, ioapic, pin);
 
-		if ((ioapic > 0) && (irq > 16))
+		if ((ioapic > 0) && (irq > NR_IRQS_LEGACY))
 			continue;
 
 		idata = irq_get_irq_data(irq);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 11/29] x86, ioapic: kill unused global variable timer_through_8259
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (9 preceding siblings ...)
  2014-05-19 16:22 ` [Patch Part1 V2 10/29] x86, irq, trivial: minor improvements of IRQ related code Jiang Liu
@ 2014-05-19 16:22 ` Jiang Liu
  2014-05-19 16:22 ` [Patch Part1 V2 12/29] x86, ioapic: kill static variable nr_irqs_gsi Jiang Liu
                   ` (17 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:22 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, x86, Jiang Liu
  Cc: Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck, Joerg Roedel,
	Paul Gortmaker, Greg Kroah-Hartman, linux-kernel, linux-pci,
	linux-acpi, Ingo Molnar

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/include/asm/io_apic.h |    4 ----
 arch/x86/kernel/apic/io_apic.c |    3 ---
 2 files changed, 7 deletions(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 8dd1e13f2989..de3d8b04cf64 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -130,9 +130,6 @@ extern int noioapicquirk;
 /* -1 if "noapic" boot option passed */
 extern int noioapicreroute;
 
-/* 1 if the timer IRQ uses the '8259A Virtual Wire' mode */
-extern int timer_through_8259;
-
 /*
  * If we use the IO-APIC for IRQ routing, disable automatic
  * assignment of PCI IRQ's.
@@ -212,7 +209,6 @@ extern void io_apic_eoi(unsigned int apic, unsigned int vector);
 
 #define io_apic_assign_pci_irqs 0
 #define setup_ioapic_ids_from_mpc x86_init_noop
-static const int timer_through_8259 = 0;
 static inline void ioapic_insert_resources(void) { }
 #define gsi_top (NR_IRQS_LEGACY)
 static inline int mp_find_ioapic(u32 gsi) { return 0; }
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 4d7d46650faa..e8dd12a04cea 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2649,8 +2649,6 @@ static int __init disable_timer_pin_setup(char *arg)
 }
 early_param("disable_timer_pin_1", disable_timer_pin_setup);
 
-int timer_through_8259 __initdata;
-
 /*
  * This code may look a bit paranoid, but it's supposed to cooperate with
  * a wide range of boards and BIOS bugs.  Fortunately only the timer IRQ
@@ -2755,7 +2753,6 @@ static inline void __init check_timer(void)
 		legacy_pic->unmask(0);
 		if (timer_irq_works()) {
 			apic_printk(APIC_QUIET, KERN_INFO "....... works.\n");
-			timer_through_8259 = 1;
 			goto out;
 		}
 		/*
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 12/29] x86, ioapic: kill static variable nr_irqs_gsi
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (10 preceding siblings ...)
  2014-05-19 16:22 ` [Patch Part1 V2 11/29] x86, ioapic: kill unused global variable timer_through_8259 Jiang Liu
@ 2014-05-19 16:22 ` Jiang Liu
  2014-05-19 16:22 ` [Patch Part1 V2 13/29] x86, ioapic: introduce helper utilities to walk ioapics and pins Jiang Liu
                   ` (16 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:22 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, x86, Jiang Liu
  Cc: Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck, Joerg Roedel,
	Paul Gortmaker, Greg Kroah-Hartman, linux-kernel, linux-pci,
	linux-acpi, Ingo Molnar

Static variable nr_irqs_gsi is used to maintain the lowest dynamic
allocatable IRQ number. It may cause trouble when enabling dynamic
IRQ allocation for IOAPIC, so use arch_dynirq_lower_bound() to
avoid directly accessing nr_irqs_gsi and kill nr_irqs_gsi.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/kernel/apic/io_apic.c |   24 +++++-------------------
 1 file changed, 5 insertions(+), 19 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index e8dd12a04cea..397fb9a02e11 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -118,9 +118,6 @@ struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];
 /* # of MP IRQ source entries */
 int mp_irq_entries;
 
-/* GSI interrupts */
-static int nr_irqs_gsi = NR_IRQS_LEGACY;
-
 #ifdef CONFIG_EISA
 int mp_bus_id_to_type[MAX_MP_BUSSES];
 #endif
@@ -3333,20 +3330,11 @@ static int __init io_apic_get_redir_entries(int ioapic)
 	return reg_01.bits.entries + 1;
 }
 
-static void __init probe_nr_irqs_gsi(void)
-{
-	int nr;
-
-	nr = gsi_top + NR_IRQS_LEGACY;
-	if (nr > nr_irqs_gsi)
-		nr_irqs_gsi = nr;
-
-	printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
-}
-
 unsigned int arch_dynirq_lower_bound(unsigned int from)
 {
-	return from < nr_irqs_gsi ? nr_irqs_gsi : from;
+	unsigned int min = gsi_top + NR_IRQS_LEGACY;
+
+	return from < min ? min : from;
 }
 
 int __init arch_probe_nr_irqs(void)
@@ -3356,12 +3344,12 @@ int __init arch_probe_nr_irqs(void)
 	if (nr_irqs > (NR_VECTORS * nr_cpu_ids))
 		nr_irqs = NR_VECTORS * nr_cpu_ids;
 
-	nr = nr_irqs_gsi + 8 * nr_cpu_ids;
+	nr = (gsi_top + NR_IRQS_LEGACY) + 8 * nr_cpu_ids;
 #if defined(CONFIG_PCI_MSI) || defined(CONFIG_HT_IRQ)
 	/*
 	 * for MSI and HT dyn irq
 	 */
-	nr += nr_irqs_gsi * 16;
+	nr += (gsi_top + NR_IRQS_LEGACY) * 16;
 #endif
 	if (nr < nr_irqs)
 		nr_irqs = nr;
@@ -3634,8 +3622,6 @@ fake_ioapic_page:
 		ioapic_res->end = ioapic_phys + IO_APIC_SLOT_SIZE - 1;
 		ioapic_res++;
 	}
-
-	probe_nr_irqs_gsi();
 }
 
 void __init ioapic_insert_resources(void)
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 13/29] x86, ioapic: introduce helper utilities to walk ioapics and pins
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (11 preceding siblings ...)
  2014-05-19 16:22 ` [Patch Part1 V2 12/29] x86, ioapic: kill static variable nr_irqs_gsi Jiang Liu
@ 2014-05-19 16:22 ` Jiang Liu
  2014-05-19 16:22 ` [Patch Part1 V2 14/29] x86, ioapic: use irq_cfg() instead of irq_get_chip_data() for better readability Jiang Liu
                   ` (15 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:22 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, x86, Jiang Liu
  Cc: Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck, Joerg Roedel,
	Paul Gortmaker, Greg Kroah-Hartman, linux-kernel, linux-pci,
	linux-acpi, Ingo Molnar

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>
---
 arch/x86/kernel/apic/io_apic.c |  120 +++++++++++++++++++++-------------------
 1 file changed, 62 insertions(+), 58 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 397fb9a02e11..55fb3c1385c5 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -62,6 +62,16 @@
 
 #define __apicdebuginit(type) static type __init
 
+#define	for_each_ioapic(idx)		\
+	for ((idx) = 0; (idx) < nr_ioapics; (idx)++)
+#define	for_each_ioapic_reverse(idx)	\
+	for ((idx) = nr_ioapics - 1; (idx) >= 0; (idx)--)
+#define	for_each_pin(idx, pin)		\
+	for ((pin) = 0; (pin) < ioapics[(idx)].nr_registers; (pin)++)
+#define	for_each_ioapic_pin(idx, pin)	\
+	for_each_ioapic((idx))		\
+		for_each_pin((idx), (pin))
+
 #define for_each_irq_pin(entry, head) \
 	for (entry = head; entry; entry = entry->next)
 
@@ -191,7 +201,7 @@ int __init arch_early_irq_init(void)
 	if (!legacy_pic->nr_legacy_irqs)
 		io_apic_irqs = ~0UL;
 
-	for (i = 0; i < nr_ioapics; i++) {
+	for_each_ioapic(i) {
 		ioapics[i].saved_registers =
 			kzalloc(sizeof(struct IO_APIC_route_entry) *
 				ioapics[i].nr_registers, GFP_KERNEL);
@@ -624,9 +634,8 @@ static void clear_IO_APIC (void)
 {
 	int apic, pin;
 
-	for (apic = 0; apic < nr_ioapics; apic++)
-		for (pin = 0; pin < ioapics[apic].nr_registers; pin++)
-			clear_IO_APIC_pin(apic, pin);
+	for_each_ioapic_pin(apic, pin)
+		clear_IO_APIC_pin(apic, pin);
 }
 
 #ifdef CONFIG_X86_32
@@ -675,13 +684,13 @@ int save_ioapic_entries(void)
 	int apic, pin;
 	int err = 0;
 
-	for (apic = 0; apic < nr_ioapics; apic++) {
+	for_each_ioapic(apic) {
 		if (!ioapics[apic].saved_registers) {
 			err = -ENOMEM;
 			continue;
 		}
 
-		for (pin = 0; pin < ioapics[apic].nr_registers; pin++)
+		for_each_pin(apic, pin)
 			ioapics[apic].saved_registers[pin] =
 				ioapic_read_entry(apic, pin);
 	}
@@ -696,11 +705,11 @@ void mask_ioapic_entries(void)
 {
 	int apic, pin;
 
-	for (apic = 0; apic < nr_ioapics; apic++) {
+	for_each_ioapic(apic) {
 		if (!ioapics[apic].saved_registers)
 			continue;
 
-		for (pin = 0; pin < ioapics[apic].nr_registers; pin++) {
+		for_each_pin(apic, pin) {
 			struct IO_APIC_route_entry entry;
 
 			entry = ioapics[apic].saved_registers[pin];
@@ -719,11 +728,11 @@ int restore_ioapic_entries(void)
 {
 	int apic, pin;
 
-	for (apic = 0; apic < nr_ioapics; apic++) {
+	for_each_ioapic(apic) {
 		if (!ioapics[apic].saved_registers)
 			continue;
 
-		for (pin = 0; pin < ioapics[apic].nr_registers; pin++)
+		for_each_pin(apic, pin)
 			ioapic_write_entry(apic, pin,
 					   ioapics[apic].saved_registers[pin]);
 	}
@@ -782,7 +791,7 @@ static int __init find_isa_irq_apic(int irq, int type)
 	if (i < mp_irq_entries) {
 		int ioapic_idx;
 
-		for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++)
+		for_each_ioapic(ioapic_idx)
 			if (mpc_ioapic_id(ioapic_idx) == mp_irqs[i].dstapic)
 				return ioapic_idx;
 	}
@@ -1001,7 +1010,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,
 	for (i = 0; i < mp_irq_entries; i++) {
 		int lbus = mp_irqs[i].srcbus;
 
-		for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++)
+		for_each_ioapic(ioapic_idx)
 			if (mpc_ioapic_id(ioapic_idx) == mp_irqs[i].dstapic ||
 			    mp_irqs[i].dstapic == MP_APIC_ALL)
 				break;
@@ -1224,12 +1233,10 @@ static inline int IO_APIC_irq_trigger(int irq)
 {
 	int apic, idx, pin;
 
-	for (apic = 0; apic < nr_ioapics; apic++) {
-		for (pin = 0; pin < ioapics[apic].nr_registers; pin++) {
-			idx = find_irq_entry(apic, pin, mp_INT);
-			if ((idx != -1) && (irq == pin_2_irq(idx, apic, pin)))
-				return irq_trigger(idx);
-		}
+	for_each_ioapic_pin(apic, pin) {
+		idx = find_irq_entry(apic, pin, mp_INT);
+		if ((idx != -1) && (irq == pin_2_irq(idx, apic, pin)))
+			return irq_trigger(idx);
 	}
 	/*
          * nonexistent IRQs are edge default
@@ -1349,7 +1356,7 @@ static void __init __io_apic_setup_irqs(unsigned int ioapic_idx)
 	struct io_apic_irq_attr attr;
 	unsigned int pin, irq;
 
-	for (pin = 0; pin < ioapics[ioapic_idx].nr_registers; pin++) {
+	for_each_pin(ioapic_idx, pin) {
 		idx = find_irq_entry(ioapic_idx, pin, mp_INT);
 		if (io_apic_pin_not_connected(idx, ioapic_idx, pin))
 			continue;
@@ -1380,7 +1387,7 @@ static void __init setup_IO_APIC_irqs(void)
 
 	apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
 
-	for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++)
+	for_each_ioapic(ioapic_idx)
 		__io_apic_setup_irqs(ioapic_idx);
 }
 
@@ -1583,7 +1590,7 @@ __apicdebuginit(void) print_IO_APICs(void)
 	struct irq_chip *chip;
 
 	printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
-	for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++)
+	for_each_ioapic(ioapic_idx)
 		printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n",
 		       mpc_ioapic_id(ioapic_idx),
 		       ioapics[ioapic_idx].nr_registers);
@@ -1594,7 +1601,7 @@ __apicdebuginit(void) print_IO_APICs(void)
 	 */
 	printk(KERN_INFO "testing the IO APIC.......................\n");
 
-	for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++)
+	for_each_ioapic(ioapic_idx)
 		print_IO_APIC(ioapic_idx);
 
 	printk(KERN_DEBUG "IRQ to pin mappings:\n");
@@ -1825,26 +1832,22 @@ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
 void __init enable_IO_APIC(void)
 {
 	int i8259_apic, i8259_pin;
-	int apic;
+	int apic, pin;
 
 	if (!legacy_pic->nr_legacy_irqs)
 		return;
 
-	for(apic = 0; apic < nr_ioapics; apic++) {
-		int pin;
+	for_each_ioapic_pin(apic, pin) {
 		/* See if any of the pins is in ExtINT mode */
-		for (pin = 0; pin < ioapics[apic].nr_registers; pin++) {
-			struct IO_APIC_route_entry entry;
-			entry = ioapic_read_entry(apic, pin);
+		struct IO_APIC_route_entry entry = ioapic_read_entry(apic, pin);
 
-			/* If the interrupt line is enabled and in ExtInt mode
-			 * I have found the pin where the i8259 is connected.
-			 */
-			if ((entry.mask == 0) && (entry.delivery_mode == dest_ExtINT)) {
-				ioapic_i8259.apic = apic;
-				ioapic_i8259.pin  = pin;
-				goto found_i8259;
-			}
+		/* If the interrupt line is enabled and in ExtInt mode
+		 * I have found the pin where the i8259 is connected.
+		 */
+		if ((entry.mask == 0) && (entry.delivery_mode == dest_ExtINT)) {
+			ioapic_i8259.apic = apic;
+			ioapic_i8259.pin  = pin;
+			goto found_i8259;
 		}
 	}
  found_i8259:
@@ -1947,7 +1950,7 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void)
 	/*
 	 * Set the IOAPIC ID to the value stored in the MPC table.
 	 */
-	for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++) {
+	for_each_ioapic(ioapic_idx) {
 		/* Read the register 0 value */
 		raw_spin_lock_irqsave(&ioapic_lock, flags);
 		reg_00.raw = io_apic_read(ioapic_idx, 0);
@@ -2874,7 +2877,7 @@ static void ioapic_resume(void)
 {
 	int ioapic_idx;
 
-	for (ioapic_idx = nr_ioapics - 1; ioapic_idx >= 0; ioapic_idx--)
+	for_each_ioapic_reverse(ioapic_idx)
 		resume_ioapic_id(ioapic_idx);
 
 	restore_ioapic_entries();
@@ -3464,9 +3467,8 @@ static u8 __init io_apic_unique_id(u8 id)
 	DECLARE_BITMAP(used, 256);
 
 	bitmap_zero(used, 256);
-	for (i = 0; i < nr_ioapics; i++) {
+	for_each_ioapic(i)
 		__set_bit(mpc_ioapic_id(i), used);
-	}
 	if (!test_bit(id, used))
 		return id;
 	return find_first_zero_bit(used, 256);
@@ -3524,8 +3526,7 @@ void __init setup_ioapic_dest(void)
 	if (skip_ioapic_setup == 1)
 		return;
 
-	for (ioapic = 0; ioapic < nr_ioapics; ioapic++)
-	for (pin = 0; pin < ioapics[ioapic].nr_registers; pin++) {
+	for_each_ioapic_pin(ioapic, pin) {
 		irq_entry = find_irq_entry(ioapic, pin, mp_INT);
 		if (irq_entry == -1)
 			continue;
@@ -3554,29 +3555,33 @@ void __init setup_ioapic_dest(void)
 
 static struct resource *ioapic_resources;
 
-static struct resource * __init ioapic_setup_resources(int nr_ioapics)
+static struct resource * __init ioapic_setup_resources(void)
 {
 	unsigned long n;
 	struct resource *res;
 	char *mem;
-	int i;
+	int i, num = 0;
 
-	if (nr_ioapics <= 0)
+	for_each_ioapic(i)
+		num++;
+	if (num == 0)
 		return NULL;
 
 	n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource);
-	n *= nr_ioapics;
+	n *= num;
 
 	mem = alloc_bootmem(n);
 	res = (void *)mem;
 
-	mem += sizeof(struct resource) * nr_ioapics;
+	mem += sizeof(struct resource) * num;
 
-	for (i = 0; i < nr_ioapics; i++) {
-		res[i].name = mem;
-		res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+	num = 0;
+	for_each_ioapic(i) {
+		res[num].name = mem;
+		res[num].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
 		snprintf(mem, IOAPIC_RESOURCE_NAME_SIZE, "IOAPIC %u", i);
 		mem += IOAPIC_RESOURCE_NAME_SIZE;
+		num++;
 	}
 
 	ioapic_resources = res;
@@ -3590,8 +3595,8 @@ void __init native_io_apic_init_mappings(void)
 	struct resource *ioapic_res;
 	int i;
 
-	ioapic_res = ioapic_setup_resources(nr_ioapics);
-	for (i = 0; i < nr_ioapics; i++) {
+	ioapic_res = ioapic_setup_resources();
+	for_each_ioapic(i) {
 		if (smp_found_config) {
 			ioapic_phys = mpc_ioapic_addr(i);
 #ifdef CONFIG_X86_32
@@ -3636,7 +3641,7 @@ void __init ioapic_insert_resources(void)
 		return;
 	}
 
-	for (i = 0; i < nr_ioapics; i++) {
+	for_each_ioapic(i) {
 		insert_resource(&iomem_resource, r);
 		r++;
 	}
@@ -3644,16 +3649,15 @@ void __init ioapic_insert_resources(void)
 
 int mp_find_ioapic(u32 gsi)
 {
-	int i = 0;
+	int i;
 
 	if (nr_ioapics == 0)
 		return -1;
 
 	/* Find the IOAPIC that manages this GSI. */
-	for (i = 0; i < nr_ioapics; i++) {
+	for_each_ioapic(i) {
 		struct mp_ioapic_gsi *gsi_cfg = mp_ioapic_gsi_routing(i);
-		if ((gsi >= gsi_cfg->gsi_base)
-		    && (gsi <= gsi_cfg->gsi_end))
+		if (gsi >= gsi_cfg->gsi_base && gsi <= gsi_cfg->gsi_end)
 			return i;
 	}
 
@@ -3665,7 +3669,7 @@ int mp_find_ioapic_pin(int ioapic, u32 gsi)
 {
 	struct mp_ioapic_gsi *gsi_cfg;
 
-	if (WARN_ON(ioapic == -1))
+	if (WARN_ON(ioapic < 0))
 		return -1;
 
 	gsi_cfg = mp_ioapic_gsi_routing(ioapic);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 14/29] x86, ioapic: use irq_cfg() instead of irq_get_chip_data() for better readability
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (12 preceding siblings ...)
  2014-05-19 16:22 ` [Patch Part1 V2 13/29] x86, ioapic: introduce helper utilities to walk ioapics and pins Jiang Liu
@ 2014-05-19 16:22 ` Jiang Liu
  2014-05-19 16:22 ` [Patch Part1 V2 15/29] x86, irq: reorganize IO_APIC_get_PCI_irq_vector() to prepare for irqdomain Jiang Liu
                   ` (14 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:22 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, x86, Jiang Liu
  Cc: Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck, Joerg Roedel,
	Paul Gortmaker, Greg Kroah-Hartman, linux-kernel, linux-pci,
	linux-acpi, Ingo Molnar

Use defined helper function irq_cfg() instead of irq_get_chip_data() for
better readability.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/kernel/apic/io_apic.c |   20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 55fb3c1385c5..18d0e8a831c0 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -230,7 +230,7 @@ int __init arch_early_irq_init(void)
 	return 0;
 }
 
-static struct irq_cfg *irq_cfg(unsigned int irq)
+static inline struct irq_cfg *irq_cfg(unsigned int irq)
 {
 	return irq_get_chip_data(irq);
 }
@@ -272,7 +272,7 @@ static struct irq_cfg *alloc_irq_and_cfg_at(unsigned int at, int node)
 	if (res < 0) {
 		if (res != -EEXIST)
 			return NULL;
-		cfg = irq_get_chip_data(at);
+		cfg = irq_cfg(at);
 		if (cfg)
 			return cfg;
 	}
@@ -1204,7 +1204,7 @@ void __setup_vector_irq(int cpu)
 	raw_spin_lock(&vector_lock);
 	/* Mark the inuse vectors */
 	for_each_active_irq(irq) {
-		cfg = irq_get_chip_data(irq);
+		cfg = irq_cfg(irq);
 		if (!cfg)
 			continue;
 
@@ -1612,7 +1612,7 @@ __apicdebuginit(void) print_IO_APICs(void)
 		if (chip != &ioapic_chip)
 			continue;
 
-		cfg = irq_get_chip_data(irq);
+		cfg = irq_cfg(irq);
 		if (!cfg)
 			continue;
 		entry = cfg->irq_2_pin;
@@ -2253,7 +2253,7 @@ static void irq_complete_move(struct irq_cfg *cfg)
 
 void irq_force_complete_move(int irq)
 {
-	struct irq_cfg *cfg = irq_get_chip_data(irq);
+	struct irq_cfg *cfg = irq_cfg(irq);
 
 	if (!cfg)
 		return;
@@ -2526,7 +2526,7 @@ static inline void init_IO_APIC_traps(void)
 	 * 0x80, because int 0x80 is hm, kind of importantish. ;)
 	 */
 	for_each_active_irq(irq) {
-		cfg = irq_get_chip_data(irq);
+		cfg = irq_cfg(irq);
 		if (IO_APIC_IRQ(irq) && cfg && !cfg->vector) {
 			/*
 			 * Hmm.. We don't have an entry for this,
@@ -2659,7 +2659,7 @@ early_param("disable_timer_pin_1", disable_timer_pin_setup);
  */
 static inline void __init check_timer(void)
 {
-	struct irq_cfg *cfg = irq_get_chip_data(0);
+	struct irq_cfg *cfg = irq_cfg(0);
 	int node = cpu_to_node(0);
 	int apic1, pin1, apic2, pin2;
 	unsigned long flags;
@@ -2923,7 +2923,7 @@ int arch_setup_hwirq(unsigned int irq, int node)
 
 void arch_teardown_hwirq(unsigned int irq)
 {
-	struct irq_cfg *cfg = irq_get_chip_data(irq);
+	struct irq_cfg *cfg = irq_cfg(irq);
 	unsigned long flags;
 
 	free_remapped_irq(irq);
@@ -3052,7 +3052,7 @@ int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc,
 	if (!irq_offset)
 		write_msi_msg(irq, &msg);
 
-	setup_remapped_irq(irq, irq_get_chip_data(irq), chip);
+	setup_remapped_irq(irq, irq_cfg(irq), chip);
 
 	irq_set_chip_and_handler_name(irq, chip, handle_edge_irq, "edge");
 
@@ -3187,7 +3187,7 @@ int default_setup_hpet_msi(unsigned int irq, unsigned int id)
 
 	hpet_msi_write(irq_get_handler_data(irq), &msg);
 	irq_set_status_flags(irq, IRQ_MOVE_PCNTXT);
-	setup_remapped_irq(irq, irq_get_chip_data(irq), chip);
+	setup_remapped_irq(irq, irq_cfg(irq), chip);
 
 	irq_set_chip_and_handler_name(irq, chip, handle_edge_irq, "edge");
 	return 0;
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 15/29] x86, irq: reorganize IO_APIC_get_PCI_irq_vector() to prepare for irqdomain
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (13 preceding siblings ...)
  2014-05-19 16:22 ` [Patch Part1 V2 14/29] x86, ioapic: use irq_cfg() instead of irq_get_chip_data() for better readability Jiang Liu
@ 2014-05-19 16:22 ` Jiang Liu
  2014-05-19 16:23 ` [Patch Part1 V2 16/29] x86, irq: introduce some helper utilities to improve readability Jiang Liu
                   ` (13 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:22 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, x86, Jiang Liu
  Cc: Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck, Joerg Roedel,
	Paul Gortmaker, Greg Kroah-Hartman, linux-kernel, linux-pci,
	linux-acpi, Ingo Molnar

Reorganize function IO_APIC_get_PCI_irq_vector() a bit to better support
coming irqdomain.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/kernel/apic/io_apic.c |   62 ++++++++++++++++++++++------------------
 1 file changed, 34 insertions(+), 28 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 18d0e8a831c0..bb013e4126c3 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -997,7 +997,7 @@ static int pin_2_irq(int idx, int apic, int pin)
 int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,
 				struct io_apic_irq_attr *irq_attr)
 {
-	int ioapic_idx, i, best_guess = -1;
+	int irq, i, best_guess = -1;
 
 	apic_printk(APIC_DEBUG,
 		    "querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n",
@@ -1007,41 +1007,47 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,
 			    "PCI BIOS passed nonexistent PCI bus %d!\n", bus);
 		return -1;
 	}
+
 	for (i = 0; i < mp_irq_entries; i++) {
 		int lbus = mp_irqs[i].srcbus;
+		int ioapic_idx, found = 0;
+
+		if (test_bit(lbus, mp_bus_not_pci) || (bus != lbus) ||
+		    mp_irqs[i].irqtype != mp_INT ||
+		    (slot != ((mp_irqs[i].srcbusirq >> 2) & 0x1f)))
+			continue;
 
 		for_each_ioapic(ioapic_idx)
 			if (mpc_ioapic_id(ioapic_idx) == mp_irqs[i].dstapic ||
-			    mp_irqs[i].dstapic == MP_APIC_ALL)
+			    mp_irqs[i].dstapic == MP_APIC_ALL) {
+				found = 1;
 				break;
+			}
+		if (!found)
+			continue;
 
-		if (!test_bit(lbus, mp_bus_not_pci) &&
-		    mp_irqs[i].irqtype == mp_INT &&
-		    (bus == lbus) &&
-		    (slot == ((mp_irqs[i].srcbusirq >> 2) & 0x1f))) {
-			int irq = pin_2_irq(i, ioapic_idx, mp_irqs[i].dstirq);
-
-			if (!(ioapic_idx || IO_APIC_IRQ(irq)))
-				continue;
+		/* Skip ISA IRQs */
+		irq = pin_2_irq(i, ioapic_idx, mp_irqs[i].dstirq);
+		if (ioapic_idx == 0 && !IO_APIC_IRQ(irq))
+			continue;
 
-			if (pin == (mp_irqs[i].srcbusirq & 3)) {
-				set_io_apic_irq_attr(irq_attr, ioapic_idx,
-						     mp_irqs[i].dstirq,
-						     irq_trigger(i),
-						     irq_polarity(i));
-				return irq;
-			}
-			/*
-			 * Use the first all-but-pin matching entry as a
-			 * best-guess fuzzy result for broken mptables.
-			 */
-			if (best_guess < 0) {
-				set_io_apic_irq_attr(irq_attr, ioapic_idx,
-						     mp_irqs[i].dstirq,
-						     irq_trigger(i),
-						     irq_polarity(i));
-				best_guess = irq;
-			}
+		if (pin == (mp_irqs[i].srcbusirq & 3)) {
+			set_io_apic_irq_attr(irq_attr, ioapic_idx,
+					     mp_irqs[i].dstirq,
+					     irq_trigger(i),
+					     irq_polarity(i));
+			return irq;
+		}
+		/*
+		 * Use the first all-but-pin matching entry as a
+		 * best-guess fuzzy result for broken mptables.
+		 */
+		if (best_guess < 0) {
+			set_io_apic_irq_attr(irq_attr, ioapic_idx,
+					     mp_irqs[i].dstirq,
+					     irq_trigger(i),
+					     irq_polarity(i));
+			best_guess = irq;
 		}
 	}
 	return best_guess;
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 16/29] x86, irq: introduce some helper utilities to improve readability
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (14 preceding siblings ...)
  2014-05-19 16:22 ` [Patch Part1 V2 15/29] x86, irq: reorganize IO_APIC_get_PCI_irq_vector() to prepare for irqdomain Jiang Liu
@ 2014-05-19 16:23 ` Jiang Liu
  2014-05-19 16:23 ` [Patch Part1 V2 17/29] x86, ACPI, irq: consolidate algorithm of mapping (ioapic, pin) to IRQ number Jiang Liu
                   ` (12 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:23 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, x86, Jiang Liu
  Cc: Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck, Joerg Roedel,
	Paul Gortmaker, Greg Kroah-Hartman, linux-kernel, linux-pci,
	linux-acpi, Ingo Molnar

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/kernel/apic/io_apic.c |   29 ++++++++++++++++++++++-------
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index bb013e4126c3..3b6e29d29903 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -117,6 +117,24 @@ struct mp_ioapic_gsi *mp_ioapic_gsi_routing(int ioapic_idx)
 	return &ioapics[ioapic_idx].gsi_config;
 }
 
+static inline int mp_ioapic_pin_count(int ioapic)
+{
+	struct mp_ioapic_gsi *gsi_cfg = mp_ioapic_gsi_routing(ioapic);
+
+	return gsi_cfg->gsi_end - gsi_cfg->gsi_base + 1;
+}
+
+static inline u32 mp_pin_2_gsi(int ioapic, int pin)
+{
+	return mp_ioapic_gsi_routing(ioapic)->gsi_base + pin;
+}
+
+/* Initialize all legacy IRQs and all pins on the first IOAPIC at boot */
+static inline int mp_init_irq_at_boot(int ioapic, int irq)
+{
+	return ioapic == 0 || (irq >= 0 && irq < NR_IRQS_LEGACY);
+}
+
 int nr_ioapics;
 
 /* The one past the highest gsi number used */
@@ -1368,8 +1386,7 @@ static void __init __io_apic_setup_irqs(unsigned int ioapic_idx)
 			continue;
 
 		irq = pin_2_irq(idx, ioapic_idx, pin);
-
-		if ((ioapic_idx > 0) && (irq > NR_IRQS_LEGACY))
+		if (!mp_init_irq_at_boot(ioapic_idx, irq))
 			continue;
 
 		/*
@@ -1420,9 +1437,7 @@ void setup_IO_APIC_irq_extra(u32 gsi)
 		return;
 
 	irq = pin_2_irq(idx, ioapic_idx, pin);
-
-	/* Only handle the non legacy irqs on secondary ioapics */
-	if (ioapic_idx == 0 || irq < NR_IRQS_LEGACY)
+	if (mp_init_irq_at_boot(ioapic_idx, irq))
 		return;
 
 	set_io_apic_irq_attr(&attr, ioapic_idx, pin, irq_trigger(idx),
@@ -3536,9 +3551,9 @@ void __init setup_ioapic_dest(void)
 		irq_entry = find_irq_entry(ioapic, pin, mp_INT);
 		if (irq_entry == -1)
 			continue;
-		irq = pin_2_irq(irq_entry, ioapic, pin);
 
-		if ((ioapic > 0) && (irq > NR_IRQS_LEGACY))
+		irq = pin_2_irq(irq_entry, ioapic, pin);
+		if (!mp_init_irq_at_boot(ioapic, irq))
 			continue;
 
 		idata = irq_get_irq_data(irq);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 17/29] x86, ACPI, irq: consolidate algorithm of mapping (ioapic, pin) to IRQ number
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (15 preceding siblings ...)
  2014-05-19 16:23 ` [Patch Part1 V2 16/29] x86, irq: introduce some helper utilities to improve readability Jiang Liu
@ 2014-05-19 16:23 ` Jiang Liu
  2014-05-19 16:23 ` [Patch Part1 V2 18/29] x86, irq: introduce mechanisms to support dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (11 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:23 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, x86, Len Brown, Pavel Machek,
	Jiang Liu
  Cc: Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck, Joerg Roedel,
	Paul Gortmaker, Greg Kroah-Hartman, linux-kernel, linux-pci,
	linux-acpi, Ingo Molnar, linux-pm

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_pin_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>
---
 arch/x86/include/asm/io_apic.h |    2 ++
 arch/x86/kernel/acpi/boot.c    |   52 +++++++++++++++++++++-------------------
 arch/x86/kernel/apic/io_apic.c |   30 +++++++++++++----------
 3 files changed, 48 insertions(+), 36 deletions(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index de3d8b04cf64..f4fd0be26cec 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -171,6 +171,7 @@ extern u32 gsi_top;
 
 extern int mp_find_ioapic(u32 gsi);
 extern int mp_find_ioapic_pin(int ioapic, u32 gsi);
+extern int mp_map_pin_to_irq(int ioapic, int pin);
 extern void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
 extern void __init pre_init_apic_IRQ0(void);
 
@@ -212,6 +213,7 @@ extern void io_apic_eoi(unsigned int apic, unsigned int vector);
 static inline void ioapic_insert_resources(void) { }
 #define gsi_top (NR_IRQS_LEGACY)
 static inline int mp_find_ioapic(u32 gsi) { return 0; }
+static inline int mp_map_pin_to_irq(int ioapic, int pin) { return -1; }
 
 struct io_apic_irq_attr;
 static 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 dccf9e88db30..6eae9a7231c4 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -99,27 +99,22 @@ static u32 isa_irq_to_gsi[NR_IRQS_LEGACY] __read_mostly = {
 
 #define	ACPI_INVALID_GSI		INT_MIN
 
-static unsigned int gsi_to_irq(unsigned int gsi)
+static int map_gsi_to_irq(unsigned int gsi)
 {
-	unsigned int irq = gsi + NR_IRQS_LEGACY;
-	unsigned int i;
+	int i, ioapic, pin;
 
-	for (i = 0; i < NR_IRQS_LEGACY; i++) {
-		if (isa_irq_to_gsi[i] == gsi) {
+	for (i = 0; i < NR_IRQS_LEGACY; i++)
+		if (isa_irq_to_gsi[i] == gsi)
 			return i;
-		}
-	}
 
-	/* Provide an identity mapping of gsi == irq
-	 * except on truly weird platforms that have
-	 * non isa irqs in the first 16 gsis.
-	 */
-	if (gsi >= NR_IRQS_LEGACY)
-		irq = gsi;
-	else
-		irq = gsi_top + gsi;
+	ioapic = mp_find_ioapic(gsi);
+	if (ioapic >= 0) {
+		pin = mp_find_ioapic_pin(ioapic, gsi);
+		return mp_map_pin_to_irq(ioapic, pin);
+	}
 
-	return irq;
+	pr_err("Failed to map GSI%d to IRQ number.\n", gsi);
+	return -1;
 }
 
 /*
@@ -493,16 +488,20 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
 	outb(new >> 8, 0x4d1);
 }
 
-int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
+int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp)
 {
-	*irq = gsi_to_irq(gsi);
+	int irq = map_gsi_to_irq(gsi);
 
+	if (irq >= 0) {
 #ifdef CONFIG_X86_IO_APIC
-	if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
-		setup_IO_APIC_irq_extra(gsi);
+		if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
+			setup_IO_APIC_irq_extra(gsi);
 #endif
+		*irqp = irq;
+		return 0;
+	}
 
-	return 0;
+	return -1;
 }
 EXPORT_SYMBOL_GPL(acpi_gsi_to_irq);
 
@@ -556,11 +555,11 @@ int (*acpi_suspend_lowlevel)(void);
  */
 int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
 {
-	unsigned int plat_gsi = gsi;
+	unsigned int plat_gsi;
 
 	plat_gsi = (*__acpi_register_gsi)(dev, gsi, trigger, polarity);
 	if (plat_gsi != ACPI_INVALID_GSI)
-		return gsi_to_irq(plat_gsi);
+		return map_gsi_to_irq(plat_gsi);
 
 	return -1;
 }
@@ -1029,6 +1028,7 @@ static int mp_config_acpi_gsi(struct device *dev, u32 gsi, int trigger,
 static int mp_register_gsi(struct device *dev, u32 gsi, int trigger,
 			   int polarity)
 {
+	int irq;
 	int ioapic;
 	int ioapic_pin;
 	struct io_apic_irq_attr irq_attr;
@@ -1041,6 +1041,10 @@ static int mp_register_gsi(struct device *dev, u32 gsi, int trigger,
 	if (acpi_gbl_FADT.sci_interrupt == gsi)
 		return gsi;
 
+	irq = map_gsi_to_irq(gsi);
+	if (irq < 0)
+		return ACPI_INVALID_GSI;
+
 	ioapic = mp_find_ioapic(gsi);
 	if (ioapic < 0) {
 		printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi);
@@ -1062,7 +1066,7 @@ static int mp_register_gsi(struct device *dev, u32 gsi, int trigger,
 	set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin,
 			     trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,
 			     polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
-	ret = io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr);
+	ret = io_apic_set_pci_routing(dev, irq, &irq_attr);
 	if (ret < 0)
 		gsi = ACPI_INVALID_GSI;
 
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 3b6e29d29903..2d776f69f4e8 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -963,11 +963,22 @@ static int irq_trigger(int idx)
 	return trigger;
 }
 
+int mp_map_pin_to_irq(int apic, int pin)
+{
+	struct mp_ioapic_gsi *gsi_cfg = mp_ioapic_gsi_routing(apic);
+	u32 gsi = gsi_cfg->gsi_base + pin;
+
+	/*
+	 * Provide an identity mapping of gsi == irq except on truly weird
+	 * platforms that have non isa irqs in the first 16 gsis.
+	 */
+	return gsi >= NR_IRQS_LEGACY ? gsi : gsi_top + gsi;
+}
+
 static int pin_2_irq(int idx, int apic, int pin)
 {
 	int irq;
 	int bus = mp_irqs[idx].srcbus;
-	struct mp_ioapic_gsi *gsi_cfg = mp_ioapic_gsi_routing(apic);
 
 	/*
 	 * Debugging check, we are in big trouble if this message pops up!
@@ -975,17 +986,6 @@ static int pin_2_irq(int idx, int apic, int pin)
 	if (mp_irqs[idx].dstirq != pin)
 		pr_err("broken BIOS or MPTABLE parser, ayiee!!\n");
 
-	if (test_bit(bus, mp_bus_not_pci)) {
-		irq = mp_irqs[idx].srcbusirq;
-	} else {
-		u32 gsi = gsi_cfg->gsi_base + pin;
-
-		if (gsi >= NR_IRQS_LEGACY)
-			irq = gsi;
-		else
-			irq = gsi_top + gsi;
-	}
-
 #ifdef CONFIG_X86_32
 	/*
 	 * PCI IRQ command line redirection. Yes, limits are hardcoded.
@@ -1000,11 +1000,17 @@ static int pin_2_irq(int idx, int apic, int pin)
 				apic_printk(APIC_VERBOSE, KERN_DEBUG
 						"using PIRQ%d -> IRQ %d\n",
 						pin-16, irq);
+				return irq;
 			}
 		}
 	}
 #endif
 
+	if (test_bit(bus, mp_bus_not_pci))
+		irq = mp_irqs[idx].srcbusirq;
+	else
+		irq = mp_map_pin_to_irq(apic, pin);
+
 	return irq;
 }
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 18/29] x86, irq: introduce mechanisms to support dynamically allocate IRQ for IOAPIC
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (16 preceding siblings ...)
  2014-05-19 16:23 ` [Patch Part1 V2 17/29] x86, ACPI, irq: consolidate algorithm of mapping (ioapic, pin) to IRQ number Jiang Liu
@ 2014-05-19 16:23 ` Jiang Liu
  2014-05-19 16:23 ` [Patch Part1 V2 19/29] x86, irq: enhance mp_register_ioapic() to support irqdomain Jiang Liu
                   ` (10 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:23 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, x86, Len Brown, Pavel Machek,
	Jiang Liu
  Cc: Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck, Joerg Roedel,
	Paul Gortmaker, Greg Kroah-Hartman, linux-kernel, linux-pci,
	linux-acpi, Ingo Molnar, linux-pm

Currently x86 support identity mapping between GSI(IOAPIC pin) and IRQ
number, so continous IRQs at low end are statically allocated to IOAPICs
at boot time. This design causes trouble to support IOAPIC hotplug.

This patch implements basic mechanism to dynamically allocate IRQ on
demand for IOAPIC pins by using irqdomain framework.

It first adds several fields into struct ioapic to support irqdomain.
Then it implements an algorithm to dynamically allocate IRQ number
on demand.
1) Legacy(ISA) IRQs is not managed by irqdomain because there may be
   multiple pins sharing the same IRQ number and current irqdomain
   only supports 1:1 mapping between pins and IRQ.
2) Build identity mapping for GSIs between NR_IRQS_LEGACY and
   arch_dynirq_lower_bound(0). This is typically used to support legacy
   IRQs and simple platforms.
3) Dynamically allocate IRQs for GSIs above arch_dynirq_lower_bound(0).
   This may be used to support big system and IOAPIC hotplug.
4) Dynamically allocate IRQs for non-ISA IRQs below NR_IRQS_LEGACY. This
   is to support some really weired platforms.

Function arch_dynirq_lower_bound(0) will be enhanced in coming patch
to enable dynamic IRQ allocation for IOAPIC. To ease our life,
arch_dynirq_lower_bound(0) must be greater than or equal to
NR_IRQS_LEGACY, otherwise it may break backward compatibilities.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/include/asm/io_apic.h |   12 ++++-
 arch/x86/kernel/acpi/boot.c    |   10 ++--
 arch/x86/kernel/apic/io_apic.c |  111 ++++++++++++++++++++++++++++------------
 3 files changed, 94 insertions(+), 39 deletions(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index f4fd0be26cec..2e593832ec6f 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -98,6 +98,8 @@ struct IR_IO_APIC_route_entry {
 #define IOAPIC_AUTO     -1
 #define IOAPIC_EDGE     0
 #define IOAPIC_LEVEL    1
+#define	IOAPIC_MAP_ALLOC		0x1
+#define	IOAPIC_MAP_CHECK		0x2
 
 #ifdef CONFIG_X86_IO_APIC
 
@@ -169,9 +171,11 @@ struct mp_ioapic_gsi{
 };
 extern u32 gsi_top;
 
+typedef struct irq_domain *(*ioapic_create_domain_fn)(int idx, void *arg);
+
 extern int mp_find_ioapic(u32 gsi);
 extern int mp_find_ioapic_pin(int ioapic, u32 gsi);
-extern int mp_map_pin_to_irq(int ioapic, int pin);
+extern int mp_map_pin_to_irq(int ioapic, int pin, int idx, unsigned int flags);
 extern void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
 extern void __init pre_init_apic_IRQ0(void);
 
@@ -213,7 +217,11 @@ extern void io_apic_eoi(unsigned int apic, unsigned int vector);
 static inline void ioapic_insert_resources(void) { }
 #define gsi_top (NR_IRQS_LEGACY)
 static inline int mp_find_ioapic(u32 gsi) { return 0; }
-static inline int mp_map_pin_to_irq(int ioapic, int pin) { return -1; }
+static inline int mp_map_pin_to_irq(int ioapic, int pin, int idx,
+				    unsigned int flags)
+{
+	return -1;
+}
 
 struct io_apic_irq_attr;
 static 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 6eae9a7231c4..9aa02b30a8bc 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -99,7 +99,7 @@ static u32 isa_irq_to_gsi[NR_IRQS_LEGACY] __read_mostly = {
 
 #define	ACPI_INVALID_GSI		INT_MIN
 
-static int map_gsi_to_irq(unsigned int gsi)
+static int map_gsi_to_irq(unsigned int gsi, unsigned int flags)
 {
 	int i, ioapic, pin;
 
@@ -110,7 +110,7 @@ static int map_gsi_to_irq(unsigned int gsi)
 	ioapic = mp_find_ioapic(gsi);
 	if (ioapic >= 0) {
 		pin = mp_find_ioapic_pin(ioapic, gsi);
-		return mp_map_pin_to_irq(ioapic, pin);
+		return mp_map_pin_to_irq(ioapic, pin, -1, flags);
 	}
 
 	pr_err("Failed to map GSI%d to IRQ number.\n", gsi);
@@ -490,7 +490,7 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
 
 int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp)
 {
-	int irq = map_gsi_to_irq(gsi);
+	int irq = map_gsi_to_irq(gsi, IOAPIC_MAP_ALLOC | IOAPIC_MAP_CHECK);
 
 	if (irq >= 0) {
 #ifdef CONFIG_X86_IO_APIC
@@ -559,7 +559,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
 
 	plat_gsi = (*__acpi_register_gsi)(dev, gsi, trigger, polarity);
 	if (plat_gsi != ACPI_INVALID_GSI)
-		return map_gsi_to_irq(plat_gsi);
+		return map_gsi_to_irq(plat_gsi, 0);
 
 	return -1;
 }
@@ -1041,7 +1041,7 @@ static int mp_register_gsi(struct device *dev, u32 gsi, int trigger,
 	if (acpi_gbl_FADT.sci_interrupt == gsi)
 		return gsi;
 
-	irq = map_gsi_to_irq(gsi);
+	irq = map_gsi_to_irq(gsi, IOAPIC_MAP_ALLOC);
 	if (irq < 0)
 		return ACPI_INVALID_GSI;
 
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 2d776f69f4e8..d0dd904007aa 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -31,6 +31,7 @@
 #include <linux/acpi.h>
 #include <linux/module.h>
 #include <linux/syscore_ops.h>
+#include <linux/irqdomain.h>
 #include <linux/msi.h>
 #include <linux/htirq.h>
 #include <linux/freezer.h>
@@ -83,6 +84,7 @@ int sis_apic_bug = -1;
 
 static DEFINE_RAW_SPINLOCK(ioapic_lock);
 static DEFINE_RAW_SPINLOCK(vector_lock);
+static DEFINE_MUTEX(ioapic_mutex);
 
 static struct ioapic {
 	/*
@@ -97,6 +99,9 @@ static struct ioapic {
 	struct mpc_ioapic mp_config;
 	/* IO APIC gsi routing info */
 	struct mp_ioapic_gsi  gsi_config;
+	struct irq_domain *irqdomain;
+	ioapic_create_domain_fn irqdomain_cb;
+	void *irqdomain_arg;
 	DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
 } ioapics[MAX_IO_APICS];
 
@@ -135,6 +140,11 @@ static inline int mp_init_irq_at_boot(int ioapic, int irq)
 	return ioapic == 0 || (irq >= 0 && irq < NR_IRQS_LEGACY);
 }
 
+static inline struct irq_domain *mp_ioapic_irqdomain(int ioapic)
+{
+	return ioapics[ioapic].irqdomain;
+}
+
 int nr_ioapics;
 
 /* The one past the highest gsi number used */
@@ -963,19 +973,47 @@ static int irq_trigger(int idx)
 	return trigger;
 }
 
-int mp_map_pin_to_irq(int apic, int pin)
+int mp_map_pin_to_irq(int ioapic, int pin, int idx, unsigned int flags)
 {
-	struct mp_ioapic_gsi *gsi_cfg = mp_ioapic_gsi_routing(apic);
-	u32 gsi = gsi_cfg->gsi_base + pin;
+	int irq = -1;
+	u32 gsi = mp_pin_2_gsi(ioapic, pin);
+	struct irq_domain *domain = mp_ioapic_irqdomain(ioapic);
 
-	/*
-	 * Provide an identity mapping of gsi == irq except on truly weird
-	 * platforms that have non isa irqs in the first 16 gsis.
-	 */
-	return gsi >= NR_IRQS_LEGACY ? gsi : gsi_top + gsi;
+	if (!domain) {
+		/*
+		 * Provide an identity mapping of gsi == irq except on truly
+		 * weird platforms that have non isa irqs in the first 16 gsis.
+		 */
+		return gsi >= NR_IRQS_LEGACY ? gsi : gsi_top + gsi;
+	}
+
+	mutex_lock(&ioapic_mutex);
+	irq = irq_find_mapping(domain, pin);
+	if (irq <= 0 && (flags & IOAPIC_MAP_ALLOC)) {
+		if ((flags & IOAPIC_MAP_CHECK) && idx < 0) {
+			idx = find_irq_entry(ioapic, pin, mp_INT);
+			if (idx < 0)
+				goto out;
+		}
+
+		/*
+		 * Dynamically allocate IRQ for GSI above
+		 * arch_dynirq_lower_bound(0), and build identity mapping for
+		 * statically assigned IRQ, and specially handle non-ISA IRQs
+		 * below NR_IRQS_LEGACY.
+		 */
+		if (gsi >= arch_dynirq_lower_bound(0) || gsi < NR_IRQS_LEGACY)
+			irq = irq_create_mapping(domain, pin);
+		else if (irq_create_strict_mappings(domain, gsi, pin, 1) == 0)
+			irq = gsi;
+	}
+out:
+	mutex_unlock(&ioapic_mutex);
+
+	return irq > 0 ? irq : -1;
 }
 
-static int pin_2_irq(int idx, int apic, int pin)
+static int pin_2_irq(int idx, int ioapic, int pin, unsigned int flags)
 {
 	int irq;
 	int bus = mp_irqs[idx].srcbus;
@@ -1009,7 +1047,7 @@ static int pin_2_irq(int idx, int apic, int pin)
 	if (test_bit(bus, mp_bus_not_pci))
 		irq = mp_irqs[idx].srcbusirq;
 	else
-		irq = mp_map_pin_to_irq(apic, pin);
+		irq = mp_map_pin_to_irq(ioapic, pin, idx, flags);
 
 	return irq;
 }
@@ -1021,7 +1059,7 @@ static int pin_2_irq(int idx, int apic, int pin)
 int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,
 				struct io_apic_irq_attr *irq_attr)
 {
-	int irq, i, best_guess = -1;
+	int irq, i, best_ioapic = -1, best_idx = -1;
 
 	apic_printk(APIC_DEBUG,
 		    "querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n",
@@ -1035,6 +1073,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,
 	for (i = 0; i < mp_irq_entries; i++) {
 		int lbus = mp_irqs[i].srcbus;
 		int ioapic_idx, found = 0;
+		int gsi;
 
 		if (test_bit(lbus, mp_bus_not_pci) || (bus != lbus) ||
 		    mp_irqs[i].irqtype != mp_INT ||
@@ -1051,30 +1090,37 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,
 			continue;
 
 		/* Skip ISA IRQs */
-		irq = pin_2_irq(i, ioapic_idx, mp_irqs[i].dstirq);
-		if (ioapic_idx == 0 && !IO_APIC_IRQ(irq))
+		gsi = mp_pin_2_gsi(ioapic_idx, mp_irqs[i].dstirq);
+		if (gsi < arch_dynirq_lower_bound(0) && !IO_APIC_IRQ(gsi))
 			continue;
 
 		if (pin == (mp_irqs[i].srcbusirq & 3)) {
-			set_io_apic_irq_attr(irq_attr, ioapic_idx,
-					     mp_irqs[i].dstirq,
-					     irq_trigger(i),
-					     irq_polarity(i));
-			return irq;
+			best_idx = i;
+			best_ioapic = ioapic_idx;
+			goto out;
 		}
+
 		/*
 		 * Use the first all-but-pin matching entry as a
 		 * best-guess fuzzy result for broken mptables.
 		 */
-		if (best_guess < 0) {
-			set_io_apic_irq_attr(irq_attr, ioapic_idx,
-					     mp_irqs[i].dstirq,
-					     irq_trigger(i),
-					     irq_polarity(i));
-			best_guess = irq;
+		if (best_idx < 0) {
+			best_idx = i;
+			best_ioapic = ioapic_idx;
 		}
 	}
-	return best_guess;
+	if (best_idx < 0)
+		return -1;
+
+out:
+	irq = pin_2_irq(best_idx, best_ioapic, mp_irqs[best_idx].dstirq,
+			IOAPIC_MAP_ALLOC);
+	if (irq > 0)
+		set_io_apic_irq_attr(irq_attr, best_ioapic,
+				     mp_irqs[best_idx].dstirq,
+				     irq_trigger(best_idx),
+				     irq_polarity(best_idx));
+	return irq;
 }
 EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
 
@@ -1265,7 +1311,7 @@ static inline int IO_APIC_irq_trigger(int irq)
 
 	for_each_ioapic_pin(apic, pin) {
 		idx = find_irq_entry(apic, pin, mp_INT);
-		if ((idx != -1) && (irq == pin_2_irq(idx, apic, pin)))
+		if ((idx != -1) && (irq == pin_2_irq(idx, apic, pin, 0)))
 			return irq_trigger(idx);
 	}
 	/*
@@ -1391,8 +1437,9 @@ static void __init __io_apic_setup_irqs(unsigned int ioapic_idx)
 		if (io_apic_pin_not_connected(idx, ioapic_idx, pin))
 			continue;
 
-		irq = pin_2_irq(idx, ioapic_idx, pin);
-		if (!mp_init_irq_at_boot(ioapic_idx, irq))
+		irq = pin_2_irq(idx, ioapic_idx, pin,
+				ioapic_idx ? 0 : IOAPIC_MAP_ALLOC);
+		if (irq < 0 || !mp_init_irq_at_boot(ioapic_idx, irq))
 			continue;
 
 		/*
@@ -1442,8 +1489,8 @@ void setup_IO_APIC_irq_extra(u32 gsi)
 	if (idx == -1)
 		return;
 
-	irq = pin_2_irq(idx, ioapic_idx, pin);
-	if (mp_init_irq_at_boot(ioapic_idx, irq))
+	irq = pin_2_irq(idx, ioapic_idx, pin, IOAPIC_MAP_ALLOC);
+	if (irq < 0 || mp_init_irq_at_boot(ioapic_idx, irq))
 		return;
 
 	set_io_apic_irq_attr(&attr, ioapic_idx, pin, irq_trigger(idx),
@@ -3558,8 +3605,8 @@ void __init setup_ioapic_dest(void)
 		if (irq_entry == -1)
 			continue;
 
-		irq = pin_2_irq(irq_entry, ioapic, pin);
-		if (!mp_init_irq_at_boot(ioapic, irq))
+		irq = pin_2_irq(irq_entry, ioapic, pin, 0);
+		if (irq < 0 || !mp_init_irq_at_boot(ioapic, irq))
 			continue;
 
 		idata = irq_get_irq_data(irq);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 19/29] x86, irq: enhance mp_register_ioapic() to support irqdomain
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (17 preceding siblings ...)
  2014-05-19 16:23 ` [Patch Part1 V2 18/29] x86, irq: introduce mechanisms to support dynamically allocate IRQ for IOAPIC Jiang Liu
@ 2014-05-19 16:23 ` Jiang Liu
  2014-05-19 16:23 ` [Patch Part1 V2 20/29] x86, ACPI, irq: provide basic irqdomain support Jiang Liu
                   ` (9 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:23 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, x86, Len Brown, Pavel Machek,
	Jiang Liu, Rob Herring, Michal Simek, Tony Lindgren
  Cc: Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck, Joerg Roedel,
	Paul Gortmaker, Greg Kroah-Hartman, linux-kernel, linux-pci,
	linux-acpi, Ingo Molnar, linux-pm, sfi-devel

Add extra arguments to function mp_register_ioapic() to support
irqdomain. When registering IOAPIC, caller may provide a callback
and corresponding argument to create irqdomain for this IOAPIC.
The callback will be called later when initializing IOAPIC subsystem.

We also provide a common implementation mp_create_irqdomain()
to create irqdomain for IOAPICs, which may be used by platform drivers.

Global variable ioapic_dynirq_base is provided for platform drivers
to override return value of arch_dynirq_lower_bound(), thus enable
or disable dynamic IRQ allocation for IOAPIC.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/include/asm/io_apic.h |    9 +++++++-
 arch/x86/kernel/acpi/boot.c    |    3 ++-
 arch/x86/kernel/apic/io_apic.c |   48 ++++++++++++++++++++++++++++++++++++++--
 arch/x86/kernel/devicetree.c   |    2 +-
 arch/x86/kernel/mpparse.c      |    2 +-
 arch/x86/platform/sfi/sfi.c    |    2 +-
 6 files changed, 59 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 2e593832ec6f..666170437d78 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -132,6 +132,9 @@ extern int noioapicquirk;
 /* -1 if "noapic" boot option passed */
 extern int noioapicreroute;
 
+/* Build identity mapping for GSIs below it */
+extern int ioapic_dynirq_base;
+
 /*
  * If we use the IO-APIC for IRQ routing, disable automatic
  * assignment of PCI IRQ's.
@@ -171,12 +174,16 @@ struct mp_ioapic_gsi{
 };
 extern u32 gsi_top;
 
+struct irq_domain_ops;
 typedef struct irq_domain *(*ioapic_create_domain_fn)(int idx, void *arg);
 
 extern int mp_find_ioapic(u32 gsi);
 extern int mp_find_ioapic_pin(int ioapic, u32 gsi);
 extern int mp_map_pin_to_irq(int ioapic, int pin, int idx, unsigned int flags);
-extern void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
+extern void __init mp_register_ioapic(int id, u32 address, u32 gsi_base,
+				      ioapic_create_domain_fn cb, void *arg);
+extern struct irq_domain *mp_irqdomain_create(int ioapic,
+		struct device_node *np, const struct irq_domain_ops *ops);
 extern void __init pre_init_apic_IRQ0(void);
 
 extern void mp_save_irq(struct mpc_intsrc *m);
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 9aa02b30a8bc..66c8feea15a7 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -344,7 +344,8 @@ acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end)
 	acpi_table_print_madt_entry(header);
 
 	mp_register_ioapic(ioapic->id,
-			   ioapic->address, ioapic->global_irq_base);
+			   ioapic->address, ioapic->global_irq_base,
+			   NULL, NULL);
 
 	return 0;
 }
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index d0dd904007aa..1b9dd0a70dfa 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -164,6 +164,15 @@ DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);
 
 int skip_ioapic_setup;
 
+/*
+ * If not zero:
+ * . build identity mapping for GSIs below it.
+ * . must be bigger than or equal to max(NR_IRQS_LEGACY, pins_on_ioapic0).
+ * If zero:
+ * . build identity mapping for all GSIs
+ */
+int ioapic_dynirq_base;
+
 /**
  * disable_ioapic_support() - disables ioapic support at runtime
  */
@@ -2898,15 +2907,28 @@ out:
  */
 #define PIC_IRQS	(1UL << PIC_CASCADE_IR)
 
-void __init setup_IO_APIC(void)
+static void ioapic_create_irqdomains(void)
 {
+	int i;
+	struct ioapic *ip;
 
+	for_each_ioapic(i) {
+		ip = &ioapics[i];
+		if (ip->irqdomain_cb)
+			ip->irqdomain = ip->irqdomain_cb(i, ip->irqdomain_arg);
+	}
+}
+
+void __init setup_IO_APIC(void)
+{
 	/*
 	 * calling enable_IO_APIC() is moved to setup_local_APIC for BP
 	 */
 	io_apic_irqs = legacy_pic->nr_legacy_irqs ? ~PIC_IRQS : ~0UL;
 
 	apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n");
+	ioapic_create_irqdomains();
+
 	/*
          * Set up IO-APIC IRQ routing.
          */
@@ -3411,6 +3433,9 @@ unsigned int arch_dynirq_lower_bound(unsigned int from)
 {
 	unsigned int min = gsi_top + NR_IRQS_LEGACY;
 
+	if (ioapic_dynirq_base)
+		return ioapic_dynirq_base;
+
 	return from < min ? min : from;
 }
 
@@ -3786,7 +3811,8 @@ static __init int bad_ioapic_register(int idx)
 	return 0;
 }
 
-void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
+void __init mp_register_ioapic(int id, u32 address, u32 gsi_base,
+			       ioapic_create_domain_fn cb, void *arg)
 {
 	int idx = 0;
 	int entries;
@@ -3800,6 +3826,9 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 	ioapics[idx].mp_config.type = MP_IOAPIC;
 	ioapics[idx].mp_config.flags = MPC_APIC_USABLE;
 	ioapics[idx].mp_config.apicaddr = address;
+	ioapics[idx].irqdomain_cb = cb;
+	ioapics[idx].irqdomain_arg = arg;
+	ioapics[idx].irqdomain = NULL;
 
 	set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
 
@@ -3836,6 +3865,21 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 	nr_ioapics++;
 }
 
+struct irq_domain *mp_irqdomain_create(int ioapic, struct device_node *np,
+				       const struct irq_domain_ops *ops)
+{
+	struct irq_domain *domain;
+	struct mp_ioapic_gsi *gsi_cfg = mp_ioapic_gsi_routing(ioapic);
+	int hwirqs = mp_ioapic_pin_count(ioapic);
+
+	domain = irq_domain_add_linear(np, hwirqs, ops, (void *)(long)ioapic);
+	BUG_ON(!domain);
+	if (gsi_cfg->gsi_base == 0)
+		irq_set_default_host(domain);
+
+	return domain;
+}
+
 /* Enable IOAPIC early just for system timer */
 void __init pre_init_apic_IRQ0(void)
 {
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index d35078ea1446..1ab002c045c9 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -176,7 +176,7 @@ static void __init dtb_add_ioapic(struct device_node *dn)
 				dn->full_name);
 		return;
 	}
-	mp_register_ioapic(++ioapic_id, r.start, gsi_top);
+	mp_register_ioapic(++ioapic_id, r.start, gsi_top, NULL, NULL);
 }
 
 static void __init dtb_ioapic_setup(void)
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index 24da837389b7..6cb9a43ecde1 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -115,7 +115,7 @@ static void __init MP_bus_info(struct mpc_bus *m)
 static void __init MP_ioapic_info(struct mpc_ioapic *m)
 {
 	if (m->flags & MPC_APIC_USABLE)
-		mp_register_ioapic(m->apicid, m->apicaddr, gsi_top);
+		mp_register_ioapic(m->apicid, m->apicaddr, gsi_top, NULL, NULL);
 }
 
 static void __init print_mp_irq_info(struct mpc_intsrc *mp_irq)
diff --git a/arch/x86/platform/sfi/sfi.c b/arch/x86/platform/sfi/sfi.c
index bcd1a703e3e6..3bd7cf642680 100644
--- a/arch/x86/platform/sfi/sfi.c
+++ b/arch/x86/platform/sfi/sfi.c
@@ -82,7 +82,7 @@ static int __init sfi_parse_ioapic(struct sfi_table_header *table)
 	pentry = (struct sfi_apic_table_entry *)sb->pentry;
 
 	for (i = 0; i < num; i++) {
-		mp_register_ioapic(i, pentry->phys_addr, gsi_top);
+		mp_register_ioapic(i, pentry->phys_addr, gsi_top, NULL, NULL);
 		pentry++;
 	}
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 20/29] x86, ACPI, irq: provide basic irqdomain support
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (18 preceding siblings ...)
  2014-05-19 16:23 ` [Patch Part1 V2 19/29] x86, irq: enhance mp_register_ioapic() to support irqdomain Jiang Liu
@ 2014-05-19 16:23 ` Jiang Liu
  2014-05-19 16:23 ` [Patch Part1 V2 21/29] x86, mpparse, " Jiang Liu
                   ` (8 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:23 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, Len Brown, Pavel Machek, x86
  Cc: Jiang Liu, Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck,
	Joerg Roedel, Paul Gortmaker, Greg Kroah-Hartman, linux-kernel,
	linux-pci, linux-acpi, linux-pm

Enhance ACPI driver to provide basic irqdomain support for IOAPIC.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/kernel/acpi/boot.c |   20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 66c8feea15a7..4e8566b071c1 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/dmi.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
 #include <linux/slab.h>
 #include <linux/bootmem.h>
 #include <linux/ioport.h>
@@ -331,6 +332,23 @@ static void  mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
 static int mp_register_gsi(struct device *dev, u32 gsi, int trigger,
 			   int polarity);
 
+static struct irq_domain_ops acpi_irqdomain_ops;
+
+static struct irq_domain *acpi_create_irqdomain(int idx, void *arg)
+{
+	struct mp_ioapic_gsi *gsi_cfg = mp_ioapic_gsi_routing(idx);
+
+	/*
+	 * Statically allocate IRQ number for legacy IRQs and all pins on the
+	 * first IOAPIC.
+	 */
+	if (gsi_cfg->gsi_base < NR_IRQS_LEGACY &&
+	    ioapic_dynirq_base < gsi_cfg->gsi_end)
+		ioapic_dynirq_base = gsi_cfg->gsi_end + 1;
+
+	return mp_irqdomain_create(idx, NULL, &acpi_irqdomain_ops);
+}
+
 static int __init
 acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end)
 {
@@ -345,7 +363,7 @@ acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end)
 
 	mp_register_ioapic(ioapic->id,
 			   ioapic->address, ioapic->global_irq_base,
-			   NULL, NULL);
+			   acpi_create_irqdomain, NULL);
 
 	return 0;
 }
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 21/29] x86, mpparse, irq: provide basic irqdomain support
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (19 preceding siblings ...)
  2014-05-19 16:23 ` [Patch Part1 V2 20/29] x86, ACPI, irq: provide basic irqdomain support Jiang Liu
@ 2014-05-19 16:23 ` Jiang Liu
  2014-05-19 16:23 ` [Patch Part1 V2 22/29] x86, devicetree, irq: use common mechanism to support irqdomain Jiang Liu
                   ` (7 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:23 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, x86, Jiang Liu
  Cc: Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck, Joerg Roedel,
	Paul Gortmaker, Greg Kroah-Hartman, linux-kernel, linux-pci,
	linux-acpi

Enhance mpparse to provide basic support of irqdomain with identity
mapping between GSIs and IRQs.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/kernel/mpparse.c |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index 6cb9a43ecde1..b9823bea332a 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <linux/smp.h>
 #include <linux/pci.h>
+#include <linux/irqdomain.h>
 
 #include <asm/mtrr.h>
 #include <asm/mpspec.h>
@@ -112,10 +113,18 @@ static void __init MP_bus_info(struct mpc_bus *m)
 		pr_warn("Unknown bustype %s - ignoring\n", str);
 }
 
+static struct irq_domain_ops mp_ioapic_irqdomain_ops;
+
+static struct irq_domain *mp_ioapic_create_irqdomain(int ioapic, void *arg)
+{
+	return mp_irqdomain_create(ioapic, NULL, &mp_ioapic_irqdomain_ops);
+}
+
 static void __init MP_ioapic_info(struct mpc_ioapic *m)
 {
 	if (m->flags & MPC_APIC_USABLE)
-		mp_register_ioapic(m->apicid, m->apicaddr, gsi_top, NULL, NULL);
+		mp_register_ioapic(m->apicid, m->apicaddr, gsi_top,
+				   mp_ioapic_create_irqdomain, NULL);
 }
 
 static void __init print_mp_irq_info(struct mpc_intsrc *mp_irq)
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 22/29] x86, devicetree, irq: use common mechanism to support irqdomain
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (20 preceding siblings ...)
  2014-05-19 16:23 ` [Patch Part1 V2 21/29] x86, mpparse, " Jiang Liu
@ 2014-05-19 16:23 ` Jiang Liu
  2014-05-19 16:23 ` [Patch Part1 V2 23/29] x86, SFI, irq: provide basic irqdomain support Jiang Liu
                   ` (6 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:23 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, x86, Rob Herring, Michal Simek,
	Tony Lindgren, Jiang Liu
  Cc: Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck, Joerg Roedel,
	Paul Gortmaker, Greg Kroah-Hartman, linux-kernel, linux-pci,
	linux-acpi

Now the ioapic driver provides a common interface to create irqdomain,
so replace the private implementation.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/include/asm/prom.h  |    2 --
 arch/x86/kernel/devicetree.c |   80 ++++--------------------------------------
 arch/x86/kernel/irqinit.c    |    6 ----
 3 files changed, 7 insertions(+), 81 deletions(-)

diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
index fbeb06ed0eaa..1d081ac1cd69 100644
--- a/arch/x86/include/asm/prom.h
+++ b/arch/x86/include/asm/prom.h
@@ -26,12 +26,10 @@
 extern int of_ioapic;
 extern u64 initial_dtb;
 extern void add_dtb(u64 data);
-extern void x86_add_irq_domains(void);
 void x86_of_pci_init(void);
 void x86_dtb_init(void);
 #else
 static inline void add_dtb(u64 data) { }
-static inline void x86_add_irq_domains(void) { }
 static inline void x86_of_pci_init(void) { }
 static inline void x86_dtb_init(void) { }
 #define of_ioapic 0
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index 1ab002c045c9..a44d45df49f5 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -164,6 +164,7 @@ static void __init dtb_lapic_setup(void)
 
 #ifdef CONFIG_X86_IO_APIC
 static unsigned int ioapic_id;
+static struct irq_domain *dt_add_ioapic_domain(int ioapic_num, void *arg);
 
 static void __init dtb_add_ioapic(struct device_node *dn)
 {
@@ -176,7 +177,8 @@ static void __init dtb_add_ioapic(struct device_node *dn)
 				dn->full_name);
 		return;
 	}
-	mp_register_ioapic(++ioapic_id, r.start, gsi_top, NULL, NULL);
+	mp_register_ioapic(++ioapic_id, r.start, gsi_top,
+			   dt_add_ioapic_domain, dn);
 }
 
 static void __init dtb_ioapic_setup(void)
@@ -293,7 +295,7 @@ static int ioapic_xlate(struct irq_domain *domain,
 
 	it = &of_ioapic_type[intspec[1]];
 
-	idx = (u32) domain->host_data;
+	idx = (u32)(long)domain->host_data;
 	set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity);
 
 	rc = io_apic_setup_irq_pin_once(irq_find_mapping(domain, line),
@@ -310,78 +312,10 @@ const struct irq_domain_ops ioapic_irq_domain_ops = {
 	.xlate = ioapic_xlate,
 };
 
-static void dt_add_ioapic_domain(unsigned int ioapic_num,
-		struct device_node *np)
+static struct irq_domain *dt_add_ioapic_domain(int ioapic, void *arg)
 {
-	struct irq_domain *id;
-	struct mp_ioapic_gsi *gsi_cfg;
-	int ret;
-	int num;
-
-	gsi_cfg = mp_ioapic_gsi_routing(ioapic_num);
-	num = gsi_cfg->gsi_end - gsi_cfg->gsi_base + 1;
-
-	id = irq_domain_add_linear(np, num, &ioapic_irq_domain_ops,
-			(void *)ioapic_num);
-	BUG_ON(!id);
-	if (gsi_cfg->gsi_base == 0) {
-		/*
-		 * The first NR_IRQS_LEGACY irq descs are allocated in
-		 * early_irq_init() and need just a mapping. The
-		 * remaining irqs need both. All of them are preallocated
-		 * and assigned so we can keep the 1:1 mapping which the ioapic
-		 * is having.
-		 */
-		irq_domain_associate_many(id, 0, 0, NR_IRQS_LEGACY);
-
-		if (num > NR_IRQS_LEGACY) {
-			ret = irq_create_strict_mappings(id, NR_IRQS_LEGACY,
-					NR_IRQS_LEGACY, num - NR_IRQS_LEGACY);
-			if (ret)
-				pr_err("Error creating mapping for the "
-						"remaining IRQs: %d\n", ret);
-		}
-		irq_set_default_host(id);
-	} else {
-		ret = irq_create_strict_mappings(id, gsi_cfg->gsi_base, 0, num);
-		if (ret)
-			pr_err("Error creating IRQ mapping: %d\n", ret);
-	}
-}
-
-static void __init ioapic_add_ofnode(struct device_node *np)
-{
-	struct resource r;
-	int i, ret;
+	struct device_node *np = arg;
 
-	ret = of_address_to_resource(np, 0, &r);
-	if (ret) {
-		printk(KERN_ERR "Failed to obtain address for %s\n",
-				np->full_name);
-		return;
-	}
-
-	for (i = 0; i < nr_ioapics; i++) {
-		if (r.start == mpc_ioapic_addr(i)) {
-			dt_add_ioapic_domain(i, np);
-			return;
-		}
-	}
-	printk(KERN_ERR "IOxAPIC at %s is not registered.\n", np->full_name);
-}
-
-void __init x86_add_irq_domains(void)
-{
-	struct device_node *dp;
-
-	if (!of_have_populated_dt())
-		return;
-
-	for_each_node_with_property(dp, "interrupt-controller") {
-		if (of_device_is_compatible(dp, "intel,ce4100-ioapic"))
-			ioapic_add_ofnode(dp);
-	}
+	return mp_irqdomain_create(ioapic, np, &ioapic_irq_domain_ops);
 }
-#else
-void __init x86_add_irq_domains(void) { }
 #endif
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index 7f50156542fb..a9c0066762e5 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -87,12 +87,6 @@ void __init init_IRQ(void)
 	int i;
 
 	/*
-	 * We probably need a better place for this, but it works for
-	 * now ...
-	 */
-	x86_add_irq_domains();
-
-	/*
 	 * On cpu 0, Assign IRQ0_VECTOR..IRQ15_VECTOR's to IRQ 0..15.
 	 * If these IRQ's are handled by legacy interrupt-controllers like PIC,
 	 * then this configuration will likely be static after the boot. If
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 23/29] x86, SFI, irq: provide basic irqdomain support
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (21 preceding siblings ...)
  2014-05-19 16:23 ` [Patch Part1 V2 22/29] x86, devicetree, irq: use common mechanism to support irqdomain Jiang Liu
@ 2014-05-19 16:23 ` Jiang Liu
  2014-05-19 16:23 ` [Patch Part1 V2 24/29] x86, irq: introduce two helper functions to support irqdomain map operation Jiang Liu
                   ` (5 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:23 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, Len Brown, x86
  Cc: Jiang Liu, Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck,
	Joerg Roedel, Paul Gortmaker, Greg Kroah-Hartman, linux-kernel,
	linux-pci, linux-acpi, sfi-devel

Enhance SFI to provide basic support of irqdomain with identity mapping
between GSIs and IRQs.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/platform/sfi/sfi.c |   10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/x86/platform/sfi/sfi.c b/arch/x86/platform/sfi/sfi.c
index 3bd7cf642680..2c3522dfa05d 100644
--- a/arch/x86/platform/sfi/sfi.c
+++ b/arch/x86/platform/sfi/sfi.c
@@ -25,6 +25,7 @@
 #include <linux/init.h>
 #include <linux/sfi.h>
 #include <linux/io.h>
+#include <linux/irqdomain.h>
 
 #include <asm/io_apic.h>
 #include <asm/mpspec.h>
@@ -70,6 +71,12 @@ static int __init sfi_parse_cpus(struct sfi_table_header *table)
 #endif /* CONFIG_X86_LOCAL_APIC */
 
 #ifdef CONFIG_X86_IO_APIC
+static struct irq_domain_ops sfi_ioapic_irqdomain_ops;
+
+static struct irq_domain *sfi_ioapic_create_irqdomain(int ioapic, void *arg)
+{
+	return mp_irqdomain_create(ioapic, NULL, &sfi_ioapic_irqdomain_ops);
+}
 
 static int __init sfi_parse_ioapic(struct sfi_table_header *table)
 {
@@ -82,7 +89,8 @@ static int __init sfi_parse_ioapic(struct sfi_table_header *table)
 	pentry = (struct sfi_apic_table_entry *)sb->pentry;
 
 	for (i = 0; i < num; i++) {
-		mp_register_ioapic(i, pentry->phys_addr, gsi_top, NULL, NULL);
+		mp_register_ioapic(i, pentry->phys_addr, gsi_top,
+				   sfi_ioapic_create_irqdomain, NULL);
 		pentry++;
 	}
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 24/29] x86, irq: introduce two helper functions to support irqdomain map operation
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (22 preceding siblings ...)
  2014-05-19 16:23 ` [Patch Part1 V2 23/29] x86, SFI, irq: provide basic irqdomain support Jiang Liu
@ 2014-05-19 16:23 ` Jiang Liu
  2014-05-19 16:23 ` [Patch Part1 V2 25/29] x86, irq, ACPI: use common irqdomain map interface to program IOAPIC pins Jiang Liu
                   ` (4 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:23 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, x86, Jiang Liu
  Cc: Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck, Joerg Roedel,
	Paul Gortmaker, Greg Kroah-Hartman, linux-kernel, linux-pci,
	linux-acpi, Ingo Molnar

Currently there are multiple entries to program IOAPIC pins, such as
io_apic_setup_irq_pin_once(), io_apic_set_pci_routing() and
setup_IO_APIC_irq_extra() etc.

This patch introduces two functions to help consolidate the code to
program IOAPIC pins. Function mp_set_pin_attr() is used to optionally
set trigger, polarity and NUMA node property for an IOAPIC pin.
If mp_set_pin_attr() is not invoked for a pin, the default configuration
from BIOS will be used.

Function mp_irqdomain_map() is an common implementation of irqdomain map()
operation. It figures out attribures for pin and then actually programs
the IOAPIC pin. We hope this will be the only entrance for programming
IOAPIC pin.

And the flow will:
1) caller such as xxx_pci_irq_enable figures out pin attributes.
2) Invoke mp_set_pin_attr() to set attributes for a pin. If the pin has
   already bin programmed,  mp_set_pin_attr() will aslo detects attribute
   confictions.
3) Invoke mp_map_pin_to_irq()
3.1) If IRQ has already been assigned, return irq_find_mapping()
3.2) Else irq_create_mapping()
		->irq_domain_associate()
			->mp_irqdomain_map()
				->io_apic_setup_irq_pin()

So every pin will only programmed once by mp_irqdomain_map(), so we
could kill io_apic_setup_irq_pin_once(), io_apic_set_pci_routing() and
setup_IO_APIC_irq_extra() etc.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/include/asm/io_apic.h |    4 ++
 arch/x86/kernel/apic/io_apic.c |   79 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 82 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 666170437d78..d71da9cc30ae 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -184,6 +184,10 @@ extern void __init mp_register_ioapic(int id, u32 address, u32 gsi_base,
 				      ioapic_create_domain_fn cb, void *arg);
 extern struct irq_domain *mp_irqdomain_create(int ioapic,
 		struct device_node *np, const struct irq_domain_ops *ops);
+extern int mp_irqdomain_map(struct irq_domain *domain, unsigned int virq,
+			    irq_hw_number_t hwirq);
+extern int mp_set_pin_attr(int ioapic, int pin, int trigger, int polarity,
+			   int node);
 extern void __init pre_init_apic_IRQ0(void);
 
 extern void mp_save_irq(struct mpc_intsrc *m);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 1b9dd0a70dfa..6c838a2ecac0 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -86,6 +86,14 @@ static DEFINE_RAW_SPINLOCK(ioapic_lock);
 static DEFINE_RAW_SPINLOCK(vector_lock);
 static DEFINE_MUTEX(ioapic_mutex);
 
+struct mp_pin_info {
+	int trigger;
+	int polarity;
+	int node;
+	int set;
+	u32 count;
+};
+
 static struct ioapic {
 	/*
 	 * # of IRQ routing registers
@@ -99,6 +107,7 @@ static struct ioapic {
 	struct mpc_ioapic mp_config;
 	/* IO APIC gsi routing info */
 	struct mp_ioapic_gsi  gsi_config;
+	struct mp_pin_info *pin_info;
 	struct irq_domain *irqdomain;
 	ioapic_create_domain_fn irqdomain_cb;
 	void *irqdomain_arg;
@@ -140,6 +149,11 @@ static inline int mp_init_irq_at_boot(int ioapic, int irq)
 	return ioapic == 0 || (irq >= 0 && irq < NR_IRQS_LEGACY);
 }
 
+static inline struct mp_pin_info *mp_pin_info(int ioapic_idx, int pin)
+{
+	return ioapics[ioapic_idx].pin_info + pin;
+}
+
 static inline struct irq_domain *mp_ioapic_irqdomain(int ioapic)
 {
 	return ioapics[ioapic].irqdomain;
@@ -987,6 +1001,7 @@ int mp_map_pin_to_irq(int ioapic, int pin, int idx, unsigned int flags)
 	int irq = -1;
 	u32 gsi = mp_pin_2_gsi(ioapic, pin);
 	struct irq_domain *domain = mp_ioapic_irqdomain(ioapic);
+	struct mp_pin_info *info = mp_pin_info(ioapic, pin);
 
 	if (!domain) {
 		/*
@@ -1015,6 +1030,11 @@ int mp_map_pin_to_irq(int ioapic, int pin, int idx, unsigned int flags)
 			irq = irq_create_mapping(domain, pin);
 		else if (irq_create_strict_mappings(domain, gsi, pin, 1) == 0)
 			irq = gsi;
+
+		if (irq > 0)
+			info->count++;
+		else if (info->count == 0)
+			info->set = 0;
 	}
 out:
 	mutex_unlock(&ioapic_mutex);
@@ -2909,11 +2929,14 @@ out:
 
 static void ioapic_create_irqdomains(void)
 {
-	int i;
+	int i, size;
 	struct ioapic *ip;
 
 	for_each_ioapic(i) {
 		ip = &ioapics[i];
+		size = sizeof(struct mp_pin_info) * mp_ioapic_pin_count(i);
+		ip->pin_info = kzalloc(size, GFP_KERNEL);
+		BUG_ON(!ip->pin_info);
 		if (ip->irqdomain_cb)
 			ip->irqdomain = ip->irqdomain_cb(i, ip->irqdomain_arg);
 	}
@@ -3880,6 +3903,60 @@ struct irq_domain *mp_irqdomain_create(int ioapic, struct device_node *np,
 	return domain;
 }
 
+int mp_irqdomain_map(struct irq_domain *domain, unsigned int virq,
+		     irq_hw_number_t hwirq)
+{
+	int ioapic = (int)(long)domain->host_data;
+	struct mp_pin_info *info = mp_pin_info(ioapic, hwirq);
+	struct io_apic_irq_attr attr;
+
+	/*
+	 * 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(ioapic, virq))
+		return 0;
+
+	/* Get default attribute if not set by caller yet */
+	if (!info->set) {
+		u32 gsi = mp_pin_2_gsi(ioapic, hwirq);
+		if (acpi_get_override_irq(gsi, &info->trigger,
+					  &info->polarity) < 0) {
+			return -ENODEV;
+		}
+		info->node = NUMA_NO_NODE;
+		info->set = 1;
+	}
+
+	set_io_apic_irq_attr(&attr, ioapic, hwirq, info->trigger,
+			     info->polarity);
+
+	return io_apic_setup_irq_pin(virq, info->node, &attr);
+}
+
+int mp_set_pin_attr(int ioapic, int pin, int trigger, int polarity, int node)
+{
+	int ret = 0;
+	struct mp_pin_info *info = mp_pin_info(ioapic, pin);
+
+	trigger = !!trigger;
+	polarity = !!polarity;
+
+	mutex_lock(&ioapic_mutex);
+	if (!info->set) {
+		info->trigger = trigger;
+		info->polarity = polarity;
+		info->node = node;
+		info->set = 1;
+	} else if (info->trigger != trigger || info->polarity != polarity) {
+		ret = -EBUSY;
+	}
+	mutex_unlock(&ioapic_mutex);
+
+	return ret;
+}
+
 /* Enable IOAPIC early just for system timer */
 void __init pre_init_apic_IRQ0(void)
 {
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 25/29] x86, irq, ACPI: use common irqdomain map interface to program IOAPIC pins
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (23 preceding siblings ...)
  2014-05-19 16:23 ` [Patch Part1 V2 24/29] x86, irq: introduce two helper functions to support irqdomain map operation Jiang Liu
@ 2014-05-19 16:23 ` Jiang Liu
  2014-05-19 16:23 ` [Patch Part1 V2 26/29] x86, irq, mpparse: " Jiang Liu
                   ` (3 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:23 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, Len Brown, Pavel Machek, x86
  Cc: Jiang Liu, Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck,
	Joerg Roedel, Paul Gortmaker, Greg Kroah-Hartman, linux-kernel,
	linux-pci, linux-acpi, linux-pm

Refine ACPI to use common irqdomain map interface to program IOAPIC pins,
so we can unify the callsite to progam IOAPIC pins.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/kernel/acpi/boot.c |   48 ++++++++++++++++---------------------------
 1 file changed, 18 insertions(+), 30 deletions(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 4e8566b071c1..68baa34b8346 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -332,7 +332,9 @@ static void  mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
 static int mp_register_gsi(struct device *dev, u32 gsi, int trigger,
 			   int polarity);
 
-static struct irq_domain_ops acpi_irqdomain_ops;
+static struct irq_domain_ops acpi_irqdomain_ops = {
+	.map = mp_irqdomain_map,
+};
 
 static struct irq_domain *acpi_create_irqdomain(int idx, void *arg)
 {
@@ -512,10 +514,6 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp)
 	int irq = map_gsi_to_irq(gsi, IOAPIC_MAP_ALLOC | IOAPIC_MAP_CHECK);
 
 	if (irq >= 0) {
-#ifdef CONFIG_X86_IO_APIC
-		if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
-			setup_IO_APIC_irq_extra(gsi);
-#endif
 		*irqp = irq;
 		return 0;
 	}
@@ -1047,11 +1045,7 @@ static int mp_config_acpi_gsi(struct device *dev, u32 gsi, int trigger,
 static int mp_register_gsi(struct device *dev, u32 gsi, int trigger,
 			   int polarity)
 {
-	int irq;
-	int ioapic;
-	int ioapic_pin;
-	struct io_apic_irq_attr irq_attr;
-	int ret;
+	int irq, ioapic, pin, node;
 
 	if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
 		return gsi;
@@ -1060,35 +1054,29 @@ static int mp_register_gsi(struct device *dev, u32 gsi, int trigger,
 	if (acpi_gbl_FADT.sci_interrupt == gsi)
 		return gsi;
 
-	irq = map_gsi_to_irq(gsi, IOAPIC_MAP_ALLOC);
-	if (irq < 0)
-		return ACPI_INVALID_GSI;
-
 	ioapic = mp_find_ioapic(gsi);
 	if (ioapic < 0) {
-		printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi);
-		return gsi;
+		pr_warn("No IOAPIC for GSI %u\n", gsi);
+		return ACPI_INVALID_GSI;
 	}
 
-	ioapic_pin = mp_find_ioapic_pin(ioapic, gsi);
-
-	if (ioapic_pin > MP_MAX_IOAPIC_PIN) {
-		printk(KERN_ERR "Invalid reference to IOAPIC pin "
-		       "%d-%d\n", mpc_ioapic_id(ioapic),
-		       ioapic_pin);
-		return gsi;
+	pin = mp_find_ioapic_pin(ioapic, gsi);
+	node = dev ? dev_to_node(dev) : NUMA_NO_NODE;
+	if (mp_set_pin_attr(ioapic, pin,
+			    trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,
+			    polarity == ACPI_ACTIVE_HIGH ? 0 : 1,
+			    node)) {
+		pr_warn("Failed to set pin attr for GSI%d\n", gsi);
+		return ACPI_INVALID_GSI;
 	}
 
+	irq = map_gsi_to_irq(gsi, IOAPIC_MAP_ALLOC);
+	if (irq < 0)
+		return ACPI_INVALID_GSI;
+
 	if (enable_update_mptable)
 		mp_config_acpi_gsi(dev, gsi, trigger, polarity);
 
-	set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin,
-			     trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,
-			     polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
-	ret = io_apic_set_pci_routing(dev, irq, &irq_attr);
-	if (ret < 0)
-		gsi = ACPI_INVALID_GSI;
-
 	return gsi;
 }
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 26/29] x86, irq, mpparse: use common irqdomain map interface to program IOAPIC pins
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (24 preceding siblings ...)
  2014-05-19 16:23 ` [Patch Part1 V2 25/29] x86, irq, ACPI: use common irqdomain map interface to program IOAPIC pins Jiang Liu
@ 2014-05-19 16:23 ` Jiang Liu
  2014-05-19 16:23 ` [Patch Part1 V2 27/29] x86, irq, SFI: " Jiang Liu
                   ` (2 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:23 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, x86, Jiang Liu
  Cc: Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck, Joerg Roedel,
	Paul Gortmaker, Greg Kroah-Hartman, linux-kernel, linux-pci,
	linux-acpi

Refine mpparse to use common irqdomain map interface to program IOAPIC pins,
so we can unify the callsite to progam IOAPIC pins.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/kernel/mpparse.c |    4 +++-
 arch/x86/pci/irq.c        |    2 --
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index b9823bea332a..55acf55b41e7 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -113,7 +113,9 @@ static void __init MP_bus_info(struct mpc_bus *m)
 		pr_warn("Unknown bustype %s - ignoring\n", str);
 }
 
-static struct irq_domain_ops mp_ioapic_irqdomain_ops;
+static struct irq_domain_ops mp_ioapic_irqdomain_ops = {
+	.map = mp_irqdomain_map,
+};
 
 static struct irq_domain *mp_ioapic_create_irqdomain(int ioapic, void *arg)
 {
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index 84112f55dd7a..e4200e5e775e 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -1227,8 +1227,6 @@ static int pirq_enable_irq(struct pci_dev *dev)
 			}
 			dev = temp_dev;
 			if (irq >= 0) {
-				io_apic_set_pci_routing(&dev->dev, irq,
-							 &irq_attr);
 				dev->irq = irq;
 				dev_info(&dev->dev, "PCI->APIC IRQ transform: "
 					 "INT %c -> IRQ %d\n", 'A' + pin - 1, irq);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 27/29] x86, irq, SFI: use common irqdomain map interface to program IOAPIC pins
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (25 preceding siblings ...)
  2014-05-19 16:23 ` [Patch Part1 V2 26/29] x86, irq, mpparse: " Jiang Liu
@ 2014-05-19 16:23 ` Jiang Liu
  2014-05-19 16:23 ` [Patch Part1 V2 28/29] x86, irq, devicetree: " Jiang Liu
  2014-05-19 16:23 ` [Patch Part1 V2 29/29] x86, irq: clean up unused IOAPIC interface Jiang Liu
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:23 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, x86, Len Brown, David Cohen,
	Kuppuswamy Sathyanarayanan, Jiang Liu
  Cc: Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck, Joerg Roedel,
	Paul Gortmaker, Greg Kroah-Hartman, linux-kernel, linux-pci,
	linux-acpi, H. Peter Anvin, sfi-devel

Refine SFI to use common irqdomain map interface to program IOAPIC pins,
so we can unify the callsite to progam IOAPIC pins.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/pci/intel_mid_pci.c      |   17 +++++++----------
 arch/x86/platform/intel-mid/sfi.c |   18 +++++++++---------
 arch/x86/platform/sfi/sfi.c       |    4 +++-
 3 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/arch/x86/pci/intel_mid_pci.c b/arch/x86/pci/intel_mid_pci.c
index 84b9d672843d..f6f3de857baa 100644
--- a/arch/x86/pci/intel_mid_pci.c
+++ b/arch/x86/pci/intel_mid_pci.c
@@ -208,23 +208,20 @@ static int pci_write(struct pci_bus *bus, unsigned int devfn, int where,
 
 static int intel_mid_pci_irq_enable(struct pci_dev *dev)
 {
-	u8 pin;
-	struct io_apic_irq_attr irq_attr;
-
-	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+	int ioapic, polarity;
 
 	/*
 	 * MRST only have IOAPIC, the PCI irq lines are 1:1 mapped to
 	 * IOAPIC RTE entries, so we just enable RTE for the device.
 	 */
-	irq_attr.ioapic = mp_find_ioapic(dev->irq);
-	irq_attr.ioapic_pin = dev->irq;
-	irq_attr.trigger = 1; /* level */
+	ioapic = mp_find_ioapic(dev->irq);
 	if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_TANGIER)
-		irq_attr.polarity = 0; /* active high */
+		polarity = 0; /* active high */
 	else
-		irq_attr.polarity = 1; /* active low */
-	io_apic_set_pci_routing(&dev->dev, dev->irq, &irq_attr);
+		polarity = 1; /* active low */
+	if (mp_set_pin_attr(ioapic, dev->irq, 1, polarity, dev_to_node(dev)))
+		return -EBUSY;
+	mp_map_gsi_to_irq(dev->irq, 1);
 
 	return 0;
 }
diff --git a/arch/x86/platform/intel-mid/sfi.c b/arch/x86/platform/intel-mid/sfi.c
index 994c40bd7cb7..3fe5c23ba1c5 100644
--- a/arch/x86/platform/intel-mid/sfi.c
+++ b/arch/x86/platform/intel-mid/sfi.c
@@ -434,6 +434,7 @@ static int __init sfi_parse_devs(struct sfi_table_header *table)
 	struct devs_id *dev = NULL;
 	int num, i;
 	int ioapic;
+	int polarity;
 	struct io_apic_irq_attr irq_attr;
 
 	sb = (struct sfi_table_simple *)table;
@@ -450,30 +451,29 @@ static int __init sfi_parse_devs(struct sfi_table_header *table)
 			 */
 			ioapic = mp_find_ioapic(irq);
 			if (ioapic >= 0) {
-				irq_attr.ioapic = ioapic;
-				irq_attr.ioapic_pin = irq;
-				irq_attr.trigger = 1;
 				if (intel_mid_identify_cpu() ==
 						INTEL_MID_CPU_CHIP_TANGIER) {
 					if (!strncmp(pentry->name,
 							"r69001-ts-i2c", 13))
 						/* active low */
-						irq_attr.polarity = 1;
+						polarity = 1;
 					else if (!strncmp(pentry->name,
 							"synaptics_3202", 14))
 						/* active low */
-						irq_attr.polarity = 1;
+						polarity = 1;
 					else if (irq == 41)
 						/* fast_int_1 */
-						irq_attr.polarity = 1;
+						polarity = 1;
 					else
 						/* active high */
-						irq_attr.polarity = 0;
+						polarity = 0;
 				} else {
 					/* PNW and CLV go with active low */
-					irq_attr.polarity = 1;
+					polarity = 1;
 				}
-				io_apic_set_pci_routing(NULL, irq, &irq_attr);
+				if (mp_set_pin_attr(ioapic, irq, 1, polarity, NUMA_NO_NODE))
+					return -EBUSY;
+				mp_map_gsi_to_irq(dev->irq, 1);
 			}
 		} else {
 			irq = 0; /* No irq */
diff --git a/arch/x86/platform/sfi/sfi.c b/arch/x86/platform/sfi/sfi.c
index 2c3522dfa05d..91e5046efae9 100644
--- a/arch/x86/platform/sfi/sfi.c
+++ b/arch/x86/platform/sfi/sfi.c
@@ -71,7 +71,9 @@ static int __init sfi_parse_cpus(struct sfi_table_header *table)
 #endif /* CONFIG_X86_LOCAL_APIC */
 
 #ifdef CONFIG_X86_IO_APIC
-static struct irq_domain_ops sfi_ioapic_irqdomain_ops;
+static struct irq_domain_ops sfi_ioapic_irqdomain_ops = {
+	.map = mp_irqdomain_map,
+};
 
 static struct irq_domain *sfi_ioapic_create_irqdomain(int ioapic, void *arg)
 {
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 28/29] x86, irq, devicetree: use common irqdomain map interface to program IOAPIC pins
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (26 preceding siblings ...)
  2014-05-19 16:23 ` [Patch Part1 V2 27/29] x86, irq, SFI: " Jiang Liu
@ 2014-05-19 16:23 ` Jiang Liu
  2014-05-19 16:23 ` [Patch Part1 V2 29/29] x86, irq: clean up unused IOAPIC interface Jiang Liu
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:23 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, x86, Rob Herring, Michal Simek,
	Tony Lindgren, Jiang Liu
  Cc: Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck, Joerg Roedel,
	Paul Gortmaker, Greg Kroah-Hartman, linux-kernel, linux-pci,
	linux-acpi

Refine devicetree to use common irqdomain map interface to program
IOAPIC pins, so we can unify the callsite to progam IOAPIC pins.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/kernel/devicetree.c |   12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index a44d45df49f5..3bd30eb92d9d 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -280,10 +280,8 @@ static int ioapic_xlate(struct irq_domain *domain,
 			const u32 *intspec, u32 intsize,
 			irq_hw_number_t *out_hwirq, u32 *out_type)
 {
-	struct io_apic_irq_attr attr;
 	struct of_ioapic_type *it;
 	u32 line, idx;
-	int rc;
 
 	if (WARN_ON(intsize < 2))
 		return -EINVAL;
@@ -296,12 +294,9 @@ static int ioapic_xlate(struct irq_domain *domain,
 	it = &of_ioapic_type[intspec[1]];
 
 	idx = (u32)(long)domain->host_data;
-	set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity);
-
-	rc = io_apic_setup_irq_pin_once(irq_find_mapping(domain, line),
-					cpu_to_node(0), &attr);
-	if (rc)
-		return rc;
+	if (mp_set_pin_attr(idx, line, it->trigger, it->polarity,
+			    cpu_to_node(0)))
+		return -EBUSY;
 
 	*out_hwirq = line;
 	*out_type = it->out_type;
@@ -309,6 +304,7 @@ static int ioapic_xlate(struct irq_domain *domain,
 }
 
 const struct irq_domain_ops ioapic_irq_domain_ops = {
+	.map = mp_irqdomain_map,
 	.xlate = ioapic_xlate,
 };
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Patch Part1 V2 29/29] x86, irq: clean up unused IOAPIC interface
  2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
                   ` (27 preceding siblings ...)
  2014-05-19 16:23 ` [Patch Part1 V2 28/29] x86, irq, devicetree: " Jiang Liu
@ 2014-05-19 16:23 ` Jiang Liu
  28 siblings, 0 replies; 30+ messages in thread
From: Jiang Liu @ 2014-05-19 16:23 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, x86, Jiang Liu
  Cc: Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck, Joerg Roedel,
	Paul Gortmaker, Greg Kroah-Hartman, linux-kernel, linux-pci,
	linux-acpi, Ingo Molnar

Now we have converted all x86 platforms to use the common irqdomain map
interface. There's no caller of io_apic_set_pci_routing(),
setup_IO_APIC_irq_extra() and io_apic_setup_irq_pin_once() any more,
so kill them.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/include/asm/io_apic.h |    9 ------
 arch/x86/kernel/apic/io_apic.c |   70 ----------------------------------------
 2 files changed, 79 deletions(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index d71da9cc30ae..ff6f253e049f 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -144,9 +144,6 @@ extern int ioapic_dynirq_base;
 
 struct io_apic_irq_attr;
 struct irq_cfg;
-extern int io_apic_set_pci_routing(struct device *dev, int irq,
-		 struct io_apic_irq_attr *irq_attr);
-extern void setup_IO_APIC_irq_extra(u32 gsi);
 extern void ioapic_insert_resources(void);
 
 extern int native_setup_ioapic_entry(int, struct IO_APIC_route_entry *,
@@ -158,8 +155,6 @@ extern void native_compose_msi_msg(struct pci_dev *pdev,
 				   unsigned int irq, unsigned int dest,
 				   struct msi_msg *msg, u8 hpet_id);
 extern void native_eoi_ioapic_pin(int apic, int pin, int vector);
-extern int io_apic_setup_irq_pin_once(unsigned int irq, int node,
-				      struct io_apic_irq_attr *attr);
 
 extern int save_ioapic_entries(void);
 extern void mask_ioapic_entries(void);
@@ -234,10 +229,6 @@ static inline int mp_map_pin_to_irq(int ioapic, int pin, int idx,
 	return -1;
 }
 
-struct io_apic_irq_attr;
-static inline int io_apic_set_pci_routing(struct device *dev, int irq,
-		 struct io_apic_irq_attr *irq_attr) { return 0; }
-
 static inline int save_ioapic_entries(void)
 {
 	return -ENOMEM;
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 6c838a2ecac0..898f1c766e9b 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -111,7 +111,6 @@ static struct ioapic {
 	struct irq_domain *irqdomain;
 	ioapic_create_domain_fn irqdomain_cb;
 	void *irqdomain_arg;
-	DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
 } ioapics[MAX_IO_APICS];
 
 #define mpc_ioapic_ver(ioapic_idx)	ioapics[ioapic_idx].mp_config.apicver
@@ -1497,38 +1496,6 @@ static void __init setup_IO_APIC_irqs(void)
 }
 
 /*
- * for the gsi that is not in first ioapic
- * but could not use acpi_register_gsi()
- * like some special sci in IBM x3330
- */
-void setup_IO_APIC_irq_extra(u32 gsi)
-{
-	int ioapic_idx = 0, pin, idx, irq, node = cpu_to_node(0);
-	struct io_apic_irq_attr attr;
-
-	/*
-	 * Convert 'gsi' to 'ioapic.pin'.
-	 */
-	ioapic_idx = mp_find_ioapic(gsi);
-	if (ioapic_idx < 0)
-		return;
-
-	pin = mp_find_ioapic_pin(ioapic_idx, gsi);
-	idx = find_irq_entry(ioapic_idx, pin, mp_INT);
-	if (idx == -1)
-		return;
-
-	irq = pin_2_irq(idx, ioapic_idx, pin, IOAPIC_MAP_ALLOC);
-	if (irq < 0 || mp_init_irq_at_boot(ioapic_idx, irq))
-		return;
-
-	set_io_apic_irq_attr(&attr, ioapic_idx, pin, irq_trigger(idx),
-			     irq_polarity(idx));
-
-	io_apic_setup_irq_pin_once(irq, node, &attr);
-}
-
-/*
  * Set up the timer pin, possibly with the 8259A-master behind.
  */
 static void __init setup_timer_IRQ0_pin(unsigned int ioapic_idx,
@@ -3415,27 +3382,6 @@ io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr)
 	return ret;
 }
 
-int io_apic_setup_irq_pin_once(unsigned int irq, int node,
-			       struct io_apic_irq_attr *attr)
-{
-	unsigned int ioapic_idx = attr->ioapic, pin = attr->ioapic_pin;
-	int ret;
-	struct IO_APIC_route_entry orig_entry;
-
-	/* Avoid redundant programming */
-	if (test_bit(pin, ioapics[ioapic_idx].pin_programmed)) {
-		pr_debug("Pin %d-%d already programmed\n", mpc_ioapic_id(ioapic_idx), pin);
-		orig_entry = ioapic_read_entry(attr->ioapic, pin);
-		if (attr->trigger == orig_entry.trigger && attr->polarity == orig_entry.polarity)
-			return 0;
-		return -EBUSY;
-	}
-	ret = io_apic_setup_irq_pin(irq, node, attr);
-	if (!ret)
-		set_bit(pin, ioapics[ioapic_idx].pin_programmed);
-	return ret;
-}
-
 static int __init io_apic_get_redir_entries(int ioapic)
 {
 	union IO_APIC_reg_01	reg_01;
@@ -3482,22 +3428,6 @@ int __init arch_probe_nr_irqs(void)
 	return NR_IRQS_LEGACY;
 }
 
-int io_apic_set_pci_routing(struct device *dev, int irq,
-			    struct io_apic_irq_attr *irq_attr)
-{
-	int node;
-
-	if (!IO_APIC_IRQ(irq)) {
-		apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n",
-			    irq_attr->ioapic);
-		return -EINVAL;
-	}
-
-	node = dev ? dev_to_node(dev) : cpu_to_node(0);
-
-	return io_apic_setup_irq_pin_once(irq, node, irq_attr);
-}
-
 #ifdef CONFIG_X86_32
 static int __init io_apic_get_unique_id(int ioapic, int apic_id)
 {
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2014-05-19 16:25 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-19 16:22 [Patch Part1 V2 00/29] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
2014-05-19 16:22 ` [Patch Part1 V2 01/29] x86, irq: update high address field when updating affinity for MSI IRQ Jiang Liu
2014-05-19 16:22 ` [Patch Part1 V2 02/29] genirq, trivial: improve documentation to match current implementation Jiang Liu
2014-05-19 16:22 ` [Patch Part1 V2 03/29] x86, mpparse: use pr_lvl() helper utilities to replace printk(KERN_LVL) Jiang Liu
2014-05-19 16:22 ` [Patch Part1 V2 04/29] x86, mpparse: simplify arch/x86/include/asm/mpspec.h Jiang Liu
2014-05-19 16:22 ` [Patch Part1 V2 05/29] x86, PCI, ACPI: use kmalloc_node() to optimize for performance Jiang Liu
2014-05-19 16:22 ` [Patch Part1 V2 06/29] x86, acpi, irq: kill static function irq_to_gsi() Jiang Liu
2014-05-19 16:22 ` [Patch Part1 V2 07/29] x86, ACPI, trivial: minor improvements to arch/x86/kernel/acpi/boot.c Jiang Liu
2014-05-19 16:22 ` [Patch Part1 V2 08/29] x86, ACPI, irq: enhance error handling in function acpi_register_gsi() Jiang Liu
2014-05-19 16:22 ` [Patch Part1 V2 09/29] x86, ACPI, irq: fix possible eror in GSI to IRQ mapping for legacy IRQ Jiang Liu
2014-05-19 16:22 ` [Patch Part1 V2 10/29] x86, irq, trivial: minor improvements of IRQ related code Jiang Liu
2014-05-19 16:22 ` [Patch Part1 V2 11/29] x86, ioapic: kill unused global variable timer_through_8259 Jiang Liu
2014-05-19 16:22 ` [Patch Part1 V2 12/29] x86, ioapic: kill static variable nr_irqs_gsi Jiang Liu
2014-05-19 16:22 ` [Patch Part1 V2 13/29] x86, ioapic: introduce helper utilities to walk ioapics and pins Jiang Liu
2014-05-19 16:22 ` [Patch Part1 V2 14/29] x86, ioapic: use irq_cfg() instead of irq_get_chip_data() for better readability Jiang Liu
2014-05-19 16:22 ` [Patch Part1 V2 15/29] x86, irq: reorganize IO_APIC_get_PCI_irq_vector() to prepare for irqdomain Jiang Liu
2014-05-19 16:23 ` [Patch Part1 V2 16/29] x86, irq: introduce some helper utilities to improve readability Jiang Liu
2014-05-19 16:23 ` [Patch Part1 V2 17/29] x86, ACPI, irq: consolidate algorithm of mapping (ioapic, pin) to IRQ number Jiang Liu
2014-05-19 16:23 ` [Patch Part1 V2 18/29] x86, irq: introduce mechanisms to support dynamically allocate IRQ for IOAPIC Jiang Liu
2014-05-19 16:23 ` [Patch Part1 V2 19/29] x86, irq: enhance mp_register_ioapic() to support irqdomain Jiang Liu
2014-05-19 16:23 ` [Patch Part1 V2 20/29] x86, ACPI, irq: provide basic irqdomain support Jiang Liu
2014-05-19 16:23 ` [Patch Part1 V2 21/29] x86, mpparse, " Jiang Liu
2014-05-19 16:23 ` [Patch Part1 V2 22/29] x86, devicetree, irq: use common mechanism to support irqdomain Jiang Liu
2014-05-19 16:23 ` [Patch Part1 V2 23/29] x86, SFI, irq: provide basic irqdomain support Jiang Liu
2014-05-19 16:23 ` [Patch Part1 V2 24/29] x86, irq: introduce two helper functions to support irqdomain map operation Jiang Liu
2014-05-19 16:23 ` [Patch Part1 V2 25/29] x86, irq, ACPI: use common irqdomain map interface to program IOAPIC pins Jiang Liu
2014-05-19 16:23 ` [Patch Part1 V2 26/29] x86, irq, mpparse: " Jiang Liu
2014-05-19 16:23 ` [Patch Part1 V2 27/29] x86, irq, SFI: " Jiang Liu
2014-05-19 16:23 ` [Patch Part1 V2 28/29] x86, irq, devicetree: " Jiang Liu
2014-05-19 16:23 ` [Patch Part1 V2 29/29] x86, irq: clean up unused IOAPIC interface Jiang Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).