linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/25] irq_domain generalization and refinement
@ 2012-01-27 21:35 Grant Likely
  2012-01-27 21:35 ` [PATCH v3 01/25] irq_domain: add documentation and MAINTAINERS entry Grant Likely
                   ` (27 more replies)
  0 siblings, 28 replies; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:35 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev

Hey everyone,

This patch series is ready for much wider consumption now.  I'd like
to get it into linux-next ASAP because there will be ARM board support
depending on it.  I'll wait a few days before I ask Stephen to pull
this in.

Stephen/Milton/Ben, any testing you can help with here would be
appreciated since you've got access to a wider variety of Power
machines than I do.

Thomas, I think it makes sense to maintain this in a separate branch
from other irq changes until the next merge window.  If you prefer,
I'm happy to maintain this branch until then.

Cheers,
g.

The following changes since commit dcd6c92267155e70a94b3927bce681ce74b80d1f:

  Linux 3.3-rc1 (2012-01-19 15:04:48 -0800)

are available in the git repository at:
  git://git.secretlab.ca/git/linux-2.6 irqdomain/next

Grant Likely (24):
      irq_domain: add documentation and MAINTAINERS entry.
      dt: Make irqdomain less verbose
      irq_domain: Make irq_domain structure match powerpc's irq_host
      irq_domain: convert microblaze from irq_host to irq_domain
      irq_domain/powerpc: Use common irq_domain structure instead of irq_host
      irq_domain/powerpc: eliminate irq_map; use irq_alloc_desc() instead
      irq_domain/powerpc: Eliminate virq_is_host()
      irq_domain: Move irq_domain code from powerpc to kernel/irq
      irqdomain: remove NO_IRQ from irq domain code
      irq_domain: Remove references to old irq_host names
      irq_domain: Replace irq_alloc_host() with revmap-specific initializers
      irq_domain: Add support for base irq and hwirq in legacy mappings
      irq_domain: Remove 'new' irq_domain in favour of the ppc one
      irq_domain: Remove irq_domain_add_simple()
      irq_domain: Create common xlate functions that device drivers can use
      irq_domain: constify irq_domain_ops
      irq_domain/c6x: constify irq_domain structures
      irq_domain/c6x: Use library of xlate functions
      irq_domain/powerpc: constify irq_domain_ops
      irqdomain/powerpc: Replace custom xlate functions with library functions
      irq_domain/x86: Convert x86 (embedded) to use common irq_domain
      irq_domain: Include hwirq number in /proc/interrupts
      irq_domain: remove "hint" when allocating irq numbers
      irq_domain: mostly eliminate slow-path revmap lookups

Mark Salter (1):
      irq_domain/c6x: Convert c6x to use generic irq_domain support.

 Documentation/IRQ-domain.txt                     |  113 +++
 MAINTAINERS                                      |    9 +
 arch/arm/common/gic.c                            |   95 ++--
 arch/arm/common/vic.c                            |   16 +-
 arch/arm/include/asm/hardware/gic.h              |    4 +-
 arch/arm/include/asm/hardware/vic.h              |    2 +
 arch/arm/mach-exynos/common.c                    |    2 +-
 arch/arm/mach-imx/mach-imx6q.c                   |    3 +-
 arch/arm/mach-msm/board-msm8x60.c                |    8 +-
 arch/arm/mach-mx5/imx51-dt.c                     |    4 +-
 arch/arm/mach-mx5/imx53-dt.c                     |    4 +-
 arch/arm/mach-omap2/board-generic.c              |    2 +-
 arch/arm/mach-prima2/irq.c                       |    2 +-
 arch/arm/mach-versatile/core.c                   |    5 +-
 arch/c6x/Kconfig                                 |    1 +
 arch/c6x/include/asm/irq.h                       |  245 +-------
 arch/c6x/kernel/irq.c                            |  612 +----------------
 arch/c6x/platforms/megamod-pic.c                 |   25 +-
 arch/microblaze/include/asm/irq.h                |    4 +-
 arch/microblaze/kernel/irq.c                     |    2 +-
 arch/microblaze/kernel/setup.c                   |    2 -
 arch/powerpc/Kconfig                             |    1 +
 arch/powerpc/include/asm/ehv_pic.h               |    2 +-
 arch/powerpc/include/asm/i8259.h                 |    2 +-
 arch/powerpc/include/asm/irq.h                   |  247 +-------
 arch/powerpc/include/asm/mpic.h                  |    2 +-
 arch/powerpc/include/asm/xics.h                  |    2 +-
 arch/powerpc/kernel/irq.c                        |  617 +----------------
 arch/powerpc/platforms/512x/mpc5121_ads_cpld.c   |   12 +-
 arch/powerpc/platforms/52xx/media5200.c          |   15 +-
 arch/powerpc/platforms/52xx/mpc52xx_gpt.c        |   16 +-
 arch/powerpc/platforms/52xx/mpc52xx_pic.c        |   12 +-
 arch/powerpc/platforms/82xx/pq2ads-pci-pic.c     |   14 +-
 arch/powerpc/platforms/85xx/socrates_fpga_pic.c  |   15 +-
 arch/powerpc/platforms/86xx/gef_pic.c            |   15 +-
 arch/powerpc/platforms/cell/axon_msi.c           |   29 +-
 arch/powerpc/platforms/cell/beat_interrupt.c     |   16 +-
 arch/powerpc/platforms/cell/interrupt.c          |   16 +-
 arch/powerpc/platforms/cell/spider-pic.c         |   14 +-
 arch/powerpc/platforms/embedded6xx/flipper-pic.c |   30 +-
 arch/powerpc/platforms/embedded6xx/hlwd-pic.c    |   35 +-
 arch/powerpc/platforms/iseries/irq.c             |   11 +-
 arch/powerpc/platforms/powermac/pic.c            |   26 +-
 arch/powerpc/platforms/powermac/smp.c            |    9 +-
 arch/powerpc/platforms/ps3/interrupt.c           |   11 +-
 arch/powerpc/platforms/wsp/opb_pic.c             |   26 +-
 arch/powerpc/sysdev/cpm1.c                       |    9 +-
 arch/powerpc/sysdev/cpm2_pic.c                   |   23 +-
 arch/powerpc/sysdev/ehv_pic.c                    |   14 +-
 arch/powerpc/sysdev/fsl_msi.c                    |   10 +-
 arch/powerpc/sysdev/fsl_msi.h                    |    2 +-
 arch/powerpc/sysdev/i8259.c                      |   15 +-
 arch/powerpc/sysdev/ipic.c                       |   31 +-
 arch/powerpc/sysdev/ipic.h                       |    2 +-
 arch/powerpc/sysdev/mpc8xx_pic.c                 |   11 +-
 arch/powerpc/sysdev/mpic.c                       |   17 +-
 arch/powerpc/sysdev/mpic_msi.c                   |    2 +-
 arch/powerpc/sysdev/mv64x60_pic.c                |   11 +-
 arch/powerpc/sysdev/qe_lib/qe_ic.c               |   26 +-
 arch/powerpc/sysdev/qe_lib/qe_ic.h               |    2 +-
 arch/powerpc/sysdev/tsi108_pci.c                 |   22 +-
 arch/powerpc/sysdev/uic.c                        |   26 +-
 arch/powerpc/sysdev/xics/xics-common.c           |   28 +-
 arch/powerpc/sysdev/xilinx_intc.c                |   19 +-
 arch/x86/Kconfig                                 |    2 +
 arch/x86/include/asm/irq_controller.h            |   12 -
 arch/x86/include/asm/prom.h                      |   10 -
 arch/x86/kernel/devicetree.c                     |  101 +--
 drivers/gpio/gpio-mpc8xxx.c                      |   30 +-
 drivers/mfd/twl-core.c                           |   12 +-
 drivers/net/phy/mdio-gpio.c                      |    4 +-
 include/linux/irqdomain.h                        |  190 ++++--
 kernel/irq/irqdomain.c                           |  816 +++++++++++++++++++---
 kernel/irq/proc.c                                |    3 +
 74 files changed, 1334 insertions(+), 2471 deletions(-)
 create mode 100644 Documentation/IRQ-domain.txt
 delete mode 100644 arch/x86/include/asm/irq_controller.h


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

* [PATCH v3 01/25] irq_domain: add documentation and MAINTAINERS entry.
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
@ 2012-01-27 21:35 ` Grant Likely
  2012-01-28 18:23   ` Randy Dunlap
  2012-01-27 21:35 ` [PATCH v3 02/25] dt: Make irqdomain less verbose Grant Likely
                   ` (26 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:35 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely

Documentation for irq_domain library which will be created in subsequent
patches.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Milton Miller <miltonm@bga.com>
---
 Documentation/IRQ-domain.txt |  113 ++++++++++++++++++++++++++++++++++++++++++
 MAINTAINERS                  |    9 +++
 2 files changed, 122 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/IRQ-domain.txt

diff --git a/Documentation/IRQ-domain.txt b/Documentation/IRQ-domain.txt
new file mode 100644
index 0000000..247f32a
--- /dev/null
+++ b/Documentation/IRQ-domain.txt
@@ -0,0 +1,113 @@
+irq_domain interrupt number mapping library
+
+The current design of the Linux kernel uses a single large number
+space where each separate IRQ source is assigned a different number.
+This is simple when there is only one interrupt controller, but in
+systems with controllers the kernel must ensure that each one does not
+get assigned overlapping allocations of Linux irq numbers.
+
+The irq_alloc_desc*() and irq_free_desc*() API provides allocation of
+irq numbers, but it doesn't provide any support for reverse mapping of
+the controller-local irq (hwirq) number into the Linux irq number
+space.
+
+The irq_domain library adds mapping between hwirq and irq numbers on
+top of the irq_alloc_desc*() API.  An irq_domain to manage mapping is
+preferred over interrupt controller drivers open coding their own
+reverse mapping scheme.
+
+irq_domain also implements translation from Device Tree interrupt
+specifiers to hwirq numbers, and can be easily extended to support
+other irq topology data sources.
+
+=== irq_domain usage ===
+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.  It must provide
+the allocator function with an irq_domain_ops structure with the .map
+callback populated as a minimum.
+
+In most cases, the irq_domain will begin empty without any mappings
+between hwirq and irq numbers.  Mappings are added to the irq_domain
+by calling irq_create_mapping() which accepts the irq_domain and a
+hwirq number as arguments.  If a mapping for the hwirq doesn't already
+exist then it will allocate a new linux irq_desc, associate it with
+the hwirq, and call the .map() callback so the driver can perform any
+required hardware setup.
+
+When an interrupt is received, irq_find_mapping() function should
+be used to find the Linux irq number from the hwirq number.
+
+If the driver has the Linux irq number or the irq_data pointer, and
+needs to know the associated hwirq number (such as in the irq_chip
+callbacks) then it can be directly obtained from irq_data->hwirq.
+
+=== Types of irq_domain mappings ===
+There are several mechanisms available for reverse mapping from hwirq
+to Linux irq, and each mechanism uses a different allocation function.
+Which reverse map type should be used depends on the use case.  Each
+of the reverse map types are described below:
+
+==== Linear ====
+irq_domain_add_linear()
+
+The linear reverse map maintains a fixed size table indexed by the
+hwirq number.  When a hwirq is mapped, an irq_desc is allocated for
+the hwirq, and the irq number is stored in the table.
+
+The Linear map is a good choice when the maximum number of hwirqs is
+fixed and a relatively small number (~ < 256).  The advantages of this
+map are fixed time lookup for irq numbers, and irq_descs are only
+allocated for in-use irqs.  The disadvantage is that the table must be
+as large as the largest possible hwirq number.
+
+The majority of drivers should use the linear map.
+
+==== Tree ====
+irq_domain_add_tree()
+
+The irq_domain maintains a radix tree map from hwirq numbers to linux
+irqs.  When an hwirq is mapped, and irq_desc is allocated and the
+hwirq is used as the lookup key for the radix tree.
+
+The tree map is a good choice if the hwirq number can be very large
+since it doesn't need to allocate a table as large as the largest
+hwirq number.  The disadvantage is that hwirq to irq number lookup is
+dependent on how many entries are in the table.
+
+Very few drivers should need this mapping.  At the moment, powerpc
+iseries is the only user.
+
+==== No Map ===-
+irq_domain_add_nomap()
+
+The No Map mapping is to be used when the hwirq number is
+programmable in the hardware.  In this case it is best to program the
+Linux irq number into the hardware itself so that no mapping is
+required.  Calling irq_create_direct_mapping() will allocate a linux
+irq number and call the .map() callback so that driver can program the
+Linux irq number into the hardware.
+
+Most drivers cannot use this mapping.
+
+==== Legacy ====
+irq_domain_add_legacy()
+irq_domain_add_legacy_isa()
+
+The Legacy mapping is a special case for drivers that already have a
+range of irq_descs allocated for the hwirqs.  It is used when the
+driver cannot be immediately converted to use the linear mapping, such
+as when the driver is used in a system with fixed irq number
+assignments, as is typical in many embedded system board files.
+
+The legacy map assumes a contiguous range of irq numbers has already
+been allocated for the controller and that the irq number can be
+calculated by adding a fixed offset to the hwirq number, and
+visa-versa.  The disadvantage is that it requires the interrupt
+controller to manage irq allocations and it requires an irq_desc to be
+allocated for every hwirq, even if it is unused.
+
+Drivers should only use the legacy map if they have fixed irq mappings
+(#define IRQ_* in embedded board files).  For example, ISA controllers
+mapped to Linux irqs 0-15 would use the legacy map.
diff --git a/MAINTAINERS b/MAINTAINERS
index 89b70df..d308f0f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3626,6 +3626,15 @@ S:	Maintained
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core
 F:	kernel/irq/
 
+IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY)
+M:	Benjamin Herrenschmidt <benh@kernel.crashing.org>
+M:	Grant Likely <grant.likely@secretlab.ca>
+T:	git git://git.secretlab.ca/git/linux-2.6.git irqdomain/next
+S:	Maintained
+F:	Documentation/IRQ-domain.txt
+F:	include/linux/irqdomain.h
+F:	kernel/irq/irqdomain.c
+
 ISAPNP
 M:	Jaroslav Kysela <perex@perex.cz>
 S:	Maintained
-- 
1.7.5.4


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

* [PATCH v3 02/25] dt: Make irqdomain less verbose
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
  2012-01-27 21:35 ` [PATCH v3 01/25] irq_domain: add documentation and MAINTAINERS entry Grant Likely
@ 2012-01-27 21:35 ` Grant Likely
  2012-01-27 21:35 ` [PATCH v3 03/25] irq_domain: Make irq_domain structure match powerpc's irq_host Grant Likely
                   ` (25 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:35 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely

It printk's too much.  Drop some output.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/irq/irqdomain.c |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 1f9e265..cc2cd43 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -170,13 +170,11 @@ void irq_domain_generate_simple(const struct of_device_id *match,
 				u64 phys_base, unsigned int irq_start)
 {
 	struct device_node *node;
-	pr_info("looking for phys_base=%llx, irq_start=%i\n",
+	pr_debug("looking for phys_base=%llx, irq_start=%i\n",
 		(unsigned long long) phys_base, (int) irq_start);
 	node = of_find_matching_node_by_address(NULL, match, phys_base);
 	if (node)
 		irq_domain_add_simple(node, irq_start);
-	else
-		pr_info("no node found\n");
 }
 EXPORT_SYMBOL_GPL(irq_domain_generate_simple);
 #endif /* CONFIG_OF_IRQ */
-- 
1.7.5.4


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

* [PATCH v3 03/25] irq_domain: Make irq_domain structure match powerpc's irq_host
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
  2012-01-27 21:35 ` [PATCH v3 01/25] irq_domain: add documentation and MAINTAINERS entry Grant Likely
  2012-01-27 21:35 ` [PATCH v3 02/25] dt: Make irqdomain less verbose Grant Likely
@ 2012-01-27 21:35 ` Grant Likely
  2012-01-27 21:35 ` [PATCH v3 04/25] irq_domain: convert microblaze from irq_host to irq_domain Grant Likely
                   ` (24 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:35 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely

Part of the series to unify the irq remapping mechanisms in the
kernel.  A follow up patch will copy the powerpc implementation into
kernel/irq/irqdomain.c, which will be a lot easier if the structures
are identical.

Where they differ, I've chose to use the powerpc names since there is
a lot more code using those names.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>
---
 arch/arm/common/gic.c     |   14 ++++----
 include/linux/irqdomain.h |   84 ++++++++++++++++++++++++++++++++++-----------
 kernel/irq/irqdomain.c    |   14 ++++----
 3 files changed, 78 insertions(+), 34 deletions(-)

diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index b2dc2dd..156bc03 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -622,10 +622,10 @@ static void __init gic_pm_init(struct gic_chip_data *gic)
 #endif
 
 #ifdef CONFIG_OF
-static int gic_irq_domain_dt_translate(struct irq_domain *d,
-				       struct device_node *controller,
-				       const u32 *intspec, unsigned int intsize,
-				       unsigned long *out_hwirq, unsigned int *out_type)
+static int gic_irq_domain_xlate(struct irq_domain *d,
+				struct device_node *controller,
+				const u32 *intspec, unsigned int intsize,
+				unsigned long *out_hwirq, unsigned int *out_type)
 {
 	if (d->of_node != controller)
 		return -EINVAL;
@@ -644,9 +644,9 @@ static int gic_irq_domain_dt_translate(struct irq_domain *d,
 }
 #endif
 
-const struct irq_domain_ops gic_irq_domain_ops = {
+struct irq_domain_ops gic_irq_domain_ops = {
 #ifdef CONFIG_OF
-	.dt_translate = gic_irq_domain_dt_translate,
+	.xlate = gic_irq_domain_xlate,
 #endif
 };
 
@@ -724,7 +724,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 		     irq_start);
 		domain->irq_base = irq_start;
 	}
-	domain->priv = gic;
+	domain->host_data = gic;
 	domain->ops = &gic_irq_domain_ops;
 	irq_domain_add(domain);
 
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index bd4272b..35b9ff3 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -9,61 +9,105 @@
  * representation into a hardware irq number that can be mapped back to a
  * Linux irq number without any extra platform support code.
  *
- * irq_domain is expected to be embedded in an interrupt controller's private
- * data structure.
+ * Interrupt controller "domain" data structure. This could be defined as a
+ * irq domain controller. That is, it handles the mapping between hardware
+ * and virtual interrupt numbers for a given interrupt domain. The domain
+ * structure is generally created by the PIC code for a given PIC instance
+ * (though a domain can cover more than one PIC if they have a flat number
+ * model). It's the domain callbacks that are responsible for setting the
+ * irq_chip on a given irq_desc after it's been mapped.
  */
+
 #ifndef _LINUX_IRQDOMAIN_H
 #define _LINUX_IRQDOMAIN_H
 
-#include <linux/irq.h>
-#include <linux/mod_devicetable.h>
+#include <linux/types.h>
+#include <linux/radix-tree.h>
 
-#ifdef CONFIG_IRQ_DOMAIN
 struct device_node;
 struct irq_domain;
+struct of_device_id;
+
+/* This type is the placeholder for a hardware interrupt number. It has to
+ * be big enough to enclose whatever representation is used by a given
+ * platform.
+ */
+typedef unsigned long irq_hw_number_t;
 
 /**
  * struct irq_domain_ops - Methods for irq_domain objects
+ * @match: Match an interrupt controller device node to a host, returns
+ *         1 on a match
+ * @map: Create or update a mapping between a virtual irq number and a hw
+ *       irq number. This is called only once for a given mapping.
+ * @unmap: Dispose of such a mapping
  * @to_irq: (optional) given a local hardware irq number, return the linux
  *          irq number.  If to_irq is not implemented, then the irq_domain
  *          will use this translation: irq = (domain->irq_base + hwirq)
- * @dt_translate: Given a device tree node and interrupt specifier, decode
- *                the hardware irq number and linux irq type value.
+ * @xlate: Given a device tree node and interrupt specifier, decode
+ *         the hardware irq number and linux irq type value.
+ *
+ * Functions below are provided by the driver and called whenever a new mapping
+ * is created or an old mapping is disposed. The driver can then proceed to
+ * whatever internal data structures management is required. It also needs
+ * to setup the irq_desc when returning from map().
  */
 struct irq_domain_ops {
+	int (*match)(struct irq_domain *d, struct device_node *node);
+	int (*map)(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw);
+	void (*unmap)(struct irq_domain *d, unsigned int virq);
 	unsigned int (*to_irq)(struct irq_domain *d, unsigned long hwirq);
-
-#ifdef CONFIG_OF
-	int (*dt_translate)(struct irq_domain *d, struct device_node *node,
-			    const u32 *intspec, unsigned int intsize,
-			    unsigned long *out_hwirq, unsigned int *out_type);
-#endif /* CONFIG_OF */
+	int (*xlate)(struct irq_domain *d, struct device_node *node,
+		     const u32 *intspec, unsigned int intsize,
+		     unsigned long *out_hwirq, unsigned int *out_type);
 };
 
 /**
  * struct irq_domain - Hardware interrupt number translation object
- * @list: Element in global irq_domain list.
+ * @link: Element in global irq_domain list.
+ * @revmap_type: Method used for reverse mapping hwirq numbers to linux irq. This
+ *               will be one of the IRQ_DOMAIN_MAP_* values.
+ * @revmap_data: Revmap method specific data.
+ * @ops: pointer to irq_domain methods
+ * @host_data: private data pointer for use by owner.  Not touched by irq_domain
+ *             core code.
  * @irq_base: Start of irq_desc range assigned to the irq_domain.  The creator
  *            of the irq_domain is responsible for allocating the array of
  *            irq_desc structures.
  * @nr_irq: Number of irqs managed by the irq domain
  * @hwirq_base: Starting number for hwirqs managed by the irq domain
- * @ops: pointer to irq_domain methods
- * @priv: private data pointer for use by owner.  Not touched by irq_domain
- *        core code.
  * @of_node: (optional) Pointer to device tree nodes associated with the
  *           irq_domain.  Used when decoding device tree interrupt specifiers.
  */
 struct irq_domain {
-	struct list_head list;
+	struct list_head link;
+
+	/* type of reverse mapping_technique */
+	unsigned int revmap_type;
+#define IRQ_DOMAIN_MAP_LEGACY 0 /* legacy 8259, gets irqs 1..15 */
+#define IRQ_DOMAIN_MAP_NOMAP 1 /* no fast reverse mapping */
+#define IRQ_DOMAIN_MAP_LINEAR 2 /* linear map of interrupts */
+#define IRQ_DOMAIN_MAP_TREE 3 /* radix tree */
+	union {
+		struct {
+			unsigned int size;
+			unsigned int *revmap;
+		} linear;
+		struct radix_tree_root tree;
+	} revmap_data;
+	struct irq_domain_ops *ops;
+	void *host_data;
+	irq_hw_number_t inval_irq;
+
 	unsigned int irq_base;
 	unsigned int nr_irq;
 	unsigned int hwirq_base;
-	const struct irq_domain_ops *ops;
-	void *priv;
+
+	/* Optional device node pointer */
 	struct device_node *of_node;
 };
 
+#ifdef CONFIG_IRQ_DOMAIN
 /**
  * irq_domain_to_irq() - Translate from a hardware irq to a linux irq number
  *
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index cc2cd43..509adb8 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -43,7 +43,7 @@ void irq_domain_add(struct irq_domain *domain)
 	}
 
 	mutex_lock(&irq_domain_mutex);
-	list_add(&domain->list, &irq_domain_list);
+	list_add(&domain->link, &irq_domain_list);
 	mutex_unlock(&irq_domain_mutex);
 }
 
@@ -57,7 +57,7 @@ void irq_domain_del(struct irq_domain *domain)
 	int hwirq, irq;
 
 	mutex_lock(&irq_domain_mutex);
-	list_del(&domain->list);
+	list_del(&domain->link);
 	mutex_unlock(&irq_domain_mutex);
 
 	/* Clear the irq_domain assignments */
@@ -88,10 +88,10 @@ unsigned int irq_create_of_mapping(struct device_node *controller,
 
 	/* Find a domain which can translate the irq spec */
 	mutex_lock(&irq_domain_mutex);
-	list_for_each_entry(domain, &irq_domain_list, list) {
-		if (!domain->ops->dt_translate)
+	list_for_each_entry(domain, &irq_domain_list, link) {
+		if (!domain->ops->xlate)
 			continue;
-		rc = domain->ops->dt_translate(domain, controller,
+		rc = domain->ops->xlate(domain, controller,
 					intspec, intsize, &hwirq, &type);
 		if (rc == 0)
 			break;
@@ -126,7 +126,7 @@ void irq_dispose_mapping(unsigned int irq)
 }
 EXPORT_SYMBOL_GPL(irq_dispose_mapping);
 
-int irq_domain_simple_dt_translate(struct irq_domain *d,
+int irq_domain_simple_xlate(struct irq_domain *d,
 			    struct device_node *controller,
 			    const u32 *intspec, unsigned int intsize,
 			    unsigned long *out_hwirq, unsigned int *out_type)
@@ -181,7 +181,7 @@ EXPORT_SYMBOL_GPL(irq_domain_generate_simple);
 
 struct irq_domain_ops irq_domain_simple_ops = {
 #ifdef CONFIG_OF_IRQ
-	.dt_translate = irq_domain_simple_dt_translate,
+	.xlate = irq_domain_simple_xlate,
 #endif /* CONFIG_OF_IRQ */
 };
 EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
-- 
1.7.5.4


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

* [PATCH v3 04/25] irq_domain: convert microblaze from irq_host to irq_domain
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (2 preceding siblings ...)
  2012-01-27 21:35 ` [PATCH v3 03/25] irq_domain: Make irq_domain structure match powerpc's irq_host Grant Likely
@ 2012-01-27 21:35 ` Grant Likely
  2012-01-27 21:35 ` [PATCH v3 05/25] irq_domain/powerpc: Use common irq_domain structure instead of irq_host Grant Likely
                   ` (23 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:35 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely,
	Michal Simek

Trivial change, microblaze doesn't use irq remapping yet.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Michal Simek <monstr@monstr.eu>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
 arch/microblaze/include/asm/irq.h |    4 ++--
 arch/microblaze/kernel/irq.c      |    2 +-
 arch/microblaze/kernel/setup.c    |    2 --
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/arch/microblaze/include/asm/irq.h b/arch/microblaze/include/asm/irq.h
index a175132..7798ad1 100644
--- a/arch/microblaze/include/asm/irq.h
+++ b/arch/microblaze/include/asm/irq.h
@@ -39,7 +39,7 @@ static inline void irq_dispose_mapping(unsigned int virq)
 	return;
 }
 
-struct irq_host;
+struct irq_domain;
 
 /**
  * irq_create_mapping - Map a hardware interrupt into linux virq space
@@ -51,7 +51,7 @@ struct irq_host;
  * If the sense/trigger is to be specified, set_irq_type() should be called
  * on the number returned from that call.
  */
-extern unsigned int irq_create_mapping(struct irq_host *host,
+extern unsigned int irq_create_mapping(struct irq_domain *host,
 					irq_hw_number_t hwirq);
 
 #endif /* _ASM_MICROBLAZE_IRQ_H */
diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c
index bbebcae..3f613df 100644
--- a/arch/microblaze/kernel/irq.c
+++ b/arch/microblaze/kernel/irq.c
@@ -51,7 +51,7 @@ next_irq:
 
 /* MS: There is no any advance mapping mechanism. We are using simple 32bit
   intc without any cascades or any connection that's why mapping is 1:1 */
-unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq)
+unsigned int irq_create_mapping(struct irq_domain *host, irq_hw_number_t hwirq)
 {
 	return hwirq + IRQ_OFFSET;
 }
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c
index d4fc1a9..208cd04 100644
--- a/arch/microblaze/kernel/setup.c
+++ b/arch/microblaze/kernel/setup.c
@@ -52,8 +52,6 @@ void __init setup_arch(char **cmdline_p)
 
 	unflatten_device_tree();
 
-	/* NOTE I think that this function is not necessary to call */
-	/* irq_early_init(); */
 	setup_cpuinfo();
 
 	microblaze_cache_init();
-- 
1.7.5.4


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

* [PATCH v3 05/25] irq_domain/powerpc: Use common irq_domain structure instead of irq_host
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (3 preceding siblings ...)
  2012-01-27 21:35 ` [PATCH v3 04/25] irq_domain: convert microblaze from irq_host to irq_domain Grant Likely
@ 2012-01-27 21:35 ` Grant Likely
  2012-01-27 21:36 ` [PATCH v3 06/25] irq_domain/powerpc: eliminate irq_map; use irq_alloc_desc() instead Grant Likely
                   ` (22 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:35 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely

This patch drops the powerpc-specific irq_host structures and uses the common
irq_domain strucutres defined in linux/irqdomain.h.  It also fixes all
the users to use the new structure names.

Renaming irq_host to irq_domain has been discussed for a long time, and this
patch is a step in the process of generalizing the powerpc virq code to be
usable by all architecture.

An astute reader will notice that this patch actually removes the irq_host
structure instead of renaming it.  This is because the irq_domain structure
already exists in include/linux/irqdomain.h and has the needed data members.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/include/asm/ehv_pic.h               |    2 +-
 arch/powerpc/include/asm/i8259.h                 |    2 +-
 arch/powerpc/include/asm/irq.h                   |  110 ++++------------------
 arch/powerpc/include/asm/mpic.h                  |    2 +-
 arch/powerpc/include/asm/xics.h                  |    2 +-
 arch/powerpc/kernel/irq.c                        |   78 ++++++++--------
 arch/powerpc/platforms/512x/mpc5121_ads_cpld.c   |   11 +-
 arch/powerpc/platforms/52xx/media5200.c          |   10 +-
 arch/powerpc/platforms/52xx/mpc52xx_gpt.c        |   12 +-
 arch/powerpc/platforms/52xx/mpc52xx_pic.c        |   10 +-
 arch/powerpc/platforms/82xx/pq2ads-pci-pic.c     |   10 +-
 arch/powerpc/platforms/85xx/socrates_fpga_pic.c  |   12 +-
 arch/powerpc/platforms/86xx/gef_pic.c            |   12 +-
 arch/powerpc/platforms/cell/axon_msi.c           |   28 +++---
 arch/powerpc/platforms/cell/beat_interrupt.c     |   14 ++--
 arch/powerpc/platforms/cell/interrupt.c          |   14 ++--
 arch/powerpc/platforms/cell/spider-pic.c         |   10 +-
 arch/powerpc/platforms/embedded6xx/flipper-pic.c |   30 +++---
 arch/powerpc/platforms/embedded6xx/hlwd-pic.c    |   36 ++++----
 arch/powerpc/platforms/iseries/irq.c             |   12 +-
 arch/powerpc/platforms/powermac/pic.c            |   12 +-
 arch/powerpc/platforms/powermac/smp.c            |    8 +-
 arch/powerpc/platforms/ps3/interrupt.c           |   10 +-
 arch/powerpc/platforms/wsp/opb_pic.c             |   10 +-
 arch/powerpc/sysdev/cpm1.c                       |    8 +-
 arch/powerpc/sysdev/cpm2_pic.c                   |   10 +-
 arch/powerpc/sysdev/ehv_pic.c                    |   10 +-
 arch/powerpc/sysdev/fsl_msi.c                    |    6 +-
 arch/powerpc/sysdev/fsl_msi.h                    |    2 +-
 arch/powerpc/sysdev/i8259.c                      |   14 ++--
 arch/powerpc/sysdev/ipic.c                       |   10 +-
 arch/powerpc/sysdev/ipic.h                       |    2 +-
 arch/powerpc/sysdev/mpc8xx_pic.c                 |   10 +-
 arch/powerpc/sysdev/mpic.c                       |   12 +-
 arch/powerpc/sysdev/mpic_msi.c                   |    2 +-
 arch/powerpc/sysdev/mv64x60_pic.c                |    8 +-
 arch/powerpc/sysdev/qe_lib/qe_ic.c               |   10 +-
 arch/powerpc/sysdev/qe_lib/qe_ic.h               |    2 +-
 arch/powerpc/sysdev/tsi108_pci.c                 |   14 ++--
 arch/powerpc/sysdev/uic.c                        |   10 +-
 arch/powerpc/sysdev/xics/xics-common.c           |   12 +-
 arch/powerpc/sysdev/xilinx_intc.c                |   16 ++--
 drivers/gpio/gpio-mpc8xxx.c                      |   10 +-
 43 files changed, 277 insertions(+), 348 deletions(-)

diff --git a/arch/powerpc/include/asm/ehv_pic.h b/arch/powerpc/include/asm/ehv_pic.h
index a9e1f4f..dc7d48e 100644
--- a/arch/powerpc/include/asm/ehv_pic.h
+++ b/arch/powerpc/include/asm/ehv_pic.h
@@ -25,7 +25,7 @@
 
 struct ehv_pic {
 	/* The remapper for this EHV_PIC */
-	struct irq_host	*irqhost;
+	struct irq_domain	*irqhost;
 
 	/* The "linux" controller struct */
 	struct irq_chip	hc_irq;
diff --git a/arch/powerpc/include/asm/i8259.h b/arch/powerpc/include/asm/i8259.h
index 105ade2..c3fdfbd 100644
--- a/arch/powerpc/include/asm/i8259.h
+++ b/arch/powerpc/include/asm/i8259.h
@@ -6,7 +6,7 @@
 
 extern void i8259_init(struct device_node *node, unsigned long intack_addr);
 extern unsigned int i8259_irq(void);
-extern struct irq_host *i8259_get_host(void);
+extern struct irq_domain *i8259_get_host(void);
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_I8259_H */
diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h
index c0e1bc3..cb06b39 100644
--- a/arch/powerpc/include/asm/irq.h
+++ b/arch/powerpc/include/asm/irq.h
@@ -9,6 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/irqdomain.h>
 #include <linux/threads.h>
 #include <linux/list.h>
 #include <linux/radix-tree.h>
@@ -41,20 +42,7 @@ extern atomic_t ppc_n_lost_interrupts;
 /* Same thing, used by the generic IRQ code */
 #define NR_IRQS_LEGACY		NUM_ISA_INTERRUPTS
 
-/* This type is the placeholder for a hardware interrupt number. It has to
- * be big enough to enclose whatever representation is used by a given
- * platform.
- */
-typedef unsigned long irq_hw_number_t;
-
-/* Interrupt controller "host" data structure. This could be defined as a
- * irq domain controller. That is, it handles the mapping between hardware
- * and virtual interrupt numbers for a given interrupt domain. The host
- * structure is generally created by the PIC code for a given PIC instance
- * (though a host can cover more than one PIC if they have a flat number
- * model). It's the host callbacks that are responsible for setting the
- * irq_chip on a given irq_desc after it's been mapped.
- *
+/*
  * The host code and data structures are fairly agnostic to the fact that
  * we use an open firmware device-tree. We do have references to struct
  * device_node in two places: in irq_find_host() to find the host matching
@@ -66,90 +54,32 @@ typedef unsigned long irq_hw_number_t;
  * by some sort of arch-specific void * "token" used to identify interrupt
  * controllers.
  */
-struct irq_host;
-struct radix_tree_root;
-
-/* Functions below are provided by the host and called whenever a new mapping
- * is created or an old mapping is disposed. The host can then proceed to
- * whatever internal data structures management is required. It also needs
- * to setup the irq_desc when returning from map().
- */
-struct irq_host_ops {
-	/* Match an interrupt controller device node to a host, returns
-	 * 1 on a match
-	 */
-	int (*match)(struct irq_host *h, struct device_node *node);
-
-	/* Create or update a mapping between a virtual irq number and a hw
-	 * irq number. This is called only once for a given mapping.
-	 */
-	int (*map)(struct irq_host *h, unsigned int virq, irq_hw_number_t hw);
-
-	/* Dispose of such a mapping */
-	void (*unmap)(struct irq_host *h, unsigned int virq);
-
-	/* Translate device-tree interrupt specifier from raw format coming
-	 * from the firmware to a irq_hw_number_t (interrupt line number) and
-	 * type (sense) that can be passed to set_irq_type(). In the absence
-	 * of this callback, irq_create_of_mapping() and irq_of_parse_and_map()
-	 * will return the hw number in the first cell and IRQ_TYPE_NONE for
-	 * the type (which amount to keeping whatever default value the
-	 * interrupt controller has for that line)
-	 */
-	int (*xlate)(struct irq_host *h, struct device_node *ctrler,
-		     const u32 *intspec, unsigned int intsize,
-		     irq_hw_number_t *out_hwirq, unsigned int *out_type);
-};
-
-struct irq_host {
-	struct list_head	link;
-
-	/* type of reverse mapping technique */
-	unsigned int		revmap_type;
-#define IRQ_HOST_MAP_LEGACY     0 /* legacy 8259, gets irqs 1..15 */
-#define IRQ_HOST_MAP_NOMAP	1 /* no fast reverse mapping */
-#define IRQ_HOST_MAP_LINEAR	2 /* linear map of interrupts */
-#define IRQ_HOST_MAP_TREE	3 /* radix tree */
-	union {
-		struct {
-			unsigned int size;
-			unsigned int *revmap;
-		} linear;
-		struct radix_tree_root tree;
-	} revmap_data;
-	struct irq_host_ops	*ops;
-	void			*host_data;
-	irq_hw_number_t		inval_irq;
-
-	/* Optional device node pointer */
-	struct device_node	*of_node;
-};
 
 struct irq_data;
 extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
 extern irq_hw_number_t virq_to_hw(unsigned int virq);
-extern bool virq_is_host(unsigned int virq, struct irq_host *host);
+extern bool virq_is_host(unsigned int virq, struct irq_domain *host);
 
 /**
- * irq_alloc_host - Allocate a new irq_host data structure
+ * irq_alloc_host - Allocate a new irq_domain data structure
  * @of_node: optional device-tree node of the interrupt controller
  * @revmap_type: type of reverse mapping to use
- * @revmap_arg: for IRQ_HOST_MAP_LINEAR linear only: size of the map
+ * @revmap_arg: for IRQ_DOMAIN_MAP_LINEAR linear only: size of the map
  * @ops: map/unmap host callbacks
  * @inval_irq: provide a hw number in that host space that is always invalid
  *
- * Allocates and initialize and irq_host structure. Note that in the case of
- * IRQ_HOST_MAP_LEGACY, the map() callback will be called before this returns
+ * Allocates and initialize and irq_domain structure. Note that in the case of
+ * IRQ_DOMAIN_MAP_LEGACY, the map() callback will be called before this returns
  * for all legacy interrupts except 0 (which is always the invalid irq for
- * a legacy controller). For a IRQ_HOST_MAP_LINEAR, the map is allocated by
- * this call as well. For a IRQ_HOST_MAP_TREE, the radix tree will be allocated
+ * a legacy controller). For a IRQ_DOMAIN_MAP_LINEAR, the map is allocated by
+ * this call as well. For a IRQ_DOMAIN_MAP_TREE, the radix tree will be allocated
  * later during boot automatically (the reverse mapping will use the slow path
  * until that happens).
  */
-extern struct irq_host *irq_alloc_host(struct device_node *of_node,
+extern struct irq_domain *irq_alloc_host(struct device_node *of_node,
 				       unsigned int revmap_type,
 				       unsigned int revmap_arg,
-				       struct irq_host_ops *ops,
+				       struct irq_domain_ops *ops,
 				       irq_hw_number_t inval_irq);
 
 
@@ -157,7 +87,7 @@ extern struct irq_host *irq_alloc_host(struct device_node *of_node,
  * irq_find_host - Locates a host for a given device node
  * @node: device-tree node of the interrupt controller
  */
-extern struct irq_host *irq_find_host(struct device_node *node);
+extern struct irq_domain *irq_find_host(struct device_node *node);
 
 
 /**
@@ -169,7 +99,7 @@ extern struct irq_host *irq_find_host(struct device_node *node);
  * platforms that want to manipulate a few hard coded interrupt numbers that
  * aren't properly represented in the device-tree.
  */
-extern void irq_set_default_host(struct irq_host *host);
+extern void irq_set_default_host(struct irq_domain *host);
 
 
 /**
@@ -192,7 +122,7 @@ extern void irq_set_virq_count(unsigned int count);
  * If the sense/trigger is to be specified, set_irq_type() should be called
  * on the number returned from that call.
  */
-extern unsigned int irq_create_mapping(struct irq_host *host,
+extern unsigned int irq_create_mapping(struct irq_domain *host,
 				       irq_hw_number_t hwirq);
 
 
@@ -211,7 +141,7 @@ extern void irq_dispose_mapping(unsigned int virq);
  * irq controller implementation directly calls the appropriate low level
  * mapping function.
  */
-extern unsigned int irq_find_mapping(struct irq_host *host,
+extern unsigned int irq_find_mapping(struct irq_domain *host,
 				     irq_hw_number_t hwirq);
 
 /**
@@ -222,7 +152,7 @@ extern unsigned int irq_find_mapping(struct irq_host *host,
  * interrupt numbers they generate. In such a case it's simplest to use
  * the linux virq as the hardware interrupt number.
  */
-extern unsigned int irq_create_direct_mapping(struct irq_host *host);
+extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
 
 /**
  * irq_radix_revmap_insert - Insert a hw irq to linux virq number mapping.
@@ -233,7 +163,7 @@ extern unsigned int irq_create_direct_mapping(struct irq_host *host);
  * This is for use by irq controllers that use a radix tree reverse
  * mapping for fast lookup.
  */
-extern void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
+extern void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq,
 				    irq_hw_number_t hwirq);
 
 /**
@@ -244,7 +174,7 @@ extern void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
  * This is a fast path, for use by irq controller code that uses radix tree
  * revmaps
  */
-extern unsigned int irq_radix_revmap_lookup(struct irq_host *host,
+extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
 					    irq_hw_number_t hwirq);
 
 /**
@@ -257,7 +187,7 @@ extern unsigned int irq_radix_revmap_lookup(struct irq_host *host,
  * yet and will create the revmap entry with appropriate locking
  */
 
-extern unsigned int irq_linear_revmap(struct irq_host *host,
+extern unsigned int irq_linear_revmap(struct irq_domain *host,
 				      irq_hw_number_t hwirq);
 
 
@@ -272,7 +202,7 @@ extern unsigned int irq_linear_revmap(struct irq_host *host,
  * and that can be used by some irq controllers implementations for things
  * like allocating ranges of numbers for MSIs. The revmaps are left untouched.
  */
-extern unsigned int irq_alloc_virt(struct irq_host *host,
+extern unsigned int irq_alloc_virt(struct irq_domain *host,
 				   unsigned int count,
 				   unsigned int hint);
 
diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
index 67b4d98..a5b7c56 100644
--- a/arch/powerpc/include/asm/mpic.h
+++ b/arch/powerpc/include/asm/mpic.h
@@ -255,7 +255,7 @@ struct mpic
 	struct device_node *node;
 
 	/* The remapper for this MPIC */
-	struct irq_host		*irqhost;
+	struct irq_domain	*irqhost;
 
 	/* The "linux" controller struct */
 	struct irq_chip		hc_irq;
diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h
index c48de98..4ae9a09 100644
--- a/arch/powerpc/include/asm/xics.h
+++ b/arch/powerpc/include/asm/xics.h
@@ -86,7 +86,7 @@ struct ics {
 extern unsigned int xics_default_server;
 extern unsigned int xics_default_distrib_server;
 extern unsigned int xics_interrupt_server_size;
-extern struct irq_host *xics_host;
+extern struct irq_domain *xics_host;
 
 struct xics_cppr {
 	unsigned char stack[MAX_NUM_PRIORITIES];
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 701d4ac..7305f2f 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -498,15 +498,15 @@ void do_softirq(void)
  */
 struct irq_map_entry {
 	irq_hw_number_t	hwirq;
-	struct irq_host	*host;
+	struct irq_domain	*host;
 };
 
-static LIST_HEAD(irq_hosts);
+static LIST_HEAD(irq_domain_list);
 static DEFINE_RAW_SPINLOCK(irq_big_lock);
 static DEFINE_MUTEX(revmap_trees_mutex);
 static struct irq_map_entry irq_map[NR_IRQS];
 static unsigned int irq_virq_count = NR_IRQS;
-static struct irq_host *irq_default_host;
+static struct irq_domain *irq_default_host;
 
 irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
 {
@@ -520,31 +520,31 @@ irq_hw_number_t virq_to_hw(unsigned int virq)
 }
 EXPORT_SYMBOL_GPL(virq_to_hw);
 
-bool virq_is_host(unsigned int virq, struct irq_host *host)
+bool virq_is_host(unsigned int virq, struct irq_domain *host)
 {
 	return irq_map[virq].host == host;
 }
 EXPORT_SYMBOL_GPL(virq_is_host);
 
-static int default_irq_host_match(struct irq_host *h, struct device_node *np)
+static int default_irq_host_match(struct irq_domain *h, struct device_node *np)
 {
 	return h->of_node != NULL && h->of_node == np;
 }
 
-struct irq_host *irq_alloc_host(struct device_node *of_node,
+struct irq_domain *irq_alloc_host(struct device_node *of_node,
 				unsigned int revmap_type,
 				unsigned int revmap_arg,
-				struct irq_host_ops *ops,
+				struct irq_domain_ops *ops,
 				irq_hw_number_t inval_irq)
 {
-	struct irq_host *host;
-	unsigned int size = sizeof(struct irq_host);
+	struct irq_domain *host;
+	unsigned int size = sizeof(struct irq_domain);
 	unsigned int i;
 	unsigned int *rmap;
 	unsigned long flags;
 
 	/* Allocate structure and revmap table if using linear mapping */
-	if (revmap_type == IRQ_HOST_MAP_LINEAR)
+	if (revmap_type == IRQ_DOMAIN_MAP_LINEAR)
 		size += revmap_arg * sizeof(unsigned int);
 	host = kzalloc(size, GFP_KERNEL);
 	if (host == NULL)
@@ -564,7 +564,7 @@ struct irq_host *irq_alloc_host(struct device_node *of_node,
 	/* If it's a legacy controller, check for duplicates and
 	 * mark it as allocated (we use irq 0 host pointer for that
 	 */
-	if (revmap_type == IRQ_HOST_MAP_LEGACY) {
+	if (revmap_type == IRQ_DOMAIN_MAP_LEGACY) {
 		if (irq_map[0].host != NULL) {
 			raw_spin_unlock_irqrestore(&irq_big_lock, flags);
 			of_node_put(host->of_node);
@@ -574,12 +574,12 @@ struct irq_host *irq_alloc_host(struct device_node *of_node,
 		irq_map[0].host = host;
 	}
 
-	list_add(&host->link, &irq_hosts);
+	list_add(&host->link, &irq_domain_list);
 	raw_spin_unlock_irqrestore(&irq_big_lock, flags);
 
 	/* Additional setups per revmap type */
 	switch(revmap_type) {
-	case IRQ_HOST_MAP_LEGACY:
+	case IRQ_DOMAIN_MAP_LEGACY:
 		/* 0 is always the invalid number for legacy */
 		host->inval_irq = 0;
 		/* setup us as the host for all legacy interrupts */
@@ -599,7 +599,7 @@ struct irq_host *irq_alloc_host(struct device_node *of_node,
 			irq_clear_status_flags(i, IRQ_NOREQUEST);
 		}
 		break;
-	case IRQ_HOST_MAP_LINEAR:
+	case IRQ_DOMAIN_MAP_LINEAR:
 		rmap = (unsigned int *)(host + 1);
 		for (i = 0; i < revmap_arg; i++)
 			rmap[i] = NO_IRQ;
@@ -607,7 +607,7 @@ struct irq_host *irq_alloc_host(struct device_node *of_node,
 		smp_wmb();
 		host->revmap_data.linear.revmap = rmap;
 		break;
-	case IRQ_HOST_MAP_TREE:
+	case IRQ_DOMAIN_MAP_TREE:
 		INIT_RADIX_TREE(&host->revmap_data.tree, GFP_KERNEL);
 		break;
 	default:
@@ -619,9 +619,9 @@ struct irq_host *irq_alloc_host(struct device_node *of_node,
 	return host;
 }
 
-struct irq_host *irq_find_host(struct device_node *node)
+struct irq_domain *irq_find_host(struct device_node *node)
 {
-	struct irq_host *h, *found = NULL;
+	struct irq_domain *h, *found = NULL;
 	unsigned long flags;
 
 	/* We might want to match the legacy controller last since
@@ -630,7 +630,7 @@ struct irq_host *irq_find_host(struct device_node *node)
 	 * yet though...
 	 */
 	raw_spin_lock_irqsave(&irq_big_lock, flags);
-	list_for_each_entry(h, &irq_hosts, link)
+	list_for_each_entry(h, &irq_domain_list, link)
 		if (h->ops->match(h, node)) {
 			found = h;
 			break;
@@ -640,7 +640,7 @@ struct irq_host *irq_find_host(struct device_node *node)
 }
 EXPORT_SYMBOL_GPL(irq_find_host);
 
-void irq_set_default_host(struct irq_host *host)
+void irq_set_default_host(struct irq_domain *host)
 {
 	pr_debug("irq: Default host set to @0x%p\n", host);
 
@@ -656,7 +656,7 @@ void irq_set_virq_count(unsigned int count)
 		irq_virq_count = count;
 }
 
-static int irq_setup_virq(struct irq_host *host, unsigned int virq,
+static int irq_setup_virq(struct irq_domain *host, unsigned int virq,
 			    irq_hw_number_t hwirq)
 {
 	int res;
@@ -688,7 +688,7 @@ error:
 	return -1;
 }
 
-unsigned int irq_create_direct_mapping(struct irq_host *host)
+unsigned int irq_create_direct_mapping(struct irq_domain *host)
 {
 	unsigned int virq;
 
@@ -696,7 +696,7 @@ unsigned int irq_create_direct_mapping(struct irq_host *host)
 		host = irq_default_host;
 
 	BUG_ON(host == NULL);
-	WARN_ON(host->revmap_type != IRQ_HOST_MAP_NOMAP);
+	WARN_ON(host->revmap_type != IRQ_DOMAIN_MAP_NOMAP);
 
 	virq = irq_alloc_virt(host, 1, 0);
 	if (virq == NO_IRQ) {
@@ -712,7 +712,7 @@ unsigned int irq_create_direct_mapping(struct irq_host *host)
 	return virq;
 }
 
-unsigned int irq_create_mapping(struct irq_host *host,
+unsigned int irq_create_mapping(struct irq_domain *host,
 				irq_hw_number_t hwirq)
 {
 	unsigned int virq, hint;
@@ -738,7 +738,7 @@ unsigned int irq_create_mapping(struct irq_host *host,
 	}
 
 	/* Get a virtual interrupt number */
-	if (host->revmap_type == IRQ_HOST_MAP_LEGACY) {
+	if (host->revmap_type == IRQ_DOMAIN_MAP_LEGACY) {
 		/* Handle legacy */
 		virq = (unsigned int)hwirq;
 		if (virq == 0 || virq >= NUM_ISA_INTERRUPTS)
@@ -767,7 +767,7 @@ EXPORT_SYMBOL_GPL(irq_create_mapping);
 unsigned int irq_create_of_mapping(struct device_node *controller,
 				   const u32 *intspec, unsigned int intsize)
 {
-	struct irq_host *host;
+	struct irq_domain *host;
 	irq_hw_number_t hwirq;
 	unsigned int type = IRQ_TYPE_NONE;
 	unsigned int virq;
@@ -806,7 +806,7 @@ EXPORT_SYMBOL_GPL(irq_create_of_mapping);
 
 void irq_dispose_mapping(unsigned int virq)
 {
-	struct irq_host *host;
+	struct irq_domain *host;
 	irq_hw_number_t hwirq;
 
 	if (virq == NO_IRQ)
@@ -817,7 +817,7 @@ void irq_dispose_mapping(unsigned int virq)
 		return;
 
 	/* Never unmap legacy interrupts */
-	if (host->revmap_type == IRQ_HOST_MAP_LEGACY)
+	if (host->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
 		return;
 
 	irq_set_status_flags(virq, IRQ_NOREQUEST);
@@ -836,11 +836,11 @@ void irq_dispose_mapping(unsigned int virq)
 	/* Clear reverse map */
 	hwirq = irq_map[virq].hwirq;
 	switch(host->revmap_type) {
-	case IRQ_HOST_MAP_LINEAR:
+	case IRQ_DOMAIN_MAP_LINEAR:
 		if (hwirq < host->revmap_data.linear.size)
 			host->revmap_data.linear.revmap[hwirq] = NO_IRQ;
 		break;
-	case IRQ_HOST_MAP_TREE:
+	case IRQ_DOMAIN_MAP_TREE:
 		mutex_lock(&revmap_trees_mutex);
 		radix_tree_delete(&host->revmap_data.tree, hwirq);
 		mutex_unlock(&revmap_trees_mutex);
@@ -857,7 +857,7 @@ void irq_dispose_mapping(unsigned int virq)
 }
 EXPORT_SYMBOL_GPL(irq_dispose_mapping);
 
-unsigned int irq_find_mapping(struct irq_host *host,
+unsigned int irq_find_mapping(struct irq_domain *host,
 			      irq_hw_number_t hwirq)
 {
 	unsigned int i;
@@ -870,7 +870,7 @@ unsigned int irq_find_mapping(struct irq_host *host,
 		return NO_IRQ;
 
 	/* legacy -> bail early */
-	if (host->revmap_type == IRQ_HOST_MAP_LEGACY)
+	if (host->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
 		return hwirq;
 
 	/* Slow path does a linear search of the map */
@@ -925,13 +925,13 @@ int irq_choose_cpu(const struct cpumask *mask)
 }
 #endif
 
-unsigned int irq_radix_revmap_lookup(struct irq_host *host,
+unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
 				     irq_hw_number_t hwirq)
 {
 	struct irq_map_entry *ptr;
 	unsigned int virq;
 
-	if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_TREE))
+	if (WARN_ON_ONCE(host->revmap_type != IRQ_DOMAIN_MAP_TREE))
 		return irq_find_mapping(host, hwirq);
 
 	/*
@@ -956,10 +956,10 @@ unsigned int irq_radix_revmap_lookup(struct irq_host *host,
 	return virq;
 }
 
-void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
+void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq,
 			     irq_hw_number_t hwirq)
 {
-	if (WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE))
+	if (WARN_ON(host->revmap_type != IRQ_DOMAIN_MAP_TREE))
 		return;
 
 	if (virq != NO_IRQ) {
@@ -970,12 +970,12 @@ void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
 	}
 }
 
-unsigned int irq_linear_revmap(struct irq_host *host,
+unsigned int irq_linear_revmap(struct irq_domain *host,
 			       irq_hw_number_t hwirq)
 {
 	unsigned int *revmap;
 
-	if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_LINEAR))
+	if (WARN_ON_ONCE(host->revmap_type != IRQ_DOMAIN_MAP_LINEAR))
 		return irq_find_mapping(host, hwirq);
 
 	/* Check revmap bounds */
@@ -994,7 +994,7 @@ unsigned int irq_linear_revmap(struct irq_host *host,
 	return revmap[hwirq];
 }
 
-unsigned int irq_alloc_virt(struct irq_host *host,
+unsigned int irq_alloc_virt(struct irq_domain *host,
 			    unsigned int count,
 			    unsigned int hint)
 {
@@ -1064,7 +1064,7 @@ void irq_free_virt(unsigned int virq, unsigned int count)
 
 	raw_spin_lock_irqsave(&irq_big_lock, flags);
 	for (i = virq; i < (virq + count); i++) {
-		struct irq_host *host;
+		struct irq_domain *host;
 
 		host = irq_map[i].host;
 		irq_map[i].hwirq = host->inval_irq;
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
index 9f09319..fefa797 100644
--- a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
+++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
@@ -21,7 +21,7 @@
 #include <asm/prom.h>
 
 static struct device_node *cpld_pic_node;
-static struct irq_host *cpld_pic_host;
+static struct irq_domain *cpld_pic_host;
 
 /*
  * Bits to ignore in the misc_status register
@@ -123,13 +123,13 @@ cpld_pic_cascade(unsigned int irq, struct irq_desc *desc)
 }
 
 static int
-cpld_pic_host_match(struct irq_host *h, struct device_node *node)
+cpld_pic_host_match(struct irq_domain *h, struct device_node *node)
 {
 	return cpld_pic_node == node;
 }
 
 static int
-cpld_pic_host_map(struct irq_host *h, unsigned int virq,
+cpld_pic_host_map(struct irq_domain *h, unsigned int virq,
 			     irq_hw_number_t hw)
 {
 	irq_set_status_flags(virq, IRQ_LEVEL);
@@ -137,8 +137,7 @@ cpld_pic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static struct
-irq_host_ops cpld_pic_host_ops = {
+static struct irq_domain_ops cpld_pic_host_ops = {
 	.match = cpld_pic_host_match,
 	.map = cpld_pic_host_map,
 };
@@ -192,7 +191,7 @@ mpc5121_ads_cpld_pic_init(void)
 	cpld_pic_node = of_node_get(np);
 
 	cpld_pic_host =
-	    irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, 16, &cpld_pic_host_ops, 16);
+	    irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, 16, &cpld_pic_host_ops, 16);
 	if (!cpld_pic_host) {
 		printk(KERN_ERR "CPLD PIC: failed to allocate irq host!\n");
 		goto end;
diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c
index 96f85e5..a746415 100644
--- a/arch/powerpc/platforms/52xx/media5200.c
+++ b/arch/powerpc/platforms/52xx/media5200.c
@@ -45,7 +45,7 @@ static struct of_device_id mpc5200_gpio_ids[] __initdata = {
 struct media5200_irq {
 	void __iomem *regs;
 	spinlock_t lock;
-	struct irq_host *irqhost;
+	struct irq_domain *irqhost;
 };
 struct media5200_irq media5200_irq;
 
@@ -112,7 +112,7 @@ void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc)
 	raw_spin_unlock(&desc->lock);
 }
 
-static int media5200_irq_map(struct irq_host *h, unsigned int virq,
+static int media5200_irq_map(struct irq_domain *h, unsigned int virq,
 			     irq_hw_number_t hw)
 {
 	pr_debug("%s: h=%p, virq=%i, hwirq=%i\n", __func__, h, virq, (int)hw);
@@ -122,7 +122,7 @@ static int media5200_irq_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int media5200_irq_xlate(struct irq_host *h, struct device_node *ct,
+static int media5200_irq_xlate(struct irq_domain *h, struct device_node *ct,
 				 const u32 *intspec, unsigned int intsize,
 				 irq_hw_number_t *out_hwirq,
 				 unsigned int *out_flags)
@@ -136,7 +136,7 @@ static int media5200_irq_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops media5200_irq_ops = {
+static struct irq_domain_ops media5200_irq_ops = {
 	.map = media5200_irq_map,
 	.xlate = media5200_irq_xlate,
 };
@@ -173,7 +173,7 @@ static void __init media5200_init_irq(void)
 
 	spin_lock_init(&media5200_irq.lock);
 
-	media5200_irq.irqhost = irq_alloc_host(fpga_np, IRQ_HOST_MAP_LINEAR,
+	media5200_irq.irqhost = irq_alloc_host(fpga_np, IRQ_DOMAIN_MAP_LINEAR,
 					       MEDIA5200_NUM_IRQS,
 					       &media5200_irq_ops, -1);
 	if (!media5200_irq.irqhost)
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index f94f06e..e90af8f 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -81,7 +81,7 @@ MODULE_LICENSE("GPL");
  * @regs: virtual address of GPT registers
  * @lock: spinlock to coordinate between different functions.
  * @gc: gpio_chip instance structure; used when GPIO is enabled
- * @irqhost: Pointer to irq_host instance; used when IRQ mode is supported
+ * @irqhost: Pointer to irq_domain instance; used when IRQ mode is supported
  * @wdt_mode: only relevant for gpt0: bit 0 (MPC52xx_GPT_CAN_WDT) indicates
  *   if the gpt may be used as wdt, bit 1 (MPC52xx_GPT_IS_WDT) indicates
  *   if the timer is actively used as wdt which blocks gpt functions
@@ -91,7 +91,7 @@ struct mpc52xx_gpt_priv {
 	struct device *dev;
 	struct mpc52xx_gpt __iomem *regs;
 	spinlock_t lock;
-	struct irq_host *irqhost;
+	struct irq_domain *irqhost;
 	u32 ipb_freq;
 	u8 wdt_mode;
 
@@ -204,7 +204,7 @@ void mpc52xx_gpt_irq_cascade(unsigned int virq, struct irq_desc *desc)
 	}
 }
 
-static int mpc52xx_gpt_irq_map(struct irq_host *h, unsigned int virq,
+static int mpc52xx_gpt_irq_map(struct irq_domain *h, unsigned int virq,
 			       irq_hw_number_t hw)
 {
 	struct mpc52xx_gpt_priv *gpt = h->host_data;
@@ -216,7 +216,7 @@ static int mpc52xx_gpt_irq_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int mpc52xx_gpt_irq_xlate(struct irq_host *h, struct device_node *ct,
+static int mpc52xx_gpt_irq_xlate(struct irq_domain *h, struct device_node *ct,
 				 const u32 *intspec, unsigned int intsize,
 				 irq_hw_number_t *out_hwirq,
 				 unsigned int *out_flags)
@@ -236,7 +236,7 @@ static int mpc52xx_gpt_irq_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops mpc52xx_gpt_irq_ops = {
+static struct irq_domain_ops mpc52xx_gpt_irq_ops = {
 	.map = mpc52xx_gpt_irq_map,
 	.xlate = mpc52xx_gpt_irq_xlate,
 };
@@ -252,7 +252,7 @@ mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
 	if (!cascade_virq)
 		return;
 
-	gpt->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, 1,
+	gpt->irqhost = irq_alloc_host(node, IRQ_DOMAIN_MAP_LINEAR, 1,
 				      &mpc52xx_gpt_irq_ops, -1);
 	if (!gpt->irqhost) {
 		dev_err(gpt->dev, "irq_alloc_host() failed\n");
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 1a9a495..8c997f1 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -132,7 +132,7 @@ static struct of_device_id mpc52xx_sdma_ids[] __initdata = {
 
 static struct mpc52xx_intr __iomem *intr;
 static struct mpc52xx_sdma __iomem *sdma;
-static struct irq_host *mpc52xx_irqhost = NULL;
+static struct irq_domain *mpc52xx_irqhost = NULL;
 
 static unsigned char mpc52xx_map_senses[4] = {
 	IRQ_TYPE_LEVEL_HIGH,
@@ -301,7 +301,7 @@ static int mpc52xx_is_extirq(int l1, int l2)
 /**
  * mpc52xx_irqhost_xlate - translate virq# from device tree interrupts property
  */
-static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
+static int mpc52xx_irqhost_xlate(struct irq_domain *h, struct device_node *ct,
 				 const u32 *intspec, unsigned int intsize,
 				 irq_hw_number_t *out_hwirq,
 				 unsigned int *out_flags)
@@ -335,7 +335,7 @@ static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
 /**
  * mpc52xx_irqhost_map - Hook to map from virq to an irq_chip structure
  */
-static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
+static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq,
 			       irq_hw_number_t irq)
 {
 	int l1irq;
@@ -384,7 +384,7 @@ static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_host_ops mpc52xx_irqhost_ops = {
+static struct irq_domain_ops mpc52xx_irqhost_ops = {
 	.xlate = mpc52xx_irqhost_xlate,
 	.map = mpc52xx_irqhost_map,
 };
@@ -444,7 +444,7 @@ void __init mpc52xx_init_irq(void)
 	 * As last step, add an irq host to translate the real
 	 * hw irq information provided by the ofw to linux virq
 	 */
-	mpc52xx_irqhost = irq_alloc_host(picnode, IRQ_HOST_MAP_LINEAR,
+	mpc52xx_irqhost = irq_alloc_host(picnode, IRQ_DOMAIN_MAP_LINEAR,
 	                                 MPC52xx_IRQ_HIGHTESTHWIRQ,
 	                                 &mpc52xx_irqhost_ops, -1);
 
diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
index 8ccf9ed..bdba174 100644
--- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
+++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
@@ -29,7 +29,7 @@ static DEFINE_RAW_SPINLOCK(pci_pic_lock);
 
 struct pq2ads_pci_pic {
 	struct device_node *node;
-	struct irq_host *host;
+	struct irq_domain *host;
 
 	struct {
 		u32 stat;
@@ -103,7 +103,7 @@ static void pq2ads_pci_irq_demux(unsigned int irq, struct irq_desc *desc)
 	}
 }
 
-static int pci_pic_host_map(struct irq_host *h, unsigned int virq,
+static int pci_pic_host_map(struct irq_domain *h, unsigned int virq,
 			    irq_hw_number_t hw)
 {
 	irq_set_status_flags(virq, IRQ_LEVEL);
@@ -112,14 +112,14 @@ static int pci_pic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_host_ops pci_pic_host_ops = {
+static struct irq_domain_ops pci_pic_host_ops = {
 	.map = pci_pic_host_map,
 };
 
 int __init pq2ads_pci_init_irq(void)
 {
 	struct pq2ads_pci_pic *priv;
-	struct irq_host *host;
+	struct irq_domain *host;
 	struct device_node *np;
 	int ret = -ENODEV;
 	int irq;
@@ -156,7 +156,7 @@ int __init pq2ads_pci_init_irq(void)
 	out_be32(&priv->regs->mask, ~0);
 	mb();
 
-	host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, NUM_IRQS,
+	host = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, NUM_IRQS,
 	                      &pci_pic_host_ops, NUM_IRQS);
 	if (!host) {
 		ret = -ENOMEM;
diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
index 12cb9bb..e3ef7c9 100644
--- a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
+++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
@@ -51,7 +51,7 @@ static struct socrates_fpga_irq_info fpga_irqs[SOCRATES_FPGA_NUM_IRQS] = {
 static DEFINE_RAW_SPINLOCK(socrates_fpga_pic_lock);
 
 static void __iomem *socrates_fpga_pic_iobase;
-static struct irq_host *socrates_fpga_pic_irq_host;
+static struct irq_domain *socrates_fpga_pic_irq_host;
 static unsigned int socrates_fpga_irqs[3];
 
 static inline uint32_t socrates_fpga_pic_read(int reg)
@@ -227,7 +227,7 @@ static struct irq_chip socrates_fpga_pic_chip = {
 	.irq_set_type	= socrates_fpga_pic_set_type,
 };
 
-static int socrates_fpga_pic_host_map(struct irq_host *h, unsigned int virq,
+static int socrates_fpga_pic_host_map(struct irq_domain *h, unsigned int virq,
 		irq_hw_number_t hwirq)
 {
 	/* All interrupts are LEVEL sensitive */
@@ -238,7 +238,7 @@ static int socrates_fpga_pic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int socrates_fpga_pic_host_xlate(struct irq_host *h,
+static int socrates_fpga_pic_host_xlate(struct irq_domain *h,
 		struct device_node *ct,	const u32 *intspec, unsigned int intsize,
 		irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 {
@@ -269,7 +269,7 @@ static int socrates_fpga_pic_host_xlate(struct irq_host *h,
 	return 0;
 }
 
-static struct irq_host_ops socrates_fpga_pic_host_ops = {
+static struct irq_domain_ops socrates_fpga_pic_host_ops = {
 	.map    = socrates_fpga_pic_host_map,
 	.xlate  = socrates_fpga_pic_host_xlate,
 };
@@ -279,8 +279,8 @@ void socrates_fpga_pic_init(struct device_node *pic)
 	unsigned long flags;
 	int i;
 
-	/* Setup an irq_host structure */
-	socrates_fpga_pic_irq_host = irq_alloc_host(pic, IRQ_HOST_MAP_LINEAR,
+	/* Setup an irq_domain structure */
+	socrates_fpga_pic_irq_host = irq_alloc_host(pic, IRQ_DOMAIN_MAP_LINEAR,
 			SOCRATES_FPGA_NUM_IRQS,	&socrates_fpga_pic_host_ops,
 			SOCRATES_FPGA_NUM_IRQS);
 	if (socrates_fpga_pic_irq_host == NULL) {
diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c
index 94594e5..0cf8af2 100644
--- a/arch/powerpc/platforms/86xx/gef_pic.c
+++ b/arch/powerpc/platforms/86xx/gef_pic.c
@@ -50,7 +50,7 @@
 static DEFINE_RAW_SPINLOCK(gef_pic_lock);
 
 static void __iomem *gef_pic_irq_reg_base;
-static struct irq_host *gef_pic_irq_host;
+static struct irq_domain *gef_pic_irq_host;
 static int gef_pic_cascade_irq;
 
 /*
@@ -153,7 +153,7 @@ static struct irq_chip gef_pic_chip = {
 /* When an interrupt is being configured, this call allows some flexibilty
  * in deciding which irq_chip structure is used
  */
-static int gef_pic_host_map(struct irq_host *h, unsigned int virq,
+static int gef_pic_host_map(struct irq_domain *h, unsigned int virq,
 			  irq_hw_number_t hwirq)
 {
 	/* All interrupts are LEVEL sensitive */
@@ -163,7 +163,7 @@ static int gef_pic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int gef_pic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int gef_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
 			    const u32 *intspec, unsigned int intsize,
 			    irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 {
@@ -177,7 +177,7 @@ static int gef_pic_host_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops gef_pic_host_ops = {
+static struct irq_domain_ops gef_pic_host_ops = {
 	.map	= gef_pic_host_map,
 	.xlate	= gef_pic_host_xlate,
 };
@@ -211,8 +211,8 @@ void __init gef_pic_init(struct device_node *np)
 		return;
 	}
 
-	/* Setup an irq_host structure */
-	gef_pic_irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
+	/* Setup an irq_domain structure */
+	gef_pic_irq_host = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR,
 					  GEF_PIC_NUM_IRQS,
 					  &gef_pic_host_ops, NO_IRQ);
 	if (gef_pic_irq_host == NULL)
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 40a6e34..1bfd18a 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -67,7 +67,7 @@
 
 
 struct axon_msic {
-	struct irq_host *irq_host;
+	struct irq_domain *irq_domain;
 	__le32 *fifo_virt;
 	dma_addr_t fifo_phys;
 	dcr_host_t dcr_host;
@@ -152,7 +152,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
 
 static struct axon_msic *find_msi_translator(struct pci_dev *dev)
 {
-	struct irq_host *irq_host;
+	struct irq_domain *irq_domain;
 	struct device_node *dn, *tmp;
 	const phandle *ph;
 	struct axon_msic *msic = NULL;
@@ -184,14 +184,14 @@ static struct axon_msic *find_msi_translator(struct pci_dev *dev)
 		goto out_error;
 	}
 
-	irq_host = irq_find_host(dn);
-	if (!irq_host) {
-		dev_dbg(&dev->dev, "axon_msi: no irq_host found for node %s\n",
+	irq_domain = irq_find_host(dn);
+	if (!irq_domain) {
+		dev_dbg(&dev->dev, "axon_msi: no irq_domain found for node %s\n",
 			dn->full_name);
 		goto out_error;
 	}
 
-	msic = irq_host->host_data;
+	msic = irq_domain->host_data;
 
 out_error:
 	of_node_put(dn);
@@ -280,7 +280,7 @@ static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 	BUILD_BUG_ON(NR_IRQS > 65536);
 
 	list_for_each_entry(entry, &dev->msi_list, list) {
-		virq = irq_create_direct_mapping(msic->irq_host);
+		virq = irq_create_direct_mapping(msic->irq_domain);
 		if (virq == NO_IRQ) {
 			dev_warn(&dev->dev,
 				 "axon_msi: virq allocation failed!\n");
@@ -318,7 +318,7 @@ static struct irq_chip msic_irq_chip = {
 	.name		= "AXON-MSI",
 };
 
-static int msic_host_map(struct irq_host *h, unsigned int virq,
+static int msic_host_map(struct irq_domain *h, unsigned int virq,
 			 irq_hw_number_t hw)
 {
 	irq_set_chip_data(virq, h->host_data);
@@ -327,7 +327,7 @@ static int msic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_host_ops msic_host_ops = {
+static struct irq_domain_ops msic_host_ops = {
 	.map	= msic_host_map,
 };
 
@@ -337,7 +337,7 @@ static void axon_msi_shutdown(struct platform_device *device)
 	u32 tmp;
 
 	pr_devel("axon_msi: disabling %s\n",
-		  msic->irq_host->of_node->full_name);
+		  msic->irq_domain->of_node->full_name);
 	tmp  = dcr_read(msic->dcr_host, MSIC_CTRL_REG);
 	tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE;
 	msic_dcr_write(msic, MSIC_CTRL_REG, tmp);
@@ -392,15 +392,15 @@ static int axon_msi_probe(struct platform_device *device)
 	}
 	memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES);
 
-	msic->irq_host = irq_alloc_host(dn, IRQ_HOST_MAP_NOMAP,
+	msic->irq_domain = irq_alloc_host(dn, IRQ_DOMAIN_MAP_NOMAP,
 					NR_IRQS, &msic_host_ops, 0);
-	if (!msic->irq_host) {
-		printk(KERN_ERR "axon_msi: couldn't allocate irq_host for %s\n",
+	if (!msic->irq_domain) {
+		printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n",
 		       dn->full_name);
 		goto out_free_fifo;
 	}
 
-	msic->irq_host->host_data = msic;
+	msic->irq_domain->host_data = msic;
 
 	irq_set_handler_data(virq, msic);
 	irq_set_chained_handler(virq, axon_msi_cascade);
diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c
index 55015e1..21b64cf 100644
--- a/arch/powerpc/platforms/cell/beat_interrupt.c
+++ b/arch/powerpc/platforms/cell/beat_interrupt.c
@@ -34,7 +34,7 @@ static DEFINE_RAW_SPINLOCK(beatic_irq_mask_lock);
 static uint64_t	beatic_irq_mask_enable[(MAX_IRQS+255)/64];
 static uint64_t	beatic_irq_mask_ack[(MAX_IRQS+255)/64];
 
-static struct irq_host *beatic_host;
+static struct irq_domain *beatic_host;
 
 /*
  * In this implementation, "virq" == "IRQ plug number",
@@ -122,7 +122,7 @@ static struct irq_chip beatic_pic = {
  *
  * Note that the number (virq) is already assigned at upper layer.
  */
-static void beatic_pic_host_unmap(struct irq_host *h, unsigned int virq)
+static void beatic_pic_host_unmap(struct irq_domain *h, unsigned int virq)
 {
 	beat_destruct_irq_plug(virq);
 }
@@ -133,7 +133,7 @@ static void beatic_pic_host_unmap(struct irq_host *h, unsigned int virq)
  *
  * Note that the number (virq) is already assigned at upper layer.
  */
-static int beatic_pic_host_map(struct irq_host *h, unsigned int virq,
+static int beatic_pic_host_map(struct irq_domain *h, unsigned int virq,
 			       irq_hw_number_t hw)
 {
 	int64_t	err;
@@ -154,7 +154,7 @@ static int beatic_pic_host_map(struct irq_host *h, unsigned int virq,
  * Called from irq_create_of_mapping() only.
  * Note: We have only 1 entry to translate.
  */
-static int beatic_pic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int beatic_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
 				 const u32 *intspec, unsigned int intsize,
 				 irq_hw_number_t *out_hwirq,
 				 unsigned int *out_flags)
@@ -166,13 +166,13 @@ static int beatic_pic_host_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static int beatic_pic_host_match(struct irq_host *h, struct device_node *np)
+static int beatic_pic_host_match(struct irq_domain *h, struct device_node *np)
 {
 	/* Match all */
 	return 1;
 }
 
-static struct irq_host_ops beatic_pic_host_ops = {
+static struct irq_domain_ops beatic_pic_host_ops = {
 	.map = beatic_pic_host_map,
 	.unmap = beatic_pic_host_unmap,
 	.xlate = beatic_pic_host_xlate,
@@ -239,7 +239,7 @@ void __init beatic_init_IRQ(void)
 	ppc_md.get_irq = beatic_get_irq;
 
 	/* Allocate an irq host */
-	beatic_host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0,
+	beatic_host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_NOMAP, 0,
 				     &beatic_pic_host_ops,
 					 0);
 	BUG_ON(beatic_host == NULL);
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 96a433d..6888475 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -56,7 +56,7 @@ struct iic {
 
 static DEFINE_PER_CPU(struct iic, cpu_iic);
 #define IIC_NODE_COUNT	2
-static struct irq_host *iic_host;
+static struct irq_domain *iic_host;
 
 /* Convert between "pending" bits and hw irq number */
 static irq_hw_number_t iic_pending_to_hwnum(struct cbe_iic_pending_bits bits)
@@ -186,7 +186,7 @@ void iic_message_pass(int cpu, int msg)
 	out_be64(&per_cpu(cpu_iic, cpu).regs->generate, (0xf - msg) << 4);
 }
 
-struct irq_host *iic_get_irq_host(int node)
+struct irq_domain *iic_get_irq_host(int node)
 {
 	return iic_host;
 }
@@ -222,13 +222,13 @@ void iic_request_IPIs(void)
 #endif /* CONFIG_SMP */
 
 
-static int iic_host_match(struct irq_host *h, struct device_node *node)
+static int iic_host_match(struct irq_domain *h, struct device_node *node)
 {
 	return of_device_is_compatible(node,
 				    "IBM,CBEA-Internal-Interrupt-Controller");
 }
 
-static int iic_host_map(struct irq_host *h, unsigned int virq,
+static int iic_host_map(struct irq_domain *h, unsigned int virq,
 			irq_hw_number_t hw)
 {
 	switch (hw & IIC_IRQ_TYPE_MASK) {
@@ -245,7 +245,7 @@ static int iic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int iic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int iic_host_xlate(struct irq_domain *h, struct device_node *ct,
 			   const u32 *intspec, unsigned int intsize,
 			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 
@@ -285,7 +285,7 @@ static int iic_host_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops iic_host_ops = {
+static struct irq_domain_ops iic_host_ops = {
 	.match = iic_host_match,
 	.map = iic_host_map,
 	.xlate = iic_host_xlate,
@@ -378,7 +378,7 @@ static int __init setup_iic(void)
 void __init iic_init_IRQ(void)
 {
 	/* Setup an irq host data structure */
-	iic_host = irq_alloc_host(NULL, IRQ_HOST_MAP_LINEAR, IIC_SOURCE_COUNT,
+	iic_host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_LINEAR, IIC_SOURCE_COUNT,
 				  &iic_host_ops, IIC_IRQ_INVALID);
 	BUG_ON(iic_host == NULL);
 	irq_set_default_host(iic_host);
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 442c28c..1f935a7 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -62,7 +62,7 @@ enum {
 #define SPIDER_IRQ_INVALID	63
 
 struct spider_pic {
-	struct irq_host		*host;
+	struct irq_domain		*host;
 	void __iomem		*regs;
 	unsigned int		node_id;
 };
@@ -168,7 +168,7 @@ static struct irq_chip spider_pic = {
 	.irq_set_type = spider_set_irq_type,
 };
 
-static int spider_host_map(struct irq_host *h, unsigned int virq,
+static int spider_host_map(struct irq_domain *h, unsigned int virq,
 			irq_hw_number_t hw)
 {
 	irq_set_chip_data(virq, h->host_data);
@@ -180,7 +180,7 @@ static int spider_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int spider_host_xlate(struct irq_host *h, struct device_node *ct,
+static int spider_host_xlate(struct irq_domain *h, struct device_node *ct,
 			   const u32 *intspec, unsigned int intsize,
 			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 
@@ -194,7 +194,7 @@ static int spider_host_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops spider_host_ops = {
+static struct irq_domain_ops spider_host_ops = {
 	.map = spider_host_map,
 	.xlate = spider_host_xlate,
 };
@@ -299,7 +299,7 @@ static void __init spider_init_one(struct device_node *of_node, int chip,
 		panic("spider_pic: can't map registers !");
 
 	/* Allocate a host */
-	pic->host = irq_alloc_host(of_node, IRQ_HOST_MAP_LINEAR,
+	pic->host = irq_alloc_host(of_node, IRQ_DOMAIN_MAP_LINEAR,
 				   SPIDER_SRC_COUNT, &spider_host_ops,
 				   SPIDER_IRQ_INVALID);
 	if (pic->host == NULL)
diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
index f61a2dd..f862361 100644
--- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
@@ -96,9 +96,9 @@ static struct irq_chip flipper_pic = {
  *
  */
 
-static struct irq_host *flipper_irq_host;
+static struct irq_domain *flipper_irq_host;
 
-static int flipper_pic_map(struct irq_host *h, unsigned int virq,
+static int flipper_pic_map(struct irq_domain *h, unsigned int virq,
 			   irq_hw_number_t hwirq)
 {
 	irq_set_chip_data(virq, h->host_data);
@@ -107,13 +107,13 @@ static int flipper_pic_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int flipper_pic_match(struct irq_host *h, struct device_node *np)
+static int flipper_pic_match(struct irq_domain *h, struct device_node *np)
 {
 	return 1;
 }
 
 
-static struct irq_host_ops flipper_irq_host_ops = {
+static struct irq_domain_ops flipper_irq_domain_ops = {
 	.map = flipper_pic_map,
 	.match = flipper_pic_match,
 };
@@ -130,10 +130,10 @@ static void __flipper_quiesce(void __iomem *io_base)
 	out_be32(io_base + FLIPPER_ICR, 0xffffffff);
 }
 
-struct irq_host * __init flipper_pic_init(struct device_node *np)
+struct irq_domain * __init flipper_pic_init(struct device_node *np)
 {
 	struct device_node *pi;
-	struct irq_host *irq_host = NULL;
+	struct irq_domain *irq_domain = NULL;
 	struct resource res;
 	void __iomem *io_base;
 	int retval;
@@ -159,22 +159,22 @@ struct irq_host * __init flipper_pic_init(struct device_node *np)
 
 	__flipper_quiesce(io_base);
 
-	irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, FLIPPER_NR_IRQS,
-				  &flipper_irq_host_ops, -1);
-	if (!irq_host) {
-		pr_err("failed to allocate irq_host\n");
+	irq_domain = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, FLIPPER_NR_IRQS,
+				  &flipper_irq_domain_ops, -1);
+	if (!irq_domain) {
+		pr_err("failed to allocate irq_domain\n");
 		return NULL;
 	}
 
-	irq_host->host_data = io_base;
+	irq_domain->host_data = io_base;
 
 out:
-	return irq_host;
+	return irq_domain;
 }
 
 unsigned int flipper_pic_get_irq(void)
 {
-	void __iomem *io_base = flipper_irq_host->host_data;
+	void __iomem *io_base = flipper_irq_domain->host_data;
 	int irq;
 	u32 irq_status;
 
@@ -184,7 +184,7 @@ unsigned int flipper_pic_get_irq(void)
 		return NO_IRQ;	/* no more IRQs pending */
 
 	irq = __ffs(irq_status);
-	return irq_linear_revmap(flipper_irq_host, irq);
+	return irq_linear_revmap(flipper_irq_domain, irq);
 }
 
 /*
@@ -199,7 +199,7 @@ void __init flipper_pic_probe(void)
 	np = of_find_compatible_node(NULL, NULL, "nintendo,flipper-pic");
 	BUG_ON(!np);
 
-	flipper_irq_host = flipper_pic_init(np);
+	flipper_irq_domain = flipper_pic_init(np);
 	BUG_ON(!flipper_irq_host);
 
 	irq_set_default_host(flipper_irq_host);
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
index e491917..2d4a5d4 100644
--- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
@@ -89,9 +89,9 @@ static struct irq_chip hlwd_pic = {
  *
  */
 
-static struct irq_host *hlwd_irq_host;
+static struct irq_domain *hlwd_irq_host;
 
-static int hlwd_pic_map(struct irq_host *h, unsigned int virq,
+static int hlwd_pic_map(struct irq_domain *h, unsigned int virq,
 			   irq_hw_number_t hwirq)
 {
 	irq_set_chip_data(virq, h->host_data);
@@ -100,11 +100,11 @@ static int hlwd_pic_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_host_ops hlwd_irq_host_ops = {
+static struct irq_domain_ops hlwd_irq_domain_ops = {
 	.map = hlwd_pic_map,
 };
 
-static unsigned int __hlwd_pic_get_irq(struct irq_host *h)
+static unsigned int __hlwd_pic_get_irq(struct irq_domain *h)
 {
 	void __iomem *io_base = h->host_data;
 	int irq;
@@ -123,14 +123,14 @@ static void hlwd_pic_irq_cascade(unsigned int cascade_virq,
 				      struct irq_desc *desc)
 {
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	struct irq_host *irq_host = irq_get_handler_data(cascade_virq);
+	struct irq_domain *irq_domain = irq_get_handler_data(cascade_virq);
 	unsigned int virq;
 
 	raw_spin_lock(&desc->lock);
 	chip->irq_mask(&desc->irq_data); /* IRQ_LEVEL */
 	raw_spin_unlock(&desc->lock);
 
-	virq = __hlwd_pic_get_irq(irq_host);
+	virq = __hlwd_pic_get_irq(irq_domain);
 	if (virq != NO_IRQ)
 		generic_handle_irq(virq);
 	else
@@ -155,9 +155,9 @@ static void __hlwd_quiesce(void __iomem *io_base)
 	out_be32(io_base + HW_BROADWAY_ICR, 0xffffffff);
 }
 
-struct irq_host *hlwd_pic_init(struct device_node *np)
+struct irq_domain *hlwd_pic_init(struct device_node *np)
 {
-	struct irq_host *irq_host;
+	struct irq_domain *irq_domain;
 	struct resource res;
 	void __iomem *io_base;
 	int retval;
@@ -177,20 +177,20 @@ struct irq_host *hlwd_pic_init(struct device_node *np)
 
 	__hlwd_quiesce(io_base);
 
-	irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, HLWD_NR_IRQS,
-				  &hlwd_irq_host_ops, -1);
-	if (!irq_host) {
-		pr_err("failed to allocate irq_host\n");
+	irq_domain = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, HLWD_NR_IRQS,
+				  &hlwd_irq_domain_ops, -1);
+	if (!irq_domain) {
+		pr_err("failed to allocate irq_domain\n");
 		return NULL;
 	}
-	irq_host->host_data = io_base;
+	irq_domain->host_data = io_base;
 
-	return irq_host;
+	return irq_domain;
 }
 
 unsigned int hlwd_pic_get_irq(void)
 {
-	return __hlwd_pic_get_irq(hlwd_irq_host);
+	return __hlwd_pic_get_irq(hlwd_irq_domain);
 }
 
 /*
@@ -200,7 +200,7 @@ unsigned int hlwd_pic_get_irq(void)
 
 void hlwd_pic_probe(void)
 {
-	struct irq_host *host;
+	struct irq_domain *host;
 	struct device_node *np;
 	const u32 *interrupts;
 	int cascade_virq;
@@ -214,7 +214,7 @@ void hlwd_pic_probe(void)
 			irq_set_handler_data(cascade_virq, host);
 			irq_set_chained_handler(cascade_virq,
 						hlwd_pic_irq_cascade);
-			hlwd_irq_host = host;
+			hlwd_irq_domain = host;
 			break;
 		}
 	}
@@ -228,7 +228,7 @@ void hlwd_pic_probe(void)
  */
 void hlwd_quiesce(void)
 {
-	void __iomem *io_base = hlwd_irq_host->host_data;
+	void __iomem *io_base = hlwd_irq_domain->host_data;
 
 	__hlwd_quiesce(io_base);
 }
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index b210345..b07d4f2 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -342,7 +342,7 @@ unsigned int iSeries_get_irq(void)
 
 #ifdef CONFIG_PCI
 
-static int iseries_irq_host_map(struct irq_host *h, unsigned int virq,
+static int iseries_irq_host_map(struct irq_domain *h, unsigned int virq,
 				irq_hw_number_t hw)
 {
 	irq_set_chip_and_handler(virq, &iseries_pic, handle_fasteoi_irq);
@@ -350,13 +350,13 @@ static int iseries_irq_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int iseries_irq_host_match(struct irq_host *h, struct device_node *np)
+static int iseries_irq_host_match(struct irq_domain *h, struct device_node *np)
 {
 	/* Match all */
 	return 1;
 }
 
-static struct irq_host_ops iseries_irq_host_ops = {
+static struct irq_domain_ops iseries_irq_domain_ops = {
 	.map = iseries_irq_host_map,
 	.match = iseries_irq_host_match,
 };
@@ -368,7 +368,7 @@ static struct irq_host_ops iseries_irq_host_ops = {
 void __init iSeries_init_IRQ(void)
 {
 	/* Register PCI event handler and open an event path */
-	struct irq_host *host;
+	struct irq_domain *host;
 	int ret;
 
 	/*
@@ -380,8 +380,8 @@ void __init iSeries_init_IRQ(void)
 	/* Create irq host. No need for a revmap since HV will give us
 	 * back our virtual irq number
 	 */
-	host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0,
-			      &iseries_irq_host_ops, 0);
+	host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_NOMAP, 0,
+			      &iseries_irq_domain_ops, 0);
 	BUG_ON(host == NULL);
 	irq_set_default_host(host);
 
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 7761aab..cff326a 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -61,7 +61,7 @@ static DEFINE_RAW_SPINLOCK(pmac_pic_lock);
 static unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
 static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
 static int pmac_irq_cascade = -1;
-static struct irq_host *pmac_pic_host;
+static struct irq_domain *pmac_pic_host;
 
 static void __pmac_retrigger(unsigned int irq_nr)
 {
@@ -268,13 +268,13 @@ static struct irqaction gatwick_cascade_action = {
 	.name		= "cascade",
 };
 
-static int pmac_pic_host_match(struct irq_host *h, struct device_node *node)
+static int pmac_pic_host_match(struct irq_domain *h, struct device_node *node)
 {
 	/* We match all, we don't always have a node anyway */
 	return 1;
 }
 
-static int pmac_pic_host_map(struct irq_host *h, unsigned int virq,
+static int pmac_pic_host_map(struct irq_domain *h, unsigned int virq,
 			     irq_hw_number_t hw)
 {
 	if (hw >= max_irqs)
@@ -288,7 +288,7 @@ static int pmac_pic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int pmac_pic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int pmac_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
 			       const u32 *intspec, unsigned int intsize,
 			       irq_hw_number_t *out_hwirq,
 			       unsigned int *out_flags)
@@ -299,7 +299,7 @@ static int pmac_pic_host_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops pmac_pic_host_ops = {
+static struct irq_domain_ops pmac_pic_host_ops = {
 	.match = pmac_pic_host_match,
 	.map = pmac_pic_host_map,
 	.xlate = pmac_pic_host_xlate,
@@ -352,7 +352,7 @@ static void __init pmac_pic_probe_oldstyle(void)
 	/*
 	 * Allocate an irq host
 	 */
-	pmac_pic_host = irq_alloc_host(master, IRQ_HOST_MAP_LINEAR, max_irqs,
+	pmac_pic_host = irq_alloc_host(master, IRQ_DOMAIN_MAP_LINEAR, max_irqs,
 				       &pmac_pic_host_ops,
 				       max_irqs);
 	BUG_ON(pmac_pic_host == NULL);
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 44d7692..6b1ef2d 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -125,7 +125,7 @@ static volatile u32 __iomem *psurge_start;
 static int psurge_type = PSURGE_NONE;
 
 /* irq for secondary cpus to report */
-static struct irq_host *psurge_host;
+static struct irq_domain *psurge_host;
 int psurge_secondary_virq;
 
 /*
@@ -176,7 +176,7 @@ static void smp_psurge_cause_ipi(int cpu, unsigned long data)
 	psurge_set_ipi(cpu);
 }
 
-static int psurge_host_map(struct irq_host *h, unsigned int virq,
+static int psurge_host_map(struct irq_domain *h, unsigned int virq,
 			 irq_hw_number_t hw)
 {
 	irq_set_chip_and_handler(virq, &dummy_irq_chip, handle_percpu_irq);
@@ -184,7 +184,7 @@ static int psurge_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-struct irq_host_ops psurge_host_ops = {
+struct irq_domain_ops psurge_host_ops = {
 	.map	= psurge_host_map,
 };
 
@@ -192,7 +192,7 @@ static int psurge_secondary_ipi_init(void)
 {
 	int rc = -ENOMEM;
 
-	psurge_host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0,
+	psurge_host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_NOMAP, 0,
 		&psurge_host_ops, 0);
 
 	if (psurge_host)
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 617efa1..c5980e4 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -667,7 +667,7 @@ static void __maybe_unused _dump_mask(struct ps3_private *pd,
 static void dump_bmp(struct ps3_private* pd) {};
 #endif /* defined(DEBUG) */
 
-static int ps3_host_map(struct irq_host *h, unsigned int virq,
+static int ps3_host_map(struct irq_domain *h, unsigned int virq,
 	irq_hw_number_t hwirq)
 {
 	DBG("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq,
@@ -678,13 +678,13 @@ static int ps3_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int ps3_host_match(struct irq_host *h, struct device_node *np)
+static int ps3_host_match(struct irq_domain *h, struct device_node *np)
 {
 	/* Match all */
 	return 1;
 }
 
-static struct irq_host_ops ps3_host_ops = {
+static struct irq_domain_ops ps3_host_ops = {
 	.map = ps3_host_map,
 	.match = ps3_host_match,
 };
@@ -751,9 +751,9 @@ void __init ps3_init_IRQ(void)
 {
 	int result;
 	unsigned cpu;
-	struct irq_host *host;
+	struct irq_domain *host;
 
-	host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0, &ps3_host_ops,
+	host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_NOMAP, 0, &ps3_host_ops,
 		PS3_INVALID_OUTLET);
 	irq_set_default_host(host);
 	irq_set_virq_count(PS3_PLUG_MAX + 1);
diff --git a/arch/powerpc/platforms/wsp/opb_pic.c b/arch/powerpc/platforms/wsp/opb_pic.c
index 19f353d..76b33bc 100644
--- a/arch/powerpc/platforms/wsp/opb_pic.c
+++ b/arch/powerpc/platforms/wsp/opb_pic.c
@@ -30,7 +30,7 @@
 static int opb_index = 0;
 
 struct opb_pic {
-	struct irq_host *host;
+	struct irq_domain *host;
 	void *regs;
 	int index;
 	spinlock_t lock;
@@ -179,7 +179,7 @@ static struct irq_chip opb_irq_chip = {
 	.irq_set_type	= opb_set_irq_type
 };
 
-static int opb_host_map(struct irq_host *host, unsigned int virq,
+static int opb_host_map(struct irq_domain *host, unsigned int virq,
 		irq_hw_number_t hwirq)
 {
 	struct opb_pic *opb;
@@ -196,7 +196,7 @@ static int opb_host_map(struct irq_host *host, unsigned int virq,
 	return 0;
 }
 
-static int opb_host_xlate(struct irq_host *host, struct device_node *dn,
+static int opb_host_xlate(struct irq_domain *host, struct device_node *dn,
 		const u32 *intspec, unsigned int intsize,
 		irq_hw_number_t *out_hwirq, unsigned int *out_type)
 {
@@ -207,7 +207,7 @@ static int opb_host_xlate(struct irq_host *host, struct device_node *dn,
 	return 0;
 }
 
-static struct irq_host_ops opb_host_ops = {
+static struct irq_domain_ops opb_host_ops = {
 	.map = opb_host_map,
 	.xlate = opb_host_xlate,
 };
@@ -267,7 +267,7 @@ struct opb_pic *opb_pic_init_one(struct device_node *dn)
 	 * having one interrupt to issue, we're the controller for multiple
 	 * hardware IRQs, so later we can lookup their virtual IRQs. */
 
-	opb->host = irq_alloc_host(dn, IRQ_HOST_MAP_LINEAR,
+	opb->host = irq_alloc_host(dn, IRQ_DOMAIN_MAP_LINEAR,
 			OPB_NR_IRQS, &opb_host_ops, -1);
 
 	if (!opb->host) {
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
index 5d7d59a..0877a75 100644
--- a/arch/powerpc/sysdev/cpm1.c
+++ b/arch/powerpc/sysdev/cpm1.c
@@ -54,7 +54,7 @@ cpm8xx_t __iomem *cpmp;  /* Pointer to comm processor space */
 immap_t __iomem *mpc8xx_immr;
 static cpic8xx_t __iomem *cpic_reg;
 
-static struct irq_host *cpm_pic_host;
+static struct irq_domain *cpm_pic_host;
 
 static void cpm_mask_irq(struct irq_data *d)
 {
@@ -98,7 +98,7 @@ int cpm_get_irq(void)
 	return irq_linear_revmap(cpm_pic_host, cpm_vec);
 }
 
-static int cpm_pic_host_map(struct irq_host *h, unsigned int virq,
+static int cpm_pic_host_map(struct irq_domain *h, unsigned int virq,
 			  irq_hw_number_t hw)
 {
 	pr_debug("cpm_pic_host_map(%d, 0x%lx)\n", virq, hw);
@@ -123,7 +123,7 @@ static struct irqaction cpm_error_irqaction = {
 	.name = "error",
 };
 
-static struct irq_host_ops cpm_pic_host_ops = {
+static struct irq_domain_ops cpm_pic_host_ops = {
 	.map = cpm_pic_host_map,
 };
 
@@ -164,7 +164,7 @@ unsigned int cpm_pic_init(void)
 
 	out_be32(&cpic_reg->cpic_cimr, 0);
 
-	cpm_pic_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
+	cpm_pic_host = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR,
 				      64, &cpm_pic_host_ops, 64);
 	if (cpm_pic_host == NULL) {
 		printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
index bcab50e..b149baa 100644
--- a/arch/powerpc/sysdev/cpm2_pic.c
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -50,7 +50,7 @@
 
 static intctl_cpm2_t __iomem *cpm2_intctl;
 
-static struct irq_host *cpm2_pic_host;
+static struct irq_domain *cpm2_pic_host;
 #define NR_MASK_WORDS   ((NR_IRQS + 31) / 32)
 static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
 
@@ -214,7 +214,7 @@ unsigned int cpm2_get_irq(void)
 	return irq_linear_revmap(cpm2_pic_host, irq);
 }
 
-static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq,
+static int cpm2_pic_host_map(struct irq_domain *h, unsigned int virq,
 			  irq_hw_number_t hw)
 {
 	pr_debug("cpm2_pic_host_map(%d, 0x%lx)\n", virq, hw);
@@ -224,7 +224,7 @@ static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int cpm2_pic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int cpm2_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
 			    const u32 *intspec, unsigned int intsize,
 			    irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 {
@@ -236,7 +236,7 @@ static int cpm2_pic_host_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops cpm2_pic_host_ops = {
+static struct irq_domain_ops cpm2_pic_host_ops = {
 	.map = cpm2_pic_host_map,
 	.xlate = cpm2_pic_host_xlate,
 };
@@ -275,7 +275,7 @@ void cpm2_pic_init(struct device_node *node)
 	out_be32(&cpm2_intctl->ic_scprrl, 0x05309770);
 
 	/* create a legacy host */
-	cpm2_pic_host = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR,
+	cpm2_pic_host = irq_alloc_host(node, IRQ_DOMAIN_MAP_LINEAR,
 				       64, &cpm2_pic_host_ops, 64);
 	if (cpm2_pic_host == NULL) {
 		printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
diff --git a/arch/powerpc/sysdev/ehv_pic.c b/arch/powerpc/sysdev/ehv_pic.c
index b6731e4..48d3ba1 100644
--- a/arch/powerpc/sysdev/ehv_pic.c
+++ b/arch/powerpc/sysdev/ehv_pic.c
@@ -182,13 +182,13 @@ unsigned int ehv_pic_get_irq(void)
 	return irq_linear_revmap(global_ehv_pic->irqhost, irq);
 }
 
-static int ehv_pic_host_match(struct irq_host *h, struct device_node *node)
+static int ehv_pic_host_match(struct irq_domain *h, struct device_node *node)
 {
 	/* Exact match, unless ehv_pic node is NULL */
 	return h->of_node == NULL || h->of_node == node;
 }
 
-static int ehv_pic_host_map(struct irq_host *h, unsigned int virq,
+static int ehv_pic_host_map(struct irq_domain *h, unsigned int virq,
 			 irq_hw_number_t hw)
 {
 	struct ehv_pic *ehv_pic = h->host_data;
@@ -217,7 +217,7 @@ static int ehv_pic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int ehv_pic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int ehv_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
 			   const u32 *intspec, unsigned int intsize,
 			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 
@@ -248,7 +248,7 @@ static int ehv_pic_host_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops ehv_pic_host_ops = {
+static struct irq_domain_ops ehv_pic_host_ops = {
 	.match = ehv_pic_host_match,
 	.map = ehv_pic_host_map,
 	.xlate = ehv_pic_host_xlate,
@@ -275,7 +275,7 @@ void __init ehv_pic_init(void)
 		return;
 	}
 
-	ehv_pic->irqhost = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
+	ehv_pic->irqhost = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR,
 		NR_EHV_PIC_INTS, &ehv_pic_host_ops, 0);
 
 	if (!ehv_pic->irqhost) {
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index ecb5c19..3f9a301 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -60,7 +60,7 @@ static struct irq_chip fsl_msi_chip = {
 	.name		= "FSL-MSI",
 };
 
-static int fsl_msi_host_map(struct irq_host *h, unsigned int virq,
+static int fsl_msi_host_map(struct irq_domain *h, unsigned int virq,
 				irq_hw_number_t hw)
 {
 	struct fsl_msi *msi_data = h->host_data;
@@ -74,7 +74,7 @@ static int fsl_msi_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_host_ops fsl_msi_host_ops = {
+static struct irq_domain_ops fsl_msi_host_ops = {
 	.map = fsl_msi_host_map,
 };
 
@@ -387,7 +387,7 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
 	}
 	platform_set_drvdata(dev, msi);
 
-	msi->irqhost = irq_alloc_host(dev->dev.of_node, IRQ_HOST_MAP_LINEAR,
+	msi->irqhost = irq_alloc_host(dev->dev.of_node, IRQ_DOMAIN_MAP_LINEAR,
 				      NR_MSI_IRQS, &fsl_msi_host_ops, 0);
 
 	if (msi->irqhost == NULL) {
diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/fsl_msi.h
index f6c646a..8225f86 100644
--- a/arch/powerpc/sysdev/fsl_msi.h
+++ b/arch/powerpc/sysdev/fsl_msi.h
@@ -26,7 +26,7 @@
 #define FSL_PIC_IP_VMPIC  0x00000003
 
 struct fsl_msi {
-	struct irq_host *irqhost;
+	struct irq_domain *irqhost;
 
 	unsigned long cascade_irq;
 
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index d18bb27..7e67890 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -25,7 +25,7 @@ static unsigned char cached_8259[2] = { 0xff, 0xff };
 
 static DEFINE_RAW_SPINLOCK(i8259_lock);
 
-static struct irq_host *i8259_host;
+static struct irq_domain *i8259_host;
 
 /*
  * Acknowledge the IRQ using either the PCI host bridge's interrupt
@@ -163,12 +163,12 @@ static struct resource pic_edgectrl_iores = {
 	.flags = IORESOURCE_BUSY,
 };
 
-static int i8259_host_match(struct irq_host *h, struct device_node *node)
+static int i8259_host_match(struct irq_domain *h, struct device_node *node)
 {
 	return h->of_node == NULL || h->of_node == node;
 }
 
-static int i8259_host_map(struct irq_host *h, unsigned int virq,
+static int i8259_host_map(struct irq_domain *h, unsigned int virq,
 			  irq_hw_number_t hw)
 {
 	pr_debug("i8259_host_map(%d, 0x%lx)\n", virq, hw);
@@ -185,7 +185,7 @@ static int i8259_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int i8259_host_xlate(struct irq_host *h, struct device_node *ct,
+static int i8259_host_xlate(struct irq_domain *h, struct device_node *ct,
 			    const u32 *intspec, unsigned int intsize,
 			    irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 {
@@ -205,13 +205,13 @@ static int i8259_host_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops i8259_host_ops = {
+static struct irq_domain_ops i8259_host_ops = {
 	.match = i8259_host_match,
 	.map = i8259_host_map,
 	.xlate = i8259_host_xlate,
 };
 
-struct irq_host *i8259_get_host(void)
+struct irq_domain *i8259_get_host(void)
 {
 	return i8259_host;
 }
@@ -263,7 +263,7 @@ void i8259_init(struct device_node *node, unsigned long intack_addr)
 	raw_spin_unlock_irqrestore(&i8259_lock, flags);
 
 	/* create a legacy host */
-	i8259_host = irq_alloc_host(node, IRQ_HOST_MAP_LEGACY,
+	i8259_host = irq_alloc_host(node, IRQ_DOMAIN_MAP_LEGACY,
 				    0, &i8259_host_ops, 0);
 	if (i8259_host == NULL) {
 		printk(KERN_ERR "i8259: failed to allocate irq host !\n");
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 95da897..9abed37 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -672,13 +672,13 @@ static struct irq_chip ipic_edge_irq_chip = {
 	.irq_set_type	= ipic_set_irq_type,
 };
 
-static int ipic_host_match(struct irq_host *h, struct device_node *node)
+static int ipic_host_match(struct irq_domain *h, struct device_node *node)
 {
 	/* Exact match, unless ipic node is NULL */
 	return h->of_node == NULL || h->of_node == node;
 }
 
-static int ipic_host_map(struct irq_host *h, unsigned int virq,
+static int ipic_host_map(struct irq_domain *h, unsigned int virq,
 			 irq_hw_number_t hw)
 {
 	struct ipic *ipic = h->host_data;
@@ -692,7 +692,7 @@ static int ipic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int ipic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int ipic_host_xlate(struct irq_domain *h, struct device_node *ct,
 			   const u32 *intspec, unsigned int intsize,
 			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 
@@ -708,7 +708,7 @@ static int ipic_host_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops ipic_host_ops = {
+static struct irq_domain_ops ipic_host_ops = {
 	.match	= ipic_host_match,
 	.map	= ipic_host_map,
 	.xlate	= ipic_host_xlate,
@@ -728,7 +728,7 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
 	if (ipic == NULL)
 		return NULL;
 
-	ipic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR,
+	ipic->irqhost = irq_alloc_host(node, IRQ_DOMAIN_MAP_LINEAR,
 				       NR_IPIC_INTS,
 				       &ipic_host_ops, 0);
 	if (ipic->irqhost == NULL) {
diff --git a/arch/powerpc/sysdev/ipic.h b/arch/powerpc/sysdev/ipic.h
index 9391c57..90031d1 100644
--- a/arch/powerpc/sysdev/ipic.h
+++ b/arch/powerpc/sysdev/ipic.h
@@ -43,7 +43,7 @@ struct ipic {
 	volatile u32 __iomem	*regs;
 
 	/* The remapper for this IPIC */
-	struct irq_host		*irqhost;
+	struct irq_domain		*irqhost;
 };
 
 struct ipic_info {
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c
index 2ca0a85..978dfc4 100644
--- a/arch/powerpc/sysdev/mpc8xx_pic.c
+++ b/arch/powerpc/sysdev/mpc8xx_pic.c
@@ -17,7 +17,7 @@
 
 extern int cpm_get_irq(struct pt_regs *regs);
 
-static struct irq_host *mpc8xx_pic_host;
+static struct irq_domain *mpc8xx_pic_host;
 #define NR_MASK_WORDS   ((NR_IRQS + 31) / 32)
 static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
 static sysconf8xx_t __iomem *siu_reg;
@@ -110,7 +110,7 @@ unsigned int mpc8xx_get_irq(void)
 
 }
 
-static int mpc8xx_pic_host_map(struct irq_host *h, unsigned int virq,
+static int mpc8xx_pic_host_map(struct irq_domain *h, unsigned int virq,
 			  irq_hw_number_t hw)
 {
 	pr_debug("mpc8xx_pic_host_map(%d, 0x%lx)\n", virq, hw);
@@ -121,7 +121,7 @@ static int mpc8xx_pic_host_map(struct irq_host *h, unsigned int virq,
 }
 
 
-static int mpc8xx_pic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int mpc8xx_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
 			    const u32 *intspec, unsigned int intsize,
 			    irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 {
@@ -142,7 +142,7 @@ static int mpc8xx_pic_host_xlate(struct irq_host *h, struct device_node *ct,
 }
 
 
-static struct irq_host_ops mpc8xx_pic_host_ops = {
+static struct irq_domain_ops mpc8xx_pic_host_ops = {
 	.map = mpc8xx_pic_host_map,
 	.xlate = mpc8xx_pic_host_xlate,
 };
@@ -171,7 +171,7 @@ int mpc8xx_pic_init(void)
 		goto out;
 	}
 
-	mpc8xx_pic_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
+	mpc8xx_pic_host = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR,
 					 64, &mpc8xx_pic_host_ops, 64);
 	if (mpc8xx_pic_host == NULL) {
 		printk(KERN_ERR "MPC8xx PIC: failed to allocate irq host!\n");
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 4e9ccb1..c844d34 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -965,13 +965,13 @@ static struct irq_chip mpic_irq_ht_chip = {
 #endif /* CONFIG_MPIC_U3_HT_IRQS */
 
 
-static int mpic_host_match(struct irq_host *h, struct device_node *node)
+static int mpic_host_match(struct irq_domain *h, struct device_node *node)
 {
 	/* Exact match, unless mpic node is NULL */
 	return h->of_node == NULL || h->of_node == node;
 }
 
-static int mpic_host_map(struct irq_host *h, unsigned int virq,
+static int mpic_host_map(struct irq_domain *h, unsigned int virq,
 			 irq_hw_number_t hw)
 {
 	struct mpic *mpic = h->host_data;
@@ -1041,7 +1041,7 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int mpic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int mpic_host_xlate(struct irq_domain *h, struct device_node *ct,
 			   const u32 *intspec, unsigned int intsize,
 			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 
@@ -1121,13 +1121,13 @@ static void mpic_cascade(unsigned int irq, struct irq_desc *desc)
 	BUG_ON(!(mpic->flags & MPIC_SECONDARY));
 
 	virq = mpic_get_one_irq(mpic);
-	if (virq != NO_IRQ)
+	if (virq)
 		generic_handle_irq(virq);
 
 	chip->irq_eoi(&desc->irq_data);
 }
 
-static struct irq_host_ops mpic_host_ops = {
+static struct irq_domain_ops mpic_host_ops = {
 	.match = mpic_host_match,
 	.map = mpic_host_map,
 	.xlate = mpic_host_xlate,
@@ -1345,7 +1345,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
 	mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
 	mpic->isu_mask = (1 << mpic->isu_shift) - 1;
 
-	mpic->irqhost = irq_alloc_host(mpic->node, IRQ_HOST_MAP_LINEAR,
+	mpic->irqhost = irq_alloc_host(mpic->node, IRQ_DOMAIN_MAP_LINEAR,
 				       isu_size ? isu_size : mpic->num_sources,
 				       &mpic_host_ops,
 				       flags & MPIC_LARGE_VECTORS ? 2048 : 256);
diff --git a/arch/powerpc/sysdev/mpic_msi.c b/arch/powerpc/sysdev/mpic_msi.c
index 0f67cd7..00395f4 100644
--- a/arch/powerpc/sysdev/mpic_msi.c
+++ b/arch/powerpc/sysdev/mpic_msi.c
@@ -32,7 +32,7 @@ void mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq)
 static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
 {
 	irq_hw_number_t hwirq;
-	struct irq_host_ops *ops = mpic->irqhost->ops;
+	struct irq_domain_ops *ops = mpic->irqhost->ops;
 	struct device_node *np;
 	int flags, index, i;
 	struct of_irq oirq;
diff --git a/arch/powerpc/sysdev/mv64x60_pic.c b/arch/powerpc/sysdev/mv64x60_pic.c
index 14d1302..45124a1 100644
--- a/arch/powerpc/sysdev/mv64x60_pic.c
+++ b/arch/powerpc/sysdev/mv64x60_pic.c
@@ -70,7 +70,7 @@ static u32 mv64x60_cached_low_mask;
 static u32 mv64x60_cached_high_mask = MV64X60_HIGH_GPP_GROUPS;
 static u32 mv64x60_cached_gpp_mask;
 
-static struct irq_host *mv64x60_irq_host;
+static struct irq_domain *mv64x60_irq_host;
 
 /*
  * mv64x60_chip_low functions
@@ -208,7 +208,7 @@ static struct irq_chip *mv64x60_chips[] = {
 	[MV64x60_LEVEL1_GPP]  = &mv64x60_chip_gpp,
 };
 
-static int mv64x60_host_map(struct irq_host *h, unsigned int virq,
+static int mv64x60_host_map(struct irq_domain *h, unsigned int virq,
 			  irq_hw_number_t hwirq)
 {
 	int level1;
@@ -223,7 +223,7 @@ static int mv64x60_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_host_ops mv64x60_host_ops = {
+static struct irq_domain_ops mv64x60_host_ops = {
 	.map   = mv64x60_host_map,
 };
 
@@ -250,7 +250,7 @@ void __init mv64x60_init_irq(void)
 	paddr = of_translate_address(np, reg);
 	mv64x60_irq_reg_base = ioremap(paddr, reg[1]);
 
-	mv64x60_irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
+	mv64x60_irq_host = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR,
 					  MV64x60_NUM_IRQS,
 					  &mv64x60_host_ops, MV64x60_NUM_IRQS);
 
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index 73034bd..78e9019 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -245,13 +245,13 @@ static struct irq_chip qe_ic_irq_chip = {
 	.irq_mask_ack = qe_ic_mask_irq,
 };
 
-static int qe_ic_host_match(struct irq_host *h, struct device_node *node)
+static int qe_ic_host_match(struct irq_domain *h, struct device_node *node)
 {
 	/* Exact match, unless qe_ic node is NULL */
 	return h->of_node == NULL || h->of_node == node;
 }
 
-static int qe_ic_host_map(struct irq_host *h, unsigned int virq,
+static int qe_ic_host_map(struct irq_domain *h, unsigned int virq,
 			  irq_hw_number_t hw)
 {
 	struct qe_ic *qe_ic = h->host_data;
@@ -272,7 +272,7 @@ static int qe_ic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int qe_ic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int qe_ic_host_xlate(struct irq_domain *h, struct device_node *ct,
 			    const u32 * intspec, unsigned int intsize,
 			    irq_hw_number_t * out_hwirq,
 			    unsigned int *out_flags)
@@ -285,7 +285,7 @@ static int qe_ic_host_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops qe_ic_host_ops = {
+static struct irq_domain_ops qe_ic_host_ops = {
 	.match = qe_ic_host_match,
 	.map = qe_ic_host_map,
 	.xlate = qe_ic_host_xlate,
@@ -339,7 +339,7 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags,
 	if (qe_ic == NULL)
 		return;
 
-	qe_ic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR,
+	qe_ic->irqhost = irq_alloc_host(node, IRQ_DOMAIN_MAP_LINEAR,
 					NR_QE_IC_INTS, &qe_ic_host_ops, 0);
 	if (qe_ic->irqhost == NULL) {
 		kfree(qe_ic);
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.h b/arch/powerpc/sysdev/qe_lib/qe_ic.h
index c1361d0..c327872 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.h
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.h
@@ -79,7 +79,7 @@ struct qe_ic {
 	volatile u32 __iomem *regs;
 
 	/* The remapper for this QEIC */
-	struct irq_host *irqhost;
+	struct irq_domain *irqhost;
 
 	/* The "linux" controller struct */
 	struct irq_chip hc_irq;
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 4d18658..f375723 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -51,7 +51,7 @@
 u32 tsi108_pci_cfg_base;
 static u32 tsi108_pci_cfg_phys;
 u32 tsi108_csr_vir_base;
-static struct irq_host *pci_irq_host;
+static struct irq_domain *pci_irq_host;
 
 extern u32 get_vir_csrbase(void);
 extern u32 tsi108_read_reg(u32 reg_offset);
@@ -376,7 +376,7 @@ static struct irq_chip tsi108_pci_irq = {
 	.irq_unmask = tsi108_pci_irq_unmask,
 };
 
-static int pci_irq_host_xlate(struct irq_host *h, struct device_node *ct,
+static int pci_irq_host_xlate(struct irq_domain *h, struct device_node *ct,
 			    const u32 *intspec, unsigned int intsize,
 			    irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 {
@@ -385,7 +385,7 @@ static int pci_irq_host_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static int pci_irq_host_map(struct irq_host *h, unsigned int virq,
+static int pci_irq_host_map(struct irq_domain *h, unsigned int virq,
 			  irq_hw_number_t hw)
 {	unsigned int irq;
 	DBG("%s(%d, 0x%lx)\n", __func__, virq, hw);
@@ -397,7 +397,7 @@ static int pci_irq_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_host_ops pci_irq_host_ops = {
+static struct irq_domain_ops pci_irq_domain_ops = {
 	.map = pci_irq_host_map,
 	.xlate = pci_irq_host_xlate,
 };
@@ -419,10 +419,10 @@ void __init tsi108_pci_int_init(struct device_node *node)
 {
 	DBG("Tsi108_pci_int_init: initializing PCI interrupts\n");
 
-	pci_irq_host = irq_alloc_host(node, IRQ_HOST_MAP_LEGACY,
-				      0, &pci_irq_host_ops, 0);
+	pci_irq_host = irq_alloc_host(node, IRQ_DOMAIN_MAP_LEGACY,
+				      0, &pci_irq_domain_ops, 0);
 	if (pci_irq_host == NULL) {
-		printk(KERN_ERR "pci_irq_host: failed to allocate irq host !\n");
+		printk(KERN_ERR "pci_irq_host: failed to allocate irq domain!\n");
 		return;
 	}
 
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
index 063c901..7eea3a6 100644
--- a/arch/powerpc/sysdev/uic.c
+++ b/arch/powerpc/sysdev/uic.c
@@ -49,7 +49,7 @@ struct uic {
 	raw_spinlock_t lock;
 
 	/* The remapper for this UIC */
-	struct irq_host	*irqhost;
+	struct irq_domain	*irqhost;
 };
 
 static void uic_unmask_irq(struct irq_data *d)
@@ -174,7 +174,7 @@ static struct irq_chip uic_irq_chip = {
 	.irq_set_type	= uic_set_irq_type,
 };
 
-static int uic_host_map(struct irq_host *h, unsigned int virq,
+static int uic_host_map(struct irq_domain *h, unsigned int virq,
 			irq_hw_number_t hw)
 {
 	struct uic *uic = h->host_data;
@@ -190,7 +190,7 @@ static int uic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int uic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int uic_host_xlate(struct irq_domain *h, struct device_node *ct,
 			  const u32 *intspec, unsigned int intsize,
 			  irq_hw_number_t *out_hwirq, unsigned int *out_type)
 
@@ -202,7 +202,7 @@ static int uic_host_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops uic_host_ops = {
+static struct irq_domain_ops uic_host_ops = {
 	.map	= uic_host_map,
 	.xlate	= uic_host_xlate,
 };
@@ -270,7 +270,7 @@ static struct uic * __init uic_init_one(struct device_node *node)
 	}
 	uic->dcrbase = *dcrreg;
 
-	uic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR,
+	uic->irqhost = irq_alloc_host(node, IRQ_DOMAIN_MAP_LINEAR,
 				      NR_UIC_INTS, &uic_host_ops, -1);
 	if (! uic->irqhost)
 		return NULL; /* FIXME: panic? */
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
index d72eda6..c4b3ce1 100644
--- a/arch/powerpc/sysdev/xics/xics-common.c
+++ b/arch/powerpc/sysdev/xics/xics-common.c
@@ -40,7 +40,7 @@ unsigned int xics_interrupt_server_size		= 8;
 
 DEFINE_PER_CPU(struct xics_cppr, xics_cppr);
 
-struct irq_host *xics_host;
+struct irq_domain *xics_host;
 
 static LIST_HEAD(ics_list);
 
@@ -301,7 +301,7 @@ int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask,
 }
 #endif /* CONFIG_SMP */
 
-static int xics_host_match(struct irq_host *h, struct device_node *node)
+static int xics_host_match(struct irq_domain *h, struct device_node *node)
 {
 	struct ics *ics;
 
@@ -323,7 +323,7 @@ static struct irq_chip xics_ipi_chip = {
 	.irq_unmask = xics_ipi_unmask,
 };
 
-static int xics_host_map(struct irq_host *h, unsigned int virq,
+static int xics_host_map(struct irq_domain *h, unsigned int virq,
 			 irq_hw_number_t hw)
 {
 	struct ics *ics;
@@ -351,7 +351,7 @@ static int xics_host_map(struct irq_host *h, unsigned int virq,
 	return -EINVAL;
 }
 
-static int xics_host_xlate(struct irq_host *h, struct device_node *ct,
+static int xics_host_xlate(struct irq_domain *h, struct device_node *ct,
 			   const u32 *intspec, unsigned int intsize,
 			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 
@@ -366,7 +366,7 @@ static int xics_host_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops xics_host_ops = {
+static struct irq_domain_ops xics_host_ops = {
 	.match = xics_host_match,
 	.map = xics_host_map,
 	.xlate = xics_host_xlate,
@@ -374,7 +374,7 @@ static struct irq_host_ops xics_host_ops = {
 
 static void __init xics_init_host(void)
 {
-	xics_host = irq_alloc_host(NULL, IRQ_HOST_MAP_TREE, 0, &xics_host_ops,
+	xics_host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_TREE, 0, &xics_host_ops,
 				   XICS_IRQ_SPURIOUS);
 	BUG_ON(xics_host == NULL);
 	irq_set_default_host(xics_host);
diff --git a/arch/powerpc/sysdev/xilinx_intc.c b/arch/powerpc/sysdev/xilinx_intc.c
index 6183799..92e7d4d 100644
--- a/arch/powerpc/sysdev/xilinx_intc.c
+++ b/arch/powerpc/sysdev/xilinx_intc.c
@@ -40,7 +40,7 @@
 #define XINTC_IVR	24	/* Interrupt Vector */
 #define XINTC_MER	28	/* Master Enable */
 
-static struct irq_host *master_irqhost;
+static struct irq_domain *master_irqhost;
 
 #define XILINX_INTC_MAXIRQS	(32)
 
@@ -141,7 +141,7 @@ static struct irq_chip xilinx_intc_edge_irqchip = {
 /**
  * xilinx_intc_xlate - translate virq# from device tree interrupts property
  */
-static int xilinx_intc_xlate(struct irq_host *h, struct device_node *ct,
+static int xilinx_intc_xlate(struct irq_domain *h, struct device_node *ct,
 				const u32 *intspec, unsigned int intsize,
 				irq_hw_number_t *out_hwirq,
 				unsigned int *out_flags)
@@ -161,7 +161,7 @@ static int xilinx_intc_xlate(struct irq_host *h, struct device_node *ct,
 
 	return 0;
 }
-static int xilinx_intc_map(struct irq_host *h, unsigned int virq,
+static int xilinx_intc_map(struct irq_domain *h, unsigned int virq,
 				  irq_hw_number_t irq)
 {
 	irq_set_chip_data(virq, h->host_data);
@@ -177,15 +177,15 @@ static int xilinx_intc_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_host_ops xilinx_intc_ops = {
+static struct irq_domain_ops xilinx_intc_ops = {
 	.map = xilinx_intc_map,
 	.xlate = xilinx_intc_xlate,
 };
 
-struct irq_host * __init
+struct irq_domain * __init
 xilinx_intc_init(struct device_node *np)
 {
-	struct irq_host * irq;
+	struct irq_domain * irq;
 	void * regs;
 
 	/* Find and map the intc registers */
@@ -200,8 +200,8 @@ xilinx_intc_init(struct device_node *np)
 	out_be32(regs + XINTC_IAR, ~(u32) 0); /* Acknowledge pending irqs */
 	out_be32(regs + XINTC_MER, 0x3UL); /* Turn on the Master Enable. */
 
-	/* Allocate and initialize an irq_host structure. */
-	irq = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, XILINX_INTC_MAXIRQS,
+	/* Allocate and initialize an irq_domain structure. */
+	irq = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, XILINX_INTC_MAXIRQS,
 			     &xilinx_intc_ops, -1);
 	if (!irq)
 		panic(__FILE__ ": Cannot allocate IRQ host\n");
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
index 5cd04b6..9efd597 100644
--- a/drivers/gpio/gpio-mpc8xxx.c
+++ b/drivers/gpio/gpio-mpc8xxx.c
@@ -37,7 +37,7 @@ struct mpc8xxx_gpio_chip {
 	 * open drain mode safely
 	 */
 	u32 data;
-	struct irq_host *irq;
+	struct irq_domain *irq;
 	void *of_dev_id_data;
 };
 
@@ -281,7 +281,7 @@ static struct irq_chip mpc8xxx_irq_chip = {
 	.irq_set_type	= mpc8xxx_irq_set_type,
 };
 
-static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
+static int mpc8xxx_gpio_irq_map(struct irq_domain *h, unsigned int virq,
 				irq_hw_number_t hw)
 {
 	struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data;
@@ -296,7 +296,7 @@ static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int mpc8xxx_gpio_irq_xlate(struct irq_host *h, struct device_node *ct,
+static int mpc8xxx_gpio_irq_xlate(struct irq_domain *h, struct device_node *ct,
 				  const u32 *intspec, unsigned int intsize,
 				  irq_hw_number_t *out_hwirq,
 				  unsigned int *out_flags)
@@ -311,7 +311,7 @@ static int mpc8xxx_gpio_irq_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops mpc8xxx_gpio_irq_ops = {
+static struct irq_domain_ops mpc8xxx_gpio_irq_ops = {
 	.map	= mpc8xxx_gpio_irq_map,
 	.xlate	= mpc8xxx_gpio_irq_xlate,
 };
@@ -365,7 +365,7 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
 		goto skip_irq;
 
 	mpc8xxx_gc->irq =
-		irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, MPC8XXX_GPIO_PINS,
+		irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, MPC8XXX_GPIO_PINS,
 			       &mpc8xxx_gpio_irq_ops, MPC8XXX_GPIO_PINS);
 	if (!mpc8xxx_gc->irq)
 		goto skip_irq;
-- 
1.7.5.4


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

* [PATCH v3 06/25] irq_domain/powerpc: eliminate irq_map; use irq_alloc_desc() instead
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (4 preceding siblings ...)
  2012-01-27 21:35 ` [PATCH v3 05/25] irq_domain/powerpc: Use common irq_domain structure instead of irq_host Grant Likely
@ 2012-01-27 21:36 ` Grant Likely
  2012-01-27 21:36 ` [PATCH v3 07/25] irq_domain/powerpc: Eliminate virq_is_host() Grant Likely
                   ` (21 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely

This patch drops the powerpc-specific irq_map table and replaces it with
directly using the irq_alloc_desc()/irq_free_desc() interfaces for allocating
and freeing irq_desc structures.

This patch is a preparation step for generalizing the powerpc-specific virq
infrastructure to become irq_domains.

As part of this change, the irq_big_lock is changed to a mutex from a raw
spinlock.  There is no longer any need to use a spin lock since the irq_desc
allocation code is now responsible for the critical section of finding
an unused range of irq numbers.

The radix lookup table is also changed to store the irq_data pointer instead
of the irq_map entry since the irq_map is removed.  This should end up being
functionally equivalent since only allocated irq_descs are ever added to the
radix tree.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/include/asm/irq.h |   27 -----
 arch/powerpc/kernel/irq.c      |  227 +++++++++++-----------------------------
 2 files changed, 59 insertions(+), 195 deletions(-)

diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h
index cb06b39..abdd7ef 100644
--- a/arch/powerpc/include/asm/irq.h
+++ b/arch/powerpc/include/asm/irq.h
@@ -191,33 +191,6 @@ extern unsigned int irq_linear_revmap(struct irq_domain *host,
 				      irq_hw_number_t hwirq);
 
 
-
-/**
- * irq_alloc_virt - Allocate virtual irq numbers
- * @host: host owning these new virtual irqs
- * @count: number of consecutive numbers to allocate
- * @hint: pass a hint number, the allocator will try to use a 1:1 mapping
- *
- * This is a low level function that is used internally by irq_create_mapping()
- * and that can be used by some irq controllers implementations for things
- * like allocating ranges of numbers for MSIs. The revmaps are left untouched.
- */
-extern unsigned int irq_alloc_virt(struct irq_domain *host,
-				   unsigned int count,
-				   unsigned int hint);
-
-/**
- * irq_free_virt - Free virtual irq numbers
- * @virq: virtual irq number of the first interrupt to free
- * @count: number of interrupts to free
- *
- * This function is the opposite of irq_alloc_virt. It will not clear reverse
- * maps, this should be done previously by unmap'ing the interrupt. In fact,
- * all interrupts covered by the range being freed should have been unmapped
- * prior to calling this.
- */
-extern void irq_free_virt(unsigned int virq, unsigned int count);
-
 /**
  * irq_early_init - Init irq remapping subsystem
  */
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 7305f2f..db5b545 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -491,38 +491,29 @@ void do_softirq(void)
  * IRQ controller and virtual interrupts
  */
 
-/* The main irq map itself is an array of NR_IRQ entries containing the
- * associate host and irq number. An entry with a host of NULL is free.
- * An entry can be allocated if it's free, the allocator always then sets
- * hwirq first to the host's invalid irq number and then fills ops.
- */
-struct irq_map_entry {
-	irq_hw_number_t	hwirq;
-	struct irq_domain	*host;
-};
-
 static LIST_HEAD(irq_domain_list);
-static DEFINE_RAW_SPINLOCK(irq_big_lock);
+static DEFINE_MUTEX(irq_domain_mutex);
 static DEFINE_MUTEX(revmap_trees_mutex);
-static struct irq_map_entry irq_map[NR_IRQS];
 static unsigned int irq_virq_count = NR_IRQS;
 static struct irq_domain *irq_default_host;
 
 irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
 {
-	return irq_map[d->irq].hwirq;
+	return d->hwirq;
 }
 EXPORT_SYMBOL_GPL(irqd_to_hwirq);
 
 irq_hw_number_t virq_to_hw(unsigned int virq)
 {
-	return irq_map[virq].hwirq;
+	struct irq_data *irq_data = irq_get_irq_data(virq);
+	return WARN_ON(!irq_data) ? 0 : irq_data->hwirq;
 }
 EXPORT_SYMBOL_GPL(virq_to_hw);
 
 bool virq_is_host(unsigned int virq, struct irq_domain *host)
 {
-	return irq_map[virq].host == host;
+	struct irq_data *irq_data = irq_get_irq_data(virq);
+	return irq_data ? irq_data->domain == host : false;
 }
 EXPORT_SYMBOL_GPL(virq_is_host);
 
@@ -537,11 +528,10 @@ struct irq_domain *irq_alloc_host(struct device_node *of_node,
 				struct irq_domain_ops *ops,
 				irq_hw_number_t inval_irq)
 {
-	struct irq_domain *host;
+	struct irq_domain *host, *h;
 	unsigned int size = sizeof(struct irq_domain);
 	unsigned int i;
 	unsigned int *rmap;
-	unsigned long flags;
 
 	/* Allocate structure and revmap table if using linear mapping */
 	if (revmap_type == IRQ_DOMAIN_MAP_LINEAR)
@@ -559,23 +549,20 @@ struct irq_domain *irq_alloc_host(struct device_node *of_node,
 	if (host->ops->match == NULL)
 		host->ops->match = default_irq_host_match;
 
-	raw_spin_lock_irqsave(&irq_big_lock, flags);
-
-	/* If it's a legacy controller, check for duplicates and
-	 * mark it as allocated (we use irq 0 host pointer for that
-	 */
+	mutex_lock(&irq_domain_mutex);
+	/* Make sure only one legacy controller can be created */
 	if (revmap_type == IRQ_DOMAIN_MAP_LEGACY) {
-		if (irq_map[0].host != NULL) {
-			raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-			of_node_put(host->of_node);
-			kfree(host);
-			return NULL;
+		list_for_each_entry(h, &irq_domain_list, link) {
+			if (WARN_ON(h->revmap_type == IRQ_DOMAIN_MAP_LEGACY)) {
+				mutex_unlock(&irq_domain_mutex);
+				of_node_put(host->of_node);
+				kfree(host);
+				return NULL;
+			}
 		}
-		irq_map[0].host = host;
 	}
-
 	list_add(&host->link, &irq_domain_list);
-	raw_spin_unlock_irqrestore(&irq_big_lock, flags);
+	mutex_unlock(&irq_domain_mutex);
 
 	/* Additional setups per revmap type */
 	switch(revmap_type) {
@@ -584,10 +571,9 @@ struct irq_domain *irq_alloc_host(struct device_node *of_node,
 		host->inval_irq = 0;
 		/* setup us as the host for all legacy interrupts */
 		for (i = 1; i < NUM_ISA_INTERRUPTS; i++) {
-			irq_map[i].hwirq = i;
-			smp_wmb();
-			irq_map[i].host = host;
-			smp_wmb();
+			struct irq_data *irq_data = irq_get_irq_data(i);
+			irq_data->hwirq = i;
+			irq_data->domain = host;
 
 			/* Legacy flags are left to default at this point,
 			 * one can then use irq_create_mapping() to
@@ -604,7 +590,6 @@ struct irq_domain *irq_alloc_host(struct device_node *of_node,
 		for (i = 0; i < revmap_arg; i++)
 			rmap[i] = NO_IRQ;
 		host->revmap_data.linear.size = revmap_arg;
-		smp_wmb();
 		host->revmap_data.linear.revmap = rmap;
 		break;
 	case IRQ_DOMAIN_MAP_TREE:
@@ -622,20 +607,19 @@ struct irq_domain *irq_alloc_host(struct device_node *of_node,
 struct irq_domain *irq_find_host(struct device_node *node)
 {
 	struct irq_domain *h, *found = NULL;
-	unsigned long flags;
 
 	/* We might want to match the legacy controller last since
 	 * it might potentially be set to match all interrupts in
 	 * the absence of a device node. This isn't a problem so far
 	 * yet though...
 	 */
-	raw_spin_lock_irqsave(&irq_big_lock, flags);
+	mutex_lock(&irq_domain_mutex);
 	list_for_each_entry(h, &irq_domain_list, link)
 		if (h->ops->match(h, node)) {
 			found = h;
 			break;
 		}
-	raw_spin_unlock_irqrestore(&irq_big_lock, flags);
+	mutex_unlock(&irq_domain_mutex);
 	return found;
 }
 EXPORT_SYMBOL_GPL(irq_find_host);
@@ -659,33 +643,20 @@ void irq_set_virq_count(unsigned int count)
 static int irq_setup_virq(struct irq_domain *host, unsigned int virq,
 			    irq_hw_number_t hwirq)
 {
-	int res;
-
-	res = irq_alloc_desc_at(virq, 0);
-	if (res != virq) {
-		pr_debug("irq: -> allocating desc failed\n");
-		goto error;
-	}
-
-	/* map it */
-	smp_wmb();
-	irq_map[virq].hwirq = hwirq;
-	smp_mb();
+	struct irq_data *irq_data = irq_get_irq_data(virq);
 
+	irq_data->hwirq = hwirq;
+	irq_data->domain = host;
 	if (host->ops->map(host, virq, hwirq)) {
 		pr_debug("irq: -> mapping failed, freeing\n");
-		goto errdesc;
+		irq_data->domain = NULL;
+		irq_data->hwirq = 0;
+		return -1;
 	}
 
 	irq_clear_status_flags(virq, IRQ_NOREQUEST);
 
 	return 0;
-
-errdesc:
-	irq_free_descs(virq, 1);
-error:
-	irq_free_virt(virq, 1);
-	return -1;
 }
 
 unsigned int irq_create_direct_mapping(struct irq_domain *host)
@@ -698,7 +669,7 @@ unsigned int irq_create_direct_mapping(struct irq_domain *host)
 	BUG_ON(host == NULL);
 	WARN_ON(host->revmap_type != IRQ_DOMAIN_MAP_NOMAP);
 
-	virq = irq_alloc_virt(host, 1, 0);
+	virq = irq_alloc_desc(0);
 	if (virq == NO_IRQ) {
 		pr_debug("irq: create_direct virq allocation failed\n");
 		return NO_IRQ;
@@ -706,8 +677,10 @@ unsigned int irq_create_direct_mapping(struct irq_domain *host)
 
 	pr_debug("irq: create_direct obtained virq %d\n", virq);
 
-	if (irq_setup_virq(host, virq, virq))
+	if (irq_setup_virq(host, virq, virq)) {
+		irq_free_desc(virq);
 		return NO_IRQ;
+	}
 
 	return virq;
 }
@@ -747,15 +720,20 @@ unsigned int irq_create_mapping(struct irq_domain *host,
 	} else {
 		/* Allocate a virtual interrupt number */
 		hint = hwirq % irq_virq_count;
-		virq = irq_alloc_virt(host, 1, hint);
+		virq = irq_alloc_desc_from(hint, 0);
+		if (!virq)
+			virq = irq_alloc_desc(0);
 		if (virq == NO_IRQ) {
 			pr_debug("irq: -> virq allocation failed\n");
 			return NO_IRQ;
 		}
 	}
 
-	if (irq_setup_virq(host, virq, hwirq))
+	if (irq_setup_virq(host, virq, hwirq)) {
+		if (host->revmap_type != IRQ_DOMAIN_MAP_LEGACY)
+			irq_free_desc(virq);
 		return NO_IRQ;
+	}
 
 	pr_debug("irq: irq %lu on host %s mapped to virtual irq %u\n",
 		hwirq, host->of_node ? host->of_node->full_name : "null", virq);
@@ -806,13 +784,14 @@ EXPORT_SYMBOL_GPL(irq_create_of_mapping);
 
 void irq_dispose_mapping(unsigned int virq)
 {
+	struct irq_data *irq_data = irq_get_irq_data(virq);
 	struct irq_domain *host;
 	irq_hw_number_t hwirq;
 
-	if (virq == NO_IRQ)
+	if (virq == NO_IRQ || !irq_data)
 		return;
 
-	host = irq_map[virq].host;
+	host = irq_data->domain;
 	if (WARN_ON(host == NULL))
 		return;
 
@@ -834,7 +813,7 @@ void irq_dispose_mapping(unsigned int virq)
 	smp_mb();
 
 	/* Clear reverse map */
-	hwirq = irq_map[virq].hwirq;
+	hwirq = irq_data->hwirq;
 	switch(host->revmap_type) {
 	case IRQ_DOMAIN_MAP_LINEAR:
 		if (hwirq < host->revmap_data.linear.size)
@@ -848,12 +827,9 @@ void irq_dispose_mapping(unsigned int virq)
 	}
 
 	/* Destroy map */
-	smp_mb();
-	irq_map[virq].hwirq = host->inval_irq;
+	irq_data->hwirq = host->inval_irq;
 
-	irq_free_descs(virq, 1);
-	/* Free it */
-	irq_free_virt(virq, 1);
+	irq_free_desc(virq);
 }
 EXPORT_SYMBOL_GPL(irq_dispose_mapping);
 
@@ -877,9 +853,9 @@ unsigned int irq_find_mapping(struct irq_domain *host,
 	if (hint < NUM_ISA_INTERRUPTS)
 		hint = NUM_ISA_INTERRUPTS;
 	i = hint;
-	do  {
-		if (irq_map[i].host == host &&
-		    irq_map[i].hwirq == hwirq)
+	do {
+		struct irq_data *data = irq_get_irq_data(i);
+		if (data && (data->domain == host) && (data->hwirq == hwirq))
 			return i;
 		i++;
 		if (i >= irq_virq_count)
@@ -928,19 +904,17 @@ int irq_choose_cpu(const struct cpumask *mask)
 unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
 				     irq_hw_number_t hwirq)
 {
-	struct irq_map_entry *ptr;
-	unsigned int virq;
+	struct irq_data *irq_data;
 
 	if (WARN_ON_ONCE(host->revmap_type != IRQ_DOMAIN_MAP_TREE))
 		return irq_find_mapping(host, hwirq);
 
 	/*
-	 * The ptr returned references the static global irq_map.
-	 * but freeing an irq can delete nodes along the path to
+	 * Freeing an irq can delete nodes along the path to
 	 * do the lookup via call_rcu.
 	 */
 	rcu_read_lock();
-	ptr = radix_tree_lookup(&host->revmap_data.tree, hwirq);
+	irq_data = radix_tree_lookup(&host->revmap_data.tree, hwirq);
 	rcu_read_unlock();
 
 	/*
@@ -948,24 +922,20 @@ unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
 	 * Else fallback to linear lookup - this should not happen in practice
 	 * as it means that we failed to insert the node in the radix tree.
 	 */
-	if (ptr)
-		virq = ptr - irq_map;
-	else
-		virq = irq_find_mapping(host, hwirq);
-
-	return virq;
+	return irq_data ? irq_data->irq : irq_find_mapping(host, hwirq);
 }
 
 void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq,
 			     irq_hw_number_t hwirq)
 {
+	struct irq_data *irq_data = irq_get_irq_data(virq);
+
 	if (WARN_ON(host->revmap_type != IRQ_DOMAIN_MAP_TREE))
 		return;
 
 	if (virq != NO_IRQ) {
 		mutex_lock(&revmap_trees_mutex);
-		radix_tree_insert(&host->revmap_data.tree, hwirq,
-				  &irq_map[virq]);
+		radix_tree_insert(&host->revmap_data.tree, hwirq, irq_data);
 		mutex_unlock(&revmap_trees_mutex);
 	}
 }
@@ -994,86 +964,6 @@ unsigned int irq_linear_revmap(struct irq_domain *host,
 	return revmap[hwirq];
 }
 
-unsigned int irq_alloc_virt(struct irq_domain *host,
-			    unsigned int count,
-			    unsigned int hint)
-{
-	unsigned long flags;
-	unsigned int i, j, found = NO_IRQ;
-
-	if (count == 0 || count > (irq_virq_count - NUM_ISA_INTERRUPTS))
-		return NO_IRQ;
-
-	raw_spin_lock_irqsave(&irq_big_lock, flags);
-
-	/* Use hint for 1 interrupt if any */
-	if (count == 1 && hint >= NUM_ISA_INTERRUPTS &&
-	    hint < irq_virq_count && irq_map[hint].host == NULL) {
-		found = hint;
-		goto hint_found;
-	}
-
-	/* Look for count consecutive numbers in the allocatable
-	 * (non-legacy) space
-	 */
-	for (i = NUM_ISA_INTERRUPTS, j = 0; i < irq_virq_count; i++) {
-		if (irq_map[i].host != NULL)
-			j = 0;
-		else
-			j++;
-
-		if (j == count) {
-			found = i - count + 1;
-			break;
-		}
-	}
-	if (found == NO_IRQ) {
-		raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-		return NO_IRQ;
-	}
- hint_found:
-	for (i = found; i < (found + count); i++) {
-		irq_map[i].hwirq = host->inval_irq;
-		smp_wmb();
-		irq_map[i].host = host;
-	}
-	raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-	return found;
-}
-
-void irq_free_virt(unsigned int virq, unsigned int count)
-{
-	unsigned long flags;
-	unsigned int i;
-
-	WARN_ON (virq < NUM_ISA_INTERRUPTS);
-	WARN_ON (count == 0 || (virq + count) > irq_virq_count);
-
-	if (virq < NUM_ISA_INTERRUPTS) {
-		if (virq + count < NUM_ISA_INTERRUPTS)
-			return;
-		count  =- NUM_ISA_INTERRUPTS - virq;
-		virq = NUM_ISA_INTERRUPTS;
-	}
-
-	if (count > irq_virq_count || virq > irq_virq_count - count) {
-		if (virq > irq_virq_count)
-			return;
-		count = irq_virq_count - virq;
-	}
-
-	raw_spin_lock_irqsave(&irq_big_lock, flags);
-	for (i = virq; i < (virq + count); i++) {
-		struct irq_domain *host;
-
-		host = irq_map[i].host;
-		irq_map[i].hwirq = host->inval_irq;
-		smp_wmb();
-		irq_map[i].host = NULL;
-	}
-	raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-}
-
 int arch_early_irq_init(void)
 {
 	return 0;
@@ -1100,10 +990,11 @@ static int virq_debug_show(struct seq_file *m, void *private)
 		raw_spin_lock_irqsave(&desc->lock, flags);
 
 		if (desc->action && desc->action->handler) {
+			struct irq_data *irq_data = irq_desc_get_data(desc);
 			struct irq_chip *chip;
 
 			seq_printf(m, "%5d  ", i);
-			seq_printf(m, "0x%05lx  ", irq_map[i].hwirq);
+			seq_printf(m, "0x%05lx  ", irq_data->hwirq);
 
 			chip = irq_desc_get_chip(desc);
 			if (chip && chip->name)
@@ -1115,8 +1006,8 @@ static int virq_debug_show(struct seq_file *m, void *private)
 			data = irq_desc_get_chip_data(desc);
 			seq_printf(m, "0x%16p  ", data);
 
-			if (irq_map[i].host && irq_map[i].host->of_node)
-				p = irq_map[i].host->of_node->full_name;
+			if (irq_data->domain.of_node)
+				p = irq_data->domain.of_node->full_name;
 			else
 				p = none;
 			seq_printf(m, "%s\n", p);
-- 
1.7.5.4


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

* [PATCH v3 07/25] irq_domain/powerpc: Eliminate virq_is_host()
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (5 preceding siblings ...)
  2012-01-27 21:36 ` [PATCH v3 06/25] irq_domain/powerpc: eliminate irq_map; use irq_alloc_desc() instead Grant Likely
@ 2012-01-27 21:36 ` Grant Likely
  2012-01-27 21:36 ` [PATCH v3 08/25] irq_domain: Move irq_domain code from powerpc to kernel/irq Grant Likely
                   ` (20 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely

There is only one user, and it is trivial to open-code.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/include/asm/irq.h         |    1 -
 arch/powerpc/kernel/irq.c              |    7 -------
 arch/powerpc/sysdev/xics/xics-common.c |   12 ++++++------
 3 files changed, 6 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h
index abdd7ef..f80f262 100644
--- a/arch/powerpc/include/asm/irq.h
+++ b/arch/powerpc/include/asm/irq.h
@@ -58,7 +58,6 @@ extern atomic_t ppc_n_lost_interrupts;
 struct irq_data;
 extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
 extern irq_hw_number_t virq_to_hw(unsigned int virq);
-extern bool virq_is_host(unsigned int virq, struct irq_domain *host);
 
 /**
  * irq_alloc_host - Allocate a new irq_domain data structure
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index db5b545..9533fa7 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -510,13 +510,6 @@ irq_hw_number_t virq_to_hw(unsigned int virq)
 }
 EXPORT_SYMBOL_GPL(virq_to_hw);
 
-bool virq_is_host(unsigned int virq, struct irq_domain *host)
-{
-	struct irq_data *irq_data = irq_get_irq_data(virq);
-	return irq_data ? irq_data->domain == host : false;
-}
-EXPORT_SYMBOL_GPL(virq_is_host);
-
 static int default_irq_host_match(struct irq_domain *h, struct device_node *np)
 {
 	return h->of_node != NULL && h->of_node == np;
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
index c4b3ce1..fb2e303 100644
--- a/arch/powerpc/sysdev/xics/xics-common.c
+++ b/arch/powerpc/sysdev/xics/xics-common.c
@@ -212,16 +212,16 @@ void xics_migrate_irqs_away(void)
 		/* We can't set affinity on ISA interrupts */
 		if (virq < NUM_ISA_INTERRUPTS)
 			continue;
-		if (!virq_is_host(virq, xics_host))
-			continue;
-		irq = (unsigned int)virq_to_hw(virq);
-		/* We need to get IPIs still. */
-		if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
-			continue;
 		desc = irq_to_desc(virq);
 		/* We only need to migrate enabled IRQS */
 		if (!desc || !desc->action)
 			continue;
+		if (desc->irq_data.domain != xics_host)
+			continue;
+		irq = desc->irq_data.hwirq;
+		/* We need to get IPIs still. */
+		if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
+			continue;
 		chip = irq_desc_get_chip(desc);
 		if (!chip || !chip->irq_set_affinity)
 			continue;
-- 
1.7.5.4


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

* [PATCH v3 08/25] irq_domain: Move irq_domain code from powerpc to kernel/irq
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (6 preceding siblings ...)
  2012-01-27 21:36 ` [PATCH v3 07/25] irq_domain/powerpc: Eliminate virq_is_host() Grant Likely
@ 2012-01-27 21:36 ` Grant Likely
  2012-01-27 21:36 ` [PATCH v3 09/25] irqdomain: remove NO_IRQ from irq domain code Grant Likely
                   ` (19 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely

This patch only moves the code.  It doesn't make any changes, and the
code is still only compiled for powerpc.  Follow-on patches will generalize
the code for other architectures.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/Kconfig           |    1 +
 arch/powerpc/include/asm/irq.h |  144 ----------
 arch/powerpc/kernel/irq.c      |  495 ---------------------------------
 include/linux/irqdomain.h      |   46 +++-
 kernel/irq/irqdomain.c         |  588 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 631 insertions(+), 643 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 1919634..303703d 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -135,6 +135,7 @@ config PPC
 	select HAVE_GENERIC_HARDIRQS
 	select HAVE_SPARSE_IRQ
 	select IRQ_PER_CPU
+	select IRQ_DOMAIN
 	select GENERIC_IRQ_SHOW
 	select GENERIC_IRQ_SHOW_LEVEL
 	select IRQ_FORCED_THREADING
diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h
index f80f262..728cc30 100644
--- a/arch/powerpc/include/asm/irq.h
+++ b/arch/powerpc/include/asm/irq.h
@@ -42,155 +42,11 @@ extern atomic_t ppc_n_lost_interrupts;
 /* Same thing, used by the generic IRQ code */
 #define NR_IRQS_LEGACY		NUM_ISA_INTERRUPTS
 
-/*
- * The host code and data structures are fairly agnostic to the fact that
- * we use an open firmware device-tree. We do have references to struct
- * device_node in two places: in irq_find_host() to find the host matching
- * a given interrupt controller node, and of course as an argument to its
- * counterpart host->ops->match() callback. However, those are treated as
- * generic pointers by the core and the fact that it's actually a device-node
- * pointer is purely a convention between callers and implementation. This
- * code could thus be used on other architectures by replacing those two
- * by some sort of arch-specific void * "token" used to identify interrupt
- * controllers.
- */
-
 struct irq_data;
 extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
 extern irq_hw_number_t virq_to_hw(unsigned int virq);
 
 /**
- * irq_alloc_host - Allocate a new irq_domain data structure
- * @of_node: optional device-tree node of the interrupt controller
- * @revmap_type: type of reverse mapping to use
- * @revmap_arg: for IRQ_DOMAIN_MAP_LINEAR linear only: size of the map
- * @ops: map/unmap host callbacks
- * @inval_irq: provide a hw number in that host space that is always invalid
- *
- * Allocates and initialize and irq_domain structure. Note that in the case of
- * IRQ_DOMAIN_MAP_LEGACY, the map() callback will be called before this returns
- * for all legacy interrupts except 0 (which is always the invalid irq for
- * a legacy controller). For a IRQ_DOMAIN_MAP_LINEAR, the map is allocated by
- * this call as well. For a IRQ_DOMAIN_MAP_TREE, the radix tree will be allocated
- * later during boot automatically (the reverse mapping will use the slow path
- * until that happens).
- */
-extern struct irq_domain *irq_alloc_host(struct device_node *of_node,
-				       unsigned int revmap_type,
-				       unsigned int revmap_arg,
-				       struct irq_domain_ops *ops,
-				       irq_hw_number_t inval_irq);
-
-
-/**
- * irq_find_host - Locates a host for a given device node
- * @node: device-tree node of the interrupt controller
- */
-extern struct irq_domain *irq_find_host(struct device_node *node);
-
-
-/**
- * irq_set_default_host - Set a "default" host
- * @host: default host pointer
- *
- * For convenience, it's possible to set a "default" host that will be used
- * whenever NULL is passed to irq_create_mapping(). It makes life easier for
- * platforms that want to manipulate a few hard coded interrupt numbers that
- * aren't properly represented in the device-tree.
- */
-extern void irq_set_default_host(struct irq_domain *host);
-
-
-/**
- * irq_set_virq_count - Set the maximum number of virt irqs
- * @count: number of linux virtual irqs, capped with NR_IRQS
- *
- * This is mainly for use by platforms like iSeries who want to program
- * the virtual irq number in the controller to avoid the reverse mapping
- */
-extern void irq_set_virq_count(unsigned int count);
-
-
-/**
- * irq_create_mapping - Map a hardware interrupt into linux virq space
- * @host: host owning this hardware interrupt or NULL for default host
- * @hwirq: hardware irq number in that host space
- *
- * Only one mapping per hardware interrupt is permitted. Returns a linux
- * virq number.
- * If the sense/trigger is to be specified, set_irq_type() should be called
- * on the number returned from that call.
- */
-extern unsigned int irq_create_mapping(struct irq_domain *host,
-				       irq_hw_number_t hwirq);
-
-
-/**
- * irq_dispose_mapping - Unmap an interrupt
- * @virq: linux virq number of the interrupt to unmap
- */
-extern void irq_dispose_mapping(unsigned int virq);
-
-/**
- * irq_find_mapping - Find a linux virq from an hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
- *
- * This is a slow path, for use by generic code. It's expected that an
- * irq controller implementation directly calls the appropriate low level
- * mapping function.
- */
-extern unsigned int irq_find_mapping(struct irq_domain *host,
-				     irq_hw_number_t hwirq);
-
-/**
- * irq_create_direct_mapping - Allocate a virq for direct mapping
- * @host: host to allocate the virq for or NULL for default host
- *
- * This routine is used for irq controllers which can choose the hardware
- * interrupt numbers they generate. In such a case it's simplest to use
- * the linux virq as the hardware interrupt number.
- */
-extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
-
-/**
- * irq_radix_revmap_insert - Insert a hw irq to linux virq number mapping.
- * @host: host owning this hardware interrupt
- * @virq: linux irq number
- * @hwirq: hardware irq number in that host space
- *
- * This is for use by irq controllers that use a radix tree reverse
- * mapping for fast lookup.
- */
-extern void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq,
-				    irq_hw_number_t hwirq);
-
-/**
- * irq_radix_revmap_lookup - Find a linux virq from a hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
- *
- * This is a fast path, for use by irq controller code that uses radix tree
- * revmaps
- */
-extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
-					    irq_hw_number_t hwirq);
-
-/**
- * irq_linear_revmap - Find a linux virq from a hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
- *
- * This is a fast path, for use by irq controller code that uses linear
- * revmaps. It does fallback to the slow path if the revmap doesn't exist
- * yet and will create the revmap entry with appropriate locking
- */
-
-extern unsigned int irq_linear_revmap(struct irq_domain *host,
-				      irq_hw_number_t hwirq);
-
-
-/**
  * irq_early_init - Init irq remapping subsystem
  */
 extern void irq_early_init(void);
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 9533fa7..e3673ff 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -486,17 +486,6 @@ void do_softirq(void)
 	local_irq_restore(flags);
 }
 
-
-/*
- * IRQ controller and virtual interrupts
- */
-
-static LIST_HEAD(irq_domain_list);
-static DEFINE_MUTEX(irq_domain_mutex);
-static DEFINE_MUTEX(revmap_trees_mutex);
-static unsigned int irq_virq_count = NR_IRQS;
-static struct irq_domain *irq_default_host;
-
 irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
 {
 	return d->hwirq;
@@ -510,354 +499,6 @@ irq_hw_number_t virq_to_hw(unsigned int virq)
 }
 EXPORT_SYMBOL_GPL(virq_to_hw);
 
-static int default_irq_host_match(struct irq_domain *h, struct device_node *np)
-{
-	return h->of_node != NULL && h->of_node == np;
-}
-
-struct irq_domain *irq_alloc_host(struct device_node *of_node,
-				unsigned int revmap_type,
-				unsigned int revmap_arg,
-				struct irq_domain_ops *ops,
-				irq_hw_number_t inval_irq)
-{
-	struct irq_domain *host, *h;
-	unsigned int size = sizeof(struct irq_domain);
-	unsigned int i;
-	unsigned int *rmap;
-
-	/* Allocate structure and revmap table if using linear mapping */
-	if (revmap_type == IRQ_DOMAIN_MAP_LINEAR)
-		size += revmap_arg * sizeof(unsigned int);
-	host = kzalloc(size, GFP_KERNEL);
-	if (host == NULL)
-		return NULL;
-
-	/* Fill structure */
-	host->revmap_type = revmap_type;
-	host->inval_irq = inval_irq;
-	host->ops = ops;
-	host->of_node = of_node_get(of_node);
-
-	if (host->ops->match == NULL)
-		host->ops->match = default_irq_host_match;
-
-	mutex_lock(&irq_domain_mutex);
-	/* Make sure only one legacy controller can be created */
-	if (revmap_type == IRQ_DOMAIN_MAP_LEGACY) {
-		list_for_each_entry(h, &irq_domain_list, link) {
-			if (WARN_ON(h->revmap_type == IRQ_DOMAIN_MAP_LEGACY)) {
-				mutex_unlock(&irq_domain_mutex);
-				of_node_put(host->of_node);
-				kfree(host);
-				return NULL;
-			}
-		}
-	}
-	list_add(&host->link, &irq_domain_list);
-	mutex_unlock(&irq_domain_mutex);
-
-	/* Additional setups per revmap type */
-	switch(revmap_type) {
-	case IRQ_DOMAIN_MAP_LEGACY:
-		/* 0 is always the invalid number for legacy */
-		host->inval_irq = 0;
-		/* setup us as the host for all legacy interrupts */
-		for (i = 1; i < NUM_ISA_INTERRUPTS; i++) {
-			struct irq_data *irq_data = irq_get_irq_data(i);
-			irq_data->hwirq = i;
-			irq_data->domain = host;
-
-			/* Legacy flags are left to default at this point,
-			 * one can then use irq_create_mapping() to
-			 * explicitly change them
-			 */
-			ops->map(host, i, i);
-
-			/* Clear norequest flags */
-			irq_clear_status_flags(i, IRQ_NOREQUEST);
-		}
-		break;
-	case IRQ_DOMAIN_MAP_LINEAR:
-		rmap = (unsigned int *)(host + 1);
-		for (i = 0; i < revmap_arg; i++)
-			rmap[i] = NO_IRQ;
-		host->revmap_data.linear.size = revmap_arg;
-		host->revmap_data.linear.revmap = rmap;
-		break;
-	case IRQ_DOMAIN_MAP_TREE:
-		INIT_RADIX_TREE(&host->revmap_data.tree, GFP_KERNEL);
-		break;
-	default:
-		break;
-	}
-
-	pr_debug("irq: Allocated host of type %d @0x%p\n", revmap_type, host);
-
-	return host;
-}
-
-struct irq_domain *irq_find_host(struct device_node *node)
-{
-	struct irq_domain *h, *found = NULL;
-
-	/* We might want to match the legacy controller last since
-	 * it might potentially be set to match all interrupts in
-	 * the absence of a device node. This isn't a problem so far
-	 * yet though...
-	 */
-	mutex_lock(&irq_domain_mutex);
-	list_for_each_entry(h, &irq_domain_list, link)
-		if (h->ops->match(h, node)) {
-			found = h;
-			break;
-		}
-	mutex_unlock(&irq_domain_mutex);
-	return found;
-}
-EXPORT_SYMBOL_GPL(irq_find_host);
-
-void irq_set_default_host(struct irq_domain *host)
-{
-	pr_debug("irq: Default host set to @0x%p\n", host);
-
-	irq_default_host = host;
-}
-
-void irq_set_virq_count(unsigned int count)
-{
-	pr_debug("irq: Trying to set virq count to %d\n", count);
-
-	BUG_ON(count < NUM_ISA_INTERRUPTS);
-	if (count < NR_IRQS)
-		irq_virq_count = count;
-}
-
-static int irq_setup_virq(struct irq_domain *host, unsigned int virq,
-			    irq_hw_number_t hwirq)
-{
-	struct irq_data *irq_data = irq_get_irq_data(virq);
-
-	irq_data->hwirq = hwirq;
-	irq_data->domain = host;
-	if (host->ops->map(host, virq, hwirq)) {
-		pr_debug("irq: -> mapping failed, freeing\n");
-		irq_data->domain = NULL;
-		irq_data->hwirq = 0;
-		return -1;
-	}
-
-	irq_clear_status_flags(virq, IRQ_NOREQUEST);
-
-	return 0;
-}
-
-unsigned int irq_create_direct_mapping(struct irq_domain *host)
-{
-	unsigned int virq;
-
-	if (host == NULL)
-		host = irq_default_host;
-
-	BUG_ON(host == NULL);
-	WARN_ON(host->revmap_type != IRQ_DOMAIN_MAP_NOMAP);
-
-	virq = irq_alloc_desc(0);
-	if (virq == NO_IRQ) {
-		pr_debug("irq: create_direct virq allocation failed\n");
-		return NO_IRQ;
-	}
-
-	pr_debug("irq: create_direct obtained virq %d\n", virq);
-
-	if (irq_setup_virq(host, virq, virq)) {
-		irq_free_desc(virq);
-		return NO_IRQ;
-	}
-
-	return virq;
-}
-
-unsigned int irq_create_mapping(struct irq_domain *host,
-				irq_hw_number_t hwirq)
-{
-	unsigned int virq, hint;
-
-	pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", host, hwirq);
-
-	/* Look for default host if nececssary */
-	if (host == NULL)
-		host = irq_default_host;
-	if (host == NULL) {
-		printk(KERN_WARNING "irq_create_mapping called for"
-		       " NULL host, hwirq=%lx\n", hwirq);
-		WARN_ON(1);
-		return NO_IRQ;
-	}
-	pr_debug("irq: -> using host @%p\n", host);
-
-	/* Check if mapping already exists */
-	virq = irq_find_mapping(host, hwirq);
-	if (virq != NO_IRQ) {
-		pr_debug("irq: -> existing mapping on virq %d\n", virq);
-		return virq;
-	}
-
-	/* Get a virtual interrupt number */
-	if (host->revmap_type == IRQ_DOMAIN_MAP_LEGACY) {
-		/* Handle legacy */
-		virq = (unsigned int)hwirq;
-		if (virq == 0 || virq >= NUM_ISA_INTERRUPTS)
-			return NO_IRQ;
-		return virq;
-	} else {
-		/* Allocate a virtual interrupt number */
-		hint = hwirq % irq_virq_count;
-		virq = irq_alloc_desc_from(hint, 0);
-		if (!virq)
-			virq = irq_alloc_desc(0);
-		if (virq == NO_IRQ) {
-			pr_debug("irq: -> virq allocation failed\n");
-			return NO_IRQ;
-		}
-	}
-
-	if (irq_setup_virq(host, virq, hwirq)) {
-		if (host->revmap_type != IRQ_DOMAIN_MAP_LEGACY)
-			irq_free_desc(virq);
-		return NO_IRQ;
-	}
-
-	pr_debug("irq: irq %lu on host %s mapped to virtual irq %u\n",
-		hwirq, host->of_node ? host->of_node->full_name : "null", virq);
-
-	return virq;
-}
-EXPORT_SYMBOL_GPL(irq_create_mapping);
-
-unsigned int irq_create_of_mapping(struct device_node *controller,
-				   const u32 *intspec, unsigned int intsize)
-{
-	struct irq_domain *host;
-	irq_hw_number_t hwirq;
-	unsigned int type = IRQ_TYPE_NONE;
-	unsigned int virq;
-
-	if (controller == NULL)
-		host = irq_default_host;
-	else
-		host = irq_find_host(controller);
-	if (host == NULL) {
-		printk(KERN_WARNING "irq: no irq host found for %s !\n",
-		       controller->full_name);
-		return NO_IRQ;
-	}
-
-	/* If host has no translation, then we assume interrupt line */
-	if (host->ops->xlate == NULL)
-		hwirq = intspec[0];
-	else {
-		if (host->ops->xlate(host, controller, intspec, intsize,
-				     &hwirq, &type))
-			return NO_IRQ;
-	}
-
-	/* Create mapping */
-	virq = irq_create_mapping(host, hwirq);
-	if (virq == NO_IRQ)
-		return virq;
-
-	/* Set type if specified and different than the current one */
-	if (type != IRQ_TYPE_NONE &&
-	    type != (irqd_get_trigger_type(irq_get_irq_data(virq))))
-		irq_set_irq_type(virq, type);
-	return virq;
-}
-EXPORT_SYMBOL_GPL(irq_create_of_mapping);
-
-void irq_dispose_mapping(unsigned int virq)
-{
-	struct irq_data *irq_data = irq_get_irq_data(virq);
-	struct irq_domain *host;
-	irq_hw_number_t hwirq;
-
-	if (virq == NO_IRQ || !irq_data)
-		return;
-
-	host = irq_data->domain;
-	if (WARN_ON(host == NULL))
-		return;
-
-	/* Never unmap legacy interrupts */
-	if (host->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
-		return;
-
-	irq_set_status_flags(virq, IRQ_NOREQUEST);
-
-	/* remove chip and handler */
-	irq_set_chip_and_handler(virq, NULL, NULL);
-
-	/* Make sure it's completed */
-	synchronize_irq(virq);
-
-	/* Tell the PIC about it */
-	if (host->ops->unmap)
-		host->ops->unmap(host, virq);
-	smp_mb();
-
-	/* Clear reverse map */
-	hwirq = irq_data->hwirq;
-	switch(host->revmap_type) {
-	case IRQ_DOMAIN_MAP_LINEAR:
-		if (hwirq < host->revmap_data.linear.size)
-			host->revmap_data.linear.revmap[hwirq] = NO_IRQ;
-		break;
-	case IRQ_DOMAIN_MAP_TREE:
-		mutex_lock(&revmap_trees_mutex);
-		radix_tree_delete(&host->revmap_data.tree, hwirq);
-		mutex_unlock(&revmap_trees_mutex);
-		break;
-	}
-
-	/* Destroy map */
-	irq_data->hwirq = host->inval_irq;
-
-	irq_free_desc(virq);
-}
-EXPORT_SYMBOL_GPL(irq_dispose_mapping);
-
-unsigned int irq_find_mapping(struct irq_domain *host,
-			      irq_hw_number_t hwirq)
-{
-	unsigned int i;
-	unsigned int hint = hwirq % irq_virq_count;
-
-	/* Look for default host if nececssary */
-	if (host == NULL)
-		host = irq_default_host;
-	if (host == NULL)
-		return NO_IRQ;
-
-	/* legacy -> bail early */
-	if (host->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
-		return hwirq;
-
-	/* Slow path does a linear search of the map */
-	if (hint < NUM_ISA_INTERRUPTS)
-		hint = NUM_ISA_INTERRUPTS;
-	i = hint;
-	do {
-		struct irq_data *data = irq_get_irq_data(i);
-		if (data && (data->domain == host) && (data->hwirq == hwirq))
-			return i;
-		i++;
-		if (i >= irq_virq_count)
-			i = NUM_ISA_INTERRUPTS;
-	} while(i != hint);
-	return NO_IRQ;
-}
-EXPORT_SYMBOL_GPL(irq_find_mapping);
-
 #ifdef CONFIG_SMP
 int irq_choose_cpu(const struct cpumask *mask)
 {
@@ -894,147 +535,11 @@ int irq_choose_cpu(const struct cpumask *mask)
 }
 #endif
 
-unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
-				     irq_hw_number_t hwirq)
-{
-	struct irq_data *irq_data;
-
-	if (WARN_ON_ONCE(host->revmap_type != IRQ_DOMAIN_MAP_TREE))
-		return irq_find_mapping(host, hwirq);
-
-	/*
-	 * Freeing an irq can delete nodes along the path to
-	 * do the lookup via call_rcu.
-	 */
-	rcu_read_lock();
-	irq_data = radix_tree_lookup(&host->revmap_data.tree, hwirq);
-	rcu_read_unlock();
-
-	/*
-	 * If found in radix tree, then fine.
-	 * Else fallback to linear lookup - this should not happen in practice
-	 * as it means that we failed to insert the node in the radix tree.
-	 */
-	return irq_data ? irq_data->irq : irq_find_mapping(host, hwirq);
-}
-
-void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq,
-			     irq_hw_number_t hwirq)
-{
-	struct irq_data *irq_data = irq_get_irq_data(virq);
-
-	if (WARN_ON(host->revmap_type != IRQ_DOMAIN_MAP_TREE))
-		return;
-
-	if (virq != NO_IRQ) {
-		mutex_lock(&revmap_trees_mutex);
-		radix_tree_insert(&host->revmap_data.tree, hwirq, irq_data);
-		mutex_unlock(&revmap_trees_mutex);
-	}
-}
-
-unsigned int irq_linear_revmap(struct irq_domain *host,
-			       irq_hw_number_t hwirq)
-{
-	unsigned int *revmap;
-
-	if (WARN_ON_ONCE(host->revmap_type != IRQ_DOMAIN_MAP_LINEAR))
-		return irq_find_mapping(host, hwirq);
-
-	/* Check revmap bounds */
-	if (unlikely(hwirq >= host->revmap_data.linear.size))
-		return irq_find_mapping(host, hwirq);
-
-	/* Check if revmap was allocated */
-	revmap = host->revmap_data.linear.revmap;
-	if (unlikely(revmap == NULL))
-		return irq_find_mapping(host, hwirq);
-
-	/* Fill up revmap with slow path if no mapping found */
-	if (unlikely(revmap[hwirq] == NO_IRQ))
-		revmap[hwirq] = irq_find_mapping(host, hwirq);
-
-	return revmap[hwirq];
-}
-
 int arch_early_irq_init(void)
 {
 	return 0;
 }
 
-#ifdef CONFIG_VIRQ_DEBUG
-static int virq_debug_show(struct seq_file *m, void *private)
-{
-	unsigned long flags;
-	struct irq_desc *desc;
-	const char *p;
-	static const char none[] = "none";
-	void *data;
-	int i;
-
-	seq_printf(m, "%-5s  %-7s  %-15s  %-18s  %s\n", "virq", "hwirq",
-		      "chip name", "chip data", "host name");
-
-	for (i = 1; i < nr_irqs; i++) {
-		desc = irq_to_desc(i);
-		if (!desc)
-			continue;
-
-		raw_spin_lock_irqsave(&desc->lock, flags);
-
-		if (desc->action && desc->action->handler) {
-			struct irq_data *irq_data = irq_desc_get_data(desc);
-			struct irq_chip *chip;
-
-			seq_printf(m, "%5d  ", i);
-			seq_printf(m, "0x%05lx  ", irq_data->hwirq);
-
-			chip = irq_desc_get_chip(desc);
-			if (chip && chip->name)
-				p = chip->name;
-			else
-				p = none;
-			seq_printf(m, "%-15s  ", p);
-
-			data = irq_desc_get_chip_data(desc);
-			seq_printf(m, "0x%16p  ", data);
-
-			if (irq_data->domain.of_node)
-				p = irq_data->domain.of_node->full_name;
-			else
-				p = none;
-			seq_printf(m, "%s\n", p);
-		}
-
-		raw_spin_unlock_irqrestore(&desc->lock, flags);
-	}
-
-	return 0;
-}
-
-static int virq_debug_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, virq_debug_show, inode->i_private);
-}
-
-static const struct file_operations virq_debug_fops = {
-	.open = virq_debug_open,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-};
-
-static int __init irq_debugfs_init(void)
-{
-	if (debugfs_create_file("virq_mapping", S_IRUGO, powerpc_debugfs_root,
-				 NULL, &virq_debug_fops) == NULL)
-		return -ENOMEM;
-
-	return 0;
-}
-__initcall(irq_debugfs_init);
-#endif /* CONFIG_VIRQ_DEBUG */
-
 #ifdef CONFIG_PPC64
 static int __init setup_noirqdistrib(char *str)
 {
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 35b9ff3..18f4ab0 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -16,6 +16,17 @@
  * (though a domain can cover more than one PIC if they have a flat number
  * model). It's the domain callbacks that are responsible for setting the
  * irq_chip on a given irq_desc after it's been mapped.
+ *
+ * The host code and data structures are agnostic to whether or not
+ * we use an open firmware device-tree. We do have references to struct
+ * device_node in two places: in irq_find_host() to find the host matching
+ * a given interrupt controller node, and of course as an argument to its
+ * counterpart domain->ops->match() callback. However, those are treated as
+ * generic pointers by the core and the fact that it's actually a device-node
+ * pointer is purely a convention between callers and implementation. This
+ * code could thus be used on other architectures by replacing those two
+ * by some sort of arch-specific void * "token" used to identify interrupt
+ * controllers.
  */
 
 #ifndef _LINUX_IRQDOMAIN_H
@@ -108,6 +119,32 @@ struct irq_domain {
 };
 
 #ifdef CONFIG_IRQ_DOMAIN
+#ifdef CONFIG_PPC
+extern struct irq_domain *irq_alloc_host(struct device_node *of_node,
+				       unsigned int revmap_type,
+				       unsigned int revmap_arg,
+				       struct irq_domain_ops *ops,
+				       irq_hw_number_t inval_irq);
+extern struct irq_domain *irq_find_host(struct device_node *node);
+extern void irq_set_default_host(struct irq_domain *host);
+extern void irq_set_virq_count(unsigned int count);
+
+
+extern unsigned int irq_create_mapping(struct irq_domain *host,
+				       irq_hw_number_t hwirq);
+extern void irq_dispose_mapping(unsigned int virq);
+extern unsigned int irq_find_mapping(struct irq_domain *host,
+				     irq_hw_number_t hwirq);
+extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
+extern void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq,
+				    irq_hw_number_t hwirq);
+extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
+					    irq_hw_number_t hwirq);
+extern unsigned int irq_linear_revmap(struct irq_domain *host,
+				      irq_hw_number_t hwirq);
+
+#else /* CONFIG_PPC */
+
 /**
  * irq_domain_to_irq() - Translate from a hardware irq to a linux irq number
  *
@@ -137,15 +174,16 @@ extern void irq_domain_add(struct irq_domain *domain);
 extern void irq_domain_del(struct irq_domain *domain);
 
 extern struct irq_domain_ops irq_domain_simple_ops;
-#endif /* CONFIG_IRQ_DOMAIN */
 
-#if defined(CONFIG_IRQ_DOMAIN) && defined(CONFIG_OF_IRQ)
+#if defined(CONFIG_OF_IRQ)
 extern void irq_domain_add_simple(struct device_node *controller, int irq_base);
 extern void irq_domain_generate_simple(const struct of_device_id *match,
 					u64 phys_base, unsigned int irq_start);
-#else /* CONFIG_IRQ_DOMAIN && CONFIG_OF_IRQ */
+#else /* CONFIG_OF_IRQ */
 static inline void irq_domain_generate_simple(const struct of_device_id *match,
 					u64 phys_base, unsigned int irq_start) { }
-#endif /* CONFIG_IRQ_DOMAIN && CONFIG_OF_IRQ */
+#endif /* !CONFIG_OF_IRQ */
+#endif /* !CONFIG_PPC */
+#endif /* CONFIG_IRQ_DOMAIN */
 
 #endif /* _LINUX_IRQDOMAIN_H */
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 509adb8..684f32d 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -1,3 +1,4 @@
+#include <linux/hardirq.h>
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
 #include <linux/module.h>
@@ -5,10 +6,595 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/slab.h>
+#include <linux/smp.h>
 
 static LIST_HEAD(irq_domain_list);
 static DEFINE_MUTEX(irq_domain_mutex);
 
+#ifdef CONFIG_PPC
+static DEFINE_MUTEX(revmap_trees_mutex);
+static unsigned int irq_virq_count = NR_IRQS;
+static struct irq_domain *irq_default_host;
+
+static int default_irq_host_match(struct irq_domain *h, struct device_node *np)
+{
+	return h->of_node != NULL && h->of_node == np;
+}
+
+/**
+ * irq_alloc_host() - Allocate a new irq_domain data structure
+ * @of_node: optional device-tree node of the interrupt controller
+ * @revmap_type: type of reverse mapping to use
+ * @revmap_arg: for IRQ_DOMAIN_MAP_LINEAR linear only: size of the map
+ * @ops: map/unmap host callbacks
+ * @inval_irq: provide a hw number in that host space that is always invalid
+ *
+ * Allocates and initialize and irq_domain structure. Note that in the case of
+ * IRQ_DOMAIN_MAP_LEGACY, the map() callback will be called before this returns
+ * for all legacy interrupts except 0 (which is always the invalid irq for
+ * a legacy controller). For a IRQ_DOMAIN_MAP_LINEAR, the map is allocated by
+ * this call as well. For a IRQ_DOMAIN_MAP_TREE, the radix tree will be
+ * allocated later during boot automatically (the reverse mapping will use the
+ * slow path until that happens).
+ */
+struct irq_domain *irq_alloc_host(struct device_node *of_node,
+				unsigned int revmap_type,
+				unsigned int revmap_arg,
+				struct irq_domain_ops *ops,
+				irq_hw_number_t inval_irq)
+{
+	struct irq_domain *host, *h;
+	unsigned int size = sizeof(struct irq_domain);
+	unsigned int i;
+	unsigned int *rmap;
+
+	/* Allocate structure and revmap table if using linear mapping */
+	if (revmap_type == IRQ_DOMAIN_MAP_LINEAR)
+		size += revmap_arg * sizeof(unsigned int);
+	host = kzalloc(size, GFP_KERNEL);
+	if (host == NULL)
+		return NULL;
+
+	/* Fill structure */
+	host->revmap_type = revmap_type;
+	host->inval_irq = inval_irq;
+	host->ops = ops;
+	host->of_node = of_node_get(of_node);
+
+	if (host->ops->match == NULL)
+		host->ops->match = default_irq_host_match;
+
+	mutex_lock(&irq_domain_mutex);
+	/* Make sure only one legacy controller can be created */
+	if (revmap_type == IRQ_DOMAIN_MAP_LEGACY) {
+		list_for_each_entry(h, &irq_domain_list, link) {
+			if (WARN_ON(h->revmap_type == IRQ_DOMAIN_MAP_LEGACY)) {
+				mutex_unlock(&irq_domain_mutex);
+				of_node_put(host->of_node);
+				kfree(host);
+				return NULL;
+			}
+		}
+	}
+	list_add(&host->link, &irq_domain_list);
+	mutex_unlock(&irq_domain_mutex);
+
+	/* Additional setups per revmap type */
+	switch(revmap_type) {
+	case IRQ_DOMAIN_MAP_LEGACY:
+		/* 0 is always the invalid number for legacy */
+		host->inval_irq = 0;
+		/* setup us as the host for all legacy interrupts */
+		for (i = 1; i < NUM_ISA_INTERRUPTS; i++) {
+			struct irq_data *irq_data = irq_get_irq_data(i);
+			irq_data->hwirq = i;
+			irq_data->domain = host;
+
+			/* Legacy flags are left to default at this point,
+			 * one can then use irq_create_mapping() to
+			 * explicitly change them
+			 */
+			ops->map(host, i, i);
+
+			/* Clear norequest flags */
+			irq_clear_status_flags(i, IRQ_NOREQUEST);
+		}
+		break;
+	case IRQ_DOMAIN_MAP_LINEAR:
+		rmap = (unsigned int *)(host + 1);
+		for (i = 0; i < revmap_arg; i++)
+			rmap[i] = NO_IRQ;
+		host->revmap_data.linear.size = revmap_arg;
+		host->revmap_data.linear.revmap = rmap;
+		break;
+	case IRQ_DOMAIN_MAP_TREE:
+		INIT_RADIX_TREE(&host->revmap_data.tree, GFP_KERNEL);
+		break;
+	default:
+		break;
+	}
+
+	pr_debug("irq: Allocated host of type %d @0x%p\n", revmap_type, host);
+
+	return host;
+}
+
+/**
+ * irq_find_host() - Locates a domain for a given device node
+ * @node: device-tree node of the interrupt controller
+ */
+struct irq_domain *irq_find_host(struct device_node *node)
+{
+	struct irq_domain *h, *found = NULL;
+
+	/* We might want to match the legacy controller last since
+	 * it might potentially be set to match all interrupts in
+	 * the absence of a device node. This isn't a problem so far
+	 * yet though...
+	 */
+	mutex_lock(&irq_domain_mutex);
+	list_for_each_entry(h, &irq_domain_list, link)
+		if (h->ops->match(h, node)) {
+			found = h;
+			break;
+		}
+	mutex_unlock(&irq_domain_mutex);
+	return found;
+}
+EXPORT_SYMBOL_GPL(irq_find_host);
+
+/**
+ * irq_set_default_host() - Set a "default" irq domain
+ * @host: default host pointer
+ *
+ * For convenience, it's possible to set a "default" domain that will be used
+ * whenever NULL is passed to irq_create_mapping(). It makes life easier for
+ * platforms that want to manipulate a few hard coded interrupt numbers that
+ * aren't properly represented in the device-tree.
+ */
+void irq_set_default_host(struct irq_domain *host)
+{
+	pr_debug("irq: Default host set to @0x%p\n", host);
+
+	irq_default_host = host;
+}
+
+/**
+ * irq_set_virq_count() - Set the maximum number of linux irqs
+ * @count: number of linux irqs, capped with NR_IRQS
+ *
+ * This is mainly for use by platforms like iSeries who want to program
+ * the virtual irq number in the controller to avoid the reverse mapping
+ */
+void irq_set_virq_count(unsigned int count)
+{
+	pr_debug("irq: Trying to set virq count to %d\n", count);
+
+	BUG_ON(count < NUM_ISA_INTERRUPTS);
+	if (count < NR_IRQS)
+		irq_virq_count = count;
+}
+
+static int irq_setup_virq(struct irq_domain *host, unsigned int virq,
+			    irq_hw_number_t hwirq)
+{
+	struct irq_data *irq_data = irq_get_irq_data(virq);
+
+	irq_data->hwirq = hwirq;
+	irq_data->domain = host;
+	if (host->ops->map(host, virq, hwirq)) {
+		pr_debug("irq: -> mapping failed, freeing\n");
+		irq_data->domain = NULL;
+		irq_data->hwirq = 0;
+		return -1;
+	}
+
+	irq_clear_status_flags(virq, IRQ_NOREQUEST);
+
+	return 0;
+}
+
+/**
+ * irq_create_direct_mapping() - Allocate an irq for direct mapping
+ * @host: domain to allocate the irq for or NULL for default host
+ *
+ * This routine is used for irq controllers which can choose the hardware
+ * interrupt numbers they generate. In such a case it's simplest to use
+ * the linux irq as the hardware interrupt number.
+ */
+unsigned int irq_create_direct_mapping(struct irq_domain *host)
+{
+	unsigned int virq;
+
+	if (host == NULL)
+		host = irq_default_host;
+
+	BUG_ON(host == NULL);
+	WARN_ON(host->revmap_type != IRQ_DOMAIN_MAP_NOMAP);
+
+	virq = irq_alloc_desc(0);
+	if (virq == NO_IRQ) {
+		pr_debug("irq: create_direct virq allocation failed\n");
+		return NO_IRQ;
+	}
+
+	pr_debug("irq: create_direct obtained virq %d\n", virq);
+
+	if (irq_setup_virq(host, virq, virq)) {
+		irq_free_desc(virq);
+		return NO_IRQ;
+	}
+
+	return virq;
+}
+
+/**
+ * irq_create_mapping() - Map a hardware interrupt into linux irq space
+ * @host: host owning this hardware interrupt or NULL for default host
+ * @hwirq: hardware irq number in that host space
+ *
+ * Only one mapping per hardware interrupt is permitted. Returns a linux
+ * irq number.
+ * If the sense/trigger is to be specified, set_irq_type() should be called
+ * on the number returned from that call.
+ */
+unsigned int irq_create_mapping(struct irq_domain *host,
+				irq_hw_number_t hwirq)
+{
+	unsigned int virq, hint;
+
+	pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", host, hwirq);
+
+	/* Look for default host if nececssary */
+	if (host == NULL)
+		host = irq_default_host;
+	if (host == NULL) {
+		printk(KERN_WARNING "irq_create_mapping called for"
+		       " NULL host, hwirq=%lx\n", hwirq);
+		WARN_ON(1);
+		return NO_IRQ;
+	}
+	pr_debug("irq: -> using host @%p\n", host);
+
+	/* Check if mapping already exists */
+	virq = irq_find_mapping(host, hwirq);
+	if (virq != NO_IRQ) {
+		pr_debug("irq: -> existing mapping on virq %d\n", virq);
+		return virq;
+	}
+
+	/* Get a virtual interrupt number */
+	if (host->revmap_type == IRQ_DOMAIN_MAP_LEGACY) {
+		/* Handle legacy */
+		virq = (unsigned int)hwirq;
+		if (virq == 0 || virq >= NUM_ISA_INTERRUPTS)
+			return NO_IRQ;
+		return virq;
+	} else {
+		/* Allocate a virtual interrupt number */
+		hint = hwirq % irq_virq_count;
+		virq = irq_alloc_desc_from(hint, 0);
+		if (!virq)
+			virq = irq_alloc_desc(0);
+		if (virq == NO_IRQ) {
+			pr_debug("irq: -> virq allocation failed\n");
+			return NO_IRQ;
+		}
+	}
+
+	if (irq_setup_virq(host, virq, hwirq)) {
+		if (host->revmap_type != IRQ_DOMAIN_MAP_LEGACY)
+			irq_free_desc(virq);
+		return NO_IRQ;
+	}
+
+	pr_debug("irq: irq %lu on host %s mapped to virtual irq %u\n",
+		hwirq, host->of_node ? host->of_node->full_name : "null", virq);
+
+	return virq;
+}
+EXPORT_SYMBOL_GPL(irq_create_mapping);
+
+unsigned int irq_create_of_mapping(struct device_node *controller,
+				   const u32 *intspec, unsigned int intsize)
+{
+	struct irq_domain *host;
+	irq_hw_number_t hwirq;
+	unsigned int type = IRQ_TYPE_NONE;
+	unsigned int virq;
+
+	if (controller == NULL)
+		host = irq_default_host;
+	else
+		host = irq_find_host(controller);
+	if (host == NULL) {
+		printk(KERN_WARNING "irq: no irq host found for %s !\n",
+		       controller->full_name);
+		return NO_IRQ;
+	}
+
+	/* If host has no translation, then we assume interrupt line */
+	if (host->ops->xlate == NULL)
+		hwirq = intspec[0];
+	else {
+		if (host->ops->xlate(host, controller, intspec, intsize,
+				     &hwirq, &type))
+			return NO_IRQ;
+	}
+
+	/* Create mapping */
+	virq = irq_create_mapping(host, hwirq);
+	if (virq == NO_IRQ)
+		return virq;
+
+	/* Set type if specified and different than the current one */
+	if (type != IRQ_TYPE_NONE &&
+	    type != (irqd_get_trigger_type(irq_get_irq_data(virq))))
+		irq_set_irq_type(virq, type);
+	return virq;
+}
+EXPORT_SYMBOL_GPL(irq_create_of_mapping);
+
+/**
+ * irq_dispose_mapping() - Unmap an interrupt
+ * @virq: linux irq number of the interrupt to unmap
+ */
+void irq_dispose_mapping(unsigned int virq)
+{
+	struct irq_data *irq_data = irq_get_irq_data(virq);
+	struct irq_domain *host;
+	irq_hw_number_t hwirq;
+
+	if (virq == NO_IRQ || !irq_data)
+		return;
+
+	host = irq_data->domain;
+	if (WARN_ON(host == NULL))
+		return;
+
+	/* Never unmap legacy interrupts */
+	if (host->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
+		return;
+
+	irq_set_status_flags(virq, IRQ_NOREQUEST);
+
+	/* remove chip and handler */
+	irq_set_chip_and_handler(virq, NULL, NULL);
+
+	/* Make sure it's completed */
+	synchronize_irq(virq);
+
+	/* Tell the PIC about it */
+	if (host->ops->unmap)
+		host->ops->unmap(host, virq);
+	smp_mb();
+
+	/* Clear reverse map */
+	hwirq = irq_data->hwirq;
+	switch(host->revmap_type) {
+	case IRQ_DOMAIN_MAP_LINEAR:
+		if (hwirq < host->revmap_data.linear.size)
+			host->revmap_data.linear.revmap[hwirq] = NO_IRQ;
+		break;
+	case IRQ_DOMAIN_MAP_TREE:
+		mutex_lock(&revmap_trees_mutex);
+		radix_tree_delete(&host->revmap_data.tree, hwirq);
+		mutex_unlock(&revmap_trees_mutex);
+		break;
+	}
+
+	/* Destroy map */
+	irq_data->hwirq = host->inval_irq;
+
+	irq_free_desc(virq);
+}
+EXPORT_SYMBOL_GPL(irq_dispose_mapping);
+
+/**
+ * irq_find_mapping() - Find a linux irq from an hw irq number.
+ * @host: domain owning this hardware interrupt
+ * @hwirq: hardware irq number in that host space
+ *
+ * This is a slow path, for use by generic code. It's expected that an
+ * irq controller implementation directly calls the appropriate low level
+ * mapping function.
+ */
+unsigned int irq_find_mapping(struct irq_domain *host,
+			      irq_hw_number_t hwirq)
+{
+	unsigned int i;
+	unsigned int hint = hwirq % irq_virq_count;
+
+	/* Look for default host if nececssary */
+	if (host == NULL)
+		host = irq_default_host;
+	if (host == NULL)
+		return NO_IRQ;
+
+	/* legacy -> bail early */
+	if (host->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
+		return hwirq;
+
+	/* Slow path does a linear search of the map */
+	if (hint < NUM_ISA_INTERRUPTS)
+		hint = NUM_ISA_INTERRUPTS;
+	i = hint;
+	do {
+		struct irq_data *data = irq_get_irq_data(i);
+		if (data && (data->domain == host) && (data->hwirq == hwirq))
+			return i;
+		i++;
+		if (i >= irq_virq_count)
+			i = NUM_ISA_INTERRUPTS;
+	} while(i != hint);
+	return NO_IRQ;
+}
+EXPORT_SYMBOL_GPL(irq_find_mapping);
+
+/**
+ * irq_radix_revmap_lookup() - Find a linux irq from a hw irq number.
+ * @host: host owning this hardware interrupt
+ * @hwirq: hardware irq number in that host space
+ *
+ * This is a fast path, for use by irq controller code that uses radix tree
+ * revmaps
+ */
+unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
+				     irq_hw_number_t hwirq)
+{
+	struct irq_data *irq_data;
+
+	if (WARN_ON_ONCE(host->revmap_type != IRQ_DOMAIN_MAP_TREE))
+		return irq_find_mapping(host, hwirq);
+
+	/*
+	 * Freeing an irq can delete nodes along the path to
+	 * do the lookup via call_rcu.
+	 */
+	rcu_read_lock();
+	irq_data = radix_tree_lookup(&host->revmap_data.tree, hwirq);
+	rcu_read_unlock();
+
+	/*
+	 * If found in radix tree, then fine.
+	 * Else fallback to linear lookup - this should not happen in practice
+	 * as it means that we failed to insert the node in the radix tree.
+	 */
+	return irq_data ? irq_data->irq : irq_find_mapping(host, hwirq);
+}
+
+/**
+ * irq_radix_revmap_insert() - Insert a hw irq to linux irq number mapping.
+ * @host: host owning this hardware interrupt
+ * @virq: linux irq number
+ * @hwirq: hardware irq number in that host space
+ *
+ * This is for use by irq controllers that use a radix tree reverse
+ * mapping for fast lookup.
+ */
+void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq,
+			     irq_hw_number_t hwirq)
+{
+	struct irq_data *irq_data = irq_get_irq_data(virq);
+
+	if (WARN_ON(host->revmap_type != IRQ_DOMAIN_MAP_TREE))
+		return;
+
+	if (virq != NO_IRQ) {
+		mutex_lock(&revmap_trees_mutex);
+		radix_tree_insert(&host->revmap_data.tree, hwirq, irq_data);
+		mutex_unlock(&revmap_trees_mutex);
+	}
+}
+
+/**
+ * irq_linear_revmap() - Find a linux irq from a hw irq number.
+ * @host: host owning this hardware interrupt
+ * @hwirq: hardware irq number in that host space
+ *
+ * This is a fast path, for use by irq controller code that uses linear
+ * revmaps. It does fallback to the slow path if the revmap doesn't exist
+ * yet and will create the revmap entry with appropriate locking
+ */
+unsigned int irq_linear_revmap(struct irq_domain *host,
+			       irq_hw_number_t hwirq)
+{
+	unsigned int *revmap;
+
+	if (WARN_ON_ONCE(host->revmap_type != IRQ_DOMAIN_MAP_LINEAR))
+		return irq_find_mapping(host, hwirq);
+
+	/* Check revmap bounds */
+	if (unlikely(hwirq >= host->revmap_data.linear.size))
+		return irq_find_mapping(host, hwirq);
+
+	/* Check if revmap was allocated */
+	revmap = host->revmap_data.linear.revmap;
+	if (unlikely(revmap == NULL))
+		return irq_find_mapping(host, hwirq);
+
+	/* Fill up revmap with slow path if no mapping found */
+	if (unlikely(revmap[hwirq] == NO_IRQ))
+		revmap[hwirq] = irq_find_mapping(host, hwirq);
+
+	return revmap[hwirq];
+}
+
+#ifdef CONFIG_VIRQ_DEBUG
+static int virq_debug_show(struct seq_file *m, void *private)
+{
+	unsigned long flags;
+	struct irq_desc *desc;
+	const char *p;
+	static const char none[] = "none";
+	void *data;
+	int i;
+
+	seq_printf(m, "%-5s  %-7s  %-15s  %-18s  %s\n", "virq", "hwirq",
+		      "chip name", "chip data", "host name");
+
+	for (i = 1; i < nr_irqs; i++) {
+		desc = irq_to_desc(i);
+		if (!desc)
+			continue;
+
+		raw_spin_lock_irqsave(&desc->lock, flags);
+
+		if (desc->action && desc->action->handler) {
+			struct irq_data *irq_data = irq_desc_get_data(desc);
+			struct irq_chip *chip;
+
+			seq_printf(m, "%5d  ", i);
+			seq_printf(m, "0x%05lx  ", irq_data->hwirq);
+
+			chip = irq_desc_get_chip(desc);
+			if (chip && chip->name)
+				p = chip->name;
+			else
+				p = none;
+			seq_printf(m, "%-15s  ", p);
+
+			data = irq_desc_get_chip_data(desc);
+			seq_printf(m, "0x%16p  ", data);
+
+			if (irq_data->domain.of_node)
+				p = irq_data->domain.of_node->full_name;
+			else
+				p = none;
+			seq_printf(m, "%s\n", p);
+		}
+
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
+	}
+
+	return 0;
+}
+
+static int virq_debug_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, virq_debug_show, inode->i_private);
+}
+
+static const struct file_operations virq_debug_fops = {
+	.open = virq_debug_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static int __init irq_debugfs_init(void)
+{
+	if (debugfs_create_file("virq_mapping", S_IRUGO, powerpc_debugfs_root,
+				 NULL, &virq_debug_fops) == NULL)
+		return -ENOMEM;
+
+	return 0;
+}
+__initcall(irq_debugfs_init);
+#endif /* CONFIG_VIRQ_DEBUG */
+
+#else /* CONFIG_PPC */
+
 /**
  * irq_domain_add() - Register an irq_domain
  * @domain: ptr to initialized irq_domain structure
@@ -185,3 +771,5 @@ struct irq_domain_ops irq_domain_simple_ops = {
 #endif /* CONFIG_OF_IRQ */
 };
 EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
+
+#endif /* !CONFIG_PPC */
-- 
1.7.5.4


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

* [PATCH v3 09/25] irqdomain: remove NO_IRQ from irq domain code
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (7 preceding siblings ...)
  2012-01-27 21:36 ` [PATCH v3 08/25] irq_domain: Move irq_domain code from powerpc to kernel/irq Grant Likely
@ 2012-01-27 21:36 ` Grant Likely
  2012-01-27 21:36 ` [PATCH v3 10/25] irq_domain: Remove references to old irq_host names Grant Likely
                   ` (18 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely

zero always means no irq when using irq domains.  Get rid of the NO_IRQ
references.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>
---
 kernel/irq/irqdomain.c |   38 +++++++++++++++++++-------------------
 1 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 684f32d..8ea2e48 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -103,7 +103,7 @@ struct irq_domain *irq_alloc_host(struct device_node *of_node,
 	case IRQ_DOMAIN_MAP_LINEAR:
 		rmap = (unsigned int *)(host + 1);
 		for (i = 0; i < revmap_arg; i++)
-			rmap[i] = NO_IRQ;
+			rmap[i] = 0;
 		host->revmap_data.linear.size = revmap_arg;
 		host->revmap_data.linear.revmap = rmap;
 		break;
@@ -213,16 +213,16 @@ unsigned int irq_create_direct_mapping(struct irq_domain *host)
 	WARN_ON(host->revmap_type != IRQ_DOMAIN_MAP_NOMAP);
 
 	virq = irq_alloc_desc(0);
-	if (virq == NO_IRQ) {
+	if (!virq) {
 		pr_debug("irq: create_direct virq allocation failed\n");
-		return NO_IRQ;
+		return 0;
 	}
 
 	pr_debug("irq: create_direct obtained virq %d\n", virq);
 
 	if (irq_setup_virq(host, virq, virq)) {
 		irq_free_desc(virq);
-		return NO_IRQ;
+		return 0;
 	}
 
 	return virq;
@@ -252,13 +252,13 @@ unsigned int irq_create_mapping(struct irq_domain *host,
 		printk(KERN_WARNING "irq_create_mapping called for"
 		       " NULL host, hwirq=%lx\n", hwirq);
 		WARN_ON(1);
-		return NO_IRQ;
+		return 0;
 	}
 	pr_debug("irq: -> using host @%p\n", host);
 
 	/* Check if mapping already exists */
 	virq = irq_find_mapping(host, hwirq);
-	if (virq != NO_IRQ) {
+	if (virq) {
 		pr_debug("irq: -> existing mapping on virq %d\n", virq);
 		return virq;
 	}
@@ -268,7 +268,7 @@ unsigned int irq_create_mapping(struct irq_domain *host,
 		/* Handle legacy */
 		virq = (unsigned int)hwirq;
 		if (virq == 0 || virq >= NUM_ISA_INTERRUPTS)
-			return NO_IRQ;
+			return 0;
 		return virq;
 	} else {
 		/* Allocate a virtual interrupt number */
@@ -276,16 +276,16 @@ unsigned int irq_create_mapping(struct irq_domain *host,
 		virq = irq_alloc_desc_from(hint, 0);
 		if (!virq)
 			virq = irq_alloc_desc(0);
-		if (virq == NO_IRQ) {
+		if (!virq) {
 			pr_debug("irq: -> virq allocation failed\n");
-			return NO_IRQ;
+			return 0;
 		}
 	}
 
 	if (irq_setup_virq(host, virq, hwirq)) {
 		if (host->revmap_type != IRQ_DOMAIN_MAP_LEGACY)
 			irq_free_desc(virq);
-		return NO_IRQ;
+		return 0;
 	}
 
 	pr_debug("irq: irq %lu on host %s mapped to virtual irq %u\n",
@@ -310,7 +310,7 @@ unsigned int irq_create_of_mapping(struct device_node *controller,
 	if (host == NULL) {
 		printk(KERN_WARNING "irq: no irq host found for %s !\n",
 		       controller->full_name);
-		return NO_IRQ;
+		return 0;
 	}
 
 	/* If host has no translation, then we assume interrupt line */
@@ -319,12 +319,12 @@ unsigned int irq_create_of_mapping(struct device_node *controller,
 	else {
 		if (host->ops->xlate(host, controller, intspec, intsize,
 				     &hwirq, &type))
-			return NO_IRQ;
+			return 0;
 	}
 
 	/* Create mapping */
 	virq = irq_create_mapping(host, hwirq);
-	if (virq == NO_IRQ)
+	if (!virq)
 		return virq;
 
 	/* Set type if specified and different than the current one */
@@ -345,7 +345,7 @@ void irq_dispose_mapping(unsigned int virq)
 	struct irq_domain *host;
 	irq_hw_number_t hwirq;
 
-	if (virq == NO_IRQ || !irq_data)
+	if (!virq || !irq_data)
 		return;
 
 	host = irq_data->domain;
@@ -374,7 +374,7 @@ void irq_dispose_mapping(unsigned int virq)
 	switch(host->revmap_type) {
 	case IRQ_DOMAIN_MAP_LINEAR:
 		if (hwirq < host->revmap_data.linear.size)
-			host->revmap_data.linear.revmap[hwirq] = NO_IRQ;
+			host->revmap_data.linear.revmap[hwirq] = 0;
 		break;
 	case IRQ_DOMAIN_MAP_TREE:
 		mutex_lock(&revmap_trees_mutex);
@@ -409,7 +409,7 @@ unsigned int irq_find_mapping(struct irq_domain *host,
 	if (host == NULL)
 		host = irq_default_host;
 	if (host == NULL)
-		return NO_IRQ;
+		return 0;
 
 	/* legacy -> bail early */
 	if (host->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
@@ -427,7 +427,7 @@ unsigned int irq_find_mapping(struct irq_domain *host,
 		if (i >= irq_virq_count)
 			i = NUM_ISA_INTERRUPTS;
 	} while(i != hint);
-	return NO_IRQ;
+	return 0;
 }
 EXPORT_SYMBOL_GPL(irq_find_mapping);
 
@@ -480,7 +480,7 @@ void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq,
 	if (WARN_ON(host->revmap_type != IRQ_DOMAIN_MAP_TREE))
 		return;
 
-	if (virq != NO_IRQ) {
+	if (virq) {
 		mutex_lock(&revmap_trees_mutex);
 		radix_tree_insert(&host->revmap_data.tree, hwirq, irq_data);
 		mutex_unlock(&revmap_trees_mutex);
@@ -514,7 +514,7 @@ unsigned int irq_linear_revmap(struct irq_domain *host,
 		return irq_find_mapping(host, hwirq);
 
 	/* Fill up revmap with slow path if no mapping found */
-	if (unlikely(revmap[hwirq] == NO_IRQ))
+	if (unlikely(!revmap[hwirq]))
 		revmap[hwirq] = irq_find_mapping(host, hwirq);
 
 	return revmap[hwirq];
-- 
1.7.5.4


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

* [PATCH v3 10/25] irq_domain: Remove references to old irq_host names
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (8 preceding siblings ...)
  2012-01-27 21:36 ` [PATCH v3 09/25] irqdomain: remove NO_IRQ from irq domain code Grant Likely
@ 2012-01-27 21:36 ` Grant Likely
  2012-01-27 21:36 ` [PATCH v3 11/25] irq_domain: Replace irq_alloc_host() with revmap-specific initializers Grant Likely
                   ` (17 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely

No functional changes.  Replaces non-exported references to 'host' with domain.
Does not change any symbol names referenced by other .c files.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>
---
 kernel/irq/irqdomain.c |  219 ++++++++++++++++++++++++------------------------
 1 files changed, 108 insertions(+), 111 deletions(-)

diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 8ea2e48..5805dd5 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -14,11 +14,11 @@ static DEFINE_MUTEX(irq_domain_mutex);
 #ifdef CONFIG_PPC
 static DEFINE_MUTEX(revmap_trees_mutex);
 static unsigned int irq_virq_count = NR_IRQS;
-static struct irq_domain *irq_default_host;
+static struct irq_domain *irq_default_domain;
 
-static int default_irq_host_match(struct irq_domain *h, struct device_node *np)
+static int default_irq_domain_match(struct irq_domain *d, struct device_node *np)
 {
-	return h->of_node != NULL && h->of_node == np;
+	return d->of_node != NULL && d->of_node == np;
 }
 
 /**
@@ -26,8 +26,8 @@ static int default_irq_host_match(struct irq_domain *h, struct device_node *np)
  * @of_node: optional device-tree node of the interrupt controller
  * @revmap_type: type of reverse mapping to use
  * @revmap_arg: for IRQ_DOMAIN_MAP_LINEAR linear only: size of the map
- * @ops: map/unmap host callbacks
- * @inval_irq: provide a hw number in that host space that is always invalid
+ * @ops: map/unmap domain callbacks
+ * @inval_irq: provide a hw number in that domain space that is always invalid
  *
  * Allocates and initialize and irq_domain structure. Note that in the case of
  * IRQ_DOMAIN_MAP_LEGACY, the map() callback will be called before this returns
@@ -43,7 +43,7 @@ struct irq_domain *irq_alloc_host(struct device_node *of_node,
 				struct irq_domain_ops *ops,
 				irq_hw_number_t inval_irq)
 {
-	struct irq_domain *host, *h;
+	struct irq_domain *domain, *h;
 	unsigned int size = sizeof(struct irq_domain);
 	unsigned int i;
 	unsigned int *rmap;
@@ -51,18 +51,18 @@ struct irq_domain *irq_alloc_host(struct device_node *of_node,
 	/* Allocate structure and revmap table if using linear mapping */
 	if (revmap_type == IRQ_DOMAIN_MAP_LINEAR)
 		size += revmap_arg * sizeof(unsigned int);
-	host = kzalloc(size, GFP_KERNEL);
-	if (host == NULL)
+	domain = kzalloc(size, GFP_KERNEL);
+	if (domain == NULL)
 		return NULL;
 
 	/* Fill structure */
-	host->revmap_type = revmap_type;
-	host->inval_irq = inval_irq;
-	host->ops = ops;
-	host->of_node = of_node_get(of_node);
+	domain->revmap_type = revmap_type;
+	domain->inval_irq = inval_irq;
+	domain->ops = ops;
+	domain->of_node = of_node_get(of_node);
 
-	if (host->ops->match == NULL)
-		host->ops->match = default_irq_host_match;
+	if (domain->ops->match == NULL)
+		domain->ops->match = default_irq_domain_match;
 
 	mutex_lock(&irq_domain_mutex);
 	/* Make sure only one legacy controller can be created */
@@ -70,53 +70,53 @@ struct irq_domain *irq_alloc_host(struct device_node *of_node,
 		list_for_each_entry(h, &irq_domain_list, link) {
 			if (WARN_ON(h->revmap_type == IRQ_DOMAIN_MAP_LEGACY)) {
 				mutex_unlock(&irq_domain_mutex);
-				of_node_put(host->of_node);
-				kfree(host);
+				of_node_put(domain->of_node);
+				kfree(domain);
 				return NULL;
 			}
 		}
 	}
-	list_add(&host->link, &irq_domain_list);
+	list_add(&domain->link, &irq_domain_list);
 	mutex_unlock(&irq_domain_mutex);
 
 	/* Additional setups per revmap type */
 	switch(revmap_type) {
 	case IRQ_DOMAIN_MAP_LEGACY:
 		/* 0 is always the invalid number for legacy */
-		host->inval_irq = 0;
-		/* setup us as the host for all legacy interrupts */
+		domain->inval_irq = 0;
+		/* setup us as the domain for all legacy interrupts */
 		for (i = 1; i < NUM_ISA_INTERRUPTS; i++) {
 			struct irq_data *irq_data = irq_get_irq_data(i);
 			irq_data->hwirq = i;
-			irq_data->domain = host;
+			irq_data->domain = domain;
 
 			/* Legacy flags are left to default at this point,
 			 * one can then use irq_create_mapping() to
 			 * explicitly change them
 			 */
-			ops->map(host, i, i);
+			ops->map(domain, i, i);
 
 			/* Clear norequest flags */
 			irq_clear_status_flags(i, IRQ_NOREQUEST);
 		}
 		break;
 	case IRQ_DOMAIN_MAP_LINEAR:
-		rmap = (unsigned int *)(host + 1);
+		rmap = (unsigned int *)(domain + 1);
 		for (i = 0; i < revmap_arg; i++)
 			rmap[i] = 0;
-		host->revmap_data.linear.size = revmap_arg;
-		host->revmap_data.linear.revmap = rmap;
+		domain->revmap_data.linear.size = revmap_arg;
+		domain->revmap_data.linear.revmap = rmap;
 		break;
 	case IRQ_DOMAIN_MAP_TREE:
-		INIT_RADIX_TREE(&host->revmap_data.tree, GFP_KERNEL);
+		INIT_RADIX_TREE(&domain->revmap_data.tree, GFP_KERNEL);
 		break;
 	default:
 		break;
 	}
 
-	pr_debug("irq: Allocated host of type %d @0x%p\n", revmap_type, host);
+	pr_debug("irq: Allocated domain of type %d @0x%p\n", revmap_type, domain);
 
-	return host;
+	return domain;
 }
 
 /**
@@ -145,18 +145,18 @@ EXPORT_SYMBOL_GPL(irq_find_host);
 
 /**
  * irq_set_default_host() - Set a "default" irq domain
- * @host: default host pointer
+ * @domain: default domain pointer
  *
  * For convenience, it's possible to set a "default" domain that will be used
  * whenever NULL is passed to irq_create_mapping(). It makes life easier for
  * platforms that want to manipulate a few hard coded interrupt numbers that
  * aren't properly represented in the device-tree.
  */
-void irq_set_default_host(struct irq_domain *host)
+void irq_set_default_host(struct irq_domain *domain)
 {
-	pr_debug("irq: Default host set to @0x%p\n", host);
+	pr_debug("irq: Default domain set to @0x%p\n", domain);
 
-	irq_default_host = host;
+	irq_default_domain = domain;
 }
 
 /**
@@ -175,14 +175,14 @@ void irq_set_virq_count(unsigned int count)
 		irq_virq_count = count;
 }
 
-static int irq_setup_virq(struct irq_domain *host, unsigned int virq,
+static int irq_setup_virq(struct irq_domain *domain, unsigned int virq,
 			    irq_hw_number_t hwirq)
 {
 	struct irq_data *irq_data = irq_get_irq_data(virq);
 
 	irq_data->hwirq = hwirq;
-	irq_data->domain = host;
-	if (host->ops->map(host, virq, hwirq)) {
+	irq_data->domain = domain;
+	if (domain->ops->map(domain, virq, hwirq)) {
 		pr_debug("irq: -> mapping failed, freeing\n");
 		irq_data->domain = NULL;
 		irq_data->hwirq = 0;
@@ -196,21 +196,21 @@ static int irq_setup_virq(struct irq_domain *host, unsigned int virq,
 
 /**
  * irq_create_direct_mapping() - Allocate an irq for direct mapping
- * @host: domain to allocate the irq for or NULL for default host
+ * @domain: domain to allocate the irq for or NULL for default domain
  *
  * This routine is used for irq controllers which can choose the hardware
  * interrupt numbers they generate. In such a case it's simplest to use
  * the linux irq as the hardware interrupt number.
  */
-unsigned int irq_create_direct_mapping(struct irq_domain *host)
+unsigned int irq_create_direct_mapping(struct irq_domain *domain)
 {
 	unsigned int virq;
 
-	if (host == NULL)
-		host = irq_default_host;
+	if (domain == NULL)
+		domain = irq_default_domain;
 
-	BUG_ON(host == NULL);
-	WARN_ON(host->revmap_type != IRQ_DOMAIN_MAP_NOMAP);
+	BUG_ON(domain == NULL);
+	WARN_ON(domain->revmap_type != IRQ_DOMAIN_MAP_NOMAP);
 
 	virq = irq_alloc_desc(0);
 	if (!virq) {
@@ -220,7 +220,7 @@ unsigned int irq_create_direct_mapping(struct irq_domain *host)
 
 	pr_debug("irq: create_direct obtained virq %d\n", virq);
 
-	if (irq_setup_virq(host, virq, virq)) {
+	if (irq_setup_virq(domain, virq, virq)) {
 		irq_free_desc(virq);
 		return 0;
 	}
@@ -230,41 +230,41 @@ unsigned int irq_create_direct_mapping(struct irq_domain *host)
 
 /**
  * irq_create_mapping() - Map a hardware interrupt into linux irq space
- * @host: host owning this hardware interrupt or NULL for default host
- * @hwirq: hardware irq number in that host space
+ * @domain: domain owning this hardware interrupt or NULL for default domain
+ * @hwirq: hardware irq number in that domain space
  *
  * Only one mapping per hardware interrupt is permitted. Returns a linux
  * irq number.
  * If the sense/trigger is to be specified, set_irq_type() should be called
  * on the number returned from that call.
  */
-unsigned int irq_create_mapping(struct irq_domain *host,
+unsigned int irq_create_mapping(struct irq_domain *domain,
 				irq_hw_number_t hwirq)
 {
 	unsigned int virq, hint;
 
-	pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", host, hwirq);
+	pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq);
 
-	/* Look for default host if nececssary */
-	if (host == NULL)
-		host = irq_default_host;
-	if (host == NULL) {
+	/* Look for default domain if nececssary */
+	if (domain == NULL)
+		domain = irq_default_domain;
+	if (domain == NULL) {
 		printk(KERN_WARNING "irq_create_mapping called for"
-		       " NULL host, hwirq=%lx\n", hwirq);
+		       " NULL domain, hwirq=%lx\n", hwirq);
 		WARN_ON(1);
 		return 0;
 	}
-	pr_debug("irq: -> using host @%p\n", host);
+	pr_debug("irq: -> using domain @%p\n", domain);
 
 	/* Check if mapping already exists */
-	virq = irq_find_mapping(host, hwirq);
+	virq = irq_find_mapping(domain, hwirq);
 	if (virq) {
 		pr_debug("irq: -> existing mapping on virq %d\n", virq);
 		return virq;
 	}
 
 	/* Get a virtual interrupt number */
-	if (host->revmap_type == IRQ_DOMAIN_MAP_LEGACY) {
+	if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY) {
 		/* Handle legacy */
 		virq = (unsigned int)hwirq;
 		if (virq == 0 || virq >= NUM_ISA_INTERRUPTS)
@@ -282,14 +282,14 @@ unsigned int irq_create_mapping(struct irq_domain *host,
 		}
 	}
 
-	if (irq_setup_virq(host, virq, hwirq)) {
-		if (host->revmap_type != IRQ_DOMAIN_MAP_LEGACY)
+	if (irq_setup_virq(domain, virq, hwirq)) {
+		if (domain->revmap_type != IRQ_DOMAIN_MAP_LEGACY)
 			irq_free_desc(virq);
 		return 0;
 	}
 
-	pr_debug("irq: irq %lu on host %s mapped to virtual irq %u\n",
-		hwirq, host->of_node ? host->of_node->full_name : "null", virq);
+	pr_debug("irq: irq %lu on domain %s mapped to virtual irq %u\n",
+		hwirq, domain->of_node ? domain->of_node->full_name : "null", virq);
 
 	return virq;
 }
@@ -298,32 +298,29 @@ EXPORT_SYMBOL_GPL(irq_create_mapping);
 unsigned int irq_create_of_mapping(struct device_node *controller,
 				   const u32 *intspec, unsigned int intsize)
 {
-	struct irq_domain *host;
+	struct irq_domain *domain;
 	irq_hw_number_t hwirq;
 	unsigned int type = IRQ_TYPE_NONE;
 	unsigned int virq;
 
-	if (controller == NULL)
-		host = irq_default_host;
-	else
-		host = irq_find_host(controller);
-	if (host == NULL) {
-		printk(KERN_WARNING "irq: no irq host found for %s !\n",
+	domain = controller ? irq_find_host(controller) : irq_default_domain;
+	if (!domain) {
+		printk(KERN_WARNING "irq: no irq domain found for %s !\n",
 		       controller->full_name);
 		return 0;
 	}
 
-	/* If host has no translation, then we assume interrupt line */
-	if (host->ops->xlate == NULL)
+	/* If domain has no translation, then we assume interrupt line */
+	if (domain->ops->xlate == NULL)
 		hwirq = intspec[0];
 	else {
-		if (host->ops->xlate(host, controller, intspec, intsize,
+		if (domain->ops->xlate(domain, controller, intspec, intsize,
 				     &hwirq, &type))
 			return 0;
 	}
 
 	/* Create mapping */
-	virq = irq_create_mapping(host, hwirq);
+	virq = irq_create_mapping(domain, hwirq);
 	if (!virq)
 		return virq;
 
@@ -342,18 +339,18 @@ EXPORT_SYMBOL_GPL(irq_create_of_mapping);
 void irq_dispose_mapping(unsigned int virq)
 {
 	struct irq_data *irq_data = irq_get_irq_data(virq);
-	struct irq_domain *host;
+	struct irq_domain *domain;
 	irq_hw_number_t hwirq;
 
 	if (!virq || !irq_data)
 		return;
 
-	host = irq_data->domain;
-	if (WARN_ON(host == NULL))
+	domain = irq_data->domain;
+	if (WARN_ON(domain == NULL))
 		return;
 
 	/* Never unmap legacy interrupts */
-	if (host->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
+	if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
 		return;
 
 	irq_set_status_flags(virq, IRQ_NOREQUEST);
@@ -365,26 +362,26 @@ void irq_dispose_mapping(unsigned int virq)
 	synchronize_irq(virq);
 
 	/* Tell the PIC about it */
-	if (host->ops->unmap)
-		host->ops->unmap(host, virq);
+	if (domain->ops->unmap)
+		domain->ops->unmap(domain, virq);
 	smp_mb();
 
 	/* Clear reverse map */
 	hwirq = irq_data->hwirq;
-	switch(host->revmap_type) {
+	switch(domain->revmap_type) {
 	case IRQ_DOMAIN_MAP_LINEAR:
-		if (hwirq < host->revmap_data.linear.size)
-			host->revmap_data.linear.revmap[hwirq] = 0;
+		if (hwirq < domain->revmap_data.linear.size)
+			domain->revmap_data.linear.revmap[hwirq] = 0;
 		break;
 	case IRQ_DOMAIN_MAP_TREE:
 		mutex_lock(&revmap_trees_mutex);
-		radix_tree_delete(&host->revmap_data.tree, hwirq);
+		radix_tree_delete(&domain->revmap_data.tree, hwirq);
 		mutex_unlock(&revmap_trees_mutex);
 		break;
 	}
 
 	/* Destroy map */
-	irq_data->hwirq = host->inval_irq;
+	irq_data->hwirq = domain->inval_irq;
 
 	irq_free_desc(virq);
 }
@@ -392,27 +389,27 @@ EXPORT_SYMBOL_GPL(irq_dispose_mapping);
 
 /**
  * irq_find_mapping() - Find a linux irq from an hw irq number.
- * @host: domain owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
+ * @domain: domain owning this hardware interrupt
+ * @hwirq: hardware irq number in that domain space
  *
  * This is a slow path, for use by generic code. It's expected that an
  * irq controller implementation directly calls the appropriate low level
  * mapping function.
  */
-unsigned int irq_find_mapping(struct irq_domain *host,
+unsigned int irq_find_mapping(struct irq_domain *domain,
 			      irq_hw_number_t hwirq)
 {
 	unsigned int i;
 	unsigned int hint = hwirq % irq_virq_count;
 
-	/* Look for default host if nececssary */
-	if (host == NULL)
-		host = irq_default_host;
-	if (host == NULL)
+	/* Look for default domain if nececssary */
+	if (domain == NULL)
+		domain = irq_default_domain;
+	if (domain == NULL)
 		return 0;
 
 	/* legacy -> bail early */
-	if (host->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
+	if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
 		return hwirq;
 
 	/* Slow path does a linear search of the map */
@@ -421,7 +418,7 @@ unsigned int irq_find_mapping(struct irq_domain *host,
 	i = hint;
 	do {
 		struct irq_data *data = irq_get_irq_data(i);
-		if (data && (data->domain == host) && (data->hwirq == hwirq))
+		if (data && (data->domain == domain) && (data->hwirq == hwirq))
 			return i;
 		i++;
 		if (i >= irq_virq_count)
@@ -433,26 +430,26 @@ EXPORT_SYMBOL_GPL(irq_find_mapping);
 
 /**
  * irq_radix_revmap_lookup() - Find a linux irq from a hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
+ * @domain: domain owning this hardware interrupt
+ * @hwirq: hardware irq number in that domain space
  *
  * This is a fast path, for use by irq controller code that uses radix tree
  * revmaps
  */
-unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
+unsigned int irq_radix_revmap_lookup(struct irq_domain *domain,
 				     irq_hw_number_t hwirq)
 {
 	struct irq_data *irq_data;
 
-	if (WARN_ON_ONCE(host->revmap_type != IRQ_DOMAIN_MAP_TREE))
-		return irq_find_mapping(host, hwirq);
+	if (WARN_ON_ONCE(domain->revmap_type != IRQ_DOMAIN_MAP_TREE))
+		return irq_find_mapping(domain, hwirq);
 
 	/*
 	 * Freeing an irq can delete nodes along the path to
 	 * do the lookup via call_rcu.
 	 */
 	rcu_read_lock();
-	irq_data = radix_tree_lookup(&host->revmap_data.tree, hwirq);
+	irq_data = radix_tree_lookup(&domain->revmap_data.tree, hwirq);
 	rcu_read_unlock();
 
 	/*
@@ -460,62 +457,62 @@ unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
 	 * Else fallback to linear lookup - this should not happen in practice
 	 * as it means that we failed to insert the node in the radix tree.
 	 */
-	return irq_data ? irq_data->irq : irq_find_mapping(host, hwirq);
+	return irq_data ? irq_data->irq : irq_find_mapping(domain, hwirq);
 }
 
 /**
  * irq_radix_revmap_insert() - Insert a hw irq to linux irq number mapping.
- * @host: host owning this hardware interrupt
+ * @domain: domain owning this hardware interrupt
  * @virq: linux irq number
- * @hwirq: hardware irq number in that host space
+ * @hwirq: hardware irq number in that domain space
  *
  * This is for use by irq controllers that use a radix tree reverse
  * mapping for fast lookup.
  */
-void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq,
+void irq_radix_revmap_insert(struct irq_domain *domain, unsigned int virq,
 			     irq_hw_number_t hwirq)
 {
 	struct irq_data *irq_data = irq_get_irq_data(virq);
 
-	if (WARN_ON(host->revmap_type != IRQ_DOMAIN_MAP_TREE))
+	if (WARN_ON(domain->revmap_type != IRQ_DOMAIN_MAP_TREE))
 		return;
 
 	if (virq) {
 		mutex_lock(&revmap_trees_mutex);
-		radix_tree_insert(&host->revmap_data.tree, hwirq, irq_data);
+		radix_tree_insert(&domain->revmap_data.tree, hwirq, irq_data);
 		mutex_unlock(&revmap_trees_mutex);
 	}
 }
 
 /**
  * irq_linear_revmap() - Find a linux irq from a hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
+ * @domain: domain owning this hardware interrupt
+ * @hwirq: hardware irq number in that domain space
  *
  * This is a fast path, for use by irq controller code that uses linear
  * revmaps. It does fallback to the slow path if the revmap doesn't exist
  * yet and will create the revmap entry with appropriate locking
  */
-unsigned int irq_linear_revmap(struct irq_domain *host,
+unsigned int irq_linear_revmap(struct irq_domain *domain,
 			       irq_hw_number_t hwirq)
 {
 	unsigned int *revmap;
 
-	if (WARN_ON_ONCE(host->revmap_type != IRQ_DOMAIN_MAP_LINEAR))
-		return irq_find_mapping(host, hwirq);
+	if (WARN_ON_ONCE(domain->revmap_type != IRQ_DOMAIN_MAP_LINEAR))
+		return irq_find_mapping(domain, hwirq);
 
 	/* Check revmap bounds */
-	if (unlikely(hwirq >= host->revmap_data.linear.size))
-		return irq_find_mapping(host, hwirq);
+	if (unlikely(hwirq >= domain->revmap_data.linear.size))
+		return irq_find_mapping(domain, hwirq);
 
 	/* Check if revmap was allocated */
-	revmap = host->revmap_data.linear.revmap;
+	revmap = domain->revmap_data.linear.revmap;
 	if (unlikely(revmap == NULL))
-		return irq_find_mapping(host, hwirq);
+		return irq_find_mapping(domain, hwirq);
 
 	/* Fill up revmap with slow path if no mapping found */
 	if (unlikely(!revmap[hwirq]))
-		revmap[hwirq] = irq_find_mapping(host, hwirq);
+		revmap[hwirq] = irq_find_mapping(domain, hwirq);
 
 	return revmap[hwirq];
 }
@@ -531,7 +528,7 @@ static int virq_debug_show(struct seq_file *m, void *private)
 	int i;
 
 	seq_printf(m, "%-5s  %-7s  %-15s  %-18s  %s\n", "virq", "hwirq",
-		      "chip name", "chip data", "host name");
+		      "chip name", "chip data", "domain name");
 
 	for (i = 1; i < nr_irqs; i++) {
 		desc = irq_to_desc(i);
-- 
1.7.5.4


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

* [PATCH v3 11/25] irq_domain: Replace irq_alloc_host() with revmap-specific initializers
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (9 preceding siblings ...)
  2012-01-27 21:36 ` [PATCH v3 10/25] irq_domain: Remove references to old irq_host names Grant Likely
@ 2012-01-27 21:36 ` Grant Likely
  2012-01-27 21:36 ` [PATCH v3 12/25] irq_domain: Add support for base irq and hwirq in legacy mappings Grant Likely
                   ` (16 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely

Each revmap type has different arguments for setting up the revmap.
This patch splits up the generator functions so that each revmap type
can do its own setup and the user doesn't need to keep track of how
each revmap type handles the arguments.

This patch also adds a host_data argument to the generators.  There are
cases where the host_data pointer will be needed before the function returns.
ie. the legacy map calls the .map callback for each irq before returning.

v2: - Add void *host_data argument to irq_domain_add_*() functions
    - fixed failure to compile
    - Moved IRQ_DOMAIN_MAP_* defines into irqdomain.c

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/platforms/512x/mpc5121_ads_cpld.c   |    3 +-
 arch/powerpc/platforms/52xx/media5200.c          |    7 +-
 arch/powerpc/platforms/52xx/mpc52xx_gpt.c        |    6 +-
 arch/powerpc/platforms/52xx/mpc52xx_pic.c        |    4 +-
 arch/powerpc/platforms/82xx/pq2ads-pci-pic.c     |    6 +-
 arch/powerpc/platforms/85xx/socrates_fpga_pic.c  |    5 +-
 arch/powerpc/platforms/86xx/gef_pic.c            |    5 +-
 arch/powerpc/platforms/cell/axon_msi.c           |    5 +-
 arch/powerpc/platforms/cell/beat_interrupt.c     |    4 +-
 arch/powerpc/platforms/cell/interrupt.c          |    4 +-
 arch/powerpc/platforms/cell/spider-pic.c         |    6 +-
 arch/powerpc/platforms/embedded6xx/flipper-pic.c |    6 +-
 arch/powerpc/platforms/embedded6xx/hlwd-pic.c    |    5 +-
 arch/powerpc/platforms/iseries/irq.c             |    3 +-
 arch/powerpc/platforms/powermac/pic.c            |    5 +-
 arch/powerpc/platforms/powermac/smp.c            |    3 +-
 arch/powerpc/platforms/ps3/interrupt.c           |    3 +-
 arch/powerpc/platforms/wsp/opb_pic.c             |    7 +-
 arch/powerpc/sysdev/cpm1.c                       |    3 +-
 arch/powerpc/sysdev/cpm2_pic.c                   |    3 +-
 arch/powerpc/sysdev/ehv_pic.c                    |    6 +-
 arch/powerpc/sysdev/fsl_msi.c                    |    6 +-
 arch/powerpc/sysdev/i8259.c                      |    3 +-
 arch/powerpc/sysdev/ipic.c                       |    7 +-
 arch/powerpc/sysdev/mpc8xx_pic.c                 |    3 +-
 arch/powerpc/sysdev/mpic.c                       |    7 +-
 arch/powerpc/sysdev/mv64x60_pic.c                |    5 +-
 arch/powerpc/sysdev/qe_lib/qe_ic.c               |    5 +-
 arch/powerpc/sysdev/tsi108_pci.c                 |    3 +-
 arch/powerpc/sysdev/uic.c                        |    6 +-
 arch/powerpc/sysdev/xics/xics-common.c           |    3 +-
 arch/powerpc/sysdev/xilinx_intc.c                |    5 +-
 drivers/gpio/gpio-mpc8xxx.c                      |    7 +-
 include/linux/irqdomain.h                        |   24 ++-
 kernel/irq/irqdomain.c                           |  200 ++++++++++++++--------
 35 files changed, 198 insertions(+), 185 deletions(-)

diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
index fefa797..291d61c 100644
--- a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
+++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
@@ -190,8 +190,7 @@ mpc5121_ads_cpld_pic_init(void)
 
 	cpld_pic_node = of_node_get(np);
 
-	cpld_pic_host =
-	    irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, 16, &cpld_pic_host_ops, 16);
+	cpld_pic_host = irq_domain_add_linear(np, 16, &cpld_pic_host_ops, NULL);
 	if (!cpld_pic_host) {
 		printk(KERN_ERR "CPLD PIC: failed to allocate irq host!\n");
 		goto end;
diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c
index a746415..5db5cfb 100644
--- a/arch/powerpc/platforms/52xx/media5200.c
+++ b/arch/powerpc/platforms/52xx/media5200.c
@@ -173,15 +173,12 @@ static void __init media5200_init_irq(void)
 
 	spin_lock_init(&media5200_irq.lock);
 
-	media5200_irq.irqhost = irq_alloc_host(fpga_np, IRQ_DOMAIN_MAP_LINEAR,
-					       MEDIA5200_NUM_IRQS,
-					       &media5200_irq_ops, -1);
+	media5200_irq.irqhost = irq_domain_add_linear(fpga_np,
+			MEDIA5200_NUM_IRQS, &media5200_irq_ops, &media5200_irq);
 	if (!media5200_irq.irqhost)
 		goto out;
 	pr_debug("%s: allocated irqhost\n", __func__);
 
-	media5200_irq.irqhost->host_data = &media5200_irq;
-
 	irq_set_handler_data(cascade_virq, &media5200_irq);
 	irq_set_chained_handler(cascade_virq, media5200_irq_cascade);
 
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index e90af8f..b53275d 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -252,14 +252,12 @@ mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
 	if (!cascade_virq)
 		return;
 
-	gpt->irqhost = irq_alloc_host(node, IRQ_DOMAIN_MAP_LINEAR, 1,
-				      &mpc52xx_gpt_irq_ops, -1);
+	gpt->irqhost = irq_domain_add_linear(node, 1, &mpc52xx_gpt_irq_ops, gpt);
 	if (!gpt->irqhost) {
-		dev_err(gpt->dev, "irq_alloc_host() failed\n");
+		dev_err(gpt->dev, "irq_domain_add_linear() failed\n");
 		return;
 	}
 
-	gpt->irqhost->host_data = gpt;
 	irq_set_handler_data(cascade_virq, gpt);
 	irq_set_chained_handler(cascade_virq, mpc52xx_gpt_irq_cascade);
 
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 8c997f1..41fa671 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -444,9 +444,9 @@ void __init mpc52xx_init_irq(void)
 	 * As last step, add an irq host to translate the real
 	 * hw irq information provided by the ofw to linux virq
 	 */
-	mpc52xx_irqhost = irq_alloc_host(picnode, IRQ_DOMAIN_MAP_LINEAR,
+	mpc52xx_irqhost = irq_domain_add_linear(picnode,
 	                                 MPC52xx_IRQ_HIGHTESTHWIRQ,
-	                                 &mpc52xx_irqhost_ops, -1);
+	                                 &mpc52xx_irqhost_ops, NULL);
 
 	if (!mpc52xx_irqhost)
 		panic(__FILE__ ": Cannot allocate the IRQ host\n");
diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
index bdba174..4ef9d69 100644
--- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
+++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
@@ -156,17 +156,13 @@ int __init pq2ads_pci_init_irq(void)
 	out_be32(&priv->regs->mask, ~0);
 	mb();
 
-	host = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, NUM_IRQS,
-	                      &pci_pic_host_ops, NUM_IRQS);
+	host = irq_domain_add_linear(np, NUM_IRQS, &pci_pic_host_ops, priv);
 	if (!host) {
 		ret = -ENOMEM;
 		goto out_unmap_regs;
 	}
 
-	host->host_data = priv;
-
 	priv->host = host;
-	host->host_data = priv;
 	irq_set_handler_data(irq, priv);
 	irq_set_chained_handler(irq, pq2ads_pci_irq_demux);
 
diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
index e3ef7c9..1092c12 100644
--- a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
+++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
@@ -280,9 +280,8 @@ void socrates_fpga_pic_init(struct device_node *pic)
 	int i;
 
 	/* Setup an irq_domain structure */
-	socrates_fpga_pic_irq_host = irq_alloc_host(pic, IRQ_DOMAIN_MAP_LINEAR,
-			SOCRATES_FPGA_NUM_IRQS,	&socrates_fpga_pic_host_ops,
-			SOCRATES_FPGA_NUM_IRQS);
+	socrates_fpga_pic_irq_host = irq_domain_add_linear(pic,
+		    SOCRATES_FPGA_NUM_IRQS, &socrates_fpga_pic_host_ops, NULL);
 	if (socrates_fpga_pic_irq_host == NULL) {
 		pr_err("FPGA PIC: Unable to allocate host\n");
 		return;
diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c
index 0cf8af2..126a94b 100644
--- a/arch/powerpc/platforms/86xx/gef_pic.c
+++ b/arch/powerpc/platforms/86xx/gef_pic.c
@@ -212,9 +212,8 @@ void __init gef_pic_init(struct device_node *np)
 	}
 
 	/* Setup an irq_domain structure */
-	gef_pic_irq_host = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR,
-					  GEF_PIC_NUM_IRQS,
-					  &gef_pic_host_ops, NO_IRQ);
+	gef_pic_irq_host = irq_domain_add_linear(np, GEF_PIC_NUM_IRQS,
+					  &gef_pic_host_ops, NULL);
 	if (gef_pic_irq_host == NULL)
 		return;
 
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 1bfd18a..cf9fd3c 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -392,16 +392,13 @@ static int axon_msi_probe(struct platform_device *device)
 	}
 	memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES);
 
-	msic->irq_domain = irq_alloc_host(dn, IRQ_DOMAIN_MAP_NOMAP,
-					NR_IRQS, &msic_host_ops, 0);
+	msic->irq_domain = irq_domain_add_nomap(dn, &msic_host_ops, msic);
 	if (!msic->irq_domain) {
 		printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n",
 		       dn->full_name);
 		goto out_free_fifo;
 	}
 
-	msic->irq_domain->host_data = msic;
-
 	irq_set_handler_data(virq, msic);
 	irq_set_chained_handler(virq, axon_msi_cascade);
 	pr_devel("axon_msi: irq 0x%x setup for axon_msi\n", virq);
diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c
index 21b64cf..bbdf574 100644
--- a/arch/powerpc/platforms/cell/beat_interrupt.c
+++ b/arch/powerpc/platforms/cell/beat_interrupt.c
@@ -239,9 +239,7 @@ void __init beatic_init_IRQ(void)
 	ppc_md.get_irq = beatic_get_irq;
 
 	/* Allocate an irq host */
-	beatic_host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_NOMAP, 0,
-				     &beatic_pic_host_ops,
-					 0);
+	beatic_host = irq_domain_add_nomap(NULL, &beatic_pic_host_ops, NULL);
 	BUG_ON(beatic_host == NULL);
 	irq_set_default_host(beatic_host);
 }
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 6888475..c844797 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -378,8 +378,8 @@ static int __init setup_iic(void)
 void __init iic_init_IRQ(void)
 {
 	/* Setup an irq host data structure */
-	iic_host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_LINEAR, IIC_SOURCE_COUNT,
-				  &iic_host_ops, IIC_IRQ_INVALID);
+	iic_host = irq_domain_add_linear(NULL, IIC_SOURCE_COUNT, &iic_host_ops,
+					 NULL);
 	BUG_ON(iic_host == NULL);
 	irq_set_default_host(iic_host);
 
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 1f935a7..6521d20 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -299,12 +299,10 @@ static void __init spider_init_one(struct device_node *of_node, int chip,
 		panic("spider_pic: can't map registers !");
 
 	/* Allocate a host */
-	pic->host = irq_alloc_host(of_node, IRQ_DOMAIN_MAP_LINEAR,
-				   SPIDER_SRC_COUNT, &spider_host_ops,
-				   SPIDER_IRQ_INVALID);
+	pic->host = irq_domain_add_linear(of_node, SPIDER_SRC_COUNT,
+					  &spider_host_ops, pic);
 	if (pic->host == NULL)
 		panic("spider_pic: can't allocate irq host !");
-	pic->host->host_data = pic;
 
 	/* Go through all sources and disable them */
 	for (i = 0; i < SPIDER_SRC_COUNT; i++) {
diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
index f862361..4345971 100644
--- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
@@ -159,15 +159,13 @@ struct irq_domain * __init flipper_pic_init(struct device_node *np)
 
 	__flipper_quiesce(io_base);
 
-	irq_domain = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, FLIPPER_NR_IRQS,
-				  &flipper_irq_domain_ops, -1);
+	irq_domain = irq_domain_add_linear(np, FLIPPER_NR_IRQS,
+				  &flipper_irq_domain_ops, io_base);
 	if (!irq_domain) {
 		pr_err("failed to allocate irq_domain\n");
 		return NULL;
 	}
 
-	irq_domain->host_data = io_base;
-
 out:
 	return irq_domain;
 }
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
index 2d4a5d4..499d410 100644
--- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
@@ -177,13 +177,12 @@ struct irq_domain *hlwd_pic_init(struct device_node *np)
 
 	__hlwd_quiesce(io_base);
 
-	irq_domain = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, HLWD_NR_IRQS,
-				  &hlwd_irq_domain_ops, -1);
+	irq_domain = irq_domain_add_linear(np, HLWD_NR_IRQS,
+					   &hlwd_irq_domain_ops, io_base);
 	if (!irq_domain) {
 		pr_err("failed to allocate irq_domain\n");
 		return NULL;
 	}
-	irq_domain->host_data = io_base;
 
 	return irq_domain;
 }
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index b07d4f2..5538b59 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -380,8 +380,7 @@ void __init iSeries_init_IRQ(void)
 	/* Create irq host. No need for a revmap since HV will give us
 	 * back our virtual irq number
 	 */
-	host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_NOMAP, 0,
-			      &iseries_irq_domain_ops, 0);
+	host = irq_domain_add_nomap(NULL, &iseries_irq_domain_ops, NULL);
 	BUG_ON(host == NULL);
 	irq_set_default_host(host);
 
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index cff326a..646fdf3 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -352,9 +352,8 @@ static void __init pmac_pic_probe_oldstyle(void)
 	/*
 	 * Allocate an irq host
 	 */
-	pmac_pic_host = irq_alloc_host(master, IRQ_DOMAIN_MAP_LINEAR, max_irqs,
-				       &pmac_pic_host_ops,
-				       max_irqs);
+	pmac_pic_host = irq_domain_add_linear(master, max_irqs,
+					      &pmac_pic_host_ops, NULL);
 	BUG_ON(pmac_pic_host == NULL);
 	irq_set_default_host(pmac_pic_host);
 
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 6b1ef2d..09afd70 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -192,8 +192,7 @@ static int psurge_secondary_ipi_init(void)
 {
 	int rc = -ENOMEM;
 
-	psurge_host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_NOMAP, 0,
-		&psurge_host_ops, 0);
+	psurge_host = irq_domain_add_nomap(NULL, &psurge_host_ops, NULL);
 
 	if (psurge_host)
 		psurge_secondary_virq = irq_create_direct_mapping(psurge_host);
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index c5980e4..c05808f 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -753,8 +753,7 @@ void __init ps3_init_IRQ(void)
 	unsigned cpu;
 	struct irq_domain *host;
 
-	host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_NOMAP, 0, &ps3_host_ops,
-		PS3_INVALID_OUTLET);
+	host = irq_domain_add_nomap(NULL, &ps3_host_ops, NULL);
 	irq_set_default_host(host);
 	irq_set_virq_count(PS3_PLUG_MAX + 1);
 
diff --git a/arch/powerpc/platforms/wsp/opb_pic.c b/arch/powerpc/platforms/wsp/opb_pic.c
index 76b33bc..4837515 100644
--- a/arch/powerpc/platforms/wsp/opb_pic.c
+++ b/arch/powerpc/platforms/wsp/opb_pic.c
@@ -263,13 +263,11 @@ struct opb_pic *opb_pic_init_one(struct device_node *dn)
 		goto free_opb;
 	}
 
-	/* Allocate an irq host so that Linux knows that despite only
+	/* Allocate an irq domain so that Linux knows that despite only
 	 * having one interrupt to issue, we're the controller for multiple
 	 * hardware IRQs, so later we can lookup their virtual IRQs. */
 
-	opb->host = irq_alloc_host(dn, IRQ_DOMAIN_MAP_LINEAR,
-			OPB_NR_IRQS, &opb_host_ops, -1);
-
+	opb->host = irq_domain_add_linear(dn, OPB_NR_IRQS, &opb_host_ops, opb);
 	if (!opb->host) {
 		printk(KERN_ERR "opb: Failed to allocate IRQ host!\n");
 		goto free_regs;
@@ -277,7 +275,6 @@ struct opb_pic *opb_pic_init_one(struct device_node *dn)
 
 	opb->index = opb_index++;
 	spin_lock_init(&opb->lock);
-	opb->host->host_data = opb;
 
 	/* Disable all interrupts by default */
 	opb_out(opb, OPB_MLSASIER, 0);
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
index 0877a75..53f39db 100644
--- a/arch/powerpc/sysdev/cpm1.c
+++ b/arch/powerpc/sysdev/cpm1.c
@@ -164,8 +164,7 @@ unsigned int cpm_pic_init(void)
 
 	out_be32(&cpic_reg->cpic_cimr, 0);
 
-	cpm_pic_host = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR,
-				      64, &cpm_pic_host_ops, 64);
+	cpm_pic_host = irq_domain_add_linear(np, 64, &cpm_pic_host_ops, NULL);
 	if (cpm_pic_host == NULL) {
 		printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
 		sirq = NO_IRQ;
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
index b149baa..b364332 100644
--- a/arch/powerpc/sysdev/cpm2_pic.c
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -275,8 +275,7 @@ void cpm2_pic_init(struct device_node *node)
 	out_be32(&cpm2_intctl->ic_scprrl, 0x05309770);
 
 	/* create a legacy host */
-	cpm2_pic_host = irq_alloc_host(node, IRQ_DOMAIN_MAP_LINEAR,
-				       64, &cpm2_pic_host_ops, 64);
+	cpm2_pic_host = irq_domain_add_linear(node, 64, &cpm2_pic_host_ops, NULL);
 	if (cpm2_pic_host == NULL) {
 		printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
 		return;
diff --git a/arch/powerpc/sysdev/ehv_pic.c b/arch/powerpc/sysdev/ehv_pic.c
index 48d3ba1..adea322 100644
--- a/arch/powerpc/sysdev/ehv_pic.c
+++ b/arch/powerpc/sysdev/ehv_pic.c
@@ -275,9 +275,8 @@ void __init ehv_pic_init(void)
 		return;
 	}
 
-	ehv_pic->irqhost = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR,
-		NR_EHV_PIC_INTS, &ehv_pic_host_ops, 0);
-
+	ehv_pic->irqhost = irq_domain_add_linear(np, NR_EHV_PIC_INTS,
+						 &ehv_pic_host_ops, ehv_pic);
 	if (!ehv_pic->irqhost) {
 		of_node_put(np);
 		kfree(ehv_pic);
@@ -293,7 +292,6 @@ void __init ehv_pic_init(void)
 		of_node_put(np2);
 	}
 
-	ehv_pic->irqhost->host_data = ehv_pic;
 	ehv_pic->hc_irq = ehv_pic_irq_chip;
 	ehv_pic->hc_irq.irq_set_affinity = ehv_pic_set_affinity;
 	ehv_pic->coreint_flag = coreint_flag;
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 3f9a301..f4fd95b 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -387,8 +387,8 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
 	}
 	platform_set_drvdata(dev, msi);
 
-	msi->irqhost = irq_alloc_host(dev->dev.of_node, IRQ_DOMAIN_MAP_LINEAR,
-				      NR_MSI_IRQS, &fsl_msi_host_ops, 0);
+	msi->irqhost = irq_domain_add_linear(dev->dev.of_node,
+				      NR_MSI_IRQS, &fsl_msi_host_ops, msi);
 
 	if (msi->irqhost == NULL) {
 		dev_err(&dev->dev, "No memory for MSI irqhost\n");
@@ -420,8 +420,6 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
 
 	msi->feature = features->fsl_pic_ip;
 
-	msi->irqhost->host_data = msi;
-
 	/*
 	 * Remember the phandle, so that we can match with any PCI nodes
 	 * that have an "fsl,msi" property.
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index 7e67890..573a73b 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -263,8 +263,7 @@ void i8259_init(struct device_node *node, unsigned long intack_addr)
 	raw_spin_unlock_irqrestore(&i8259_lock, flags);
 
 	/* create a legacy host */
-	i8259_host = irq_alloc_host(node, IRQ_DOMAIN_MAP_LEGACY,
-				    0, &i8259_host_ops, 0);
+	i8259_host = irq_domain_add_legacy(node, &i8259_host_ops, NULL);
 	if (i8259_host == NULL) {
 		printk(KERN_ERR "i8259: failed to allocate irq host !\n");
 		return;
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 9abed37..0eaaa01 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -728,9 +728,8 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
 	if (ipic == NULL)
 		return NULL;
 
-	ipic->irqhost = irq_alloc_host(node, IRQ_DOMAIN_MAP_LINEAR,
-				       NR_IPIC_INTS,
-				       &ipic_host_ops, 0);
+	ipic->irqhost = irq_domain_add_linear(node, NR_IPIC_INTS,
+					      &ipic_host_ops, ipic);
 	if (ipic->irqhost == NULL) {
 		kfree(ipic);
 		return NULL;
@@ -738,8 +737,6 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
 
 	ipic->regs = ioremap(res.start, resource_size(&res));
 
-	ipic->irqhost->host_data = ipic;
-
 	/* init hw */
 	ipic_write(ipic->regs, IPIC_SICNR, 0x0);
 
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c
index 978dfc4..d5f5416 100644
--- a/arch/powerpc/sysdev/mpc8xx_pic.c
+++ b/arch/powerpc/sysdev/mpc8xx_pic.c
@@ -171,8 +171,7 @@ int mpc8xx_pic_init(void)
 		goto out;
 	}
 
-	mpc8xx_pic_host = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR,
-					 64, &mpc8xx_pic_host_ops, 64);
+	mpc8xx_pic_host = irq_domain_add_linear(np, 64, &mpc8xx_pic_host_ops, NULL);
 	if (mpc8xx_pic_host == NULL) {
 		printk(KERN_ERR "MPC8xx PIC: failed to allocate irq host!\n");
 		ret = -ENOMEM;
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index c844d34..c83a512 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -1345,10 +1345,9 @@ struct mpic * __init mpic_alloc(struct device_node *node,
 	mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
 	mpic->isu_mask = (1 << mpic->isu_shift) - 1;
 
-	mpic->irqhost = irq_alloc_host(mpic->node, IRQ_DOMAIN_MAP_LINEAR,
+	mpic->irqhost = irq_domain_add_linear(mpic->node,
 				       isu_size ? isu_size : mpic->num_sources,
-				       &mpic_host_ops,
-				       flags & MPIC_LARGE_VECTORS ? 2048 : 256);
+				       &mpic_host_ops, mpic);
 
 	/*
 	 * FIXME: The code leaks the MPIC object and mappings here; this
@@ -1357,8 +1356,6 @@ struct mpic * __init mpic_alloc(struct device_node *node,
 	if (mpic->irqhost == NULL)
 		return NULL;
 
-	mpic->irqhost->host_data = mpic;
-
 	/* Display version */
 	switch (greg_feature & MPIC_GREG_FEATURE_VERSION_MASK) {
 	case 1:
diff --git a/arch/powerpc/sysdev/mv64x60_pic.c b/arch/powerpc/sysdev/mv64x60_pic.c
index 45124a1..8848e99 100644
--- a/arch/powerpc/sysdev/mv64x60_pic.c
+++ b/arch/powerpc/sysdev/mv64x60_pic.c
@@ -250,9 +250,8 @@ void __init mv64x60_init_irq(void)
 	paddr = of_translate_address(np, reg);
 	mv64x60_irq_reg_base = ioremap(paddr, reg[1]);
 
-	mv64x60_irq_host = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR,
-					  MV64x60_NUM_IRQS,
-					  &mv64x60_host_ops, MV64x60_NUM_IRQS);
+	mv64x60_irq_host = irq_domain_add_linear(np, MV64x60_NUM_IRQS,
+					  &mv64x60_host_ops, NULL);
 
 	spin_lock_irqsave(&mv64x60_lock, flags);
 	out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index 78e9019..e9b3d5c 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -339,8 +339,8 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags,
 	if (qe_ic == NULL)
 		return;
 
-	qe_ic->irqhost = irq_alloc_host(node, IRQ_DOMAIN_MAP_LINEAR,
-					NR_QE_IC_INTS, &qe_ic_host_ops, 0);
+	qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS,
+					       &qe_ic_host_ops, qe_ic);
 	if (qe_ic->irqhost == NULL) {
 		kfree(qe_ic);
 		return;
@@ -348,7 +348,6 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags,
 
 	qe_ic->regs = ioremap(res.start, resource_size(&res));
 
-	qe_ic->irqhost->host_data = qe_ic;
 	qe_ic->hc_irq = qe_ic_irq_chip;
 
 	qe_ic->virq_high = irq_of_parse_and_map(node, 0);
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index f375723..1be26f4 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -419,8 +419,7 @@ void __init tsi108_pci_int_init(struct device_node *node)
 {
 	DBG("Tsi108_pci_int_init: initializing PCI interrupts\n");
 
-	pci_irq_host = irq_alloc_host(node, IRQ_DOMAIN_MAP_LEGACY,
-				      0, &pci_irq_domain_ops, 0);
+	pci_irq_host = irq_domain_add_legacy(node, &pci_irq_domain_ops, NULL);
 	if (pci_irq_host == NULL) {
 		printk(KERN_ERR "pci_irq_host: failed to allocate irq domain!\n");
 		return;
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
index 7eea3a6..84e59c9 100644
--- a/arch/powerpc/sysdev/uic.c
+++ b/arch/powerpc/sysdev/uic.c
@@ -270,13 +270,11 @@ static struct uic * __init uic_init_one(struct device_node *node)
 	}
 	uic->dcrbase = *dcrreg;
 
-	uic->irqhost = irq_alloc_host(node, IRQ_DOMAIN_MAP_LINEAR,
-				      NR_UIC_INTS, &uic_host_ops, -1);
+	uic->irqhost = irq_domain_add_linear(node, NR_UIC_INTS, &uic_host_ops,
+					     uic);
 	if (! uic->irqhost)
 		return NULL; /* FIXME: panic? */
 
-	uic->irqhost->host_data = uic;
-
 	/* Start with all interrupts disabled, level and non-critical */
 	mtdcr(uic->dcrbase + UIC_ER, 0);
 	mtdcr(uic->dcrbase + UIC_CR, 0);
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
index fb2e303..ea5e204 100644
--- a/arch/powerpc/sysdev/xics/xics-common.c
+++ b/arch/powerpc/sysdev/xics/xics-common.c
@@ -374,8 +374,7 @@ static struct irq_domain_ops xics_host_ops = {
 
 static void __init xics_init_host(void)
 {
-	xics_host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_TREE, 0, &xics_host_ops,
-				   XICS_IRQ_SPURIOUS);
+	xics_host = irq_domain_add_tree(NULL, &xics_host_ops, NULL);
 	BUG_ON(xics_host == NULL);
 	irq_set_default_host(xics_host);
 }
diff --git a/arch/powerpc/sysdev/xilinx_intc.c b/arch/powerpc/sysdev/xilinx_intc.c
index 92e7d4d..8d73c3c 100644
--- a/arch/powerpc/sysdev/xilinx_intc.c
+++ b/arch/powerpc/sysdev/xilinx_intc.c
@@ -201,11 +201,10 @@ xilinx_intc_init(struct device_node *np)
 	out_be32(regs + XINTC_MER, 0x3UL); /* Turn on the Master Enable. */
 
 	/* Allocate and initialize an irq_domain structure. */
-	irq = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, XILINX_INTC_MAXIRQS,
-			     &xilinx_intc_ops, -1);
+	irq = irq_domain_add_linear(np, XILINX_INTC_MAXIRQS, &xilinx_intc_ops,
+				    regs);
 	if (!irq)
 		panic(__FILE__ ": Cannot allocate IRQ host\n");
-	irq->host_data = regs;
 
 	return irq;
 }
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
index 9efd597..149d987 100644
--- a/drivers/gpio/gpio-mpc8xxx.c
+++ b/drivers/gpio/gpio-mpc8xxx.c
@@ -364,9 +364,8 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
 	if (hwirq == NO_IRQ)
 		goto skip_irq;
 
-	mpc8xxx_gc->irq =
-		irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, MPC8XXX_GPIO_PINS,
-			       &mpc8xxx_gpio_irq_ops, MPC8XXX_GPIO_PINS);
+	mpc8xxx_gc->irq = irq_domain_add_linear(np, MPC8XXX_GPIO_PINS,
+					&mpc8xxx_gpio_irq_ops, mpc8xxx_gc);
 	if (!mpc8xxx_gc->irq)
 		goto skip_irq;
 
@@ -374,8 +373,6 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
 	if (id)
 		mpc8xxx_gc->of_dev_id_data = id->data;
 
-	mpc8xxx_gc->irq->host_data = mpc8xxx_gc;
-
 	/* ack and mask all irqs */
 	out_be32(mm_gc->regs + GPIO_IER, 0xffffffff);
 	out_be32(mm_gc->regs + GPIO_IMR, 0);
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 18f4ab0..f95553f 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -95,10 +95,6 @@ struct irq_domain {
 
 	/* type of reverse mapping_technique */
 	unsigned int revmap_type;
-#define IRQ_DOMAIN_MAP_LEGACY 0 /* legacy 8259, gets irqs 1..15 */
-#define IRQ_DOMAIN_MAP_NOMAP 1 /* no fast reverse mapping */
-#define IRQ_DOMAIN_MAP_LINEAR 2 /* linear map of interrupts */
-#define IRQ_DOMAIN_MAP_TREE 3 /* radix tree */
 	union {
 		struct {
 			unsigned int size;
@@ -120,11 +116,21 @@ struct irq_domain {
 
 #ifdef CONFIG_IRQ_DOMAIN
 #ifdef CONFIG_PPC
-extern struct irq_domain *irq_alloc_host(struct device_node *of_node,
-				       unsigned int revmap_type,
-				       unsigned int revmap_arg,
-				       struct irq_domain_ops *ops,
-				       irq_hw_number_t inval_irq);
+struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
+					 struct irq_domain_ops *ops,
+					 void *host_data);
+struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
+					 unsigned int size,
+					 struct irq_domain_ops *ops,
+					 void *host_data);
+struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
+					 struct irq_domain_ops *ops,
+					 void *host_data);
+struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
+					 struct irq_domain_ops *ops,
+					 void *host_data);
+
+
 extern struct irq_domain *irq_find_host(struct device_node *node);
 extern void irq_set_default_host(struct irq_domain *host);
 extern void irq_set_virq_count(unsigned int count);
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 5805dd5..6440c83 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -8,6 +8,11 @@
 #include <linux/slab.h>
 #include <linux/smp.h>
 
+#define IRQ_DOMAIN_MAP_LEGACY 0 /* legacy 8259, gets irqs 1..15 */
+#define IRQ_DOMAIN_MAP_NOMAP 1 /* no fast reverse mapping */
+#define IRQ_DOMAIN_MAP_LINEAR 2 /* linear map of interrupts */
+#define IRQ_DOMAIN_MAP_TREE 3 /* radix tree */
+
 static LIST_HEAD(irq_domain_list);
 static DEFINE_MUTEX(irq_domain_mutex);
 
@@ -22,100 +27,158 @@ static int default_irq_domain_match(struct irq_domain *d, struct device_node *np
 }
 
 /**
- * irq_alloc_host() - Allocate a new irq_domain data structure
+ * irq_domain_alloc() - Allocate a new irq_domain data structure
  * @of_node: optional device-tree node of the interrupt controller
  * @revmap_type: type of reverse mapping to use
- * @revmap_arg: for IRQ_DOMAIN_MAP_LINEAR linear only: size of the map
  * @ops: map/unmap domain callbacks
- * @inval_irq: provide a hw number in that domain space that is always invalid
+ * @host_data: Controller private data pointer
  *
- * Allocates and initialize and irq_domain structure. Note that in the case of
- * IRQ_DOMAIN_MAP_LEGACY, the map() callback will be called before this returns
- * for all legacy interrupts except 0 (which is always the invalid irq for
- * a legacy controller). For a IRQ_DOMAIN_MAP_LINEAR, the map is allocated by
- * this call as well. For a IRQ_DOMAIN_MAP_TREE, the radix tree will be
- * allocated later during boot automatically (the reverse mapping will use the
- * slow path until that happens).
+ * 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.
  */
-struct irq_domain *irq_alloc_host(struct device_node *of_node,
-				unsigned int revmap_type,
-				unsigned int revmap_arg,
-				struct irq_domain_ops *ops,
-				irq_hw_number_t inval_irq)
+static struct irq_domain *irq_domain_alloc(struct device_node *of_node,
+					   unsigned int revmap_type,
+					   struct irq_domain_ops *ops,
+					   void *host_data)
 {
-	struct irq_domain *domain, *h;
-	unsigned int size = sizeof(struct irq_domain);
-	unsigned int i;
-	unsigned int *rmap;
+	struct irq_domain *domain;
 
-	/* Allocate structure and revmap table if using linear mapping */
-	if (revmap_type == IRQ_DOMAIN_MAP_LINEAR)
-		size += revmap_arg * sizeof(unsigned int);
-	domain = kzalloc(size, GFP_KERNEL);
-	if (domain == NULL)
+	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
+	if (WARN_ON(!domain))
 		return NULL;
 
 	/* Fill structure */
 	domain->revmap_type = revmap_type;
-	domain->inval_irq = inval_irq;
 	domain->ops = ops;
+	domain->host_data = host_data;
 	domain->of_node = of_node_get(of_node);
 
 	if (domain->ops->match == NULL)
 		domain->ops->match = default_irq_domain_match;
 
+	return domain;
+}
+
+static void irq_domain_add(struct irq_domain *domain)
+{
+	mutex_lock(&irq_domain_mutex);
+	list_add(&domain->link, &irq_domain_list);
+	mutex_unlock(&irq_domain_mutex);
+	pr_debug("irq: Allocated domain of type %d @0x%p\n",
+		 domain->revmap_type, domain);
+}
+
+/**
+ * irq_domain_add_legacy() - Allocate and register a legacy revmap irq_domain.
+ * @of_node: pointer to interrupt controller's device tree node.
+ * @ops: map/unmap domain callbacks
+ * @host_data: Controller private data pointer
+ *
+ * Note: the map() callback will be called before this function returns
+ * for all legacy interrupts except 0 (which is always the invalid irq for
+ * a legacy controller).
+ */
+struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
+					 struct irq_domain_ops *ops,
+					 void *host_data)
+{
+	struct irq_domain *domain, *h;
+	unsigned int i;
+
+	domain = irq_domain_alloc(of_node, IRQ_DOMAIN_MAP_LEGACY, ops, host_data);
+	if (!domain)
+		return NULL;
+
 	mutex_lock(&irq_domain_mutex);
 	/* Make sure only one legacy controller can be created */
-	if (revmap_type == IRQ_DOMAIN_MAP_LEGACY) {
-		list_for_each_entry(h, &irq_domain_list, link) {
-			if (WARN_ON(h->revmap_type == IRQ_DOMAIN_MAP_LEGACY)) {
-				mutex_unlock(&irq_domain_mutex);
-				of_node_put(domain->of_node);
-				kfree(domain);
-				return NULL;
-			}
+	list_for_each_entry(h, &irq_domain_list, link) {
+		if (WARN_ON(h->revmap_type == IRQ_DOMAIN_MAP_LEGACY)) {
+			mutex_unlock(&irq_domain_mutex);
+			of_node_put(domain->of_node);
+			kfree(domain);
+			return NULL;
 		}
 	}
 	list_add(&domain->link, &irq_domain_list);
 	mutex_unlock(&irq_domain_mutex);
 
-	/* Additional setups per revmap type */
-	switch(revmap_type) {
-	case IRQ_DOMAIN_MAP_LEGACY:
-		/* 0 is always the invalid number for legacy */
-		domain->inval_irq = 0;
-		/* setup us as the domain for all legacy interrupts */
-		for (i = 1; i < NUM_ISA_INTERRUPTS; i++) {
-			struct irq_data *irq_data = irq_get_irq_data(i);
-			irq_data->hwirq = i;
-			irq_data->domain = domain;
-
-			/* Legacy flags are left to default at this point,
-			 * one can then use irq_create_mapping() to
-			 * explicitly change them
-			 */
-			ops->map(domain, i, i);
-
-			/* Clear norequest flags */
-			irq_clear_status_flags(i, IRQ_NOREQUEST);
-		}
-		break;
-	case IRQ_DOMAIN_MAP_LINEAR:
-		rmap = (unsigned int *)(domain + 1);
-		for (i = 0; i < revmap_arg; i++)
-			rmap[i] = 0;
-		domain->revmap_data.linear.size = revmap_arg;
-		domain->revmap_data.linear.revmap = rmap;
-		break;
-	case IRQ_DOMAIN_MAP_TREE:
-		INIT_RADIX_TREE(&domain->revmap_data.tree, GFP_KERNEL);
-		break;
-	default:
-		break;
+	/* setup us as the domain for all legacy interrupts */
+	for (i = 1; i < NUM_ISA_INTERRUPTS; i++) {
+		struct irq_data *irq_data = irq_get_irq_data(i);
+		irq_data->hwirq = i;
+		irq_data->domain = domain;
+
+		/* Legacy flags are left to default at this point,
+		 * one can then use irq_create_mapping() to
+		 * explicitly change them
+		 */
+		ops->map(domain, i, i);
+
+		/* Clear norequest flags */
+		irq_clear_status_flags(i, IRQ_NOREQUEST);
 	}
+	return domain;
+}
 
-	pr_debug("irq: Allocated domain of type %d @0x%p\n", revmap_type, domain);
+/**
+ * irq_domain_add_linear() - Allocate and register a legacy revmap irq_domain.
+ * @of_node: pointer to interrupt controller's device tree node.
+ * @ops: map/unmap domain callbacks
+ * @host_data: Controller private data pointer
+ */
+struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
+					 unsigned int size,
+					 struct irq_domain_ops *ops,
+					 void *host_data)
+{
+	struct irq_domain *domain;
+	unsigned int *revmap;
+
+	revmap = kzalloc(sizeof(*revmap) * size, GFP_KERNEL);
+	if (WARN_ON(!revmap))
+		return NULL;
 
+	domain = irq_domain_alloc(of_node, IRQ_DOMAIN_MAP_LINEAR, ops, host_data);
+	if (!domain) {
+		kfree(revmap);
+		return NULL;
+	}
+	domain->revmap_data.linear.size = size;
+	domain->revmap_data.linear.revmap = revmap;
+	irq_domain_add(domain);
+	return domain;
+}
+
+struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
+					 struct irq_domain_ops *ops,
+					 void *host_data)
+{
+	struct irq_domain *domain = irq_domain_alloc(of_node,
+					IRQ_DOMAIN_MAP_NOMAP, ops, host_data);
+	if (domain)
+		irq_domain_add(domain);
+	return domain;
+}
+
+/**
+ * irq_domain_add_tree()
+ * @of_node: pointer to interrupt controller's device tree node.
+ * @ops: map/unmap domain callbacks
+ *
+ * Note: The radix tree will be allocated later during boot automatically
+ * (the reverse mapping will use the slow path until that happens).
+ */
+struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
+					 struct irq_domain_ops *ops,
+					 void *host_data)
+{
+	struct irq_domain *domain = irq_domain_alloc(of_node,
+					IRQ_DOMAIN_MAP_TREE, ops, host_data);
+	if (domain) {
+		INIT_RADIX_TREE(&domain->revmap_data.tree, GFP_KERNEL);
+		irq_domain_add(domain);
+	}
 	return domain;
 }
 
@@ -380,9 +443,6 @@ void irq_dispose_mapping(unsigned int virq)
 		break;
 	}
 
-	/* Destroy map */
-	irq_data->hwirq = domain->inval_irq;
-
 	irq_free_desc(virq);
 }
 EXPORT_SYMBOL_GPL(irq_dispose_mapping);
-- 
1.7.5.4


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

* [PATCH v3 12/25] irq_domain: Add support for base irq and hwirq in legacy mappings
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (10 preceding siblings ...)
  2012-01-27 21:36 ` [PATCH v3 11/25] irq_domain: Replace irq_alloc_host() with revmap-specific initializers Grant Likely
@ 2012-01-27 21:36 ` Grant Likely
  2012-01-27 21:36 ` [PATCH v3 13/25] irq_domain: Remove 'new' irq_domain in favour of the ppc one Grant Likely
                   ` (15 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely

Add support for a legacy mapping where irq = (hwirq - first_hwirq + first_irq)
so that a controller driver can allocate a fixed range of irq_descs and use
a simple calculation to translate back and forth between linux and hw irq
numbers.  This is needed to use an irq_domain with many of the ARM interrupt
controller drivers that manage their own irq_desc allocations.  Ultimately
the goal is to migrate those drivers to use the linear revmap, but doing it
this way allows each driver to be converted separately which makes the
migration path easier.

This patch generalizes the IRQ_DOMAIN_MAP_LEGACY method to use
(first_irq-first_hwirq) as the offset between hwirq and linux irq number,
and adds checks to make sure that the hwirq number does not exceed range
assigned to the controller.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/include/asm/irq.h   |    3 -
 arch/powerpc/sysdev/i8259.c      |    2 +-
 arch/powerpc/sysdev/tsi108_pci.c |    2 +-
 include/linux/irqdomain.h        |   20 ++++++++-
 kernel/irq/irqdomain.c           |   92 +++++++++++++++++++++++++------------
 5 files changed, 83 insertions(+), 36 deletions(-)

diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h
index 728cc30..fe0b09d 100644
--- a/arch/powerpc/include/asm/irq.h
+++ b/arch/powerpc/include/asm/irq.h
@@ -36,9 +36,6 @@ extern atomic_t ppc_n_lost_interrupts;
 /* Total number of virq in the platform */
 #define NR_IRQS		CONFIG_NR_IRQS
 
-/* Number of irqs reserved for the legacy controller */
-#define NUM_ISA_INTERRUPTS	16
-
 /* Same thing, used by the generic IRQ code */
 #define NR_IRQS_LEGACY		NUM_ISA_INTERRUPTS
 
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index 573a73b..997df6a 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -263,7 +263,7 @@ void i8259_init(struct device_node *node, unsigned long intack_addr)
 	raw_spin_unlock_irqrestore(&i8259_lock, flags);
 
 	/* create a legacy host */
-	i8259_host = irq_domain_add_legacy(node, &i8259_host_ops, NULL);
+	i8259_host = irq_domain_add_legacy_isa(node, &i8259_host_ops, NULL);
 	if (i8259_host == NULL) {
 		printk(KERN_ERR "i8259: failed to allocate irq host !\n");
 		return;
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 1be26f4..188012c 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -419,7 +419,7 @@ void __init tsi108_pci_int_init(struct device_node *node)
 {
 	DBG("Tsi108_pci_int_init: initializing PCI interrupts\n");
 
-	pci_irq_host = irq_domain_add_legacy(node, &pci_irq_domain_ops, NULL);
+	pci_irq_host = irq_domain_add_legacy_isa(node, &pci_irq_domain_ops, NULL);
 	if (pci_irq_host == NULL) {
 		printk(KERN_ERR "pci_irq_host: failed to allocate irq domain!\n");
 		return;
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index f95553f..7fef39e 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -39,6 +39,9 @@ struct device_node;
 struct irq_domain;
 struct of_device_id;
 
+/* Number of irqs reserved for a legacy isa controller */
+#define NUM_ISA_INTERRUPTS	16
+
 /* This type is the placeholder for a hardware interrupt number. It has to
  * be big enough to enclose whatever representation is used by a given
  * platform.
@@ -98,6 +101,11 @@ struct irq_domain {
 	union {
 		struct {
 			unsigned int size;
+			unsigned int first_irq;
+			irq_hw_number_t first_hwirq;
+		} legacy;
+		struct {
+			unsigned int size;
 			unsigned int *revmap;
 		} linear;
 		struct radix_tree_root tree;
@@ -117,6 +125,9 @@ struct irq_domain {
 #ifdef CONFIG_IRQ_DOMAIN
 #ifdef CONFIG_PPC
 struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
+					 unsigned int size,
+					 unsigned int first_irq,
+					 irq_hw_number_t first_hwirq,
 					 struct irq_domain_ops *ops,
 					 void *host_data);
 struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
@@ -130,11 +141,18 @@ struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
 					 struct irq_domain_ops *ops,
 					 void *host_data);
 
-
 extern struct irq_domain *irq_find_host(struct device_node *node);
 extern void irq_set_default_host(struct irq_domain *host);
 extern void irq_set_virq_count(unsigned int count);
 
+static inline struct irq_domain *irq_domain_add_legacy_isa(
+				struct device_node *of_node,
+				struct irq_domain_ops *ops,
+				void *host_data)
+{
+	return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops,
+				     host_data);
+}
 
 extern unsigned int irq_create_mapping(struct irq_domain *host,
 				       irq_hw_number_t hwirq);
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 6440c83..18ba492 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -8,7 +8,8 @@
 #include <linux/slab.h>
 #include <linux/smp.h>
 
-#define IRQ_DOMAIN_MAP_LEGACY 0 /* legacy 8259, gets irqs 1..15 */
+#define IRQ_DOMAIN_MAP_LEGACY 0 /* driver allocated fixed range of irqs.
+				 * ie. legacy 8259, gets irqs 1..15 */
 #define IRQ_DOMAIN_MAP_NOMAP 1 /* no fast reverse mapping */
 #define IRQ_DOMAIN_MAP_LINEAR 2 /* linear map of interrupts */
 #define IRQ_DOMAIN_MAP_TREE 3 /* radix tree */
@@ -69,9 +70,25 @@ static void irq_domain_add(struct irq_domain *domain)
 		 domain->revmap_type, domain);
 }
 
+static unsigned int irq_domain_legacy_revmap(struct irq_domain *domain,
+					     irq_hw_number_t hwirq)
+{
+	irq_hw_number_t first_hwirq = domain->revmap_data.legacy.first_hwirq;
+	int size = domain->revmap_data.legacy.size;
+
+	if (WARN_ON(hwirq < first_hwirq || hwirq >= first_hwirq + size))
+		return 0;
+	return hwirq - first_hwirq + domain->revmap_data.legacy.first_irq;
+}
+
 /**
  * irq_domain_add_legacy() - Allocate and register a legacy revmap irq_domain.
  * @of_node: pointer to interrupt controller's device tree node.
+ * @size: total number of irqs in legacy mapping
+ * @first_irq: first number of irq block assigned to the domain
+ * @first_hwirq: first hwirq number to use for the translation. Should normally
+ *               be '0', but a positive integer can be used if the effective
+ *               hwirqs numbering does not begin at zero.
  * @ops: map/unmap domain callbacks
  * @host_data: Controller private data pointer
  *
@@ -80,44 +97,64 @@ static void irq_domain_add(struct irq_domain *domain)
  * a legacy controller).
  */
 struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
+					 unsigned int size,
+					 unsigned int first_irq,
+					 irq_hw_number_t first_hwirq,
 					 struct irq_domain_ops *ops,
 					 void *host_data)
 {
-	struct irq_domain *domain, *h;
+	struct irq_domain *domain;
 	unsigned int i;
 
 	domain = irq_domain_alloc(of_node, IRQ_DOMAIN_MAP_LEGACY, ops, host_data);
 	if (!domain)
 		return NULL;
 
+	domain->revmap_data.legacy.first_irq = first_irq;
+	domain->revmap_data.legacy.first_hwirq = first_hwirq;
+	domain->revmap_data.legacy.size = size;
+
 	mutex_lock(&irq_domain_mutex);
-	/* Make sure only one legacy controller can be created */
-	list_for_each_entry(h, &irq_domain_list, link) {
-		if (WARN_ON(h->revmap_type == IRQ_DOMAIN_MAP_LEGACY)) {
+	/* Verify that all the irqs are available */
+	for (i = 0; i < size; i++) {
+		int irq = first_irq + i;
+		struct irq_data *irq_data = irq_get_irq_data(irq);
+
+		if (WARN_ON(!irq_data || irq_data->domain)) {
 			mutex_unlock(&irq_domain_mutex);
 			of_node_put(domain->of_node);
 			kfree(domain);
 			return NULL;
 		}
 	}
-	list_add(&domain->link, &irq_domain_list);
-	mutex_unlock(&irq_domain_mutex);
 
-	/* setup us as the domain for all legacy interrupts */
-	for (i = 1; i < NUM_ISA_INTERRUPTS; i++) {
-		struct irq_data *irq_data = irq_get_irq_data(i);
-		irq_data->hwirq = i;
+	/* Claim all of the irqs before registering a legacy domain */
+	for (i = 0; i < size; i++) {
+		struct irq_data *irq_data = irq_get_irq_data(first_irq + i);
+		irq_data->hwirq = first_hwirq + i;
 		irq_data->domain = domain;
+	}
+	mutex_unlock(&irq_domain_mutex);
+
+	for (i = 0; i < size; i++) {
+		int irq = first_irq + i;
+		int hwirq = first_hwirq + i;
+
+		/* IRQ0 gets ignored */
+		if (!irq)
+			continue;
 
 		/* Legacy flags are left to default at this point,
 		 * one can then use irq_create_mapping() to
 		 * explicitly change them
 		 */
-		ops->map(domain, i, i);
+		ops->map(domain, irq, hwirq);
 
 		/* Clear norequest flags */
-		irq_clear_status_flags(i, IRQ_NOREQUEST);
+		irq_clear_status_flags(irq, IRQ_NOREQUEST);
 	}
+
+	irq_domain_add(domain);
 	return domain;
 }
 
@@ -327,22 +364,17 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
 	}
 
 	/* Get a virtual interrupt number */
-	if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY) {
-		/* Handle legacy */
-		virq = (unsigned int)hwirq;
-		if (virq == 0 || virq >= NUM_ISA_INTERRUPTS)
-			return 0;
-		return virq;
-	} else {
-		/* Allocate a virtual interrupt number */
-		hint = hwirq % irq_virq_count;
-		virq = irq_alloc_desc_from(hint, 0);
-		if (!virq)
-			virq = irq_alloc_desc(0);
-		if (!virq) {
-			pr_debug("irq: -> virq allocation failed\n");
-			return 0;
-		}
+	if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
+		return irq_domain_legacy_revmap(domain, hwirq);
+
+	/* Allocate a virtual interrupt number */
+	hint = hwirq % irq_virq_count;
+	virq = irq_alloc_desc_from(hint, 0);
+	if (!virq)
+		virq = irq_alloc_desc(0);
+	if (!virq) {
+		pr_debug("irq: -> virq allocation failed\n");
+		return 0;
 	}
 
 	if (irq_setup_virq(domain, virq, hwirq)) {
@@ -470,7 +502,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
 
 	/* legacy -> bail early */
 	if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
-		return hwirq;
+		return irq_domain_legacy_revmap(domain, hwirq);
 
 	/* Slow path does a linear search of the map */
 	if (hint < NUM_ISA_INTERRUPTS)
-- 
1.7.5.4


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

* [PATCH v3 13/25] irq_domain: Remove 'new' irq_domain in favour of the ppc one
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (11 preceding siblings ...)
  2012-01-27 21:36 ` [PATCH v3 12/25] irq_domain: Add support for base irq and hwirq in legacy mappings Grant Likely
@ 2012-01-27 21:36 ` Grant Likely
  2012-02-03 14:48   ` Cousson, Benoit
  2012-01-27 21:36 ` [PATCH v3 14/25] irq_domain: Remove irq_domain_add_simple() Grant Likely
                   ` (14 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely

This patch removes the simplistic implementation of irq_domains and enables
the powerpc infrastructure for all irq_domain users.  The powerpc
infrastructure includes support for complex mappings between Linux and
hardware irq numbers, and can manage allocation of irq_descs.

This patch also converts the few users of irq_domain_add()/irq_domain_del()
to call irq_domain_add_legacy() instead.

v3: Fix bug that set up too many irqs in translation range.
v2: Fix removal of irq_alloc_descs() call in gic driver

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>
---
 arch/arm/common/gic.c               |   85 ++++++++-----------
 arch/arm/common/vic.c               |   16 +---
 arch/arm/include/asm/hardware/gic.h |    4 +-
 arch/arm/include/asm/hardware/vic.h |    2 +
 arch/arm/mach-exynos/common.c       |    2 +-
 arch/arm/mach-versatile/core.c      |    5 +-
 drivers/mfd/twl-core.c              |   12 +--
 include/linux/irqdomain.h           |   45 +---------
 kernel/irq/irqdomain.c              |  159 +++--------------------------------
 9 files changed, 69 insertions(+), 261 deletions(-)

diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 156bc03..5d91eb9 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -50,7 +50,6 @@ union gic_base {
 };
 
 struct gic_chip_data {
-	unsigned int irq_offset;
 	union gic_base dist_base;
 	union gic_base cpu_base;
 #ifdef CONFIG_CPU_PM
@@ -60,9 +59,7 @@ struct gic_chip_data {
 	u32 __percpu *saved_ppi_enable;
 	u32 __percpu *saved_ppi_conf;
 #endif
-#ifdef CONFIG_IRQ_DOMAIN
-	struct irq_domain domain;
-#endif
+	struct irq_domain *domain;
 	unsigned int gic_irqs;
 #ifdef CONFIG_GIC_NON_BANKED
 	void __iomem *(*get_base)(union gic_base *);
@@ -281,7 +278,7 @@ asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
 		irqnr = irqstat & ~0x1c00;
 
 		if (likely(irqnr > 15 && irqnr < 1021)) {
-			irqnr = irq_domain_to_irq(&gic->domain, irqnr);
+			irqnr = irq_find_mapping(gic->domain, irqnr);
 			handle_IRQ(irqnr, regs);
 			continue;
 		}
@@ -313,8 +310,8 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
 	if (gic_irq == 1023)
 		goto out;
 
-	cascade_irq = irq_domain_to_irq(&chip_data->domain, gic_irq);
-	if (unlikely(gic_irq < 32 || gic_irq > 1020 || cascade_irq >= NR_IRQS))
+	cascade_irq = irq_find_mapping(chip_data->domain, gic_irq);
+	if (unlikely(gic_irq < 32 || gic_irq > 1020))
 		do_bad_IRQ(cascade_irq, desc);
 	else
 		generic_handle_irq(cascade_irq);
@@ -347,10 +344,9 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
 
 static void __init gic_dist_init(struct gic_chip_data *gic)
 {
-	unsigned int i, irq;
+	unsigned int i;
 	u32 cpumask;
 	unsigned int gic_irqs = gic->gic_irqs;
-	struct irq_domain *domain = &gic->domain;
 	void __iomem *base = gic_data_dist_base(gic);
 	u32 cpu = 0;
 
@@ -389,23 +385,6 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
 	for (i = 32; i < gic_irqs; i += 32)
 		writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
 
-	/*
-	 * Setup the Linux IRQ subsystem.
-	 */
-	irq_domain_for_each_irq(domain, i, irq) {
-		if (i < 32) {
-			irq_set_percpu_devid(irq);
-			irq_set_chip_and_handler(irq, &gic_chip,
-						 handle_percpu_devid_irq);
-			set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
-		} else {
-			irq_set_chip_and_handler(irq, &gic_chip,
-						 handle_fasteoi_irq);
-			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-		}
-		irq_set_chip_data(irq, gic);
-	}
-
 	writel_relaxed(1, base + GIC_DIST_CTRL);
 }
 
@@ -621,7 +600,23 @@ static void __init gic_pm_init(struct gic_chip_data *gic)
 }
 #endif
 
-#ifdef CONFIG_OF
+static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
+				irq_hw_number_t hw)
+{
+	if (hw < 32) {
+		irq_set_percpu_devid(irq);
+		irq_set_chip_and_handler(irq, &gic_chip,
+					 handle_percpu_devid_irq);
+		set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
+	} else {
+		irq_set_chip_and_handler(irq, &gic_chip,
+					 handle_fasteoi_irq);
+		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+	}
+	irq_set_chip_data(irq, d->host_data);
+	return 0;
+}
+
 static int gic_irq_domain_xlate(struct irq_domain *d,
 				struct device_node *controller,
 				const u32 *intspec, unsigned int intsize,
@@ -642,26 +637,23 @@ static int gic_irq_domain_xlate(struct irq_domain *d,
 	*out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
 	return 0;
 }
-#endif
 
 struct irq_domain_ops gic_irq_domain_ops = {
-#ifdef CONFIG_OF
+	.map = gic_irq_domain_map,
 	.xlate = gic_irq_domain_xlate,
-#endif
 };
 
 void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 			   void __iomem *dist_base, void __iomem *cpu_base,
-			   u32 percpu_offset)
+			   u32 percpu_offset, struct device_node *node)
 {
+	irq_hw_number_t hwirq_base;
 	struct gic_chip_data *gic;
-	struct irq_domain *domain;
-	int gic_irqs;
+	int gic_irqs, irq_base;
 
 	BUG_ON(gic_nr >= MAX_GIC_NR);
 
 	gic = &gic_data[gic_nr];
-	domain = &gic->domain;
 #ifdef CONFIG_GIC_NON_BANKED
 	if (percpu_offset) { /* Frankein-GIC without banked registers... */
 		unsigned int cpu;
@@ -697,10 +689,10 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 	 * For primary GICs, skip over SGIs.
 	 * For secondary GICs, skip over PPIs, too.
 	 */
-	domain->hwirq_base = 32;
+	hwirq_base = 32;
 	if (gic_nr == 0) {
 		if ((irq_start & 31) > 0) {
-			domain->hwirq_base = 16;
+			hwirq_base = 16;
 			if (irq_start != -1)
 				irq_start = (irq_start & ~31) + 16;
 		}
@@ -716,17 +708,17 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 		gic_irqs = 1020;
 	gic->gic_irqs = gic_irqs;
 
-	domain->nr_irq = gic_irqs - domain->hwirq_base;
-	domain->irq_base = irq_alloc_descs(irq_start, 16, domain->nr_irq,
-					   numa_node_id());
-	if (IS_ERR_VALUE(domain->irq_base)) {
+	gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */
+	irq_base = irq_alloc_descs(irq_start, 16, gic_irqs, numa_node_id());
+	if (IS_ERR_VALUE(irq_base)) {
 		WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",
 		     irq_start);
-		domain->irq_base = irq_start;
+		irq_base = irq_start;
 	}
-	domain->host_data = gic;
-	domain->ops = &gic_irq_domain_ops;
-	irq_domain_add(domain);
+	gic->domain = irq_domain_add_legacy(node, gic_irqs, irq_base,
+				    hwirq_base, &gic_irq_domain_ops, gic);
+	if (WARN_ON(!gic->domain))
+		return;
 
 	gic_chip.flags |= gic_arch_extn.flags;
 	gic_dist_init(gic);
@@ -771,7 +763,6 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent)
 	void __iomem *dist_base;
 	u32 percpu_offset;
 	int irq;
-	struct irq_domain *domain = &gic_data[gic_cnt].domain;
 
 	if (WARN_ON(!node))
 		return -ENODEV;
@@ -785,9 +776,7 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent)
 	if (of_property_read_u32(node, "cpu-offset", &percpu_offset))
 		percpu_offset = 0;
 
-	domain->of_node = of_node_get(node);
-
-	gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset);
+	gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset, node);
 
 	if (parent) {
 		irq = irq_of_parse_and_map(node, 0);
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index dcb004a..7a66311 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -56,7 +56,7 @@ struct vic_device {
 	u32		int_enable;
 	u32		soft_int;
 	u32		protect;
-	struct irq_domain domain;
+	struct irq_domain *domain;
 };
 
 /* we cannot allocate memory when VICs are initially registered */
@@ -192,14 +192,8 @@ static void __init vic_register(void __iomem *base, unsigned int irq,
 	v->resume_sources = resume_sources;
 	v->irq = irq;
 	vic_id++;
-
-	v->domain.irq_base = irq;
-	v->domain.nr_irq = 32;
-#ifdef CONFIG_OF_IRQ
-	v->domain.of_node = of_node_get(node);
-#endif /* CONFIG_OF */
-	v->domain.ops = &irq_domain_simple_ops;
-	irq_domain_add(&v->domain);
+	v->domain = irq_domain_add_legacy(node, 32, irq, 0,
+					  &irq_domain_simple_ops, v);
 }
 
 static void vic_ack_irq(struct irq_data *d)
@@ -348,7 +342,7 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
 	vic_register(base, irq_start, 0, node);
 }
 
-static void __init __vic_init(void __iomem *base, unsigned int irq_start,
+void __init __vic_init(void __iomem *base, unsigned int irq_start,
 			      u32 vic_sources, u32 resume_sources,
 			      struct device_node *node)
 {
@@ -444,7 +438,7 @@ static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs)
 	stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
 	while (stat) {
 		irq = ffs(stat) - 1;
-		handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs);
+		handle_IRQ(irq_find_mapping(vic->domain, irq), regs);
 		stat &= ~(1 << irq);
 		handled = 1;
 	}
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
index 4bdfe00..4b1ce6c 100644
--- a/arch/arm/include/asm/hardware/gic.h
+++ b/arch/arm/include/asm/hardware/gic.h
@@ -39,7 +39,7 @@ struct device_node;
 extern struct irq_chip gic_arch_extn;
 
 void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *,
-		    u32 offset);
+		    u32 offset, struct device_node *);
 int gic_of_init(struct device_node *node, struct device_node *parent);
 void gic_secondary_init(unsigned int);
 void gic_handle_irq(struct pt_regs *regs);
@@ -49,7 +49,7 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
 static inline void gic_init(unsigned int nr, int start,
 			    void __iomem *dist , void __iomem *cpu)
 {
-	gic_init_bases(nr, start, dist, cpu, 0);
+	gic_init_bases(nr, start, dist, cpu, 0, NULL);
 }
 
 #endif
diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
index f42ebd6..e14af1a 100644
--- a/arch/arm/include/asm/hardware/vic.h
+++ b/arch/arm/include/asm/hardware/vic.h
@@ -47,6 +47,8 @@
 struct device_node;
 struct pt_regs;
 
+void __vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources,
+		u32 resume_sources, struct device_node *node);
 void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
 int vic_of_init(struct device_node *node, struct device_node *parent);
 void vic_handle_irq(struct pt_regs *regs);
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index c59e188..6de298c 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -402,7 +402,7 @@ void __init exynos4_init_irq(void)
 	gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000;
 
 	if (!of_have_populated_dt())
-		gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset);
+		gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset, NULL);
 #ifdef CONFIG_OF
 	else
 		of_irq_init(exynos4_dt_irq_match);
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 02b7b93..e924f15 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -98,8 +98,9 @@ static const struct of_device_id sic_of_match[] __initconst = {
 
 void __init versatile_init_irq(void)
 {
-	vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0);
-	irq_domain_generate_simple(vic_of_match, VERSATILE_VIC_BASE, IRQ_VIC_START);
+	__vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0,
+			of_find_matching_node_by_address(NULL, vic_of_match,
+							 VERSATILE_VIC_BASE));
 
 	writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
 
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index e04e04dd..aab236f 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -263,8 +263,6 @@ struct twl_client {
 
 static struct twl_client twl_modules[TWL_NUM_SLAVES];
 
-static struct irq_domain domain;
-
 /* mapping the module id to slave id and base address */
 struct twl_mapping {
 	unsigned char sid;	/* Slave ID */
@@ -1225,14 +1223,8 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 
 	pdata->irq_base = status;
 	pdata->irq_end = pdata->irq_base + nr_irqs;
-
-	domain.irq_base = pdata->irq_base;
-	domain.nr_irq = nr_irqs;
-#ifdef CONFIG_OF_IRQ
-	domain.of_node = of_node_get(node);
-	domain.ops = &irq_domain_simple_ops;
-#endif
-	irq_domain_add(&domain);
+	irq_domain_add_legacy(node, nr_irqs, pdata->irq_base, 0,
+			      &irq_domain_simple_ops);
 
 	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
 		dev_dbg(&client->dev, "can't talk I2C?\n");
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 7fef39e..624e9ac 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -55,9 +55,6 @@ typedef unsigned long irq_hw_number_t;
  * @map: Create or update a mapping between a virtual irq number and a hw
  *       irq number. This is called only once for a given mapping.
  * @unmap: Dispose of such a mapping
- * @to_irq: (optional) given a local hardware irq number, return the linux
- *          irq number.  If to_irq is not implemented, then the irq_domain
- *          will use this translation: irq = (domain->irq_base + hwirq)
  * @xlate: Given a device tree node and interrupt specifier, decode
  *         the hardware irq number and linux irq type value.
  *
@@ -70,7 +67,6 @@ struct irq_domain_ops {
 	int (*match)(struct irq_domain *d, struct device_node *node);
 	int (*map)(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw);
 	void (*unmap)(struct irq_domain *d, unsigned int virq);
-	unsigned int (*to_irq)(struct irq_domain *d, unsigned long hwirq);
 	int (*xlate)(struct irq_domain *d, struct device_node *node,
 		     const u32 *intspec, unsigned int intsize,
 		     unsigned long *out_hwirq, unsigned int *out_type);
@@ -114,16 +110,11 @@ struct irq_domain {
 	void *host_data;
 	irq_hw_number_t inval_irq;
 
-	unsigned int irq_base;
-	unsigned int nr_irq;
-	unsigned int hwirq_base;
-
 	/* Optional device node pointer */
 	struct device_node *of_node;
 };
 
 #ifdef CONFIG_IRQ_DOMAIN
-#ifdef CONFIG_PPC
 struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
 					 unsigned int size,
 					 unsigned int first_irq,
@@ -153,6 +144,10 @@ static inline struct irq_domain *irq_domain_add_legacy_isa(
 	return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops,
 				     host_data);
 }
+extern struct irq_domain *irq_find_host(struct device_node *node);
+extern void irq_set_default_host(struct irq_domain *host);
+extern void irq_set_virq_count(unsigned int count);
+
 
 extern unsigned int irq_create_mapping(struct irq_domain *host,
 				       irq_hw_number_t hwirq);
@@ -167,38 +162,7 @@ extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
 extern unsigned int irq_linear_revmap(struct irq_domain *host,
 				      irq_hw_number_t hwirq);
 
-#else /* CONFIG_PPC */
-
-/**
- * irq_domain_to_irq() - Translate from a hardware irq to a linux irq number
- *
- * Returns the linux irq number associated with a hardware irq.  By default,
- * the mapping is irq == domain->irq_base + hwirq, but this mapping can
- * be overridden if the irq_domain implements a .to_irq() hook.
- */
-static inline unsigned int irq_domain_to_irq(struct irq_domain *d,
-					     unsigned long hwirq)
-{
-	if (d->ops->to_irq)
-		return d->ops->to_irq(d, hwirq);
-	if (WARN_ON(hwirq < d->hwirq_base))
-		return 0;
-	return d->irq_base + hwirq - d->hwirq_base;
-}
-
-#define irq_domain_for_each_hwirq(d, hw) \
-	for (hw = d->hwirq_base; hw < d->hwirq_base + d->nr_irq; hw++)
-
-#define irq_domain_for_each_irq(d, hw, irq) \
-	for (hw = d->hwirq_base, irq = irq_domain_to_irq(d, hw); \
-	     hw < d->hwirq_base + d->nr_irq; \
-	     hw++, irq = irq_domain_to_irq(d, hw))
-
-extern void irq_domain_add(struct irq_domain *domain);
-extern void irq_domain_del(struct irq_domain *domain);
-
 extern struct irq_domain_ops irq_domain_simple_ops;
-
 #if defined(CONFIG_OF_IRQ)
 extern void irq_domain_add_simple(struct device_node *controller, int irq_base);
 extern void irq_domain_generate_simple(const struct of_device_id *match,
@@ -207,7 +171,6 @@ extern void irq_domain_generate_simple(const struct of_device_id *match,
 static inline void irq_domain_generate_simple(const struct of_device_id *match,
 					u64 phys_base, unsigned int irq_start) { }
 #endif /* !CONFIG_OF_IRQ */
-#endif /* !CONFIG_PPC */
 #endif /* CONFIG_IRQ_DOMAIN */
 
 #endif /* _LINUX_IRQDOMAIN_H */
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 18ba492..8eff85c06 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -17,7 +17,6 @@
 static LIST_HEAD(irq_domain_list);
 static DEFINE_MUTEX(irq_domain_mutex);
 
-#ifdef CONFIG_PPC
 static DEFINE_MUTEX(revmap_trees_mutex);
 static unsigned int irq_virq_count = NR_IRQS;
 static struct irq_domain *irq_default_domain;
@@ -682,124 +681,11 @@ static int __init irq_debugfs_init(void)
 __initcall(irq_debugfs_init);
 #endif /* CONFIG_VIRQ_DEBUG */
 
-#else /* CONFIG_PPC */
-
-/**
- * irq_domain_add() - Register an irq_domain
- * @domain: ptr to initialized irq_domain structure
- *
- * Registers an irq_domain structure.  The irq_domain must at a minimum be
- * initialized with an ops structure pointer, and either a ->to_irq hook or
- * a valid irq_base value.  Everything else is optional.
- */
-void irq_domain_add(struct irq_domain *domain)
-{
-	struct irq_data *d;
-	int hwirq, irq;
-
-	/*
-	 * This assumes that the irq_domain owner has already allocated
-	 * the irq_descs.  This block will be removed when support for dynamic
-	 * allocation of irq_descs is added to irq_domain.
-	 */
-	irq_domain_for_each_irq(domain, hwirq, irq) {
-		d = irq_get_irq_data(irq);
-		if (!d) {
-			WARN(1, "error: assigning domain to non existant irq_desc");
-			return;
-		}
-		if (d->domain) {
-			/* things are broken; just report, don't clean up */
-			WARN(1, "error: irq_desc already assigned to a domain");
-			return;
-		}
-		d->domain = domain;
-		d->hwirq = hwirq;
-	}
-
-	mutex_lock(&irq_domain_mutex);
-	list_add(&domain->link, &irq_domain_list);
-	mutex_unlock(&irq_domain_mutex);
-}
-
-/**
- * irq_domain_del() - Unregister an irq_domain
- * @domain: ptr to registered irq_domain.
- */
-void irq_domain_del(struct irq_domain *domain)
-{
-	struct irq_data *d;
-	int hwirq, irq;
-
-	mutex_lock(&irq_domain_mutex);
-	list_del(&domain->link);
-	mutex_unlock(&irq_domain_mutex);
-
-	/* Clear the irq_domain assignments */
-	irq_domain_for_each_irq(domain, hwirq, irq) {
-		d = irq_get_irq_data(irq);
-		d->domain = NULL;
-	}
-}
-
-#if defined(CONFIG_OF_IRQ)
-/**
- * irq_create_of_mapping() - Map a linux irq number from a DT interrupt spec
- *
- * Used by the device tree interrupt mapping code to translate a device tree
- * interrupt specifier to a valid linux irq number.  Returns either a valid
- * linux IRQ number or 0.
- *
- * When the caller no longer need the irq number returned by this function it
- * should arrange to call irq_dispose_mapping().
- */
-unsigned int irq_create_of_mapping(struct device_node *controller,
-				   const u32 *intspec, unsigned int intsize)
-{
-	struct irq_domain *domain;
-	unsigned long hwirq;
-	unsigned int irq, type;
-	int rc = -EINVAL;
-
-	/* Find a domain which can translate the irq spec */
-	mutex_lock(&irq_domain_mutex);
-	list_for_each_entry(domain, &irq_domain_list, link) {
-		if (!domain->ops->xlate)
-			continue;
-		rc = domain->ops->xlate(domain, controller,
-					intspec, intsize, &hwirq, &type);
-		if (rc == 0)
-			break;
-	}
-	mutex_unlock(&irq_domain_mutex);
-
-	if (rc != 0)
-		return 0;
-
-	irq = irq_domain_to_irq(domain, hwirq);
-	if (type != IRQ_TYPE_NONE)
-		irq_set_irq_type(irq, type);
-	pr_debug("%s: mapped hwirq=%i to irq=%i, flags=%x\n",
-		 controller->full_name, (int)hwirq, irq, type);
-	return irq;
-}
-EXPORT_SYMBOL_GPL(irq_create_of_mapping);
-
-/**
- * irq_dispose_mapping() - Discard a mapping created by irq_create_of_mapping()
- * @irq: linux irq number to be discarded
- *
- * Calling this function indicates the caller no longer needs a reference to
- * the linux irq number returned by a prior call to irq_create_of_mapping().
- */
-void irq_dispose_mapping(unsigned int irq)
+int irq_domain_simple_map(struct irq_domain *d, unsigned int irq,
+			  irq_hw_number_t hwirq)
 {
-	/*
-	 * nothing yet; will be filled when support for dynamic allocation of
-	 * irq_descs is added to irq_domain
-	 */
+	return 0;
 }
-EXPORT_SYMBOL_GPL(irq_dispose_mapping);
 
 int irq_domain_simple_xlate(struct irq_domain *d,
 			    struct device_node *controller,
@@ -810,10 +696,6 @@ int irq_domain_simple_xlate(struct irq_domain *d,
 		return -EINVAL;
 	if (intsize < 1)
 		return -EINVAL;
-	if (d->nr_irq && ((intspec[0] < d->hwirq_base) ||
-	    (intspec[0] >= d->hwirq_base + d->nr_irq)))
-		return -EINVAL;
-
 	*out_hwirq = intspec[0];
 	*out_type = IRQ_TYPE_NONE;
 	if (intsize > 1)
@@ -821,23 +703,17 @@ int irq_domain_simple_xlate(struct irq_domain *d,
 	return 0;
 }
 
-/**
- * irq_domain_create_simple() - Set up a 'simple' translation range
- */
+struct irq_domain_ops irq_domain_simple_ops = {
+	.map = irq_domain_simple_map,
+	.xlate = irq_domain_simple_xlate,
+};
+EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
+
+#ifdef CONFIG_OF_IRQ
 void irq_domain_add_simple(struct device_node *controller, int irq_base)
 {
-	struct irq_domain *domain;
-
-	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
-	if (!domain) {
-		WARN_ON(1);
-		return;
-	}
-
-	domain->irq_base = irq_base;
-	domain->of_node = of_node_get(controller);
-	domain->ops = &irq_domain_simple_ops;
-	irq_domain_add(domain);
+	irq_domain_add_legacy(controller, 32, irq_base, 0,
+			      &irq_domain_simple_ops, NULL);
 }
 EXPORT_SYMBOL_GPL(irq_domain_add_simple);
 
@@ -852,13 +728,4 @@ void irq_domain_generate_simple(const struct of_device_id *match,
 		irq_domain_add_simple(node, irq_start);
 }
 EXPORT_SYMBOL_GPL(irq_domain_generate_simple);
-#endif /* CONFIG_OF_IRQ */
-
-struct irq_domain_ops irq_domain_simple_ops = {
-#ifdef CONFIG_OF_IRQ
-	.xlate = irq_domain_simple_xlate,
-#endif /* CONFIG_OF_IRQ */
-};
-EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
-
-#endif /* !CONFIG_PPC */
+#endif
-- 
1.7.5.4


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

* [PATCH v3 14/25] irq_domain: Remove irq_domain_add_simple()
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (12 preceding siblings ...)
  2012-01-27 21:36 ` [PATCH v3 13/25] irq_domain: Remove 'new' irq_domain in favour of the ppc one Grant Likely
@ 2012-01-27 21:36 ` Grant Likely
  2012-01-31 12:45   ` Shawn Guo
  2012-02-01  5:46   ` [PATCH] irq_domain: fix the irq number of imx5 tzic Shawn Guo
  2012-01-27 21:36 ` [PATCH v3 15/25] irq_domain: Create common xlate functions that device drivers can use Grant Likely
                   ` (13 subsequent siblings)
  27 siblings, 2 replies; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely

irq_domain_add_simple() was a stop-gap measure until complete irq_domain
support was complete.  This patch removes the irq_domain_add_simple()
interface.

v2: Updated to pass in host_data pointer on irq_domain allocation.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>
---
 arch/arm/mach-imx/mach-imx6q.c      |    3 ++-
 arch/arm/mach-msm/board-msm8x60.c   |    8 ++------
 arch/arm/mach-mx5/imx51-dt.c        |    4 ++--
 arch/arm/mach-mx5/imx53-dt.c        |    4 ++--
 arch/arm/mach-omap2/board-generic.c |    2 +-
 arch/arm/mach-prima2/irq.c          |    2 +-
 drivers/mfd/twl-core.c              |    2 +-
 include/linux/irqdomain.h           |    1 -
 kernel/irq/irqdomain.c              |   10 ++--------
 9 files changed, 13 insertions(+), 23 deletions(-)

diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index c257281..6075d4d 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -97,7 +97,8 @@ static int __init imx6q_gpio_add_irq_domain(struct device_node *np,
 	static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
 
 	gpio_irq_base -= 32;
-	irq_domain_add_simple(np, gpio_irq_base);
+	irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops,
+			      NULL);
 
 	return 0;
 }
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 0a11342..962e711 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -80,12 +80,8 @@ static struct of_device_id msm_dt_gic_match[] __initdata = {
 
 static void __init msm8x60_dt_init(void)
 {
-	struct device_node *node;
-
-	node = of_find_matching_node_by_address(NULL, msm_dt_gic_match,
-			MSM8X60_QGIC_DIST_PHYS);
-	if (node)
-		irq_domain_add_simple(node, GIC_SPI_START);
+	irq_domain_generate_simple(msm_dt_gic_match, MSM8X60_QGIC_DIST_PHYS,
+				GIC_SPI_START);
 
 	if (of_machine_is_compatible("qcom,msm8660-surf")) {
 		printk(KERN_INFO "Init surf UART registers\n");
diff --git a/arch/arm/mach-mx5/imx51-dt.c b/arch/arm/mach-mx5/imx51-dt.c
index e6bad17..e1b5edf 100644
--- a/arch/arm/mach-mx5/imx51-dt.c
+++ b/arch/arm/mach-mx5/imx51-dt.c
@@ -47,7 +47,7 @@ static const struct of_dev_auxdata imx51_auxdata_lookup[] __initconst = {
 static int __init imx51_tzic_add_irq_domain(struct device_node *np,
 				struct device_node *interrupt_parent)
 {
-	irq_domain_add_simple(np, 0);
+	irq_domain_add_legacy(np, 32, 0, 0, &irq_domain_simple_ops, NULL);
 	return 0;
 }
 
@@ -57,7 +57,7 @@ static int __init imx51_gpio_add_irq_domain(struct device_node *np,
 	static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
 
 	gpio_irq_base -= 32;
-	irq_domain_add_simple(np, gpio_irq_base);
+	irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, NULL);
 
 	return 0;
 }
diff --git a/arch/arm/mach-mx5/imx53-dt.c b/arch/arm/mach-mx5/imx53-dt.c
index 05ebb3e..89de5d4 100644
--- a/arch/arm/mach-mx5/imx53-dt.c
+++ b/arch/arm/mach-mx5/imx53-dt.c
@@ -51,7 +51,7 @@ static const struct of_dev_auxdata imx53_auxdata_lookup[] __initconst = {
 static int __init imx53_tzic_add_irq_domain(struct device_node *np,
 				struct device_node *interrupt_parent)
 {
-	irq_domain_add_simple(np, 0);
+	irq_domain_add_legacy(np, 32, 0, 0, &irq_domain_simple_ops, NULL);
 	return 0;
 }
 
@@ -61,7 +61,7 @@ static int __init imx53_gpio_add_irq_domain(struct device_node *np,
 	static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
 
 	gpio_irq_base -= 32;
-	irq_domain_add_simple(np, gpio_irq_base);
+	irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, NULL);
 
 	return 0;
 }
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index d587560..00b1d02 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -67,7 +67,7 @@ static void __init omap_generic_init(void)
 {
 	struct device_node *node = of_find_matching_node(NULL, intc_match);
 	if (node)
-		irq_domain_add_simple(node, 0);
+		irq_domain_add_legacy(node, 32, 0, 0, &irq_domain_simple_ops, NULL);
 
 	omap_sdrc_init(NULL, NULL);
 
diff --git a/arch/arm/mach-prima2/irq.c b/arch/arm/mach-prima2/irq.c
index d93ceef..37c2de9 100644
--- a/arch/arm/mach-prima2/irq.c
+++ b/arch/arm/mach-prima2/irq.c
@@ -68,7 +68,7 @@ void __init sirfsoc_of_irq_init(void)
 	if (!sirfsoc_intc_base)
 		panic("unable to map intc cpu registers\n");
 
-	irq_domain_add_simple(np, 0);
+	irq_domain_add_legacy(np, 32, 0, 0, &irq_domain_simple_ops, NULL);
 
 	of_node_put(np);
 
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index aab236f..e63b408 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -1224,7 +1224,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	pdata->irq_base = status;
 	pdata->irq_end = pdata->irq_base + nr_irqs;
 	irq_domain_add_legacy(node, nr_irqs, pdata->irq_base, 0,
-			      &irq_domain_simple_ops);
+			      &irq_domain_simple_ops, NULL);
 
 	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
 		dev_dbg(&client->dev, "can't talk I2C?\n");
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 624e9ac..e7379a3 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -164,7 +164,6 @@ extern unsigned int irq_linear_revmap(struct irq_domain *host,
 
 extern struct irq_domain_ops irq_domain_simple_ops;
 #if defined(CONFIG_OF_IRQ)
-extern void irq_domain_add_simple(struct device_node *controller, int irq_base);
 extern void irq_domain_generate_simple(const struct of_device_id *match,
 					u64 phys_base, unsigned int irq_start);
 #else /* CONFIG_OF_IRQ */
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 8eff85c06..6627dc7 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -710,13 +710,6 @@ struct irq_domain_ops irq_domain_simple_ops = {
 EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
 
 #ifdef CONFIG_OF_IRQ
-void irq_domain_add_simple(struct device_node *controller, int irq_base)
-{
-	irq_domain_add_legacy(controller, 32, irq_base, 0,
-			      &irq_domain_simple_ops, NULL);
-}
-EXPORT_SYMBOL_GPL(irq_domain_add_simple);
-
 void irq_domain_generate_simple(const struct of_device_id *match,
 				u64 phys_base, unsigned int irq_start)
 {
@@ -725,7 +718,8 @@ void irq_domain_generate_simple(const struct of_device_id *match,
 		(unsigned long long) phys_base, (int) irq_start);
 	node = of_find_matching_node_by_address(NULL, match, phys_base);
 	if (node)
-		irq_domain_add_simple(node, irq_start);
+		irq_domain_add_legacy(node, 32, irq_start, 0,
+				      &irq_domain_simple_ops, NULL);
 }
 EXPORT_SYMBOL_GPL(irq_domain_generate_simple);
 #endif
-- 
1.7.5.4


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

* [PATCH v3 15/25] irq_domain: Create common xlate functions that device drivers can use
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (13 preceding siblings ...)
  2012-01-27 21:36 ` [PATCH v3 14/25] irq_domain: Remove irq_domain_add_simple() Grant Likely
@ 2012-01-27 21:36 ` Grant Likely
  2012-01-27 21:36 ` [PATCH v3 16/25] irq_domain: constify irq_domain_ops Grant Likely
                   ` (12 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely,
	Mark Salter

Rather than having each interrupt controller driver creating its own barely
unique .xlate function for irq_domain, create a library of translators which
any driver can use directly.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Mark Salter <msalter@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>
---
 include/linux/irqdomain.h |   15 ++++++++
 kernel/irq/irqdomain.c    |   83 +++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 88 insertions(+), 10 deletions(-)

diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index e7379a3..1db30df 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -163,6 +163,21 @@ extern unsigned int irq_linear_revmap(struct irq_domain *host,
 				      irq_hw_number_t hwirq);
 
 extern struct irq_domain_ops irq_domain_simple_ops;
+
+/* stock xlate functions */
+int irq_domain_xlate_onecell(struct irq_domain *d, struct device_node *ctrlr,
+			const u32 *intspec, unsigned int intsize,
+			irq_hw_number_t *out_hwirq, unsigned int *out_type);
+int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
+			const u32 *intspec, unsigned int intsize,
+			irq_hw_number_t *out_hwirq, unsigned int *out_type);
+int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
+			const u32 *intspec, unsigned int intsize,
+			irq_hw_number_t *out_hwirq, unsigned int *out_type);
+int irq_domain_xlate_pci(struct irq_domain *d, struct device_node *ctrlr,
+			const u32 *intspec, unsigned int intsize,
+			irq_hw_number_t *out_hwirq, unsigned int *out_type);
+
 #if defined(CONFIG_OF_IRQ)
 extern void irq_domain_generate_simple(const struct of_device_id *match,
 					u64 phys_base, unsigned int irq_start);
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 6627dc7..b0ed3be 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -687,25 +687,88 @@ int irq_domain_simple_map(struct irq_domain *d, unsigned int irq,
 	return 0;
 }
 
-int irq_domain_simple_xlate(struct irq_domain *d,
-			    struct device_node *controller,
-			    const u32 *intspec, unsigned int intsize,
-			    unsigned long *out_hwirq, unsigned int *out_type)
+/**
+ * irq_domain_xlate_onecell() - Generic xlate for direct one cell bindings
+ *
+ * Device Tree IRQ specifier translation function which works with one cell
+ * bindings where the cell value maps directly to the hwirq number.
+ */
+int irq_domain_xlate_onecell(struct irq_domain *d, struct device_node *ctrlr,
+			     const u32 *intspec, unsigned int intsize,
+			     unsigned long *out_hwirq, unsigned int *out_type)
 {
-	if (d->of_node != controller)
-		return -EINVAL;
-	if (intsize < 1)
+	if (WARN_ON(intsize < 1))
 		return -EINVAL;
 	*out_hwirq = intspec[0];
 	*out_type = IRQ_TYPE_NONE;
-	if (intsize > 1)
-		*out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
 	return 0;
 }
+EXPORT_SYMBOL_GPL(irq_domain_xlate_onecell);
+
+/**
+ * irq_domain_xlate_twocell() - Generic xlate for direct two cell bindings
+ *
+ * Device Tree IRQ specifier translation function which works with two cell
+ * bindings where the cell values map directly to the hwirq number
+ * and linux irq flags.
+ */
+int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
+			const u32 *intspec, unsigned int intsize,
+			irq_hw_number_t *out_hwirq, unsigned int *out_type)
+{
+	if (WARN_ON(intsize < 2))
+		return -EINVAL;
+	*out_hwirq = intspec[0];
+	*out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(irq_domain_xlate_twocell);
+
+/**
+ * irq_domain_xlate_onetwocell() - Generic xlate for one or two cell bindings
+ *
+ * Device Tree IRQ specifier translation function which works with either one
+ * or two cell bindings where the cell values map directly to the hwirq number
+ * and linux irq flags.
+ *
+ * Note: don't use this function unless your interrupt controller explicitly
+ * supports both one and two cell bindings.  For the majority of controllers
+ * the _onecell() or _twocell() variants above should be used.
+ */
+int irq_domain_xlate_onetwocell(struct irq_domain *d,
+				struct device_node *ctrlr,
+				const u32 *intspec, unsigned int intsize,
+				unsigned long *out_hwirq, unsigned int *out_type)
+{
+	if (WARN_ON(intsize < 1))
+		return -EINVAL;
+	*out_hwirq = intspec[0];
+	*out_type = (intsize > 1) ? intspec[1] : IRQ_TYPE_NONE;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(irq_domain_xlate_onetwocell);
+
+/**
+ * irq_domain_xlate_pci() - Generic xlate for the PCI binding
+ *
+ * Device Tree IRQ specifier translation function which works with one cell
+ * bindings where the cell value maps directly to the hwirq number.
+ */
+int irq_domain_xlate_pci(struct irq_domain *d, struct device_node *ctrlr,
+			 const u32 *intspec, unsigned int intsize,
+			 unsigned long *out_hwirq, unsigned int *out_type)
+{
+	if (WARN_ON(intsize != 1))
+		return -EINVAL;
+	*out_hwirq = intspec[0];
+	*out_type = IRQ_TYPE_LEVEL_HIGH;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(irq_domain_xlate_pci);
 
 struct irq_domain_ops irq_domain_simple_ops = {
 	.map = irq_domain_simple_map,
-	.xlate = irq_domain_simple_xlate,
+	.xlate = irq_domain_xlate_onetwocell,
 };
 EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
 
-- 
1.7.5.4


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

* [PATCH v3 16/25] irq_domain: constify irq_domain_ops
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (14 preceding siblings ...)
  2012-01-27 21:36 ` [PATCH v3 15/25] irq_domain: Create common xlate functions that device drivers can use Grant Likely
@ 2012-01-27 21:36 ` Grant Likely
  2012-01-27 21:36 ` [PATCH v3 17/25] irq_domain/c6x: Convert c6x to use generic irq_domain support Grant Likely
                   ` (11 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely

Make irq_domain_ops pointer a constant to make it safer for multiple
instances to share the same ops pointer and change the irq_domain code
so that it does not modify the ops.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Milton Miller <miltonm@bga.com>
---
 include/linux/irqdomain.h |   14 +++++++-------
 kernel/irq/irqdomain.c    |   31 +++++++++++++++----------------
 2 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 1db30df..0b00f83 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -106,7 +106,7 @@ struct irq_domain {
 		} linear;
 		struct radix_tree_root tree;
 	} revmap_data;
-	struct irq_domain_ops *ops;
+	const struct irq_domain_ops *ops;
 	void *host_data;
 	irq_hw_number_t inval_irq;
 
@@ -119,17 +119,17 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
 					 unsigned int size,
 					 unsigned int first_irq,
 					 irq_hw_number_t first_hwirq,
-					 struct irq_domain_ops *ops,
+					 const struct irq_domain_ops *ops,
 					 void *host_data);
 struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
 					 unsigned int size,
-					 struct irq_domain_ops *ops,
+					 const struct irq_domain_ops *ops,
 					 void *host_data);
 struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
-					 struct irq_domain_ops *ops,
+					 const struct irq_domain_ops *ops,
 					 void *host_data);
 struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
-					 struct irq_domain_ops *ops,
+					 const struct irq_domain_ops *ops,
 					 void *host_data);
 
 extern struct irq_domain *irq_find_host(struct device_node *node);
@@ -138,7 +138,7 @@ extern void irq_set_virq_count(unsigned int count);
 
 static inline struct irq_domain *irq_domain_add_legacy_isa(
 				struct device_node *of_node,
-				struct irq_domain_ops *ops,
+				const struct irq_domain_ops *ops,
 				void *host_data)
 {
 	return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops,
@@ -162,7 +162,7 @@ extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
 extern unsigned int irq_linear_revmap(struct irq_domain *host,
 				      irq_hw_number_t hwirq);
 
-extern struct irq_domain_ops irq_domain_simple_ops;
+extern const struct irq_domain_ops irq_domain_simple_ops;
 
 /* stock xlate functions */
 int irq_domain_xlate_onecell(struct irq_domain *d, struct device_node *ctrlr,
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index b0ed3be..bf181ef 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -21,11 +21,6 @@ static DEFINE_MUTEX(revmap_trees_mutex);
 static unsigned int irq_virq_count = NR_IRQS;
 static struct irq_domain *irq_default_domain;
 
-static int default_irq_domain_match(struct irq_domain *d, struct device_node *np)
-{
-	return d->of_node != NULL && d->of_node == np;
-}
-
 /**
  * irq_domain_alloc() - Allocate a new irq_domain data structure
  * @of_node: optional device-tree node of the interrupt controller
@@ -39,7 +34,7 @@ static int default_irq_domain_match(struct irq_domain *d, struct device_node *np
  */
 static struct irq_domain *irq_domain_alloc(struct device_node *of_node,
 					   unsigned int revmap_type,
-					   struct irq_domain_ops *ops,
+					   const struct irq_domain_ops *ops,
 					   void *host_data)
 {
 	struct irq_domain *domain;
@@ -54,9 +49,6 @@ static struct irq_domain *irq_domain_alloc(struct device_node *of_node,
 	domain->host_data = host_data;
 	domain->of_node = of_node_get(of_node);
 
-	if (domain->ops->match == NULL)
-		domain->ops->match = default_irq_domain_match;
-
 	return domain;
 }
 
@@ -99,7 +91,7 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
 					 unsigned int size,
 					 unsigned int first_irq,
 					 irq_hw_number_t first_hwirq,
-					 struct irq_domain_ops *ops,
+					 const struct irq_domain_ops *ops,
 					 void *host_data)
 {
 	struct irq_domain *domain;
@@ -165,7 +157,7 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
  */
 struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
 					 unsigned int size,
-					 struct irq_domain_ops *ops,
+					 const struct irq_domain_ops *ops,
 					 void *host_data)
 {
 	struct irq_domain *domain;
@@ -187,7 +179,7 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
 }
 
 struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
-					 struct irq_domain_ops *ops,
+					 const struct irq_domain_ops *ops,
 					 void *host_data)
 {
 	struct irq_domain *domain = irq_domain_alloc(of_node,
@@ -206,7 +198,7 @@ struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
  * (the reverse mapping will use the slow path until that happens).
  */
 struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
-					 struct irq_domain_ops *ops,
+					 const struct irq_domain_ops *ops,
 					 void *host_data)
 {
 	struct irq_domain *domain = irq_domain_alloc(of_node,
@@ -225,6 +217,7 @@ struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
 struct irq_domain *irq_find_host(struct device_node *node)
 {
 	struct irq_domain *h, *found = NULL;
+	int rc;
 
 	/* We might want to match the legacy controller last since
 	 * it might potentially be set to match all interrupts in
@@ -232,11 +225,17 @@ struct irq_domain *irq_find_host(struct device_node *node)
 	 * yet though...
 	 */
 	mutex_lock(&irq_domain_mutex);
-	list_for_each_entry(h, &irq_domain_list, link)
-		if (h->ops->match(h, node)) {
+	list_for_each_entry(h, &irq_domain_list, link) {
+		if (h->ops->match)
+			rc = h->ops->match(h, node);
+		else
+			rc = (h->of_node != NULL) && (h->of_node == node);
+
+		if (rc) {
 			found = h;
 			break;
 		}
+	}
 	mutex_unlock(&irq_domain_mutex);
 	return found;
 }
@@ -766,7 +765,7 @@ int irq_domain_xlate_pci(struct irq_domain *d, struct device_node *ctrlr,
 }
 EXPORT_SYMBOL_GPL(irq_domain_xlate_pci);
 
-struct irq_domain_ops irq_domain_simple_ops = {
+const struct irq_domain_ops irq_domain_simple_ops = {
 	.map = irq_domain_simple_map,
 	.xlate = irq_domain_xlate_onetwocell,
 };
-- 
1.7.5.4


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

* [PATCH v3 17/25] irq_domain/c6x: Convert c6x to use generic irq_domain support.
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (15 preceding siblings ...)
  2012-01-27 21:36 ` [PATCH v3 16/25] irq_domain: constify irq_domain_ops Grant Likely
@ 2012-01-27 21:36 ` Grant Likely
  2012-01-27 21:36 ` [PATCH v3 18/25] irq_domain/c6x: constify irq_domain structures Grant Likely
                   ` (10 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Mark Salter,
	Grant Likely, Aurelien Jacquiot

From: Mark Salter <msalter@redhat.com>

The C6X IRQ support was copied almost verbatim from the PowerPC virtual IRQ
code. The PowerPC code was used as the basis for generic irq_domain support,
so this patch mostly copies what what done to arch/powerpc by Grant Likely
in his irq_domain patch series.

Signed-off-by: Mark Salter <msalter@redhat.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Aurelien Jacquiot <a-jacquiot@ti.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
 arch/c6x/Kconfig                 |    1 +
 arch/c6x/include/asm/irq.h       |  245 +---------------
 arch/c6x/kernel/irq.c            |  611 +-------------------------------------
 arch/c6x/platforms/megamod-pic.c |   13 +-
 4 files changed, 21 insertions(+), 849 deletions(-)

diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig
index 26e67f0..3c64b28 100644
--- a/arch/c6x/Kconfig
+++ b/arch/c6x/Kconfig
@@ -12,6 +12,7 @@ config TMS320C6X
 	select HAVE_GENERIC_HARDIRQS
 	select HAVE_MEMBLOCK
 	select HAVE_SPARSE_IRQ
+	select IRQ_DOMAIN
 	select OF
 	select OF_EARLY_FLATTREE
 
diff --git a/arch/c6x/include/asm/irq.h b/arch/c6x/include/asm/irq.h
index a6ae3c9..f13b78d 100644
--- a/arch/c6x/include/asm/irq.h
+++ b/arch/c6x/include/asm/irq.h
@@ -13,6 +13,7 @@
 #ifndef _ASM_C6X_IRQ_H
 #define _ASM_C6X_IRQ_H
 
+#include <linux/irqdomain.h>
 #include <linux/threads.h>
 #include <linux/list.h>
 #include <linux/radix-tree.h>
@@ -41,253 +42,9 @@
 /* This number is used when no interrupt has been assigned */
 #define NO_IRQ		0
 
-/* This type is the placeholder for a hardware interrupt number. It has to
- * be big enough to enclose whatever representation is used by a given
- * platform.
- */
-typedef unsigned long irq_hw_number_t;
-
-/* Interrupt controller "host" data structure. This could be defined as a
- * irq domain controller. That is, it handles the mapping between hardware
- * and virtual interrupt numbers for a given interrupt domain. The host
- * structure is generally created by the PIC code for a given PIC instance
- * (though a host can cover more than one PIC if they have a flat number
- * model). It's the host callbacks that are responsible for setting the
- * irq_chip on a given irq_desc after it's been mapped.
- *
- * The host code and data structures are fairly agnostic to the fact that
- * we use an open firmware device-tree. We do have references to struct
- * device_node in two places: in irq_find_host() to find the host matching
- * a given interrupt controller node, and of course as an argument to its
- * counterpart host->ops->match() callback. However, those are treated as
- * generic pointers by the core and the fact that it's actually a device-node
- * pointer is purely a convention between callers and implementation. This
- * code could thus be used on other architectures by replacing those two
- * by some sort of arch-specific void * "token" used to identify interrupt
- * controllers.
- */
-struct irq_host;
-struct radix_tree_root;
-struct device_node;
-
-/* Functions below are provided by the host and called whenever a new mapping
- * is created or an old mapping is disposed. The host can then proceed to
- * whatever internal data structures management is required. It also needs
- * to setup the irq_desc when returning from map().
- */
-struct irq_host_ops {
-	/* Match an interrupt controller device node to a host, returns
-	 * 1 on a match
-	 */
-	int (*match)(struct irq_host *h, struct device_node *node);
-
-	/* Create or update a mapping between a virtual irq number and a hw
-	 * irq number. This is called only once for a given mapping.
-	 */
-	int (*map)(struct irq_host *h, unsigned int virq, irq_hw_number_t hw);
-
-	/* Dispose of such a mapping */
-	void (*unmap)(struct irq_host *h, unsigned int virq);
-
-	/* Translate device-tree interrupt specifier from raw format coming
-	 * from the firmware to a irq_hw_number_t (interrupt line number) and
-	 * type (sense) that can be passed to set_irq_type(). In the absence
-	 * of this callback, irq_create_of_mapping() and irq_of_parse_and_map()
-	 * will return the hw number in the first cell and IRQ_TYPE_NONE for
-	 * the type (which amount to keeping whatever default value the
-	 * interrupt controller has for that line)
-	 */
-	int (*xlate)(struct irq_host *h, struct device_node *ctrler,
-		     const u32 *intspec, unsigned int intsize,
-		     irq_hw_number_t *out_hwirq, unsigned int *out_type);
-};
-
-struct irq_host {
-	struct list_head	link;
-
-	/* type of reverse mapping technique */
-	unsigned int		revmap_type;
-#define IRQ_HOST_MAP_PRIORITY   0 /* core priority irqs, get irqs 1..15 */
-#define IRQ_HOST_MAP_NOMAP	1 /* no fast reverse mapping */
-#define IRQ_HOST_MAP_LINEAR	2 /* linear map of interrupts */
-#define IRQ_HOST_MAP_TREE	3 /* radix tree */
-	union {
-		struct {
-			unsigned int size;
-			unsigned int *revmap;
-		} linear;
-		struct radix_tree_root tree;
-	} revmap_data;
-	struct irq_host_ops	*ops;
-	void			*host_data;
-	irq_hw_number_t		inval_irq;
-
-	/* Optional device node pointer */
-	struct device_node	*of_node;
-};
-
 struct irq_data;
 extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
 extern irq_hw_number_t virq_to_hw(unsigned int virq);
-extern bool virq_is_host(unsigned int virq, struct irq_host *host);
-
-/**
- * irq_alloc_host - Allocate a new irq_host data structure
- * @of_node: optional device-tree node of the interrupt controller
- * @revmap_type: type of reverse mapping to use
- * @revmap_arg: for IRQ_HOST_MAP_LINEAR linear only: size of the map
- * @ops: map/unmap host callbacks
- * @inval_irq: provide a hw number in that host space that is always invalid
- *
- * Allocates and initialize and irq_host structure. Note that in the case of
- * IRQ_HOST_MAP_LEGACY, the map() callback will be called before this returns
- * for all legacy interrupts except 0 (which is always the invalid irq for
- * a legacy controller). For a IRQ_HOST_MAP_LINEAR, the map is allocated by
- * this call as well. For a IRQ_HOST_MAP_TREE, the radix tree will be allocated
- * later during boot automatically (the reverse mapping will use the slow path
- * until that happens).
- */
-extern struct irq_host *irq_alloc_host(struct device_node *of_node,
-				       unsigned int revmap_type,
-				       unsigned int revmap_arg,
-				       struct irq_host_ops *ops,
-				       irq_hw_number_t inval_irq);
-
-
-/**
- * irq_find_host - Locates a host for a given device node
- * @node: device-tree node of the interrupt controller
- */
-extern struct irq_host *irq_find_host(struct device_node *node);
-
-
-/**
- * irq_set_default_host - Set a "default" host
- * @host: default host pointer
- *
- * For convenience, it's possible to set a "default" host that will be used
- * whenever NULL is passed to irq_create_mapping(). It makes life easier for
- * platforms that want to manipulate a few hard coded interrupt numbers that
- * aren't properly represented in the device-tree.
- */
-extern void irq_set_default_host(struct irq_host *host);
-
-
-/**
- * irq_set_virq_count - Set the maximum number of virt irqs
- * @count: number of linux virtual irqs, capped with NR_IRQS
- *
- * This is mainly for use by platforms like iSeries who want to program
- * the virtual irq number in the controller to avoid the reverse mapping
- */
-extern void irq_set_virq_count(unsigned int count);
-
-
-/**
- * irq_create_mapping - Map a hardware interrupt into linux virq space
- * @host: host owning this hardware interrupt or NULL for default host
- * @hwirq: hardware irq number in that host space
- *
- * Only one mapping per hardware interrupt is permitted. Returns a linux
- * virq number.
- * If the sense/trigger is to be specified, set_irq_type() should be called
- * on the number returned from that call.
- */
-extern unsigned int irq_create_mapping(struct irq_host *host,
-				       irq_hw_number_t hwirq);
-
-
-/**
- * irq_dispose_mapping - Unmap an interrupt
- * @virq: linux virq number of the interrupt to unmap
- */
-extern void irq_dispose_mapping(unsigned int virq);
-
-/**
- * irq_find_mapping - Find a linux virq from an hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
- *
- * This is a slow path, for use by generic code. It's expected that an
- * irq controller implementation directly calls the appropriate low level
- * mapping function.
- */
-extern unsigned int irq_find_mapping(struct irq_host *host,
-				     irq_hw_number_t hwirq);
-
-/**
- * irq_create_direct_mapping - Allocate a virq for direct mapping
- * @host: host to allocate the virq for or NULL for default host
- *
- * This routine is used for irq controllers which can choose the hardware
- * interrupt numbers they generate. In such a case it's simplest to use
- * the linux virq as the hardware interrupt number.
- */
-extern unsigned int irq_create_direct_mapping(struct irq_host *host);
-
-/**
- * irq_radix_revmap_insert - Insert a hw irq to linux virq number mapping.
- * @host: host owning this hardware interrupt
- * @virq: linux irq number
- * @hwirq: hardware irq number in that host space
- *
- * This is for use by irq controllers that use a radix tree reverse
- * mapping for fast lookup.
- */
-extern void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
-				    irq_hw_number_t hwirq);
-
-/**
- * irq_radix_revmap_lookup - Find a linux virq from a hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
- *
- * This is a fast path, for use by irq controller code that uses radix tree
- * revmaps
- */
-extern unsigned int irq_radix_revmap_lookup(struct irq_host *host,
-					    irq_hw_number_t hwirq);
-
-/**
- * irq_linear_revmap - Find a linux virq from a hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
- *
- * This is a fast path, for use by irq controller code that uses linear
- * revmaps. It does fallback to the slow path if the revmap doesn't exist
- * yet and will create the revmap entry with appropriate locking
- */
-
-extern unsigned int irq_linear_revmap(struct irq_host *host,
-				      irq_hw_number_t hwirq);
-
-
-
-/**
- * irq_alloc_virt - Allocate virtual irq numbers
- * @host: host owning these new virtual irqs
- * @count: number of consecutive numbers to allocate
- * @hint: pass a hint number, the allocator will try to use a 1:1 mapping
- *
- * This is a low level function that is used internally by irq_create_mapping()
- * and that can be used by some irq controllers implementations for things
- * like allocating ranges of numbers for MSIs. The revmaps are left untouched.
- */
-extern unsigned int irq_alloc_virt(struct irq_host *host,
-				   unsigned int count,
-				   unsigned int hint);
-
-/**
- * irq_free_virt - Free virtual irq numbers
- * @virq: virtual irq number of the first interrupt to free
- * @count: number of interrupts to free
- *
- * This function is the opposite of irq_alloc_virt. It will not clear reverse
- * maps, this should be done previously by unmap'ing the interrupt. In fact,
- * all interrupts covered by the range being freed should have been unmapped
- * prior to calling this.
- */
-extern void irq_free_virt(unsigned int virq, unsigned int count);
 
 extern void __init init_pic_c64xplus(void);
 
diff --git a/arch/c6x/kernel/irq.c b/arch/c6x/kernel/irq.c
index 0929e4b..3d5ac60 100644
--- a/arch/c6x/kernel/irq.c
+++ b/arch/c6x/kernel/irq.c
@@ -73,10 +73,10 @@ asmlinkage void c6x_do_IRQ(unsigned int prio, struct pt_regs *regs)
 	set_irq_regs(old_regs);
 }
 
-static struct irq_host *core_host;
+static struct irq_domain *core_domain;
 
-static int core_host_map(struct irq_host *h, unsigned int virq,
-			 irq_hw_number_t hw)
+static int core_domain_map(struct irq_domain *h, unsigned int virq,
+			   irq_hw_number_t hw)
 {
 	if (hw < 4 || hw >= NR_PRIORITY_IRQS)
 		return -EINVAL;
@@ -86,8 +86,8 @@ static int core_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_host_ops core_host_ops = {
-	.map = core_host_map,
+static struct irq_domain_ops core_domain_ops = {
+	.map = core_domain_map,
 };
 
 void __init init_IRQ(void)
@@ -100,10 +100,11 @@ void __init init_IRQ(void)
 	np = of_find_compatible_node(NULL, NULL, "ti,c64x+core-pic");
 	if (np != NULL) {
 		/* create the core host */
-		core_host = irq_alloc_host(np, IRQ_HOST_MAP_PRIORITY, 0,
-					   &core_host_ops, 0);
-		if (core_host)
-			irq_set_default_host(core_host);
+		core_domain = irq_domain_add_legacy(np, NR_PRIORITY_IRQS,
+						    0, 0, &core_domain_ops,
+						    NULL);
+		if (core_domain)
+			irq_set_default_host(core_domain);
 		of_node_put(np);
 	}
 
@@ -128,601 +129,15 @@ int arch_show_interrupts(struct seq_file *p, int prec)
 	return 0;
 }
 
-/*
- * IRQ controller and virtual interrupts
- */
-
-/* The main irq map itself is an array of NR_IRQ entries containing the
- * associate host and irq number. An entry with a host of NULL is free.
- * An entry can be allocated if it's free, the allocator always then sets
- * hwirq first to the host's invalid irq number and then fills ops.
- */
-struct irq_map_entry {
-	irq_hw_number_t	hwirq;
-	struct irq_host	*host;
-};
-
-static LIST_HEAD(irq_hosts);
-static DEFINE_RAW_SPINLOCK(irq_big_lock);
-static DEFINE_MUTEX(revmap_trees_mutex);
-static struct irq_map_entry irq_map[NR_IRQS];
-static unsigned int irq_virq_count = NR_IRQS;
-static struct irq_host *irq_default_host;
-
 irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
 {
-	return irq_map[d->irq].hwirq;
+	return d->hwirq;
 }
 EXPORT_SYMBOL_GPL(irqd_to_hwirq);
 
 irq_hw_number_t virq_to_hw(unsigned int virq)
 {
-	return irq_map[virq].hwirq;
+	struct irq_data *irq_data = irq_get_irq_data(virq);
+	return WARN_ON(!irq_data) ? 0 : irq_data->hwirq;
 }
 EXPORT_SYMBOL_GPL(virq_to_hw);
-
-bool virq_is_host(unsigned int virq, struct irq_host *host)
-{
-	return irq_map[virq].host == host;
-}
-EXPORT_SYMBOL_GPL(virq_is_host);
-
-static int default_irq_host_match(struct irq_host *h, struct device_node *np)
-{
-	return h->of_node != NULL && h->of_node == np;
-}
-
-struct irq_host *irq_alloc_host(struct device_node *of_node,
-				unsigned int revmap_type,
-				unsigned int revmap_arg,
-				struct irq_host_ops *ops,
-				irq_hw_number_t inval_irq)
-{
-	struct irq_host *host;
-	unsigned int size = sizeof(struct irq_host);
-	unsigned int i;
-	unsigned int *rmap;
-	unsigned long flags;
-
-	/* Allocate structure and revmap table if using linear mapping */
-	if (revmap_type == IRQ_HOST_MAP_LINEAR)
-		size += revmap_arg * sizeof(unsigned int);
-	host = kzalloc(size, GFP_KERNEL);
-	if (host == NULL)
-		return NULL;
-
-	/* Fill structure */
-	host->revmap_type = revmap_type;
-	host->inval_irq = inval_irq;
-	host->ops = ops;
-	host->of_node = of_node_get(of_node);
-
-	if (host->ops->match == NULL)
-		host->ops->match = default_irq_host_match;
-
-	raw_spin_lock_irqsave(&irq_big_lock, flags);
-
-	/* Check for the priority controller. */
-	if (revmap_type == IRQ_HOST_MAP_PRIORITY) {
-		if (irq_map[0].host != NULL) {
-			raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-			of_node_put(host->of_node);
-			kfree(host);
-			return NULL;
-		}
-		irq_map[0].host = host;
-	}
-
-	list_add(&host->link, &irq_hosts);
-	raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-
-	/* Additional setups per revmap type */
-	switch (revmap_type) {
-	case IRQ_HOST_MAP_PRIORITY:
-		/* 0 is always the invalid number for priority */
-		host->inval_irq = 0;
-		/* setup us as the host for all priority interrupts */
-		for (i = 1; i < NR_PRIORITY_IRQS; i++) {
-			irq_map[i].hwirq = i;
-			smp_wmb();
-			irq_map[i].host = host;
-			smp_wmb();
-
-			ops->map(host, i, i);
-		}
-		break;
-	case IRQ_HOST_MAP_LINEAR:
-		rmap = (unsigned int *)(host + 1);
-		for (i = 0; i < revmap_arg; i++)
-			rmap[i] = NO_IRQ;
-		host->revmap_data.linear.size = revmap_arg;
-		smp_wmb();
-		host->revmap_data.linear.revmap = rmap;
-		break;
-	case IRQ_HOST_MAP_TREE:
-		INIT_RADIX_TREE(&host->revmap_data.tree, GFP_KERNEL);
-		break;
-	default:
-		break;
-	}
-
-	pr_debug("irq: Allocated host of type %d @0x%p\n", revmap_type, host);
-
-	return host;
-}
-
-struct irq_host *irq_find_host(struct device_node *node)
-{
-	struct irq_host *h, *found = NULL;
-	unsigned long flags;
-
-	/* We might want to match the legacy controller last since
-	 * it might potentially be set to match all interrupts in
-	 * the absence of a device node. This isn't a problem so far
-	 * yet though...
-	 */
-	raw_spin_lock_irqsave(&irq_big_lock, flags);
-	list_for_each_entry(h, &irq_hosts, link)
-		if (h->ops->match(h, node)) {
-			found = h;
-			break;
-		}
-	raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-	return found;
-}
-EXPORT_SYMBOL_GPL(irq_find_host);
-
-void irq_set_default_host(struct irq_host *host)
-{
-	pr_debug("irq: Default host set to @0x%p\n", host);
-
-	irq_default_host = host;
-}
-
-void irq_set_virq_count(unsigned int count)
-{
-	pr_debug("irq: Trying to set virq count to %d\n", count);
-
-	BUG_ON(count < NR_PRIORITY_IRQS);
-	if (count < NR_IRQS)
-		irq_virq_count = count;
-}
-
-static int irq_setup_virq(struct irq_host *host, unsigned int virq,
-			    irq_hw_number_t hwirq)
-{
-	int res;
-
-	res = irq_alloc_desc_at(virq, 0);
-	if (res != virq) {
-		pr_debug("irq: -> allocating desc failed\n");
-		goto error;
-	}
-
-	/* map it */
-	smp_wmb();
-	irq_map[virq].hwirq = hwirq;
-	smp_mb();
-
-	if (host->ops->map(host, virq, hwirq)) {
-		pr_debug("irq: -> mapping failed, freeing\n");
-		goto errdesc;
-	}
-
-	irq_clear_status_flags(virq, IRQ_NOREQUEST);
-
-	return 0;
-
-errdesc:
-	irq_free_descs(virq, 1);
-error:
-	irq_free_virt(virq, 1);
-	return -1;
-}
-
-unsigned int irq_create_direct_mapping(struct irq_host *host)
-{
-	unsigned int virq;
-
-	if (host == NULL)
-		host = irq_default_host;
-
-	BUG_ON(host == NULL);
-	WARN_ON(host->revmap_type != IRQ_HOST_MAP_NOMAP);
-
-	virq = irq_alloc_virt(host, 1, 0);
-	if (virq == NO_IRQ) {
-		pr_debug("irq: create_direct virq allocation failed\n");
-		return NO_IRQ;
-	}
-
-	pr_debug("irq: create_direct obtained virq %d\n", virq);
-
-	if (irq_setup_virq(host, virq, virq))
-		return NO_IRQ;
-
-	return virq;
-}
-
-unsigned int irq_create_mapping(struct irq_host *host,
-				irq_hw_number_t hwirq)
-{
-	unsigned int virq, hint;
-
-	pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", host, hwirq);
-
-	/* Look for default host if nececssary */
-	if (host == NULL)
-		host = irq_default_host;
-	if (host == NULL) {
-		printk(KERN_WARNING "irq_create_mapping called for"
-		       " NULL host, hwirq=%lx\n", hwirq);
-		WARN_ON(1);
-		return NO_IRQ;
-	}
-	pr_debug("irq: -> using host @%p\n", host);
-
-	/* Check if mapping already exists */
-	virq = irq_find_mapping(host, hwirq);
-	if (virq != NO_IRQ) {
-		pr_debug("irq: -> existing mapping on virq %d\n", virq);
-		return virq;
-	}
-
-	/* Allocate a virtual interrupt number */
-	hint = hwirq % irq_virq_count;
-	virq = irq_alloc_virt(host, 1, hint);
-	if (virq == NO_IRQ) {
-		pr_debug("irq: -> virq allocation failed\n");
-		return NO_IRQ;
-	}
-
-	if (irq_setup_virq(host, virq, hwirq))
-		return NO_IRQ;
-
-	pr_debug("irq: irq %lu on host %s mapped to virtual irq %u\n",
-		hwirq, host->of_node ? host->of_node->full_name : "null", virq);
-
-	return virq;
-}
-EXPORT_SYMBOL_GPL(irq_create_mapping);
-
-unsigned int irq_create_of_mapping(struct device_node *controller,
-				   const u32 *intspec, unsigned int intsize)
-{
-	struct irq_host *host;
-	irq_hw_number_t hwirq;
-	unsigned int type = IRQ_TYPE_NONE;
-	unsigned int virq;
-
-	if (controller == NULL)
-		host = irq_default_host;
-	else
-		host = irq_find_host(controller);
-	if (host == NULL) {
-		printk(KERN_WARNING "irq: no irq host found for %s !\n",
-		       controller->full_name);
-		return NO_IRQ;
-	}
-
-	/* If host has no translation, then we assume interrupt line */
-	if (host->ops->xlate == NULL)
-		hwirq = intspec[0];
-	else {
-		if (host->ops->xlate(host, controller, intspec, intsize,
-				     &hwirq, &type))
-			return NO_IRQ;
-	}
-
-	/* Create mapping */
-	virq = irq_create_mapping(host, hwirq);
-	if (virq == NO_IRQ)
-		return virq;
-
-	/* Set type if specified and different than the current one */
-	if (type != IRQ_TYPE_NONE &&
-	    type != (irqd_get_trigger_type(irq_get_irq_data(virq))))
-		irq_set_irq_type(virq, type);
-	return virq;
-}
-EXPORT_SYMBOL_GPL(irq_create_of_mapping);
-
-void irq_dispose_mapping(unsigned int virq)
-{
-	struct irq_host *host;
-	irq_hw_number_t hwirq;
-
-	if (virq == NO_IRQ)
-		return;
-
-	/* Never unmap priority interrupts */
-	if (virq < NR_PRIORITY_IRQS)
-		return;
-
-	host = irq_map[virq].host;
-	if (WARN_ON(host == NULL))
-		return;
-
-	irq_set_status_flags(virq, IRQ_NOREQUEST);
-
-	/* remove chip and handler */
-	irq_set_chip_and_handler(virq, NULL, NULL);
-
-	/* Make sure it's completed */
-	synchronize_irq(virq);
-
-	/* Tell the PIC about it */
-	if (host->ops->unmap)
-		host->ops->unmap(host, virq);
-	smp_mb();
-
-	/* Clear reverse map */
-	hwirq = irq_map[virq].hwirq;
-	switch (host->revmap_type) {
-	case IRQ_HOST_MAP_LINEAR:
-		if (hwirq < host->revmap_data.linear.size)
-			host->revmap_data.linear.revmap[hwirq] = NO_IRQ;
-		break;
-	case IRQ_HOST_MAP_TREE:
-		mutex_lock(&revmap_trees_mutex);
-		radix_tree_delete(&host->revmap_data.tree, hwirq);
-		mutex_unlock(&revmap_trees_mutex);
-		break;
-	}
-
-	/* Destroy map */
-	smp_mb();
-	irq_map[virq].hwirq = host->inval_irq;
-
-	irq_free_descs(virq, 1);
-	/* Free it */
-	irq_free_virt(virq, 1);
-}
-EXPORT_SYMBOL_GPL(irq_dispose_mapping);
-
-unsigned int irq_find_mapping(struct irq_host *host,
-			      irq_hw_number_t hwirq)
-{
-	unsigned int i;
-	unsigned int hint = hwirq % irq_virq_count;
-
-	/* Look for default host if nececssary */
-	if (host == NULL)
-		host = irq_default_host;
-	if (host == NULL)
-		return NO_IRQ;
-
-	/* Slow path does a linear search of the map */
-	i = hint;
-	do  {
-		if (irq_map[i].host == host &&
-		    irq_map[i].hwirq == hwirq)
-			return i;
-		i++;
-		if (i >= irq_virq_count)
-			i = 4;
-	} while (i != hint);
-	return NO_IRQ;
-}
-EXPORT_SYMBOL_GPL(irq_find_mapping);
-
-unsigned int irq_radix_revmap_lookup(struct irq_host *host,
-				     irq_hw_number_t hwirq)
-{
-	struct irq_map_entry *ptr;
-	unsigned int virq;
-
-	if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_TREE))
-		return irq_find_mapping(host, hwirq);
-
-	/*
-	 * The ptr returned references the static global irq_map.
-	 * but freeing an irq can delete nodes along the path to
-	 * do the lookup via call_rcu.
-	 */
-	rcu_read_lock();
-	ptr = radix_tree_lookup(&host->revmap_data.tree, hwirq);
-	rcu_read_unlock();
-
-	/*
-	 * If found in radix tree, then fine.
-	 * Else fallback to linear lookup - this should not happen in practice
-	 * as it means that we failed to insert the node in the radix tree.
-	 */
-	if (ptr)
-		virq = ptr - irq_map;
-	else
-		virq = irq_find_mapping(host, hwirq);
-
-	return virq;
-}
-
-void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
-			     irq_hw_number_t hwirq)
-{
-	if (WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE))
-		return;
-
-	if (virq != NO_IRQ) {
-		mutex_lock(&revmap_trees_mutex);
-		radix_tree_insert(&host->revmap_data.tree, hwirq,
-				  &irq_map[virq]);
-		mutex_unlock(&revmap_trees_mutex);
-	}
-}
-
-unsigned int irq_linear_revmap(struct irq_host *host,
-			       irq_hw_number_t hwirq)
-{
-	unsigned int *revmap;
-
-	if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_LINEAR))
-		return irq_find_mapping(host, hwirq);
-
-	/* Check revmap bounds */
-	if (unlikely(hwirq >= host->revmap_data.linear.size))
-		return irq_find_mapping(host, hwirq);
-
-	/* Check if revmap was allocated */
-	revmap = host->revmap_data.linear.revmap;
-	if (unlikely(revmap == NULL))
-		return irq_find_mapping(host, hwirq);
-
-	/* Fill up revmap with slow path if no mapping found */
-	if (unlikely(revmap[hwirq] == NO_IRQ))
-		revmap[hwirq] = irq_find_mapping(host, hwirq);
-
-	return revmap[hwirq];
-}
-
-unsigned int irq_alloc_virt(struct irq_host *host,
-			    unsigned int count,
-			    unsigned int hint)
-{
-	unsigned long flags;
-	unsigned int i, j, found = NO_IRQ;
-
-	if (count == 0 || count > (irq_virq_count - NR_PRIORITY_IRQS))
-		return NO_IRQ;
-
-	raw_spin_lock_irqsave(&irq_big_lock, flags);
-
-	/* Use hint for 1 interrupt if any */
-	if (count == 1 && hint >= NR_PRIORITY_IRQS &&
-	    hint < irq_virq_count && irq_map[hint].host == NULL) {
-		found = hint;
-		goto hint_found;
-	}
-
-	/* Look for count consecutive numbers in the allocatable
-	 * (non-legacy) space
-	 */
-	for (i = NR_PRIORITY_IRQS, j = 0; i < irq_virq_count; i++) {
-		if (irq_map[i].host != NULL)
-			j = 0;
-		else
-			j++;
-
-		if (j == count) {
-			found = i - count + 1;
-			break;
-		}
-	}
-	if (found == NO_IRQ) {
-		raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-		return NO_IRQ;
-	}
- hint_found:
-	for (i = found; i < (found + count); i++) {
-		irq_map[i].hwirq = host->inval_irq;
-		smp_wmb();
-		irq_map[i].host = host;
-	}
-	raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-	return found;
-}
-
-void irq_free_virt(unsigned int virq, unsigned int count)
-{
-	unsigned long flags;
-	unsigned int i;
-
-	WARN_ON(virq < NR_PRIORITY_IRQS);
-	WARN_ON(count == 0 || (virq + count) > irq_virq_count);
-
-	if (virq < NR_PRIORITY_IRQS) {
-		if (virq + count < NR_PRIORITY_IRQS)
-			return;
-		count  -= NR_PRIORITY_IRQS - virq;
-		virq = NR_PRIORITY_IRQS;
-	}
-
-	if (count > irq_virq_count || virq > irq_virq_count - count) {
-		if (virq > irq_virq_count)
-			return;
-		count = irq_virq_count - virq;
-	}
-
-	raw_spin_lock_irqsave(&irq_big_lock, flags);
-	for (i = virq; i < (virq + count); i++) {
-		struct irq_host *host;
-
-		host = irq_map[i].host;
-		irq_map[i].hwirq = host->inval_irq;
-		smp_wmb();
-		irq_map[i].host = NULL;
-	}
-	raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-}
-
-#ifdef CONFIG_VIRQ_DEBUG
-static int virq_debug_show(struct seq_file *m, void *private)
-{
-	unsigned long flags;
-	struct irq_desc *desc;
-	const char *p;
-	static const char none[] = "none";
-	void *data;
-	int i;
-
-	seq_printf(m, "%-5s  %-7s  %-15s  %-18s  %s\n", "virq", "hwirq",
-		      "chip name", "chip data", "host name");
-
-	for (i = 1; i < nr_irqs; i++) {
-		desc = irq_to_desc(i);
-		if (!desc)
-			continue;
-
-		raw_spin_lock_irqsave(&desc->lock, flags);
-
-		if (desc->action && desc->action->handler) {
-			struct irq_chip *chip;
-
-			seq_printf(m, "%5d  ", i);
-			seq_printf(m, "0x%05lx  ", irq_map[i].hwirq);
-
-			chip = irq_desc_get_chip(desc);
-			if (chip && chip->name)
-				p = chip->name;
-			else
-				p = none;
-			seq_printf(m, "%-15s  ", p);
-
-			data = irq_desc_get_chip_data(desc);
-			seq_printf(m, "0x%16p  ", data);
-
-			if (irq_map[i].host && irq_map[i].host->of_node)
-				p = irq_map[i].host->of_node->full_name;
-			else
-				p = none;
-			seq_printf(m, "%s\n", p);
-		}
-
-		raw_spin_unlock_irqrestore(&desc->lock, flags);
-	}
-
-	return 0;
-}
-
-static int virq_debug_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, virq_debug_show, inode->i_private);
-}
-
-static const struct file_operations virq_debug_fops = {
-	.open = virq_debug_open,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-};
-
-static int __init irq_debugfs_init(void)
-{
-	if (debugfs_create_file("virq_mapping", S_IRUGO, powerpc_debugfs_root,
-				 NULL, &virq_debug_fops) == NULL)
-		return -ENOMEM;
-
-	return 0;
-}
-device_initcall(irq_debugfs_init);
-#endif /* CONFIG_VIRQ_DEBUG */
diff --git a/arch/c6x/platforms/megamod-pic.c b/arch/c6x/platforms/megamod-pic.c
index 7c37a94..61f5863 100644
--- a/arch/c6x/platforms/megamod-pic.c
+++ b/arch/c6x/platforms/megamod-pic.c
@@ -48,7 +48,7 @@ struct megamod_regs {
 };
 
 struct megamod_pic {
-	struct irq_host	*irqhost;
+	struct irq_domain *irqhost;
 	struct megamod_regs __iomem *regs;
 	raw_spinlock_t lock;
 
@@ -116,7 +116,7 @@ static void megamod_irq_cascade(unsigned int irq, struct irq_desc *desc)
 	}
 }
 
-static int megamod_map(struct irq_host *h, unsigned int virq,
+static int megamod_map(struct irq_domain *h, unsigned int virq,
 		       irq_hw_number_t hw)
 {
 	struct megamod_pic *pic = h->host_data;
@@ -136,7 +136,7 @@ static int megamod_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int megamod_xlate(struct irq_host *h, struct device_node *ct,
+static int megamod_xlate(struct irq_domain *h, struct device_node *ct,
 			 const u32 *intspec, unsigned int intsize,
 			 irq_hw_number_t *out_hwirq, unsigned int *out_type)
 
@@ -148,7 +148,7 @@ static int megamod_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops megamod_host_ops = {
+static struct irq_domain_ops megamod_domain_ops = {
 	.map	= megamod_map,
 	.xlate	= megamod_xlate,
 };
@@ -223,9 +223,8 @@ static struct megamod_pic * __init init_megamod_pic(struct device_node *np)
 		return NULL;
 	}
 
-	pic->irqhost = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
-				      NR_COMBINERS * 32, &megamod_host_ops,
-				      IRQ_UNMAPPED);
+	pic->irqhost = irq_domain_add_linear(np, NR_COMBINERS * 32,
+					     &megamod_domain_ops, pic);
 	if (!pic->irqhost) {
 		pr_err("%s: Could not alloc host.\n", np->full_name);
 		goto error_free;
-- 
1.7.5.4


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

* [PATCH v3 18/25] irq_domain/c6x: constify irq_domain structures
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (16 preceding siblings ...)
  2012-01-27 21:36 ` [PATCH v3 17/25] irq_domain/c6x: Convert c6x to use generic irq_domain support Grant Likely
@ 2012-01-27 21:36 ` Grant Likely
  2012-01-27 21:36 ` [PATCH v3 19/25] irq_domain/c6x: Use library of xlate functions Grant Likely
                   ` (9 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely,
	Mark Salter

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Mark Salter <msalter@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
 arch/arm/common/gic.c            |    2 +-
 arch/c6x/kernel/irq.c            |    2 +-
 arch/c6x/platforms/megamod-pic.c |    2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 5d91eb9..8cf934c 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -638,7 +638,7 @@ static int gic_irq_domain_xlate(struct irq_domain *d,
 	return 0;
 }
 
-struct irq_domain_ops gic_irq_domain_ops = {
+const struct irq_domain_ops gic_irq_domain_ops = {
 	.map = gic_irq_domain_map,
 	.xlate = gic_irq_domain_xlate,
 };
diff --git a/arch/c6x/kernel/irq.c b/arch/c6x/kernel/irq.c
index 3d5ac60..c6b36e8 100644
--- a/arch/c6x/kernel/irq.c
+++ b/arch/c6x/kernel/irq.c
@@ -86,7 +86,7 @@ static int core_domain_map(struct irq_domain *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_domain_ops core_domain_ops = {
+static const struct irq_domain_ops core_domain_ops = {
 	.map = core_domain_map,
 };
 
diff --git a/arch/c6x/platforms/megamod-pic.c b/arch/c6x/platforms/megamod-pic.c
index 61f5863..9f35fbf 100644
--- a/arch/c6x/platforms/megamod-pic.c
+++ b/arch/c6x/platforms/megamod-pic.c
@@ -148,7 +148,7 @@ static int megamod_xlate(struct irq_domain *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_domain_ops megamod_domain_ops = {
+static const struct irq_domain_ops megamod_domain_ops = {
 	.map	= megamod_map,
 	.xlate	= megamod_xlate,
 };
-- 
1.7.5.4


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

* [PATCH v3 19/25] irq_domain/c6x: Use library of xlate functions
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (17 preceding siblings ...)
  2012-01-27 21:36 ` [PATCH v3 18/25] irq_domain/c6x: constify irq_domain structures Grant Likely
@ 2012-01-27 21:36 ` Grant Likely
  2012-01-27 21:36 ` [PATCH v3 20/25] irq_domain/powerpc: constify irq_domain_ops Grant Likely
                   ` (8 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely,
	Mark Salter

The c6x irq controllers don't need to define custom .xlate hooks

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Mark Salter <msalter@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
 arch/c6x/kernel/irq.c            |    1 +
 arch/c6x/platforms/megamod-pic.c |   14 +-------------
 2 files changed, 2 insertions(+), 13 deletions(-)

diff --git a/arch/c6x/kernel/irq.c b/arch/c6x/kernel/irq.c
index c6b36e8..d77bcfd 100644
--- a/arch/c6x/kernel/irq.c
+++ b/arch/c6x/kernel/irq.c
@@ -88,6 +88,7 @@ static int core_domain_map(struct irq_domain *h, unsigned int virq,
 
 static const struct irq_domain_ops core_domain_ops = {
 	.map = core_domain_map,
+	.xlate = irq_domain_xlate_onecell,
 };
 
 void __init init_IRQ(void)
diff --git a/arch/c6x/platforms/megamod-pic.c b/arch/c6x/platforms/megamod-pic.c
index 9f35fbf..c1c4e2a 100644
--- a/arch/c6x/platforms/megamod-pic.c
+++ b/arch/c6x/platforms/megamod-pic.c
@@ -136,21 +136,9 @@ static int megamod_map(struct irq_domain *h, unsigned int virq,
 	return 0;
 }
 
-static int megamod_xlate(struct irq_domain *h, struct device_node *ct,
-			 const u32 *intspec, unsigned int intsize,
-			 irq_hw_number_t *out_hwirq, unsigned int *out_type)
-
-{
-	/* megamod intspecs must have 1 cell */
-	BUG_ON(intsize != 1);
-	*out_hwirq = intspec[0];
-	*out_type = IRQ_TYPE_NONE;
-	return 0;
-}
-
 static const struct irq_domain_ops megamod_domain_ops = {
 	.map	= megamod_map,
-	.xlate	= megamod_xlate,
+	.xlate	= irq_domain_xlate_onecell,
 };
 
 static void __init set_megamod_mux(struct megamod_pic *pic, int src, int output)
-- 
1.7.5.4


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

* [PATCH v3 20/25] irq_domain/powerpc: constify irq_domain_ops
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (18 preceding siblings ...)
  2012-01-27 21:36 ` [PATCH v3 19/25] irq_domain/c6x: Use library of xlate functions Grant Likely
@ 2012-01-27 21:36 ` Grant Likely
  2012-01-27 21:36 ` [PATCH v3 21/25] irqdomain/powerpc: Replace custom xlate functions with library functions Grant Likely
                   ` (7 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely

Make all the irq_domain_ops structures in powerpc 'static const'

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/platforms/512x/mpc5121_ads_cpld.c   |    2 +-
 arch/powerpc/platforms/52xx/media5200.c          |    2 +-
 arch/powerpc/platforms/52xx/mpc52xx_gpt.c        |    2 +-
 arch/powerpc/platforms/52xx/mpc52xx_pic.c        |    2 +-
 arch/powerpc/platforms/82xx/pq2ads-pci-pic.c     |    2 +-
 arch/powerpc/platforms/85xx/socrates_fpga_pic.c  |    2 +-
 arch/powerpc/platforms/86xx/gef_pic.c            |    2 +-
 arch/powerpc/platforms/cell/axon_msi.c           |    2 +-
 arch/powerpc/platforms/cell/beat_interrupt.c     |    2 +-
 arch/powerpc/platforms/cell/interrupt.c          |    2 +-
 arch/powerpc/platforms/cell/spider-pic.c         |    2 +-
 arch/powerpc/platforms/embedded6xx/flipper-pic.c |    2 +-
 arch/powerpc/platforms/embedded6xx/hlwd-pic.c    |    2 +-
 arch/powerpc/platforms/iseries/irq.c             |    2 +-
 arch/powerpc/platforms/powermac/pic.c            |    2 +-
 arch/powerpc/platforms/powermac/smp.c            |    2 +-
 arch/powerpc/platforms/ps3/interrupt.c           |    2 +-
 arch/powerpc/platforms/wsp/opb_pic.c             |    2 +-
 arch/powerpc/sysdev/cpm1.c                       |    2 +-
 arch/powerpc/sysdev/cpm2_pic.c                   |    2 +-
 arch/powerpc/sysdev/ehv_pic.c                    |    2 +-
 arch/powerpc/sysdev/fsl_msi.c                    |    2 +-
 22 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
index 291d61c..ca3a062 100644
--- a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
+++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
@@ -137,7 +137,7 @@ cpld_pic_host_map(struct irq_domain *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_domain_ops cpld_pic_host_ops = {
+static const struct irq_domain_ops cpld_pic_host_ops = {
 	.match = cpld_pic_host_match,
 	.map = cpld_pic_host_map,
 };
diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c
index 5db5cfb..17d91b7 100644
--- a/arch/powerpc/platforms/52xx/media5200.c
+++ b/arch/powerpc/platforms/52xx/media5200.c
@@ -136,7 +136,7 @@ static int media5200_irq_xlate(struct irq_domain *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_domain_ops media5200_irq_ops = {
+static const struct irq_domain_ops media5200_irq_ops = {
 	.map = media5200_irq_map,
 	.xlate = media5200_irq_xlate,
 };
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index b53275d..028470b 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -236,7 +236,7 @@ static int mpc52xx_gpt_irq_xlate(struct irq_domain *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_domain_ops mpc52xx_gpt_irq_ops = {
+static const struct irq_domain_ops mpc52xx_gpt_irq_ops = {
 	.map = mpc52xx_gpt_irq_map,
 	.xlate = mpc52xx_gpt_irq_xlate,
 };
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 41fa671..8520b58 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -384,7 +384,7 @@ static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_domain_ops mpc52xx_irqhost_ops = {
+static const struct irq_domain_ops mpc52xx_irqhost_ops = {
 	.xlate = mpc52xx_irqhost_xlate,
 	.map = mpc52xx_irqhost_map,
 };
diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
index 4ef9d69..328d221 100644
--- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
+++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
@@ -112,7 +112,7 @@ static int pci_pic_host_map(struct irq_domain *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_domain_ops pci_pic_host_ops = {
+static const struct irq_domain_ops pci_pic_host_ops = {
 	.map = pci_pic_host_map,
 };
 
diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
index 1092c12..3bbbf74 100644
--- a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
+++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
@@ -269,7 +269,7 @@ static int socrates_fpga_pic_host_xlate(struct irq_domain *h,
 	return 0;
 }
 
-static struct irq_domain_ops socrates_fpga_pic_host_ops = {
+static const struct irq_domain_ops socrates_fpga_pic_host_ops = {
 	.map    = socrates_fpga_pic_host_map,
 	.xlate  = socrates_fpga_pic_host_xlate,
 };
diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c
index 126a94b..af3fd69 100644
--- a/arch/powerpc/platforms/86xx/gef_pic.c
+++ b/arch/powerpc/platforms/86xx/gef_pic.c
@@ -177,7 +177,7 @@ static int gef_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_domain_ops gef_pic_host_ops = {
+static const struct irq_domain_ops gef_pic_host_ops = {
 	.map	= gef_pic_host_map,
 	.xlate	= gef_pic_host_xlate,
 };
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index cf9fd3c..db360fc 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -327,7 +327,7 @@ static int msic_host_map(struct irq_domain *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_domain_ops msic_host_ops = {
+static const struct irq_domain_ops msic_host_ops = {
 	.map	= msic_host_map,
 };
 
diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c
index bbdf574..e5c3a2c 100644
--- a/arch/powerpc/platforms/cell/beat_interrupt.c
+++ b/arch/powerpc/platforms/cell/beat_interrupt.c
@@ -172,7 +172,7 @@ static int beatic_pic_host_match(struct irq_domain *h, struct device_node *np)
 	return 1;
 }
 
-static struct irq_domain_ops beatic_pic_host_ops = {
+static const struct irq_domain_ops beatic_pic_host_ops = {
 	.map = beatic_pic_host_map,
 	.unmap = beatic_pic_host_unmap,
 	.xlate = beatic_pic_host_xlate,
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index c844797..2d42f3b 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -285,7 +285,7 @@ static int iic_host_xlate(struct irq_domain *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_domain_ops iic_host_ops = {
+static const struct irq_domain_ops iic_host_ops = {
 	.match = iic_host_match,
 	.map = iic_host_map,
 	.xlate = iic_host_xlate,
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 6521d20..d8b7cc8 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -194,7 +194,7 @@ static int spider_host_xlate(struct irq_domain *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_domain_ops spider_host_ops = {
+static const struct irq_domain_ops spider_host_ops = {
 	.map = spider_host_map,
 	.xlate = spider_host_xlate,
 };
diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
index 4345971..675335a 100644
--- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
@@ -113,7 +113,7 @@ static int flipper_pic_match(struct irq_domain *h, struct device_node *np)
 }
 
 
-static struct irq_domain_ops flipper_irq_domain_ops = {
+static const struct irq_domain_ops flipper_irq_domain_ops = {
 	.map = flipper_pic_map,
 	.match = flipper_pic_match,
 };
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
index 499d410..da6ca02 100644
--- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
@@ -100,7 +100,7 @@ static int hlwd_pic_map(struct irq_domain *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_domain_ops hlwd_irq_domain_ops = {
+static const struct irq_domain_ops hlwd_irq_domain_ops = {
 	.map = hlwd_pic_map,
 };
 
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index 5538b59..05ce516 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -356,7 +356,7 @@ static int iseries_irq_host_match(struct irq_domain *h, struct device_node *np)
 	return 1;
 }
 
-static struct irq_domain_ops iseries_irq_domain_ops = {
+static const struct irq_domain_ops iseries_irq_domain_ops = {
 	.map = iseries_irq_host_map,
 	.match = iseries_irq_host_match,
 };
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 646fdf3..46a5f32 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -299,7 +299,7 @@ static int pmac_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_domain_ops pmac_pic_host_ops = {
+static const struct irq_domain_ops pmac_pic_host_ops = {
 	.match = pmac_pic_host_match,
 	.map = pmac_pic_host_map,
 	.xlate = pmac_pic_host_xlate,
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 09afd70..a81e5a8 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -184,7 +184,7 @@ static int psurge_host_map(struct irq_domain *h, unsigned int virq,
 	return 0;
 }
 
-struct irq_domain_ops psurge_host_ops = {
+static const struct irq_domain_ops psurge_host_ops = {
 	.map	= psurge_host_map,
 };
 
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index c05808f..2a4ff86 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -684,7 +684,7 @@ static int ps3_host_match(struct irq_domain *h, struct device_node *np)
 	return 1;
 }
 
-static struct irq_domain_ops ps3_host_ops = {
+static const struct irq_domain_ops ps3_host_ops = {
 	.map = ps3_host_map,
 	.match = ps3_host_match,
 };
diff --git a/arch/powerpc/platforms/wsp/opb_pic.c b/arch/powerpc/platforms/wsp/opb_pic.c
index 4837515..0c6fe0b 100644
--- a/arch/powerpc/platforms/wsp/opb_pic.c
+++ b/arch/powerpc/platforms/wsp/opb_pic.c
@@ -207,7 +207,7 @@ static int opb_host_xlate(struct irq_domain *host, struct device_node *dn,
 	return 0;
 }
 
-static struct irq_domain_ops opb_host_ops = {
+static const struct irq_domain_ops opb_host_ops = {
 	.map = opb_host_map,
 	.xlate = opb_host_xlate,
 };
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
index 53f39db..d4fa03f 100644
--- a/arch/powerpc/sysdev/cpm1.c
+++ b/arch/powerpc/sysdev/cpm1.c
@@ -123,7 +123,7 @@ static struct irqaction cpm_error_irqaction = {
 	.name = "error",
 };
 
-static struct irq_domain_ops cpm_pic_host_ops = {
+static const struct irq_domain_ops cpm_pic_host_ops = {
 	.map = cpm_pic_host_map,
 };
 
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
index b364332..8c9fc9c 100644
--- a/arch/powerpc/sysdev/cpm2_pic.c
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -236,7 +236,7 @@ static int cpm2_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_domain_ops cpm2_pic_host_ops = {
+static const struct irq_domain_ops cpm2_pic_host_ops = {
 	.map = cpm2_pic_host_map,
 	.xlate = cpm2_pic_host_xlate,
 };
diff --git a/arch/powerpc/sysdev/ehv_pic.c b/arch/powerpc/sysdev/ehv_pic.c
index adea322..6e0e100 100644
--- a/arch/powerpc/sysdev/ehv_pic.c
+++ b/arch/powerpc/sysdev/ehv_pic.c
@@ -248,7 +248,7 @@ static int ehv_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_domain_ops ehv_pic_host_ops = {
+static const struct irq_domain_ops ehv_pic_host_ops = {
 	.match = ehv_pic_host_match,
 	.map = ehv_pic_host_map,
 	.xlate = ehv_pic_host_xlate,
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index f4fd95b..0c01deb 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -74,7 +74,7 @@ static int fsl_msi_host_map(struct irq_domain *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_domain_ops fsl_msi_host_ops = {
+static const struct irq_domain_ops fsl_msi_host_ops = {
 	.map = fsl_msi_host_map,
 };
 
-- 
1.7.5.4


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

* [PATCH v3 21/25] irqdomain/powerpc: Replace custom xlate functions with library functions
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (19 preceding siblings ...)
  2012-01-27 21:36 ` [PATCH v3 20/25] irq_domain/powerpc: constify irq_domain_ops Grant Likely
@ 2012-01-27 21:36 ` Grant Likely
  2012-02-06  5:22   ` Michael Neuling
  2012-01-27 21:36 ` [PATCH v3 22/25] irq_domain/x86: Convert x86 (embedded) to use common irq_domain Grant Likely
                   ` (6 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely

This patch converts a number of the powerpc drivers to use the common library
of irq_domain xlate functions, dropping a bunch of lines in the process.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/platforms/powermac/pic.c |   13 +------------
 arch/powerpc/platforms/wsp/opb_pic.c  |   13 +------------
 arch/powerpc/sysdev/cpm2_pic.c        |   14 +-------------
 arch/powerpc/sysdev/ipic.c            |   18 +-----------------
 arch/powerpc/sysdev/qe_lib/qe_ic.c    |   15 +--------------
 arch/powerpc/sysdev/tsi108_pci.c      |   11 +----------
 arch/powerpc/sysdev/uic.c             |   14 +-------------
 drivers/gpio/gpio-mpc8xxx.c           |   17 +----------------
 8 files changed, 8 insertions(+), 107 deletions(-)

diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 46a5f32..3af29d1 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -288,21 +288,10 @@ static int pmac_pic_host_map(struct irq_domain *h, unsigned int virq,
 	return 0;
 }
 
-static int pmac_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
-			       const u32 *intspec, unsigned int intsize,
-			       irq_hw_number_t *out_hwirq,
-			       unsigned int *out_flags)
-
-{
-	*out_flags = IRQ_TYPE_NONE;
-	*out_hwirq = *intspec;
-	return 0;
-}
-
 static const struct irq_domain_ops pmac_pic_host_ops = {
 	.match = pmac_pic_host_match,
 	.map = pmac_pic_host_map,
-	.xlate = pmac_pic_host_xlate,
+	.xlate = irq_domain_xlate_onecell;
 };
 
 static void __init pmac_pic_probe_oldstyle(void)
diff --git a/arch/powerpc/platforms/wsp/opb_pic.c b/arch/powerpc/platforms/wsp/opb_pic.c
index 0c6fe0b..cb565bf 100644
--- a/arch/powerpc/platforms/wsp/opb_pic.c
+++ b/arch/powerpc/platforms/wsp/opb_pic.c
@@ -196,20 +196,9 @@ static int opb_host_map(struct irq_domain *host, unsigned int virq,
 	return 0;
 }
 
-static int opb_host_xlate(struct irq_domain *host, struct device_node *dn,
-		const u32 *intspec, unsigned int intsize,
-		irq_hw_number_t *out_hwirq, unsigned int *out_type)
-{
-	/* Interrupt size must == 2 */
-	BUG_ON(intsize != 2);
-	*out_hwirq = intspec[0];
-	*out_type = intspec[1];
-	return 0;
-}
-
 static const struct irq_domain_ops opb_host_ops = {
 	.map = opb_host_map,
-	.xlate = opb_host_xlate,
+	.xlate = irq_domain_xlate_twocell,
 };
 
 irqreturn_t opb_irq_handler(int irq, void *private)
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
index 8c9fc9c..d3be961 100644
--- a/arch/powerpc/sysdev/cpm2_pic.c
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -224,21 +224,9 @@ static int cpm2_pic_host_map(struct irq_domain *h, unsigned int virq,
 	return 0;
 }
 
-static int cpm2_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
-			    const u32 *intspec, unsigned int intsize,
-			    irq_hw_number_t *out_hwirq, unsigned int *out_flags)
-{
-	*out_hwirq = intspec[0];
-	if (intsize > 1)
-		*out_flags = intspec[1];
-	else
-		*out_flags = IRQ_TYPE_NONE;
-	return 0;
-}
-
 static const struct irq_domain_ops cpm2_pic_host_ops = {
 	.map = cpm2_pic_host_map,
-	.xlate = cpm2_pic_host_xlate,
+	.xlate = irq_domain_xlate_onetwocell,
 };
 
 void cpm2_pic_init(struct device_node *node)
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 0eaaa01..b50f978 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -692,26 +692,10 @@ static int ipic_host_map(struct irq_domain *h, unsigned int virq,
 	return 0;
 }
 
-static int ipic_host_xlate(struct irq_domain *h, struct device_node *ct,
-			   const u32 *intspec, unsigned int intsize,
-			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
-
-{
-	/* interrupt sense values coming from the device tree equal either
-	 * LEVEL_LOW (low assertion) or EDGE_FALLING (high-to-low change)
-	 */
-	*out_hwirq = intspec[0];
-	if (intsize > 1)
-		*out_flags = intspec[1];
-	else
-		*out_flags = IRQ_TYPE_NONE;
-	return 0;
-}
-
 static struct irq_domain_ops ipic_host_ops = {
 	.match	= ipic_host_match,
 	.map	= ipic_host_map,
-	.xlate	= ipic_host_xlate,
+	.xlate	= irq_domain_xlate_onetwocell,
 };
 
 struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index e9b3d5c..2fba6ef 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -272,23 +272,10 @@ static int qe_ic_host_map(struct irq_domain *h, unsigned int virq,
 	return 0;
 }
 
-static int qe_ic_host_xlate(struct irq_domain *h, struct device_node *ct,
-			    const u32 * intspec, unsigned int intsize,
-			    irq_hw_number_t * out_hwirq,
-			    unsigned int *out_flags)
-{
-	*out_hwirq = intspec[0];
-	if (intsize > 1)
-		*out_flags = intspec[1];
-	else
-		*out_flags = IRQ_TYPE_NONE;
-	return 0;
-}
-
 static struct irq_domain_ops qe_ic_host_ops = {
 	.match = qe_ic_host_match,
 	.map = qe_ic_host_map,
-	.xlate = qe_ic_host_xlate,
+	.xlate = irq_domain_xlate_onetwocell,
 };
 
 /* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 188012c..470c1ef 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -376,15 +376,6 @@ static struct irq_chip tsi108_pci_irq = {
 	.irq_unmask = tsi108_pci_irq_unmask,
 };
 
-static int pci_irq_host_xlate(struct irq_domain *h, struct device_node *ct,
-			    const u32 *intspec, unsigned int intsize,
-			    irq_hw_number_t *out_hwirq, unsigned int *out_flags)
-{
-	*out_hwirq = intspec[0];
-	*out_flags = IRQ_TYPE_LEVEL_HIGH;
-	return 0;
-}
-
 static int pci_irq_host_map(struct irq_domain *h, unsigned int virq,
 			  irq_hw_number_t hw)
 {	unsigned int irq;
@@ -399,7 +390,7 @@ static int pci_irq_host_map(struct irq_domain *h, unsigned int virq,
 
 static struct irq_domain_ops pci_irq_domain_ops = {
 	.map = pci_irq_host_map,
-	.xlate = pci_irq_host_xlate,
+	.xlate = irq_domain_xlate_pci,
 };
 
 /*
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
index 84e59c9..9203393 100644
--- a/arch/powerpc/sysdev/uic.c
+++ b/arch/powerpc/sysdev/uic.c
@@ -190,21 +190,9 @@ static int uic_host_map(struct irq_domain *h, unsigned int virq,
 	return 0;
 }
 
-static int uic_host_xlate(struct irq_domain *h, struct device_node *ct,
-			  const u32 *intspec, unsigned int intsize,
-			  irq_hw_number_t *out_hwirq, unsigned int *out_type)
-
-{
-	/* UIC intspecs must have 2 cells */
-	BUG_ON(intsize != 2);
-	*out_hwirq = intspec[0];
-	*out_type = intspec[1];
-	return 0;
-}
-
 static struct irq_domain_ops uic_host_ops = {
 	.map	= uic_host_map,
-	.xlate	= uic_host_xlate,
+	.xlate	= irq_domain_xlate_twocell,
 };
 
 void uic_irq_cascade(unsigned int virq, struct irq_desc *desc)
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
index 149d987..e6568c1 100644
--- a/drivers/gpio/gpio-mpc8xxx.c
+++ b/drivers/gpio/gpio-mpc8xxx.c
@@ -296,24 +296,9 @@ static int mpc8xxx_gpio_irq_map(struct irq_domain *h, unsigned int virq,
 	return 0;
 }
 
-static int mpc8xxx_gpio_irq_xlate(struct irq_domain *h, struct device_node *ct,
-				  const u32 *intspec, unsigned int intsize,
-				  irq_hw_number_t *out_hwirq,
-				  unsigned int *out_flags)
-
-{
-	/* interrupt sense values coming from the device tree equal either
-	 * EDGE_FALLING or EDGE_BOTH
-	 */
-	*out_hwirq = intspec[0];
-	*out_flags = intspec[1];
-
-	return 0;
-}
-
 static struct irq_domain_ops mpc8xxx_gpio_irq_ops = {
 	.map	= mpc8xxx_gpio_irq_map,
-	.xlate	= mpc8xxx_gpio_irq_xlate,
+	.xlate	= irq_domain_xlate_twocell,
 };
 
 static struct of_device_id mpc8xxx_gpio_ids[] __initdata = {
-- 
1.7.5.4


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

* [PATCH v3 22/25] irq_domain/x86: Convert x86 (embedded) to use common irq_domain
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (20 preceding siblings ...)
  2012-01-27 21:36 ` [PATCH v3 21/25] irqdomain/powerpc: Replace custom xlate functions with library functions Grant Likely
@ 2012-01-27 21:36 ` Grant Likely
  2012-01-28 16:44   ` Sebastian Andrzej Siewior
  2012-01-27 21:36 ` [PATCH v3 23/25] irq_domain: Include hwirq number in /proc/interrupts Grant Likely
                   ` (5 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely,
	Sebastian Andrzej Siewior

This patch removes the x86-specific definition of irq_domain and replaces
it with the common implementation.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/Kconfig                      |    2 +
 arch/x86/include/asm/irq_controller.h |   12 ----
 arch/x86/include/asm/prom.h           |   10 ---
 arch/x86/kernel/devicetree.c          |  101 ++++++++++-----------------------
 drivers/net/phy/mdio-gpio.c           |    4 +-
 5 files changed, 34 insertions(+), 95 deletions(-)
 delete mode 100644 arch/x86/include/asm/irq_controller.h

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 864cc6e..5c44039 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -399,6 +399,7 @@ config X86_INTEL_CE
 	select X86_REBOOTFIXUPS
 	select OF
 	select OF_EARLY_FLATTREE
+	select IRQ_DOMAIN
 	---help---
 	  Select for the Intel CE media processor (CE4100) SOC.
 	  This option compiles in support for the CE4100 SOC for settop
@@ -2077,6 +2078,7 @@ config OLPC
 	select GPIOLIB
 	select OF
 	select OF_PROMTREE
+	select IRQ_DOMAIN
 	---help---
 	  Add support for detecting the unique features of the OLPC
 	  XO hardware.
diff --git a/arch/x86/include/asm/irq_controller.h b/arch/x86/include/asm/irq_controller.h
deleted file mode 100644
index 423bbbd..0000000
--- a/arch/x86/include/asm/irq_controller.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef __IRQ_CONTROLLER__
-#define __IRQ_CONTROLLER__
-
-struct irq_domain {
-	int (*xlate)(struct irq_domain *h, const u32 *intspec, u32 intsize,
-			u32 *out_hwirq, u32 *out_type);
-	void *priv;
-	struct device_node *controller;
-	struct list_head l;
-};
-
-#endif
diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
index 644dd885..60bef66 100644
--- a/arch/x86/include/asm/prom.h
+++ b/arch/x86/include/asm/prom.h
@@ -21,7 +21,6 @@
 #include <asm/irq.h>
 #include <linux/atomic.h>
 #include <asm/setup.h>
-#include <asm/irq_controller.h>
 
 #ifdef CONFIG_OF
 extern int of_ioapic;
@@ -43,15 +42,6 @@ extern char cmd_line[COMMAND_LINE_SIZE];
 #define pci_address_to_pio pci_address_to_pio
 unsigned long pci_address_to_pio(phys_addr_t addr);
 
-/**
- * irq_dispose_mapping - Unmap an interrupt
- * @virq: linux virq number of the interrupt to unmap
- *
- * FIXME: We really should implement proper virq handling like power,
- * but that's going to be major surgery.
- */
-static inline void irq_dispose_mapping(unsigned int virq) { }
-
 #define HAVE_ARCH_DEVTREE_FIXUPS
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index 5282179..3ae2ced 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -4,6 +4,7 @@
 #include <linux/bootmem.h>
 #include <linux/export.h>
 #include <linux/io.h>
+#include <linux/irqdomain.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/of.h>
@@ -17,64 +18,14 @@
 #include <linux/initrd.h>
 
 #include <asm/hpet.h>
-#include <asm/irq_controller.h>
 #include <asm/apic.h>
 #include <asm/pci_x86.h>
 
 __initdata u64 initial_dtb;
 char __initdata cmd_line[COMMAND_LINE_SIZE];
-static LIST_HEAD(irq_domains);
-static DEFINE_RAW_SPINLOCK(big_irq_lock);
 
 int __initdata of_ioapic;
 
-#ifdef CONFIG_X86_IO_APIC
-static void add_interrupt_host(struct irq_domain *ih)
-{
-	unsigned long flags;
-
-	raw_spin_lock_irqsave(&big_irq_lock, flags);
-	list_add(&ih->l, &irq_domains);
-	raw_spin_unlock_irqrestore(&big_irq_lock, flags);
-}
-#endif
-
-static struct irq_domain *get_ih_from_node(struct device_node *controller)
-{
-	struct irq_domain *ih, *found = NULL;
-	unsigned long flags;
-
-	raw_spin_lock_irqsave(&big_irq_lock, flags);
-	list_for_each_entry(ih, &irq_domains, l) {
-		if (ih->controller ==  controller) {
-			found = ih;
-			break;
-		}
-	}
-	raw_spin_unlock_irqrestore(&big_irq_lock, flags);
-	return found;
-}
-
-unsigned int irq_create_of_mapping(struct device_node *controller,
-				   const u32 *intspec, unsigned int intsize)
-{
-	struct irq_domain *ih;
-	u32 virq, type;
-	int ret;
-
-	ih = get_ih_from_node(controller);
-	if (!ih)
-		return 0;
-	ret = ih->xlate(ih, intspec, intsize, &virq, &type);
-	if (ret)
-		return 0;
-	if (type == IRQ_TYPE_NONE)
-		return virq;
-	irq_set_irq_type(virq, type);
-	return virq;
-}
-EXPORT_SYMBOL_GPL(irq_create_of_mapping);
-
 unsigned long pci_address_to_pio(phys_addr_t address)
 {
 	/*
@@ -354,36 +305,43 @@ static struct of_ioapic_type of_ioapic_type[] =
 	},
 };
 
-static int ioapic_xlate(struct irq_domain *id, const u32 *intspec, u32 intsize,
-			u32 *out_hwirq, u32 *out_type)
+static int ioapic_xlate(struct irq_domain *domain,
+			struct device_node *controller,
+			const u32 *intspec, u32 intsize,
+			irq_hw_number_t *out_hwirq, u32 *out_type)
 {
-	struct mp_ioapic_gsi *gsi_cfg;
 	struct io_apic_irq_attr attr;
 	struct of_ioapic_type *it;
-	u32 line, idx, type;
+	u32 line, idx;
+	int rc;
 
-	if (intsize < 2)
+	if (WARN_ON(intsize < 2))
 		return -EINVAL;
 
-	line = *intspec;
-	idx = (u32) id->priv;
-	gsi_cfg = mp_ioapic_gsi_routing(idx);
-	*out_hwirq = line + gsi_cfg->gsi_base;
-
-	intspec++;
-	type = *intspec;
+	line = intspec[0];
 
-	if (type >= ARRAY_SIZE(of_ioapic_type))
+	if (intspec[1] >= ARRAY_SIZE(of_ioapic_type))
 		return -EINVAL;
 
-	it = of_ioapic_type + type;
-	*out_type = it->out_type;
+	it = &of_ioapic_type[intspec[1]];
 
+	idx = (u32) domain->host_data;
 	set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity);
 
-	return io_apic_setup_irq_pin_once(*out_hwirq, cpu_to_node(0), &attr);
+	rc = io_apic_setup_irq_pin_once(irq_find_mapping(domain, line),
+					cpu_to_node(0), &attr);
+	if (rc)
+		return rc;
+
+	*out_hwirq = line;
+	*out_type = it->out_type;
+	return 0;
 }
 
+const struct irq_domain_ops ioapic_irq_domain_ops = {
+	.xlate = ioapic_xlate,
+};
+
 static void __init ioapic_add_ofnode(struct device_node *np)
 {
 	struct resource r;
@@ -399,13 +357,14 @@ static void __init ioapic_add_ofnode(struct device_node *np)
 	for (i = 0; i < nr_ioapics; i++) {
 		if (r.start == mpc_ioapic_addr(i)) {
 			struct irq_domain *id;
+			struct mp_ioapic_gsi *gsi_cfg;
+
+			gsi_cfg = mp_ioapic_gsi_routing(i);
 
-			id = kzalloc(sizeof(*id), GFP_KERNEL);
+			id = irq_domain_add_legacy(np, 32, gsi_cfg->gsi_base, 0,
+						   &ioapic_irq_domain_ops,
+						   (void*)i);
 			BUG_ON(!id);
-			id->controller = np;
-			id->xlate = ioapic_xlate;
-			id->priv = (void *)i;
-			add_interrupt_host(id);
 			return;
 		}
 	}
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
index 50e8e5e..7189adf 100644
--- a/drivers/net/phy/mdio-gpio.c
+++ b/drivers/net/phy/mdio-gpio.c
@@ -255,13 +255,13 @@ static inline int __init mdio_ofgpio_init(void)
 	return platform_driver_register(&mdio_ofgpio_driver);
 }
 
-static inline void __exit mdio_ofgpio_exit(void)
+static inline void mdio_ofgpio_exit(void)
 {
 	platform_driver_unregister(&mdio_ofgpio_driver);
 }
 #else
 static inline int __init mdio_ofgpio_init(void) { return 0; }
-static inline void __exit mdio_ofgpio_exit(void) { }
+static inline void mdio_ofgpio_exit(void) { }
 #endif /* CONFIG_OF_GPIO */
 
 static struct platform_driver mdio_gpio_driver = {
-- 
1.7.5.4


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

* [PATCH v3 23/25] irq_domain: Include hwirq number in /proc/interrupts
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (21 preceding siblings ...)
  2012-01-27 21:36 ` [PATCH v3 22/25] irq_domain/x86: Convert x86 (embedded) to use common irq_domain Grant Likely
@ 2012-01-27 21:36 ` Grant Likely
  2012-01-27 21:36 ` [PATCH v3 24/25] irq_domain: remove "hint" when allocating irq numbers Grant Likely
                   ` (4 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely

Add the hardware interrupt number to the output of /proc/interrupts.
It is often important to have access to the hardware interrupt number because
it identifies exactly how an interrupt signal is wired up to the interrupt
controller.  This is especially important when using irq_domains since irq
numbers get dynamically allocated in that case, and have no relation to the
actual hardware number.

Note: This output is currently conditional on whether or not the irq_domain
pointer is set; however hwirq could still be used without irq_domain.  It
may be worthwhile to always output the hwirq number regardless of the
domain pointer.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/irq/proc.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index 4bd4faa..2ec61d0 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -472,6 +472,9 @@ int show_interrupts(struct seq_file *p, void *v)
 	if (desc->name)
 		seq_printf(p, "-%-8s", desc->name);
 
+	if (desc->irq_data.domain)
+		seq_printf(p, " %-8d", (int) desc->irq_data.hwirq);
+
 	if (action) {
 		seq_printf(p, "  %s", action->name);
 		while ((action = action->next) != NULL)
-- 
1.7.5.4


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

* [PATCH v3 24/25] irq_domain: remove "hint" when allocating irq numbers
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (22 preceding siblings ...)
  2012-01-27 21:36 ` [PATCH v3 23/25] irq_domain: Include hwirq number in /proc/interrupts Grant Likely
@ 2012-01-27 21:36 ` Grant Likely
  2012-02-07 18:07   ` Nicolas Ferre
  2012-01-27 21:36 ` [PATCH v3 25/25] irq_domain: mostly eliminate slow-path revmap lookups Grant Likely
                   ` (3 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely

The 'hint' used to try and line up irq numbers with hw irq numbers is
rather a hack and not very useful.  Now that /proc/interrupts also outputs
the hwirq number, it is even less useful to keep around the 'hint' heuristic.

This patch removes it.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>
---
 kernel/irq/irqdomain.c |   18 ++++--------------
 1 files changed, 4 insertions(+), 14 deletions(-)

diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index bf181ef..5b4fc4d 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -339,7 +339,7 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain)
 unsigned int irq_create_mapping(struct irq_domain *domain,
 				irq_hw_number_t hwirq)
 {
-	unsigned int virq, hint;
+	unsigned int virq;
 
 	pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq);
 
@@ -366,10 +366,7 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
 		return irq_domain_legacy_revmap(domain, hwirq);
 
 	/* Allocate a virtual interrupt number */
-	hint = hwirq % irq_virq_count;
-	virq = irq_alloc_desc_from(hint, 0);
-	if (!virq)
-		virq = irq_alloc_desc(0);
+	virq = irq_alloc_desc(0);
 	if (!virq) {
 		pr_debug("irq: -> virq allocation failed\n");
 		return 0;
@@ -490,7 +487,6 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
 			      irq_hw_number_t hwirq)
 {
 	unsigned int i;
-	unsigned int hint = hwirq % irq_virq_count;
 
 	/* Look for default domain if nececssary */
 	if (domain == NULL)
@@ -503,17 +499,11 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
 		return irq_domain_legacy_revmap(domain, hwirq);
 
 	/* Slow path does a linear search of the map */
-	if (hint < NUM_ISA_INTERRUPTS)
-		hint = NUM_ISA_INTERRUPTS;
-	i = hint;
-	do {
+	for (i = 0; i < irq_virq_count; i++)  {
 		struct irq_data *data = irq_get_irq_data(i);
 		if (data && (data->domain == domain) && (data->hwirq == hwirq))
 			return i;
-		i++;
-		if (i >= irq_virq_count)
-			i = NUM_ISA_INTERRUPTS;
-	} while(i != hint);
+	}
 	return 0;
 }
 EXPORT_SYMBOL_GPL(irq_find_mapping);
-- 
1.7.5.4


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

* [PATCH v3 25/25] irq_domain: mostly eliminate slow-path revmap lookups
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (23 preceding siblings ...)
  2012-01-27 21:36 ` [PATCH v3 24/25] irq_domain: remove "hint" when allocating irq numbers Grant Likely
@ 2012-01-27 21:36 ` Grant Likely
  2012-02-15 16:36   ` Nicolas Ferre
  2012-01-28 18:38 ` [PATCH v3 00/25] irq_domain generalization and refinement Rob Herring
                   ` (2 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
  To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell
  Cc: devicetree-discuss, linux-arm-kernel, linuxppc-dev, Grant Likely

With the current state of irq_domain, the reverse map is always used when
new IRQs get mapped.  This means that the irq_find_mapping() function
can be simplified to always call out to the revmap-specific lookup function.

This patch adds lookup functions for the revmaps that don't yet have one
and removes the slow path lookup from most of the code paths.  The only
place where the slow path legitimately remains is when the linear map
is used with a hwirq number larger than the revmap size.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/sysdev/xics/xics-common.c |    3 -
 include/linux/irqdomain.h              |    3 +-
 kernel/irq/irqdomain.c                 |   94 +++++++++++++++++---------------
 3 files changed, 51 insertions(+), 49 deletions(-)

diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
index ea5e204..1d7067d 100644
--- a/arch/powerpc/sysdev/xics/xics-common.c
+++ b/arch/powerpc/sysdev/xics/xics-common.c
@@ -330,9 +330,6 @@ static int xics_host_map(struct irq_domain *h, unsigned int virq,
 
 	pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hw);
 
-	/* Insert the interrupt mapping into the radix tree for fast lookup */
-	irq_radix_revmap_insert(xics_host, virq, hw);
-
 	/* They aren't all level sensitive but we just don't really know */
 	irq_set_status_flags(virq, IRQ_LEVEL);
 
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 0b00f83..38314f2 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -93,6 +93,7 @@ struct irq_domain {
 	struct list_head link;
 
 	/* type of reverse mapping_technique */
+	unsigned int (*revmap)(struct irq_domain *host, irq_hw_number_t hwirq);
 	unsigned int revmap_type;
 	union {
 		struct {
@@ -155,8 +156,6 @@ extern void irq_dispose_mapping(unsigned int virq);
 extern unsigned int irq_find_mapping(struct irq_domain *host,
 				     irq_hw_number_t hwirq);
 extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
-extern void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq,
-				    irq_hw_number_t hwirq);
 extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
 					    irq_hw_number_t hwirq);
 extern unsigned int irq_linear_revmap(struct irq_domain *host,
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 5b4fc4d..91c1cb7 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -104,6 +104,7 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
 	domain->revmap_data.legacy.first_irq = first_irq;
 	domain->revmap_data.legacy.first_hwirq = first_hwirq;
 	domain->revmap_data.legacy.size = size;
+	domain->revmap = irq_domain_legacy_revmap;
 
 	mutex_lock(&irq_domain_mutex);
 	/* Verify that all the irqs are available */
@@ -174,18 +175,35 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
 	}
 	domain->revmap_data.linear.size = size;
 	domain->revmap_data.linear.revmap = revmap;
+	domain->revmap = irq_linear_revmap;
 	irq_domain_add(domain);
 	return domain;
 }
 
+static unsigned int irq_domain_nomap_revmap(struct irq_domain *domain,
+					    irq_hw_number_t hwirq)
+{
+	struct irq_data *data = irq_get_irq_data(hwirq);
+
+	if (WARN_ON_ONCE(domain->revmap_type != IRQ_DOMAIN_MAP_NOMAP))
+		return irq_find_mapping(domain, hwirq);
+
+	/* Verify that the map has actually been established */
+	if (data && (data->domain == domain) && (data->hwirq == hwirq))
+		return hwirq;
+	return 0;
+}
+
 struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
 					 const struct irq_domain_ops *ops,
 					 void *host_data)
 {
 	struct irq_domain *domain = irq_domain_alloc(of_node,
 					IRQ_DOMAIN_MAP_NOMAP, ops, host_data);
-	if (domain)
+	if (domain) {
+		domain->revmap = irq_domain_nomap_revmap;
 		irq_domain_add(domain);
+	}
 	return domain;
 }
 
@@ -205,6 +223,7 @@ struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
 					IRQ_DOMAIN_MAP_TREE, ops, host_data);
 	if (domain) {
 		INIT_RADIX_TREE(&domain->revmap_data.tree, GFP_KERNEL);
+		domain->revmap = irq_radix_revmap_lookup;
 		irq_domain_add(domain);
 	}
 	return domain;
@@ -378,6 +397,19 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
 		return 0;
 	}
 
+	switch(domain->revmap_type) {
+	case IRQ_DOMAIN_MAP_LINEAR:
+		if (hwirq < domain->revmap_data.linear.size)
+			domain->revmap_data.linear.revmap[hwirq] = irq;
+		break;
+	case IRQ_DOMAIN_MAP_TREE:
+		mutex_lock(&revmap_trees_mutex);
+		radix_tree_insert(&domain->revmap_data.tree, hwirq,
+				  irq_get_irq_data(irq));
+		mutex_unlock(&revmap_trees_mutex);
+
+		break;
+	}
 	pr_debug("irq: irq %lu on domain %s mapped to virtual irq %u\n",
 		hwirq, domain->of_node ? domain->of_node->full_name : "null", virq);
 
@@ -478,25 +510,27 @@ EXPORT_SYMBOL_GPL(irq_dispose_mapping);
  * irq_find_mapping() - Find a linux irq from an hw irq number.
  * @domain: domain owning this hardware interrupt
  * @hwirq: hardware irq number in that domain space
- *
- * This is a slow path, for use by generic code. It's expected that an
- * irq controller implementation directly calls the appropriate low level
- * mapping function.
  */
 unsigned int irq_find_mapping(struct irq_domain *domain,
 			      irq_hw_number_t hwirq)
 {
-	unsigned int i;
-
-	/* Look for default domain if nececssary */
-	if (domain == NULL)
+	if (!domain)
 		domain = irq_default_domain;
-	if (domain == NULL)
-		return 0;
+	return domain ? domain->revmap(domain, hwirq) : 0;
+}
+EXPORT_SYMBOL_GPL(irq_find_mapping);
 
-	/* legacy -> bail early */
-	if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
-		return irq_domain_legacy_revmap(domain, hwirq);
+/**
+ * irq_find_mapping_slow() - slow path for finding the irq mapped to a hwirq
+ *
+ * This is the failsafe slow path for finding an irq mapping.  The only time
+ * this will reasonably get called is when the linear map is used with a
+ * hwirq number larger than the size of the reverse map.
+ */
+static unsigned int irq_find_mapping_slow(struct irq_domain *domain,
+					  irq_hw_number_t hwirq)
+{
+	int i;
 
 	/* Slow path does a linear search of the map */
 	for (i = 0; i < irq_virq_count; i++)  {
@@ -506,7 +540,6 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
 	}
 	return 0;
 }
-EXPORT_SYMBOL_GPL(irq_find_mapping);
 
 /**
  * irq_radix_revmap_lookup() - Find a linux irq from a hw irq number.
@@ -537,31 +570,7 @@ unsigned int irq_radix_revmap_lookup(struct irq_domain *domain,
 	 * Else fallback to linear lookup - this should not happen in practice
 	 * as it means that we failed to insert the node in the radix tree.
 	 */
-	return irq_data ? irq_data->irq : irq_find_mapping(domain, hwirq);
-}
-
-/**
- * irq_radix_revmap_insert() - Insert a hw irq to linux irq number mapping.
- * @domain: domain owning this hardware interrupt
- * @virq: linux irq number
- * @hwirq: hardware irq number in that domain space
- *
- * This is for use by irq controllers that use a radix tree reverse
- * mapping for fast lookup.
- */
-void irq_radix_revmap_insert(struct irq_domain *domain, unsigned int virq,
-			     irq_hw_number_t hwirq)
-{
-	struct irq_data *irq_data = irq_get_irq_data(virq);
-
-	if (WARN_ON(domain->revmap_type != IRQ_DOMAIN_MAP_TREE))
-		return;
-
-	if (virq) {
-		mutex_lock(&revmap_trees_mutex);
-		radix_tree_insert(&domain->revmap_data.tree, hwirq, irq_data);
-		mutex_unlock(&revmap_trees_mutex);
-	}
+	return irq_data ? irq_data->irq : irq_find_mapping_slow(domain, hwirq);
 }
 
 /**
@@ -585,14 +594,11 @@ unsigned int irq_linear_revmap(struct irq_domain *domain,
 	if (unlikely(hwirq >= domain->revmap_data.linear.size))
 		return irq_find_mapping(domain, hwirq);
 
-	/* Check if revmap was allocated */
 	revmap = domain->revmap_data.linear.revmap;
-	if (unlikely(revmap == NULL))
-		return irq_find_mapping(domain, hwirq);
 
 	/* Fill up revmap with slow path if no mapping found */
 	if (unlikely(!revmap[hwirq]))
-		revmap[hwirq] = irq_find_mapping(domain, hwirq);
+		revmap[hwirq] = irq_find_mapping_slow(domain, hwirq);
 
 	return revmap[hwirq];
 }
-- 
1.7.5.4


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

* Re: [PATCH v3 22/25] irq_domain/x86: Convert x86 (embedded) to use common irq_domain
  2012-01-27 21:36 ` [PATCH v3 22/25] irq_domain/x86: Convert x86 (embedded) to use common irq_domain Grant Likely
@ 2012-01-28 16:44   ` Sebastian Andrzej Siewior
  2012-01-29  0:35     ` Grant Likely
  2012-01-30 19:58     ` Grant Likely
  0 siblings, 2 replies; 66+ messages in thread
From: Sebastian Andrzej Siewior @ 2012-01-28 16:44 UTC (permalink / raw)
  To: Grant Likely
  Cc: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell, devicetree-discuss,
	linux-arm-kernel, linuxppc-dev

* Grant Likely | 2012-01-27 14:36:16 [-0700]:

>This patch removes the x86-specific definition of irq_domain and replaces
>it with the common implementation.

I pulled your devicetree/next tree. After this patch I get:

|Hierarchical RCU implementation.
|NR_IRQS:2304 nr_irqs:256 16
|------------[ cut here ]------------
|WARNING: at /home/bigeasy/work/shiva/git/linux-2.6-tip/kernel/irq/irqdomain.c:114 irq_domain_add_legacy+0x75/0x150()
|Modules linked in:
|Pid: 0, comm: swapper/0 Not tainted 3.3.0-rc1+ #65
|Call Trace:
| [<c15044e0>] ? printk+0x18/0x1a
| [<c102cdbd>] warn_slowpath_common+0x6d/0xa0
| [<c1095575>] ? irq_domain_add_legacy+0x75/0x150
| [<c1095575>] ? irq_domain_add_legacy+0x75/0x150
| [<c102ce0d>] warn_slowpath_null+0x1d/0x20
| [<c1095575>] irq_domain_add_legacy+0x75/0x150
| [<c1714824>] x86_add_irq_domains+0x96/0xd6
| [<c1708df2>] init_IRQ+0x8/0x33
| [<c170557f>] start_kernel+0x191/0x2e1
| [<c170517f>] ? loglevel+0x2b/0x2b
| [<c1705081>] i386_start_kernel+0x81/0x86
|---[ end trace 4eaa2a86a8e2da22 ]---
|------------[ cut here ]------------
|kernel BUG at /home/bigeasy/work/shiva/git/linux-2.6-tip/arch/x86/kernel/devicetree.c:367!

The warning is comming from this piece in irq_domain_add_legacy()
|for (i = 0; i < size; i++) {
|                 int irq = first_irq + i;
|                 struct irq_data *irq_data = irq_get_irq_data(irq);
| 
|                 if (WARN_ON(!irq_data || irq_data->domain)) {

irq_data is NULL here.

|                         mutex_unlock(&irq_domain_mutex);
|                         of_node_put(domain->of_node);
|                         kfree(domain);
|                         return NULL;
|                 }
|         }
| 

This is not always the case. arch_early_irq_init() in [0] sets up the
first 16 entries. The reminaing few (there is a toal of 24 irqs for
first ioapic and a second ioapic) are not initialized. This happens
later via ->xlate, ioapic_xlate() => io_apic_setup_irq_pin() =>
alloc_irq_and_cfg_at() calls irq_set_chip_data() on demand.

[0] arch/x86/kernel/apic/io_apic.c

Sebastian

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

* Re: [PATCH v3 01/25] irq_domain: add documentation and MAINTAINERS entry.
  2012-01-27 21:35 ` [PATCH v3 01/25] irq_domain: add documentation and MAINTAINERS entry Grant Likely
@ 2012-01-28 18:23   ` Randy Dunlap
  0 siblings, 0 replies; 66+ messages in thread
From: Randy Dunlap @ 2012-01-28 18:23 UTC (permalink / raw)
  To: Grant Likely
  Cc: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell, devicetree-discuss,
	linux-arm-kernel, linuxppc-dev

On 01/27/2012 01:35 PM, Grant Likely wrote:
> Documentation for irq_domain library which will be created in subsequent
> patches.

I posted a lot of comments to v2 on Jan. 24.
Looks like they were ignored.

Please see  http://marc.info/?l=linuxppc-embedded&m=132742951211808&w=2


> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Rob Herring <rob.herring@calxeda.com>
> Cc: Milton Miller <miltonm@bga.com>
> ---
>  Documentation/IRQ-domain.txt |  113 ++++++++++++++++++++++++++++++++++++++++++
>  MAINTAINERS                  |    9 +++
>  2 files changed, 122 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/IRQ-domain.txt


-- 
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***

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

* Re: [PATCH v3 00/25] irq_domain generalization and refinement
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (24 preceding siblings ...)
  2012-01-27 21:36 ` [PATCH v3 25/25] irq_domain: mostly eliminate slow-path revmap lookups Grant Likely
@ 2012-01-28 18:38 ` Rob Herring
  2012-01-31  4:53 ` Olof Johansson
  2012-02-04 22:17 ` Russell King - ARM Linux
  27 siblings, 0 replies; 66+ messages in thread
From: Rob Herring @ 2012-01-28 18:38 UTC (permalink / raw)
  To: Grant Likely
  Cc: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell, devicetree-discuss,
	linuxppc-dev, linux-arm-kernel

On 01/27/2012 03:35 PM, Grant Likely wrote:
> Hey everyone,
> 
> This patch series is ready for much wider consumption now.  I'd like
> to get it into linux-next ASAP because there will be ARM board support
> depending on it.  I'll wait a few days before I ask Stephen to pull
> this in.
> 
> Stephen/Milton/Ben, any testing you can help with here would be
> appreciated since you've got access to a wider variety of Power
> machines than I do.
> 
> Thomas, I think it makes sense to maintain this in a separate branch
> from other irq changes until the next merge window.  If you prefer,
> I'm happy to maintain this branch until then.
> 

I picked up your irqdomain/next branch and it doesn't compile:

  CC      kernel/irq/irqdomain.o
kernel/irq/irqdomain.c: In function ‘irq_create_mapping’:
kernel/irq/irqdomain.c:403:47: error: ‘irq’ undeclared (first use in
this function)
kernel/irq/irqdomain.c:403:47: note: each undeclared identifier is
reported only once for each function it app

Rob

> Cheers,
> g.
> 
> The following changes since commit dcd6c92267155e70a94b3927bce681ce74b80d1f:
> 
>   Linux 3.3-rc1 (2012-01-19 15:04:48 -0800)
> 
> are available in the git repository at:
>   git://git.secretlab.ca/git/linux-2.6 irqdomain/next
> 
> Grant Likely (24):
>       irq_domain: add documentation and MAINTAINERS entry.
>       dt: Make irqdomain less verbose
>       irq_domain: Make irq_domain structure match powerpc's irq_host
>       irq_domain: convert microblaze from irq_host to irq_domain
>       irq_domain/powerpc: Use common irq_domain structure instead of irq_host
>       irq_domain/powerpc: eliminate irq_map; use irq_alloc_desc() instead
>       irq_domain/powerpc: Eliminate virq_is_host()
>       irq_domain: Move irq_domain code from powerpc to kernel/irq
>       irqdomain: remove NO_IRQ from irq domain code
>       irq_domain: Remove references to old irq_host names
>       irq_domain: Replace irq_alloc_host() with revmap-specific initializers
>       irq_domain: Add support for base irq and hwirq in legacy mappings
>       irq_domain: Remove 'new' irq_domain in favour of the ppc one
>       irq_domain: Remove irq_domain_add_simple()
>       irq_domain: Create common xlate functions that device drivers can use
>       irq_domain: constify irq_domain_ops
>       irq_domain/c6x: constify irq_domain structures
>       irq_domain/c6x: Use library of xlate functions
>       irq_domain/powerpc: constify irq_domain_ops
>       irqdomain/powerpc: Replace custom xlate functions with library functions
>       irq_domain/x86: Convert x86 (embedded) to use common irq_domain
>       irq_domain: Include hwirq number in /proc/interrupts
>       irq_domain: remove "hint" when allocating irq numbers
>       irq_domain: mostly eliminate slow-path revmap lookups
> 
> Mark Salter (1):
>       irq_domain/c6x: Convert c6x to use generic irq_domain support.
> 
>  Documentation/IRQ-domain.txt                     |  113 +++
>  MAINTAINERS                                      |    9 +
>  arch/arm/common/gic.c                            |   95 ++--
>  arch/arm/common/vic.c                            |   16 +-
>  arch/arm/include/asm/hardware/gic.h              |    4 +-
>  arch/arm/include/asm/hardware/vic.h              |    2 +
>  arch/arm/mach-exynos/common.c                    |    2 +-
>  arch/arm/mach-imx/mach-imx6q.c                   |    3 +-
>  arch/arm/mach-msm/board-msm8x60.c                |    8 +-
>  arch/arm/mach-mx5/imx51-dt.c                     |    4 +-
>  arch/arm/mach-mx5/imx53-dt.c                     |    4 +-
>  arch/arm/mach-omap2/board-generic.c              |    2 +-
>  arch/arm/mach-prima2/irq.c                       |    2 +-
>  arch/arm/mach-versatile/core.c                   |    5 +-
>  arch/c6x/Kconfig                                 |    1 +
>  arch/c6x/include/asm/irq.h                       |  245 +-------
>  arch/c6x/kernel/irq.c                            |  612 +----------------
>  arch/c6x/platforms/megamod-pic.c                 |   25 +-
>  arch/microblaze/include/asm/irq.h                |    4 +-
>  arch/microblaze/kernel/irq.c                     |    2 +-
>  arch/microblaze/kernel/setup.c                   |    2 -
>  arch/powerpc/Kconfig                             |    1 +
>  arch/powerpc/include/asm/ehv_pic.h               |    2 +-
>  arch/powerpc/include/asm/i8259.h                 |    2 +-
>  arch/powerpc/include/asm/irq.h                   |  247 +-------
>  arch/powerpc/include/asm/mpic.h                  |    2 +-
>  arch/powerpc/include/asm/xics.h                  |    2 +-
>  arch/powerpc/kernel/irq.c                        |  617 +----------------
>  arch/powerpc/platforms/512x/mpc5121_ads_cpld.c   |   12 +-
>  arch/powerpc/platforms/52xx/media5200.c          |   15 +-
>  arch/powerpc/platforms/52xx/mpc52xx_gpt.c        |   16 +-
>  arch/powerpc/platforms/52xx/mpc52xx_pic.c        |   12 +-
>  arch/powerpc/platforms/82xx/pq2ads-pci-pic.c     |   14 +-
>  arch/powerpc/platforms/85xx/socrates_fpga_pic.c  |   15 +-
>  arch/powerpc/platforms/86xx/gef_pic.c            |   15 +-
>  arch/powerpc/platforms/cell/axon_msi.c           |   29 +-
>  arch/powerpc/platforms/cell/beat_interrupt.c     |   16 +-
>  arch/powerpc/platforms/cell/interrupt.c          |   16 +-
>  arch/powerpc/platforms/cell/spider-pic.c         |   14 +-
>  arch/powerpc/platforms/embedded6xx/flipper-pic.c |   30 +-
>  arch/powerpc/platforms/embedded6xx/hlwd-pic.c    |   35 +-
>  arch/powerpc/platforms/iseries/irq.c             |   11 +-
>  arch/powerpc/platforms/powermac/pic.c            |   26 +-
>  arch/powerpc/platforms/powermac/smp.c            |    9 +-
>  arch/powerpc/platforms/ps3/interrupt.c           |   11 +-
>  arch/powerpc/platforms/wsp/opb_pic.c             |   26 +-
>  arch/powerpc/sysdev/cpm1.c                       |    9 +-
>  arch/powerpc/sysdev/cpm2_pic.c                   |   23 +-
>  arch/powerpc/sysdev/ehv_pic.c                    |   14 +-
>  arch/powerpc/sysdev/fsl_msi.c                    |   10 +-
>  arch/powerpc/sysdev/fsl_msi.h                    |    2 +-
>  arch/powerpc/sysdev/i8259.c                      |   15 +-
>  arch/powerpc/sysdev/ipic.c                       |   31 +-
>  arch/powerpc/sysdev/ipic.h                       |    2 +-
>  arch/powerpc/sysdev/mpc8xx_pic.c                 |   11 +-
>  arch/powerpc/sysdev/mpic.c                       |   17 +-
>  arch/powerpc/sysdev/mpic_msi.c                   |    2 +-
>  arch/powerpc/sysdev/mv64x60_pic.c                |   11 +-
>  arch/powerpc/sysdev/qe_lib/qe_ic.c               |   26 +-
>  arch/powerpc/sysdev/qe_lib/qe_ic.h               |    2 +-
>  arch/powerpc/sysdev/tsi108_pci.c                 |   22 +-
>  arch/powerpc/sysdev/uic.c                        |   26 +-
>  arch/powerpc/sysdev/xics/xics-common.c           |   28 +-
>  arch/powerpc/sysdev/xilinx_intc.c                |   19 +-
>  arch/x86/Kconfig                                 |    2 +
>  arch/x86/include/asm/irq_controller.h            |   12 -
>  arch/x86/include/asm/prom.h                      |   10 -
>  arch/x86/kernel/devicetree.c                     |  101 +--
>  drivers/gpio/gpio-mpc8xxx.c                      |   30 +-
>  drivers/mfd/twl-core.c                           |   12 +-
>  drivers/net/phy/mdio-gpio.c                      |    4 +-
>  include/linux/irqdomain.h                        |  190 ++++--
>  kernel/irq/irqdomain.c                           |  816 +++++++++++++++++++---
>  kernel/irq/proc.c                                |    3 +
>  74 files changed, 1334 insertions(+), 2471 deletions(-)
>  create mode 100644 Documentation/IRQ-domain.txt
>  delete mode 100644 arch/x86/include/asm/irq_controller.h
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss


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

* Re: [PATCH v3 22/25] irq_domain/x86: Convert x86 (embedded) to use common irq_domain
  2012-01-28 16:44   ` Sebastian Andrzej Siewior
@ 2012-01-29  0:35     ` Grant Likely
  2012-01-29  0:39       ` Grant Likely
  2012-01-30 19:58     ` Grant Likely
  1 sibling, 1 reply; 66+ messages in thread
From: Grant Likely @ 2012-01-29  0:35 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell, devicetree-discuss,
	linux-arm-kernel, linuxppc-dev

On Sat, Jan 28, 2012 at 05:44:05PM +0100, Sebastian Andrzej Siewior wrote:
> * Grant Likely | 2012-01-27 14:36:16 [-0700]:
> 
> >This patch removes the x86-specific definition of irq_domain and replaces
> >it with the common implementation.
> 
> I pulled your devicetree/next tree. After this patch I get:
> 
> |Hierarchical RCU implementation.
> |NR_IRQS:2304 nr_irqs:256 16
> |------------[ cut here ]------------
> |WARNING: at /home/bigeasy/work/shiva/git/linux-2.6-tip/kernel/irq/irqdomain.c:114 irq_domain_add_legacy+0x75/0x150()
> |Modules linked in:
> |Pid: 0, comm: swapper/0 Not tainted 3.3.0-rc1+ #65
> |Call Trace:
> | [<c15044e0>] ? printk+0x18/0x1a
> | [<c102cdbd>] warn_slowpath_common+0x6d/0xa0
> | [<c1095575>] ? irq_domain_add_legacy+0x75/0x150
> | [<c1095575>] ? irq_domain_add_legacy+0x75/0x150
> | [<c102ce0d>] warn_slowpath_null+0x1d/0x20
> | [<c1095575>] irq_domain_add_legacy+0x75/0x150
> | [<c1714824>] x86_add_irq_domains+0x96/0xd6
> | [<c1708df2>] init_IRQ+0x8/0x33
> | [<c170557f>] start_kernel+0x191/0x2e1
> | [<c170517f>] ? loglevel+0x2b/0x2b
> | [<c1705081>] i386_start_kernel+0x81/0x86
> |---[ end trace 4eaa2a86a8e2da22 ]---
> |------------[ cut here ]------------
> |kernel BUG at /home/bigeasy/work/shiva/git/linux-2.6-tip/arch/x86/kernel/devicetree.c:367!
> 
> The warning is comming from this piece in irq_domain_add_legacy()
> |for (i = 0; i < size; i++) {
> |                 int irq = first_irq + i;
> |                 struct irq_data *irq_data = irq_get_irq_data(irq);
> | 
> |                 if (WARN_ON(!irq_data || irq_data->domain)) {
> 
> irq_data is NULL here.
> 
> |                         mutex_unlock(&irq_domain_mutex);
> |                         of_node_put(domain->of_node);
> |                         kfree(domain);
> |                         return NULL;
> |                 }
> |         }
> | 
> 
> This is not always the case. arch_early_irq_init() in [0] sets up the
> first 16 entries. The reminaing few (there is a toal of 24 irqs for
> first ioapic and a second ioapic) are not initialized. This happens
> later via ->xlate, ioapic_xlate() => io_apic_setup_irq_pin() =>
> alloc_irq_and_cfg_at() calls irq_set_chip_data() on demand.
> 
> [0] arch/x86/kernel/apic/io_apic.c

That's not going to work then.  The irqs must not be set up in ->xlate.
They need to be set up either before creating the irq_domain, or in the
.map hook.  Inside the map hook is preferred, but having some
configured and some not at initialization time does make it difficult

g.



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

* Re: [PATCH v3 22/25] irq_domain/x86: Convert x86 (embedded) to use common irq_domain
  2012-01-29  0:35     ` Grant Likely
@ 2012-01-29  0:39       ` Grant Likely
  0 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-01-29  0:39 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell, devicetree-discuss,
	linux-arm-kernel, linuxppc-dev

On Sat, Jan 28, 2012 at 5:35 PM, Grant Likely <grant.likely@secretlab.ca> wrote:
> On Sat, Jan 28, 2012 at 05:44:05PM +0100, Sebastian Andrzej Siewior wrote:
>> * Grant Likely | 2012-01-27 14:36:16 [-0700]:
>>
>> >This patch removes the x86-specific definition of irq_domain and replaces
>> >it with the common implementation.
>>
>> I pulled your devicetree/next tree. After this patch I get:
>>
>> |Hierarchical RCU implementation.
>> |NR_IRQS:2304 nr_irqs:256 16
>> |------------[ cut here ]------------
>> |WARNING: at /home/bigeasy/work/shiva/git/linux-2.6-tip/kernel/irq/irqdomain.c:114 irq_domain_add_legacy+0x75/0x150()
>> |Modules linked in:
>> |Pid: 0, comm: swapper/0 Not tainted 3.3.0-rc1+ #65
>> |Call Trace:
>> | [<c15044e0>] ? printk+0x18/0x1a
>> | [<c102cdbd>] warn_slowpath_common+0x6d/0xa0
>> | [<c1095575>] ? irq_domain_add_legacy+0x75/0x150
>> | [<c1095575>] ? irq_domain_add_legacy+0x75/0x150
>> | [<c102ce0d>] warn_slowpath_null+0x1d/0x20
>> | [<c1095575>] irq_domain_add_legacy+0x75/0x150
>> | [<c1714824>] x86_add_irq_domains+0x96/0xd6
>> | [<c1708df2>] init_IRQ+0x8/0x33
>> | [<c170557f>] start_kernel+0x191/0x2e1
>> | [<c170517f>] ? loglevel+0x2b/0x2b
>> | [<c1705081>] i386_start_kernel+0x81/0x86
>> |---[ end trace 4eaa2a86a8e2da22 ]---
>> |------------[ cut here ]------------
>> |kernel BUG at /home/bigeasy/work/shiva/git/linux-2.6-tip/arch/x86/kernel/devicetree.c:367!
>>
>> The warning is comming from this piece in irq_domain_add_legacy()
>> |for (i = 0; i < size; i++) {
>> |                 int irq = first_irq + i;
>> |                 struct irq_data *irq_data = irq_get_irq_data(irq);
>> |
>> |                 if (WARN_ON(!irq_data || irq_data->domain)) {
>>
>> irq_data is NULL here.
>>
>> |                         mutex_unlock(&irq_domain_mutex);
>> |                         of_node_put(domain->of_node);
>> |                         kfree(domain);
>> |                         return NULL;
>> |                 }
>> |         }
>> |
>>
>> This is not always the case. arch_early_irq_init() in [0] sets up the
>> first 16 entries. The reminaing few (there is a toal of 24 irqs for
>> first ioapic and a second ioapic) are not initialized. This happens
>> later via ->xlate, ioapic_xlate() => io_apic_setup_irq_pin() =>
>> alloc_irq_and_cfg_at() calls irq_set_chip_data() on demand.
>>
>> [0] arch/x86/kernel/apic/io_apic.c
>
> That's not going to work then.  The irqs must not be set up in ->xlate.
> They need to be set up either before creating the irq_domain, or in the
> .map hook.  Inside the map hook is preferred, but having some
> configured and some not at initialization time does make it difficult

Actually, that's still not right.  irq_set_chip_data() (sets
desc->irq_data.chip_data) has nothing to do with irq_get_irq_data()
(which returns desc->irq_data).  It's the   allocation of the irq_desc
that is at issue here.  Where does the allocation occur?  (I haven't
dug in to find it yet)

g.

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

* Re: [PATCH v3 22/25] irq_domain/x86: Convert x86 (embedded) to use common irq_domain
  2012-01-28 16:44   ` Sebastian Andrzej Siewior
  2012-01-29  0:35     ` Grant Likely
@ 2012-01-30 19:58     ` Grant Likely
  2012-02-01 14:17       ` Sebastian Andrzej Siewior
  1 sibling, 1 reply; 66+ messages in thread
From: Grant Likely @ 2012-01-30 19:58 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell, devicetree-discuss,
	linux-arm-kernel, linuxppc-dev

On Sat, Jan 28, 2012 at 05:44:05PM +0100, Sebastian Andrzej Siewior wrote:
> * Grant Likely | 2012-01-27 14:36:16 [-0700]:
> 
> >This patch removes the x86-specific definition of irq_domain and replaces
> >it with the common implementation.
> 
> I pulled your devicetree/next tree. After this patch I get:
> 
> |Hierarchical RCU implementation.
> |NR_IRQS:2304 nr_irqs:256 16
> |------------[ cut here ]------------
> |WARNING: at /home/bigeasy/work/shiva/git/linux-2.6-tip/kernel/irq/irqdomain.c:114 irq_domain_add_legacy+0x75/0x150()
> |Modules linked in:
> |Pid: 0, comm: swapper/0 Not tainted 3.3.0-rc1+ #65
> |Call Trace:
> | [<c15044e0>] ? printk+0x18/0x1a
> | [<c102cdbd>] warn_slowpath_common+0x6d/0xa0
> | [<c1095575>] ? irq_domain_add_legacy+0x75/0x150
> | [<c1095575>] ? irq_domain_add_legacy+0x75/0x150
> | [<c102ce0d>] warn_slowpath_null+0x1d/0x20
> | [<c1095575>] irq_domain_add_legacy+0x75/0x150
> | [<c1714824>] x86_add_irq_domains+0x96/0xd6
> | [<c1708df2>] init_IRQ+0x8/0x33
> | [<c170557f>] start_kernel+0x191/0x2e1
> | [<c170517f>] ? loglevel+0x2b/0x2b
> | [<c1705081>] i386_start_kernel+0x81/0x86
> |---[ end trace 4eaa2a86a8e2da22 ]---
> |------------[ cut here ]------------
> |kernel BUG at /home/bigeasy/work/shiva/git/linux-2.6-tip/arch/x86/kernel/devicetree.c:367!
> 
> The warning is comming from this piece in irq_domain_add_legacy()
> |for (i = 0; i < size; i++) {
> |                 int irq = first_irq + i;
> |                 struct irq_data *irq_data = irq_get_irq_data(irq);
> | 
> |                 if (WARN_ON(!irq_data || irq_data->domain)) {
> 
> irq_data is NULL here.
> 
> |                         mutex_unlock(&irq_domain_mutex);
> |                         of_node_put(domain->of_node);
> |                         kfree(domain);
> |                         return NULL;
> |                 }
> |         }
> | 
> 
> This is not always the case. arch_early_irq_init() in [0] sets up the
> first 16 entries. The reminaing few (there is a toal of 24 irqs for
> first ioapic and a second ioapic) are not initialized. This happens
> later via ->xlate, ioapic_xlate() => io_apic_setup_irq_pin() =>
> alloc_irq_and_cfg_at() calls irq_set_chip_data() on demand.
> 
> [0] arch/x86/kernel/apic/io_apic.c

Ugh.  This isn't easy.  The legacy mapping really needs all the
irq_desc structures to be allocated.  You could call irq_alloc_descs()
before calling irq_domain_add_legacy(), but that causes all the
irq_descs to be allocated (regardless of whether they are used), and
it will break io_apic_setup_irq_pin() which also wants to call
irq_alloc_desc().

Ideally irq_domain support would be rolled directly into ioapic.
That's more work though, and a greater change of breaking x86 on
non-embedded.  Looking at the ioapic code, it seems to me that it
could be simplified quite a bit by switching to irq_domain instead of
using the custom irq_cfg linked list.  Faster too since it could use
the irq_data->hwirq to go from linux irq to the hw irq number.  It
doesn't look like it would be even that hard, but of course the devil
is in the details and I don't have sufficient time right now to dig
into the guts of the ioapic.  Maybe after connect, but it would help
if you can find time to look at it.

If integrated into the ioapic code, then the irq_domain linear map is
probably the type of irq_domain to use.

g.


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

* Re: [PATCH v3 00/25] irq_domain generalization and refinement
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (25 preceding siblings ...)
  2012-01-28 18:38 ` [PATCH v3 00/25] irq_domain generalization and refinement Rob Herring
@ 2012-01-31  4:53 ` Olof Johansson
  2012-02-01  0:07   ` Grant Likely
  2012-02-04 22:17 ` Russell King - ARM Linux
  27 siblings, 1 reply; 66+ messages in thread
From: Olof Johansson @ 2012-01-31  4:53 UTC (permalink / raw)
  To: Grant Likely
  Cc: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell, devicetree-discuss,
	linux-arm-kernel, linuxppc-dev

On Fri, Jan 27, 2012 at 02:35:54PM -0700, Grant Likely wrote:
> Hey everyone,
> 
> This patch series is ready for much wider consumption now.  I'd like
> to get it into linux-next ASAP because there will be ARM board support
> depending on it.  I'll wait a few days before I ask Stephen to pull
> this in.
> 
> Stephen/Milton/Ben, any testing you can help with here would be
> appreciated since you've got access to a wider variety of Power
> machines than I do.

This series has been:

Tested-by: Olof Johansson <olof@lixom.net>

On powerpc/pasemi (it's the only one I still have easy access to).


-Olof

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

* Re: [PATCH v3 14/25] irq_domain: Remove irq_domain_add_simple()
  2012-01-27 21:36 ` [PATCH v3 14/25] irq_domain: Remove irq_domain_add_simple() Grant Likely
@ 2012-01-31 12:45   ` Shawn Guo
  2012-01-31 13:15     ` Rob Herring
  2012-02-01  5:46   ` [PATCH] irq_domain: fix the irq number of imx5 tzic Shawn Guo
  1 sibling, 1 reply; 66+ messages in thread
From: Shawn Guo @ 2012-01-31 12:45 UTC (permalink / raw)
  To: Grant Likely
  Cc: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell, devicetree-discuss,
	linux-arm-kernel, linuxppc-dev

On Fri, Jan 27, 2012 at 02:36:08PM -0700, Grant Likely wrote:
> irq_domain_add_simple() was a stop-gap measure until complete irq_domain
> support was complete.  This patch removes the irq_domain_add_simple()
> interface.
> 
> v2: Updated to pass in host_data pointer on irq_domain allocation.
> 
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> Cc: Rob Herring <rob.herring@calxeda.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Milton Miller <miltonm@bga.com>
> ---
>  arch/arm/mach-imx/mach-imx6q.c      |    3 ++-
>  arch/arm/mach-msm/board-msm8x60.c   |    8 ++------
>  arch/arm/mach-mx5/imx51-dt.c        |    4 ++--
>  arch/arm/mach-mx5/imx53-dt.c        |    4 ++--
>  arch/arm/mach-omap2/board-generic.c |    2 +-
>  arch/arm/mach-prima2/irq.c          |    2 +-
>  drivers/mfd/twl-core.c              |    2 +-
>  include/linux/irqdomain.h           |    1 -
>  kernel/irq/irqdomain.c              |   10 ++--------
>  9 files changed, 13 insertions(+), 23 deletions(-)
> 
...
> --- a/arch/arm/mach-mx5/imx51-dt.c
> +++ b/arch/arm/mach-mx5/imx51-dt.c
> @@ -47,7 +47,7 @@ static const struct of_dev_auxdata imx51_auxdata_lookup[] __initconst = {
>  static int __init imx51_tzic_add_irq_domain(struct device_node *np,
>  				struct device_node *interrupt_parent)
>  {
> -	irq_domain_add_simple(np, 0);
> +	irq_domain_add_legacy(np, 32, 0, 0, &irq_domain_simple_ops, NULL);
>  	return 0;
>  }
>  
> @@ -57,7 +57,7 @@ static int __init imx51_gpio_add_irq_domain(struct device_node *np,
>  	static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
>  
>  	gpio_irq_base -= 32;
> -	irq_domain_add_simple(np, gpio_irq_base);
> +	irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, NULL);

The tzic on imx5 gets 128 irq lines rather than 32 here.  The current
code will make any hwirq that is > 32 hit the WARN_ON below in
irq_domain_legacy_revmap().

	WARN_ON(hwirq < first_hwirq || hwirq >= first_hwirq + size)

The first_hwirq is 0 and size is 32 in this case.

Changing 32 to 128 seems fixing the problem.

>  
>  	return 0;
>  }
> diff --git a/arch/arm/mach-mx5/imx53-dt.c b/arch/arm/mach-mx5/imx53-dt.c
> index 05ebb3e..89de5d4 100644
> --- a/arch/arm/mach-mx5/imx53-dt.c
> +++ b/arch/arm/mach-mx5/imx53-dt.c
> @@ -51,7 +51,7 @@ static const struct of_dev_auxdata imx53_auxdata_lookup[] __initconst = {
>  static int __init imx53_tzic_add_irq_domain(struct device_node *np,
>  				struct device_node *interrupt_parent)
>  {
> -	irq_domain_add_simple(np, 0);
> +	irq_domain_add_legacy(np, 32, 0, 0, &irq_domain_simple_ops, NULL);

Ditto

Regards,
Shawn

>  	return 0;
>  }
>  
> @@ -61,7 +61,7 @@ static int __init imx53_gpio_add_irq_domain(struct device_node *np,
>  	static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
>  
>  	gpio_irq_base -= 32;
> -	irq_domain_add_simple(np, gpio_irq_base);
> +	irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, NULL);
>  
>  	return 0;
>  }

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

* Re: [PATCH v3 14/25] irq_domain: Remove irq_domain_add_simple()
  2012-01-31 12:45   ` Shawn Guo
@ 2012-01-31 13:15     ` Rob Herring
  2012-01-31 13:58       ` Shawn Guo
  0 siblings, 1 reply; 66+ messages in thread
From: Rob Herring @ 2012-01-31 13:15 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Grant Likely, linux-kernel, Benjamin Herrenschmidt,
	Thomas Gleixner, Milton Miller, Stephen Rothwell,
	devicetree-discuss, linux-arm-kernel, linuxppc-dev

Shawn,

On 01/31/2012 06:45 AM, Shawn Guo wrote:
> On Fri, Jan 27, 2012 at 02:36:08PM -0700, Grant Likely wrote:
>> irq_domain_add_simple() was a stop-gap measure until complete irq_domain
>> support was complete.  This patch removes the irq_domain_add_simple()
>> interface.
>>
>> v2: Updated to pass in host_data pointer on irq_domain allocation.
>>
>> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
>> Cc: Rob Herring <rob.herring@calxeda.com>
>> Cc: Thomas Gleixner <tglx@linutronix.de>
>> Cc: Milton Miller <miltonm@bga.com>
>> ---
>>  arch/arm/mach-imx/mach-imx6q.c      |    3 ++-
>>  arch/arm/mach-msm/board-msm8x60.c   |    8 ++------
>>  arch/arm/mach-mx5/imx51-dt.c        |    4 ++--
>>  arch/arm/mach-mx5/imx53-dt.c        |    4 ++--
>>  arch/arm/mach-omap2/board-generic.c |    2 +-
>>  arch/arm/mach-prima2/irq.c          |    2 +-
>>  drivers/mfd/twl-core.c              |    2 +-
>>  include/linux/irqdomain.h           |    1 -
>>  kernel/irq/irqdomain.c              |   10 ++--------
>>  9 files changed, 13 insertions(+), 23 deletions(-)
>>
> ...
>> --- a/arch/arm/mach-mx5/imx51-dt.c
>> +++ b/arch/arm/mach-mx5/imx51-dt.c
>> @@ -47,7 +47,7 @@ static const struct of_dev_auxdata imx51_auxdata_lookup[] __initconst = {
>>  static int __init imx51_tzic_add_irq_domain(struct device_node *np,
>>  				struct device_node *interrupt_parent)
>>  {
>> -	irq_domain_add_simple(np, 0);
>> +	irq_domain_add_legacy(np, 32, 0, 0, &irq_domain_simple_ops, NULL);
>>  	return 0;
>>  }
>>  
>> @@ -57,7 +57,7 @@ static int __init imx51_gpio_add_irq_domain(struct device_node *np,
>>  	static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
>>  
>>  	gpio_irq_base -= 32;
>> -	irq_domain_add_simple(np, gpio_irq_base);
>> +	irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, NULL);
> 
> The tzic on imx5 gets 128 irq lines rather than 32 here.  The current
> code will make any hwirq that is > 32 hit the WARN_ON below in
> irq_domain_legacy_revmap().

But this is the gpio controller code? Really this should be 4 domains,
but this temp fix is probably fine until you use my generic irq chip
support.

Rob

> 
> 	WARN_ON(hwirq < first_hwirq || hwirq >= first_hwirq + size)
> 
> The first_hwirq is 0 and size is 32 in this case.
> 
> Changing 32 to 128 seems fixing the problem.
> 

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

* Re: [PATCH v3 14/25] irq_domain: Remove irq_domain_add_simple()
  2012-01-31 13:15     ` Rob Herring
@ 2012-01-31 13:58       ` Shawn Guo
  2012-02-01  0:08         ` Grant Likely
  0 siblings, 1 reply; 66+ messages in thread
From: Shawn Guo @ 2012-01-31 13:58 UTC (permalink / raw)
  To: Rob Herring
  Cc: Shawn Guo, Grant Likely, linux-kernel, Benjamin Herrenschmidt,
	Thomas Gleixner, Milton Miller, Stephen Rothwell,
	devicetree-discuss, linux-arm-kernel, linuxppc-dev

On Tue, Jan 31, 2012 at 07:15:26AM -0600, Rob Herring wrote:
...
> >> --- a/arch/arm/mach-mx5/imx51-dt.c
> >> +++ b/arch/arm/mach-mx5/imx51-dt.c
> >> @@ -47,7 +47,7 @@ static const struct of_dev_auxdata imx51_auxdata_lookup[] __initconst = {
> >>  static int __init imx51_tzic_add_irq_domain(struct device_node *np,
> >>  				struct device_node *interrupt_parent)
> >>  {
> >> -	irq_domain_add_simple(np, 0);
> >> +	irq_domain_add_legacy(np, 32, 0, 0, &irq_domain_simple_ops, NULL);
> >>  	return 0;
> >>  }
> >>  
> >> @@ -57,7 +57,7 @@ static int __init imx51_gpio_add_irq_domain(struct device_node *np,
> >>  	static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
> >>  
> >>  	gpio_irq_base -= 32;
> >> -	irq_domain_add_simple(np, gpio_irq_base);
> >> +	irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, NULL);
> > 
> > The tzic on imx5 gets 128 irq lines rather than 32 here.  The current
> > code will make any hwirq that is > 32 hit the WARN_ON below in
> > irq_domain_legacy_revmap().
> 
> But this is the gpio controller code? Really this should be 4 domains,
> but this temp fix is probably fine until you use my generic irq chip
> support.
> 
Sorry.  The comment was put at the wrong place.  It should be against
imx51_tzic_add_irq_domain() just above.

-- 
Regards,
Shawn


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

* Re: [PATCH v3 00/25] irq_domain generalization and refinement
  2012-01-31  4:53 ` Olof Johansson
@ 2012-02-01  0:07   ` Grant Likely
  0 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-02-01  0:07 UTC (permalink / raw)
  To: Olof Johansson
  Cc: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell, devicetree-discuss,
	linux-arm-kernel, linuxppc-dev

On Mon, Jan 30, 2012 at 08:53:44PM -0800, Olof Johansson wrote:
> On Fri, Jan 27, 2012 at 02:35:54PM -0700, Grant Likely wrote:
> > Hey everyone,
> > 
> > This patch series is ready for much wider consumption now.  I'd like
> > to get it into linux-next ASAP because there will be ARM board support
> > depending on it.  I'll wait a few days before I ask Stephen to pull
> > this in.
> > 
> > Stephen/Milton/Ben, any testing you can help with here would be
> > appreciated since you've got access to a wider variety of Power
> > machines than I do.
> 
> This series has been:
> 
> Tested-by: Olof Johansson <olof@lixom.net>
> 
> On powerpc/pasemi (it's the only one I still have easy access to).

Excellent, thanks Olof!

g.

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

* Re: [PATCH v3 14/25] irq_domain: Remove irq_domain_add_simple()
  2012-01-31 13:58       ` Shawn Guo
@ 2012-02-01  0:08         ` Grant Likely
  0 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-02-01  0:08 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Rob Herring, Shawn Guo, linux-kernel, Benjamin Herrenschmidt,
	Thomas Gleixner, Milton Miller, Stephen Rothwell,
	devicetree-discuss, linux-arm-kernel, linuxppc-dev

On Tue, Jan 31, 2012 at 09:58:22PM +0800, Shawn Guo wrote:
> On Tue, Jan 31, 2012 at 07:15:26AM -0600, Rob Herring wrote:
> ...
> > >> --- a/arch/arm/mach-mx5/imx51-dt.c
> > >> +++ b/arch/arm/mach-mx5/imx51-dt.c
> > >> @@ -47,7 +47,7 @@ static const struct of_dev_auxdata imx51_auxdata_lookup[] __initconst = {
> > >>  static int __init imx51_tzic_add_irq_domain(struct device_node *np,
> > >>  				struct device_node *interrupt_parent)
> > >>  {
> > >> -	irq_domain_add_simple(np, 0);
> > >> +	irq_domain_add_legacy(np, 32, 0, 0, &irq_domain_simple_ops, NULL);
> > >>  	return 0;
> > >>  }
> > >>  
> > >> @@ -57,7 +57,7 @@ static int __init imx51_gpio_add_irq_domain(struct device_node *np,
> > >>  	static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
> > >>  
> > >>  	gpio_irq_base -= 32;
> > >> -	irq_domain_add_simple(np, gpio_irq_base);
> > >> +	irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, NULL);
> > > 
> > > The tzic on imx5 gets 128 irq lines rather than 32 here.  The current
> > > code will make any hwirq that is > 32 hit the WARN_ON below in
> > > irq_domain_legacy_revmap().
> > 
> > But this is the gpio controller code? Really this should be 4 domains,
> > but this temp fix is probably fine until you use my generic irq chip
> > support.
> > 
> Sorry.  The comment was put at the wrong place.  It should be against
> imx51_tzic_add_irq_domain() just above.

I didn't know how large the bank was, so I just assumed 32.  If it should
be 128 then I'll change it.  Please confirm (or reply with a fixup patch)

g.


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

* [PATCH] irq_domain: fix the irq number of imx5 tzic
  2012-01-27 21:36 ` [PATCH v3 14/25] irq_domain: Remove irq_domain_add_simple() Grant Likely
  2012-01-31 12:45   ` Shawn Guo
@ 2012-02-01  5:46   ` Shawn Guo
  2012-02-02  4:58     ` Grant Likely
  1 sibling, 1 reply; 66+ messages in thread
From: Shawn Guo @ 2012-02-01  5:46 UTC (permalink / raw)
  To: linux-kernel, devicetree-discuss, linux-arm-kernel
  Cc: Grant Likely, Shawn Guo

The tzic controller found on imx51 and imx53 gets 128 irq lines rather
than 32.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/mach-mx5/imx51-dt.c |    2 +-
 arch/arm/mach-mx5/imx53-dt.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-mx5/imx51-dt.c b/arch/arm/mach-mx5/imx51-dt.c
index e1b5edf..1e03ef4 100644
--- a/arch/arm/mach-mx5/imx51-dt.c
+++ b/arch/arm/mach-mx5/imx51-dt.c
@@ -47,7 +47,7 @@ static const struct of_dev_auxdata imx51_auxdata_lookup[] __initconst = {
 static int __init imx51_tzic_add_irq_domain(struct device_node *np,
 				struct device_node *interrupt_parent)
 {
-	irq_domain_add_legacy(np, 32, 0, 0, &irq_domain_simple_ops, NULL);
+	irq_domain_add_legacy(np, 128, 0, 0, &irq_domain_simple_ops, NULL);
 	return 0;
 }
 
diff --git a/arch/arm/mach-mx5/imx53-dt.c b/arch/arm/mach-mx5/imx53-dt.c
index 89de5d4..fd5be0f 100644
--- a/arch/arm/mach-mx5/imx53-dt.c
+++ b/arch/arm/mach-mx5/imx53-dt.c
@@ -51,7 +51,7 @@ static const struct of_dev_auxdata imx53_auxdata_lookup[] __initconst = {
 static int __init imx53_tzic_add_irq_domain(struct device_node *np,
 				struct device_node *interrupt_parent)
 {
-	irq_domain_add_legacy(np, 32, 0, 0, &irq_domain_simple_ops, NULL);
+	irq_domain_add_legacy(np, 128, 0, 0, &irq_domain_simple_ops, NULL);
 	return 0;
 }
 
-- 
1.7.4.1



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

* Re: [PATCH v3 22/25] irq_domain/x86: Convert x86 (embedded) to use common irq_domain
  2012-01-30 19:58     ` Grant Likely
@ 2012-02-01 14:17       ` Sebastian Andrzej Siewior
  2012-02-01 18:06         ` Grant Likely
  0 siblings, 1 reply; 66+ messages in thread
From: Sebastian Andrzej Siewior @ 2012-02-01 14:17 UTC (permalink / raw)
  To: Grant Likely
  Cc: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell, devicetree-discuss,
	linux-arm-kernel, linuxppc-dev

* Grant Likely | 2012-01-30 12:58:42 [-0700]:

>Ugh.  This isn't easy.  The legacy mapping really needs all the

Feel free to merge this patch. I don't have the time to look at this now
so I take a look at the ioapic later.

>g.

Sebastian

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

* Re: [PATCH v3 22/25] irq_domain/x86: Convert x86 (embedded) to use common irq_domain
  2012-02-01 14:17       ` Sebastian Andrzej Siewior
@ 2012-02-01 18:06         ` Grant Likely
  2012-02-23 19:56           ` Grant Likely
  0 siblings, 1 reply; 66+ messages in thread
From: Grant Likely @ 2012-02-01 18:06 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell, devicetree-discuss,
	linux-arm-kernel, linuxppc-dev

On Wed, Feb 1, 2012 at 7:17 AM, Sebastian Andrzej Siewior
<bigeasy@linutronix.de> wrote:
> * Grant Likely | 2012-01-30 12:58:42 [-0700]:
>
>>Ugh.  This isn't easy.  The legacy mapping really needs all the
>
> Feel free to merge this patch. I don't have the time to look at this now
> so I take a look at the ioapic later.

There's no rush here.  I can leave it as-is with IRQ_DOMAIN turned off
for x86 for now.

g.

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

* Re: [PATCH] irq_domain: fix the irq number of imx5 tzic
  2012-02-01  5:46   ` [PATCH] irq_domain: fix the irq number of imx5 tzic Shawn Guo
@ 2012-02-02  4:58     ` Grant Likely
  0 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-02-02  4:58 UTC (permalink / raw)
  To: Shawn Guo; +Cc: linux-kernel, devicetree-discuss, linux-arm-kernel

On Wed, Feb 01, 2012 at 01:46:54PM +0800, Shawn Guo wrote:
> The tzic controller found on imx51 and imx53 gets 128 irq lines rather
> than 32.
> 
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>

Applied, thanks.

g.

> ---
>  arch/arm/mach-mx5/imx51-dt.c |    2 +-
>  arch/arm/mach-mx5/imx53-dt.c |    2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/mach-mx5/imx51-dt.c b/arch/arm/mach-mx5/imx51-dt.c
> index e1b5edf..1e03ef4 100644
> --- a/arch/arm/mach-mx5/imx51-dt.c
> +++ b/arch/arm/mach-mx5/imx51-dt.c
> @@ -47,7 +47,7 @@ static const struct of_dev_auxdata imx51_auxdata_lookup[] __initconst = {
>  static int __init imx51_tzic_add_irq_domain(struct device_node *np,
>  				struct device_node *interrupt_parent)
>  {
> -	irq_domain_add_legacy(np, 32, 0, 0, &irq_domain_simple_ops, NULL);
> +	irq_domain_add_legacy(np, 128, 0, 0, &irq_domain_simple_ops, NULL);
>  	return 0;
>  }
>  
> diff --git a/arch/arm/mach-mx5/imx53-dt.c b/arch/arm/mach-mx5/imx53-dt.c
> index 89de5d4..fd5be0f 100644
> --- a/arch/arm/mach-mx5/imx53-dt.c
> +++ b/arch/arm/mach-mx5/imx53-dt.c
> @@ -51,7 +51,7 @@ static const struct of_dev_auxdata imx53_auxdata_lookup[] __initconst = {
>  static int __init imx53_tzic_add_irq_domain(struct device_node *np,
>  				struct device_node *interrupt_parent)
>  {
> -	irq_domain_add_legacy(np, 32, 0, 0, &irq_domain_simple_ops, NULL);
> +	irq_domain_add_legacy(np, 128, 0, 0, &irq_domain_simple_ops, NULL);
>  	return 0;
>  }
>  
> -- 
> 1.7.4.1
> 
> 

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

* Re: [PATCH v3 13/25] irq_domain: Remove 'new' irq_domain in favour of the ppc one
  2012-01-27 21:36 ` [PATCH v3 13/25] irq_domain: Remove 'new' irq_domain in favour of the ppc one Grant Likely
@ 2012-02-03 14:48   ` Cousson, Benoit
  2012-02-03 16:42     ` Grant Likely
  0 siblings, 1 reply; 66+ messages in thread
From: Cousson, Benoit @ 2012-02-03 14:48 UTC (permalink / raw)
  To: Grant Likely
  Cc: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell, devicetree-discuss,
	linuxppc-dev, linux-arm-kernel

Hi Grant,

I finally had the time to rebase most of the OMAP3 and OMAP4 DT patches 
on your latest irq_domain series and found a couple of minors 
regressions that breaks OMAP3 boot.

On 1/27/2012 10:36 PM, Grant Likely wrote:

[...]

> diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
> index e04e04dd..aab236f 100644
> --- a/drivers/mfd/twl-core.c
> +++ b/drivers/mfd/twl-core.c
> @@ -263,8 +263,6 @@ struct twl_client {
>
>   static struct twl_client twl_modules[TWL_NUM_SLAVES];
>
> -static struct irq_domain domain;
> -
>   /* mapping the module id to slave id and base address */
>   struct twl_mapping {
>   	unsigned char sid;	/* Slave ID */
> @@ -1225,14 +1223,8 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
>
>   	pdata->irq_base = status;
>   	pdata->irq_end = pdata->irq_base + nr_irqs;
> -
> -	domain.irq_base = pdata->irq_base;
> -	domain.nr_irq = nr_irqs;
> -#ifdef CONFIG_OF_IRQ
> -	domain.of_node = of_node_get(node);
> -	domain.ops =&irq_domain_simple_ops;
> -#endif
> -	irq_domain_add(&domain);
> +	irq_domain_add_legacy(node, nr_irqs, pdata->irq_base, 0,
> +			&irq_domain_simple_ops);

This commit cannot build due to the missing last parameter.

And in fact you fixed that in the next commit (#14), but the will break 
git bisect and anyway that fix does not really belong to this commit.

[PATCH v3 14/25] irq_domain: Remove irq_domain_add_simple()

  	irq_domain_add_legacy(node, nr_irqs, pdata->irq_base, 0,
-			      &irq_domain_simple_ops);
+			      &irq_domain_simple_ops, NULL);


Moreover, it looks like this new irq_domain code is checking the number 
of hwirq and is not as lazy as the previous one :-)

Because of that and because of the wrong number of IRQs I put for the 
twl4030 :-(, it does not handle properly the children of the twl4030 now 
and print a big warning at boot time due to the following check.

   WARN_ON(hwirq < first_hwirq || hwirq >= first_hwirq + size)

In fact 8 was just the number for the core functionality, but that chip 
does have some other interrupts for sub function like GPIOs and power 
events.

With the following fix, it works fine.

Regards,
Benoit


---
 From 12781619d2ab8d6d724acabc6873954f0f9f4347 Mon Sep 17 00:00:00 2001
From: Benoit Cousson <b-cousson@ti.com>
Date: Fri, 3 Feb 2012 14:58:17 +0100
Subject: [PATCH] mfd: twl-core.c: Fix the number of interrupts managed 
by twl4030

TWL4030 does handle 3 different interrupts ranges: 8 for the core, 8 for 
the power events and 18 for the GPIOs.

Change the total number of interrupts managed by TWL4030 from 8 to 34.

Signed-off-by: Benoit Cousson <b-cousson@ti.com>
---
  drivers/mfd/twl-core.c |    2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index e63b408..66f9bff 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -149,7 +149,7 @@

  #define TWL_MODULE_LAST TWL4030_MODULE_LAST

-#define TWL4030_NR_IRQS    8
+#define TWL4030_NR_IRQS    34 /* core:8, power:8, gpio: 18 */
  #define TWL6030_NR_IRQS    20

  /* Base Address defns for twl4030_map[] */
-- 
1.7.0.4




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

* Re: [PATCH v3 13/25] irq_domain: Remove 'new' irq_domain in favour of the ppc one
  2012-02-03 14:48   ` Cousson, Benoit
@ 2012-02-03 16:42     ` Grant Likely
  0 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-02-03 16:42 UTC (permalink / raw)
  To: Cousson, Benoit
  Cc: Stephen Rothwell, Benjamin Herrenschmidt, devicetree-discuss,
	linux-kernel, Rob Herring, Milton Miller, Thomas Gleixner,
	linuxppc-dev, linux-arm-kernel

On Fri, Feb 03, 2012 at 03:48:09PM +0100, Cousson, Benoit wrote:
> Hi Grant,
> 
> I finally had the time to rebase most of the OMAP3 and OMAP4 DT
> patches on your latest irq_domain series and found a couple of
> minors regressions that breaks OMAP3 boot.
> 
> On 1/27/2012 10:36 PM, Grant Likely wrote:
> 
> [...]
> 
> >diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
> >index e04e04dd..aab236f 100644
> >--- a/drivers/mfd/twl-core.c
> >+++ b/drivers/mfd/twl-core.c
> >@@ -263,8 +263,6 @@ struct twl_client {
> >
> >  static struct twl_client twl_modules[TWL_NUM_SLAVES];
> >
> >-static struct irq_domain domain;
> >-
> >  /* mapping the module id to slave id and base address */
> >  struct twl_mapping {
> >  	unsigned char sid;	/* Slave ID */
> >@@ -1225,14 +1223,8 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
> >
> >  	pdata->irq_base = status;
> >  	pdata->irq_end = pdata->irq_base + nr_irqs;
> >-
> >-	domain.irq_base = pdata->irq_base;
> >-	domain.nr_irq = nr_irqs;
> >-#ifdef CONFIG_OF_IRQ
> >-	domain.of_node = of_node_get(node);
> >-	domain.ops =&irq_domain_simple_ops;
> >-#endif
> >-	irq_domain_add(&domain);
> >+	irq_domain_add_legacy(node, nr_irqs, pdata->irq_base, 0,
> >+			&irq_domain_simple_ops);
> 
> This commit cannot build due to the missing last parameter.
> 
> And in fact you fixed that in the next commit (#14), but the will
> break git bisect and anyway that fix does not really belong to this
> commit.
> 
> [PATCH v3 14/25] irq_domain: Remove irq_domain_add_simple()
> 
>  	irq_domain_add_legacy(node, nr_irqs, pdata->irq_base, 0,
> -			      &irq_domain_simple_ops);
> +			      &irq_domain_simple_ops, NULL);

Good catch, thanks.  I'll update the series to fix that.

> 
> 
> Moreover, it looks like this new irq_domain code is checking the
> number of hwirq and is not as lazy as the previous one :-)
> 
> Because of that and because of the wrong number of IRQs I put for
> the twl4030 :-(, it does not handle properly the children of the
> twl4030 now and print a big warning at boot time due to the
> following check.
> 
>   WARN_ON(hwirq < first_hwirq || hwirq >= first_hwirq + size)

Good! The warning is doing it's job.  :-)

> In fact 8 was just the number for the core functionality, but that
> chip does have some other interrupts for sub function like GPIOs and
> power events.

Okay, I'll add this patch to the series before patch 13.

> 
> With the following fix, it works fine.
> 
> Regards,
> Benoit
> 
> 
> ---
> From 12781619d2ab8d6d724acabc6873954f0f9f4347 Mon Sep 17 00:00:00 2001
> From: Benoit Cousson <b-cousson@ti.com>
> Date: Fri, 3 Feb 2012 14:58:17 +0100
> Subject: [PATCH] mfd: twl-core.c: Fix the number of interrupts
> managed by twl4030
> 
> TWL4030 does handle 3 different interrupts ranges: 8 for the core, 8
> for the power events and 18 for the GPIOs.
> 
> Change the total number of interrupts managed by TWL4030 from 8 to 34.
> 
> Signed-off-by: Benoit Cousson <b-cousson@ti.com>
> ---
>  drivers/mfd/twl-core.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
> index e63b408..66f9bff 100644
> --- a/drivers/mfd/twl-core.c
> +++ b/drivers/mfd/twl-core.c
> @@ -149,7 +149,7 @@
> 
>  #define TWL_MODULE_LAST TWL4030_MODULE_LAST
> 
> -#define TWL4030_NR_IRQS    8
> +#define TWL4030_NR_IRQS    34 /* core:8, power:8, gpio: 18 */
>  #define TWL6030_NR_IRQS    20
> 
>  /* Base Address defns for twl4030_map[] */
> -- 
> 1.7.0.4
> 
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 00/25] irq_domain generalization and refinement
  2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
                   ` (26 preceding siblings ...)
  2012-01-31  4:53 ` Olof Johansson
@ 2012-02-04 22:17 ` Russell King - ARM Linux
  2012-02-04 22:31   ` Russell King - ARM Linux
                     ` (3 more replies)
  27 siblings, 4 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-02-04 22:17 UTC (permalink / raw)
  To: Grant Likely
  Cc: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell, devicetree-discuss,
	linuxppc-dev, linux-arm-kernel

On Fri, Jan 27, 2012 at 02:35:54PM -0700, Grant Likely wrote:
> Hey everyone,
> 
> This patch series is ready for much wider consumption now.  I'd like
> to get it into linux-next ASAP because there will be ARM board support
> depending on it.  I'll wait a few days before I ask Stephen to pull
> this in.

Grant,

Can you answer me this: does this irqdomain support require DT?

The question comes up because OMAP has converted some of their support
to require irq domain support for their PMICs, and it seems irq domain
support requires DT.  This seems to have made the whole of OMAP
essentially become a DT-only platform.

Removing the dependency on IRQ_DOMAIN brings up these build errors
in the twl-core code (that being the PMIC for OMAP CPUs):

drivers/mfd/twl-core.c: In function 'twl_probe':
drivers/mfd/twl-core.c:1229: error: invalid use of undefined type 'struct irq_domain'
drivers/mfd/twl-core.c:1230: error: invalid use of undefined type 'struct irq_domain'
drivers/mfd/twl-core.c:1235: error: implicit declaration of function 'irq_domain_add'

That's a bit of a problem, because afaik there aren't the DT descriptions
for the boards I have yet, so it's causing me to see regressions when
building and booting kernels with CONFIG_OF=n.

The more core-code we end up with which requires DT, the worse this
problem is going to become - and obviously saying "everyone must now
convert to DT" is, even today, a mammoth task.

Now, here's the thing: I believe that IRQ domains - at least as far as
the hwirq stuff - should be available irrespective of whether we have
the rest of the IRQ domain support code in place, so that IRQ support
code doesn't have to keep playing games to decode from the global
space to the per-controller number space.

I believe that would certainly help the current OMAP problems, where
the current lack of CONFIG_IRQ_DOMAIN basically makes the kernel oops
on boot.

How we fix this regression for 3.4 I've no idea at present, I'm trying
to work out what the real dependencies are for OMAP on this stuff.

Finally, do we need asm/irq.h in our asm/prom.h ?  That's causing
fragility between DT and non-DT builds, because people are finding
that their DT builds work without their mach/irqs.h includes but
fail when built with non-DT.  The only thing which DT might need -
at the most - is NR_IRQS, but I'd hope with things like irq domains
it doesn't actually require it.

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

* Re: [PATCH v3 00/25] irq_domain generalization and refinement
  2012-02-04 22:17 ` Russell King - ARM Linux
@ 2012-02-04 22:31   ` Russell King - ARM Linux
  2012-02-05  1:38     ` Tony Lindgren
  2012-02-05  0:01   ` Benjamin Herrenschmidt
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-02-04 22:31 UTC (permalink / raw)
  To: Grant Likely
  Cc: Stephen Rothwell, Benjamin Herrenschmidt, devicetree-discuss,
	linux-kernel, Rob Herring, Milton Miller, Thomas Gleixner,
	linuxppc-dev, linux-arm-kernel

On Sat, Feb 04, 2012 at 10:17:48PM +0000, Russell King - ARM Linux wrote:
> On Fri, Jan 27, 2012 at 02:35:54PM -0700, Grant Likely wrote:
> > Hey everyone,
> > 
> > This patch series is ready for much wider consumption now.  I'd like
> > to get it into linux-next ASAP because there will be ARM board support
> > depending on it.  I'll wait a few days before I ask Stephen to pull
> > this in.
> 
> Grant,
> 
> Can you answer me this: does this irqdomain support require DT?
> 
> The question comes up because OMAP has converted some of their support
> to require irq domain support for their PMICs, and it seems irq domain
> support requires DT.  This seems to have made the whole of OMAP
> essentially become a DT-only platform.
> 
> Removing the dependency on IRQ_DOMAIN brings up these build errors
> in the twl-core code (that being the PMIC for OMAP CPUs):
> 
> drivers/mfd/twl-core.c: In function 'twl_probe':
> drivers/mfd/twl-core.c:1229: error: invalid use of undefined type 'struct irq_domain'
> drivers/mfd/twl-core.c:1230: error: invalid use of undefined type 'struct irq_domain'
> drivers/mfd/twl-core.c:1235: error: implicit declaration of function 'irq_domain_add'
> 
> That's a bit of a problem, because afaik there aren't the DT descriptions
> for the boards I have yet, so it's causing me to see regressions when
> building and booting kernels with CONFIG_OF=n.
> 
> The more core-code we end up with which requires DT, the worse this
> problem is going to become - and obviously saying "everyone must now
> convert to DT" is, even today, a mammoth task.
> 
> Now, here's the thing: I believe that IRQ domains - at least as far as
> the hwirq stuff - should be available irrespective of whether we have
> the rest of the IRQ domain support code in place, so that IRQ support
> code doesn't have to keep playing games to decode from the global
> space to the per-controller number space.
> 
> I believe that would certainly help the current OMAP problems, where
> the current lack of CONFIG_IRQ_DOMAIN basically makes the kernel oops
> on boot.
> 
> How we fix this regression for 3.4 I've no idea at present, I'm trying
> to work out what the real dependencies are for OMAP on this stuff.

Actually, it turns out to be not that hard, because twl doesn't actually
make use of the IRQ domain stuff:

commit aeb5032b3f8b9ab69daa545777433fa94b3494c4
Author:     Benoit Cousson <b-cousson@ti.com>
AuthorDate: Mon Aug 29 16:20:23 2011 +0200
Commit:     Samuel Ortiz <sameo@linux.intel.com>
CommitDate: Mon Jan 9 00:37:40 2012 +0100

    mfd: twl-core: Add initial DT support for twl4030/twl6030

    [grant.likely@secretlab.ca: Fix IRQ_DOMAIN dependency in kconfig]

Adding any dependency - especially one which wouldn't be enabled - for
a new feature which wasn't required before is going to break existing
users, so this shouldn't have been done in the first place.

A better fix to preserve existing users would've been as below - yes
it means more ifdefs, but if irq domain is to remain a DT only thing
then we're going to end up with _lots_ of this stuff.

I'd much prefer to see irq domain become more widely available so it
doesn't require these ifdefs everywhere.

 drivers/mfd/Kconfig    |    2 +-
 drivers/mfd/twl-core.c |    4 ++++
 2 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 28a301b..bd60ce0 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -200,7 +200,7 @@ config MENELAUS
 
 config TWL4030_CORE
 	bool "Texas Instruments TWL4030/TWL5030/TWL6030/TPS659x0 Support"
-	depends on I2C=y && GENERIC_HARDIRQS && IRQ_DOMAIN
+	depends on I2C=y && GENERIC_HARDIRQS
 	help
 	  Say yes here if you have TWL4030 / TWL6030 family chip on your board.
 	  This core driver provides register access and IRQ handling
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index e04e04d..5913aaa 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -263,7 +263,9 @@ struct twl_client {
 
 static struct twl_client twl_modules[TWL_NUM_SLAVES];
 
+#ifdef CONFIG_IRQ_DOMAIN
 static struct irq_domain domain;
+#endif
 
 /* mapping the module id to slave id and base address */
 struct twl_mapping {
@@ -1226,6 +1228,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	pdata->irq_base = status;
 	pdata->irq_end = pdata->irq_base + nr_irqs;
 
+#ifdef CONFIG_IRQ_DOMAIN
 	domain.irq_base = pdata->irq_base;
 	domain.nr_irq = nr_irqs;
 #ifdef CONFIG_OF_IRQ
@@ -1233,6 +1236,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	domain.ops = &irq_domain_simple_ops;
 #endif
 	irq_domain_add(&domain);
+#endif
 
 	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
 		dev_dbg(&client->dev, "can't talk I2C?\n");

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

* Re: [PATCH v3 00/25] irq_domain generalization and refinement
  2012-02-04 22:17 ` Russell King - ARM Linux
  2012-02-04 22:31   ` Russell King - ARM Linux
@ 2012-02-05  0:01   ` Benjamin Herrenschmidt
  2012-02-06  0:51   ` Rob Herring
  2012-02-06  5:56   ` Grant Likely
  3 siblings, 0 replies; 66+ messages in thread
From: Benjamin Herrenschmidt @ 2012-02-05  0:01 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Grant Likely, linux-kernel, Thomas Gleixner, Milton Miller,
	Rob Herring, Stephen Rothwell, devicetree-discuss, linuxppc-dev,
	linux-arm-kernel

On Sat, 2012-02-04 at 22:17 +0000, Russell King - ARM Linux wrote:
> On Fri, Jan 27, 2012 at 02:35:54PM -0700, Grant Likely wrote:
> > Hey everyone,
> > 
> > This patch series is ready for much wider consumption now.  I'd like
> > to get it into linux-next ASAP because there will be ARM board support
> > depending on it.  I'll wait a few days before I ask Stephen to pull
> > this in.
> 
> Grant,
> 
> Can you answer me this: does this irqdomain support require DT?

The original powerpc code this is based on didn't require it. It was an
explicit design decision and I remember insisting that Grant follows it,
but I haven't yet reviewed his last batch.

DT is orthogonal. You have "helpers" that use the DT to resolve the
domain of an interrupt source and do the mapping for you, but I made
sure that you call always still create domains and map interrupts using
explicit domain pointers & hw numbers.

(And I need them to deal with ancient broken device-tree's on some
platforms such as oldworld PowerMacs).

> The question comes up because OMAP has converted some of their support
> to require irq domain support for their PMICs, and it seems irq domain
> support requires DT.  This seems to have made the whole of OMAP
> essentially become a DT-only platform.

 .../...

> Now, here's the thing: I believe that IRQ domains - at least as far as
> the hwirq stuff - should be available irrespective of whether we have
> the rest of the IRQ domain support code in place, so that IRQ support
> code doesn't have to keep playing games to decode from the global
> space to the per-controller number space.
> 
> I believe that would certainly help the current OMAP problems, where
> the current lack of CONFIG_IRQ_DOMAIN basically makes the kernel oops
> on boot.
> 
> How we fix this regression for 3.4 I've no idea at present, I'm trying
> to work out what the real dependencies are for OMAP on this stuff.
> 
> Finally, do we need asm/irq.h in our asm/prom.h ?  That's causing
> fragility between DT and non-DT builds, because people are finding
> that their DT builds work without their mach/irqs.h includes but
> fail when built with non-DT.  The only thing which DT might need -
> at the most - is NR_IRQS, but I'd hope with things like irq domains
> it doesn't actually require it.

Cheers,
Ben.



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

* Re: [PATCH v3 00/25] irq_domain generalization and refinement
  2012-02-04 22:31   ` Russell King - ARM Linux
@ 2012-02-05  1:38     ` Tony Lindgren
  2012-02-05 16:13       ` Russell King - ARM Linux
  0 siblings, 1 reply; 66+ messages in thread
From: Tony Lindgren @ 2012-02-05  1:38 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Grant Likely, Stephen Rothwell, devicetree-discuss, linux-kernel,
	Milton Miller, Rob Herring, Thomas Gleixner, linuxppc-dev,
	linux-arm-kernel

* Russell King - ARM Linux <linux@arm.linux.org.uk> [120204 14:00]:
> 
> Actually, it turns out to be not that hard, because twl doesn't actually
> make use of the IRQ domain stuff:
> 
> commit aeb5032b3f8b9ab69daa545777433fa94b3494c4
> Author:     Benoit Cousson <b-cousson@ti.com>
> AuthorDate: Mon Aug 29 16:20:23 2011 +0200
> Commit:     Samuel Ortiz <sameo@linux.intel.com>
> CommitDate: Mon Jan 9 00:37:40 2012 +0100
> 
>     mfd: twl-core: Add initial DT support for twl4030/twl6030
> 
>     [grant.likely@secretlab.ca: Fix IRQ_DOMAIN dependency in kconfig]
> 
> Adding any dependency - especially one which wouldn't be enabled - for
> a new feature which wasn't required before is going to break existing
> users, so this shouldn't have been done in the first place.
> 
> A better fix to preserve existing users would've been as below - yes
> it means more ifdefs, but if irq domain is to remain a DT only thing
> then we're going to end up with _lots_ of this stuff.
> 
> I'd much prefer to see irq domain become more widely available so it
> doesn't require these ifdefs everywhere.

Your patch below looks like a correct fix to me to the problem
you and Grazvydas are seeing:

Acked-by: Tony Lindgren <tony@atomide.com>
 
>  drivers/mfd/Kconfig    |    2 +-
>  drivers/mfd/twl-core.c |    4 ++++
>  2 files changed, 5 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 28a301b..bd60ce0 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -200,7 +200,7 @@ config MENELAUS
>  
>  config TWL4030_CORE
>  	bool "Texas Instruments TWL4030/TWL5030/TWL6030/TPS659x0 Support"
> -	depends on I2C=y && GENERIC_HARDIRQS && IRQ_DOMAIN
> +	depends on I2C=y && GENERIC_HARDIRQS
>  	help
>  	  Say yes here if you have TWL4030 / TWL6030 family chip on your board.
>  	  This core driver provides register access and IRQ handling
> diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
> index e04e04d..5913aaa 100644
> --- a/drivers/mfd/twl-core.c
> +++ b/drivers/mfd/twl-core.c
> @@ -263,7 +263,9 @@ struct twl_client {
>  
>  static struct twl_client twl_modules[TWL_NUM_SLAVES];
>  
> +#ifdef CONFIG_IRQ_DOMAIN
>  static struct irq_domain domain;
> +#endif
>  
>  /* mapping the module id to slave id and base address */
>  struct twl_mapping {
> @@ -1226,6 +1228,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
>  	pdata->irq_base = status;
>  	pdata->irq_end = pdata->irq_base + nr_irqs;
>  
> +#ifdef CONFIG_IRQ_DOMAIN
>  	domain.irq_base = pdata->irq_base;
>  	domain.nr_irq = nr_irqs;
>  #ifdef CONFIG_OF_IRQ
> @@ -1233,6 +1236,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
>  	domain.ops = &irq_domain_simple_ops;
>  #endif
>  	irq_domain_add(&domain);
> +#endif
>  
>  	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
>  		dev_dbg(&client->dev, "can't talk I2C?\n");
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

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

* Re: [PATCH v3 00/25] irq_domain generalization and refinement
  2012-02-05  1:38     ` Tony Lindgren
@ 2012-02-05 16:13       ` Russell King - ARM Linux
  2012-02-07 15:26         ` Mark Brown
  0 siblings, 1 reply; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-02-05 16:13 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Grant Likely, Stephen Rothwell, devicetree-discuss, linux-kernel,
	Milton Miller, Rob Herring, Thomas Gleixner, linuxppc-dev,
	linux-arm-kernel

On Sat, Feb 04, 2012 at 05:38:53PM -0800, Tony Lindgren wrote:
> * Russell King - ARM Linux <linux@arm.linux.org.uk> [120204 14:00]:
> > 
> > Actually, it turns out to be not that hard, because twl doesn't actually
> > make use of the IRQ domain stuff:
> > 
> > commit aeb5032b3f8b9ab69daa545777433fa94b3494c4
> > Author:     Benoit Cousson <b-cousson@ti.com>
> > AuthorDate: Mon Aug 29 16:20:23 2011 +0200
> > Commit:     Samuel Ortiz <sameo@linux.intel.com>
> > CommitDate: Mon Jan 9 00:37:40 2012 +0100
> > 
> >     mfd: twl-core: Add initial DT support for twl4030/twl6030
> > 
> >     [grant.likely@secretlab.ca: Fix IRQ_DOMAIN dependency in kconfig]
> > 
> > Adding any dependency - especially one which wouldn't be enabled - for
> > a new feature which wasn't required before is going to break existing
> > users, so this shouldn't have been done in the first place.
> > 
> > A better fix to preserve existing users would've been as below - yes
> > it means more ifdefs, but if irq domain is to remain a DT only thing
> > then we're going to end up with _lots_ of this stuff.
> > 
> > I'd much prefer to see irq domain become more widely available so it
> > doesn't require these ifdefs everywhere.
> 
> Your patch below looks like a correct fix to me to the problem
> you and Grazvydas are seeing:
> 
> Acked-by: Tony Lindgren <tony@atomide.com>

It's not quite correct, because OMAP4 has issues in this area as well
(which does select IRQ_DOMAIN but can be without OF.)  The result is
an oops from irq_domain_add() because domain->ops is NULL.

The right solution is three fold:

1. Wrap the bits of code in CONFIG_IRQ_DOMAIN
2. Get rid of the #ifdef CONFIG_OF there, so the 'ops' member can be
   initialized.
3. Fix the OMAP vp code not to oops when voltdm->pmic is NULL

which I have in my combined patch for fixing OMAP so far.

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

* Re: [PATCH v3 00/25] irq_domain generalization and refinement
  2012-02-04 22:17 ` Russell King - ARM Linux
  2012-02-04 22:31   ` Russell King - ARM Linux
  2012-02-05  0:01   ` Benjamin Herrenschmidt
@ 2012-02-06  0:51   ` Rob Herring
  2012-02-06  5:56   ` Grant Likely
  3 siblings, 0 replies; 66+ messages in thread
From: Rob Herring @ 2012-02-06  0:51 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Grant Likely, Stephen Rothwell, devicetree-discuss, linux-kernel,
	Rob Herring, Milton Miller, Thomas Gleixner, linuxppc-dev,
	linux-arm-kernel

Russell,

On 02/04/2012 04:17 PM, Russell King - ARM Linux wrote:
> On Fri, Jan 27, 2012 at 02:35:54PM -0700, Grant Likely wrote:
>> Hey everyone,
>>
>> This patch series is ready for much wider consumption now.  I'd like
>> to get it into linux-next ASAP because there will be ARM board support
>> depending on it.  I'll wait a few days before I ask Stephen to pull
>> this in.
> 
> Grant,
> 
> Can you answer me this: does this irqdomain support require DT?
> 

No. It's the other way around, DT requires irqdomain. The GIC and VIC
code for example can be built with or w/o DT enabled, but both select
IRQ_DOMAIN.

FYI, I just submitted a patch that selects IRQ_DOMAIN for all of ARM:

http://www.gossamer-threads.com/lists/linux/kernel/1487231?page=last

Either we do that or we select IRQ_DOMAIN one irq_chip at a time. With
the "new" irq_domain code, we could probably do better to shrink the
code needed in the non-DT case.

> The question comes up because OMAP has converted some of their support
> to require irq domain support for their PMICs, and it seems irq domain
> support requires DT.  This seems to have made the whole of OMAP
> essentially become a DT-only platform.

I think we should select DT or not at the sub-arch level. Trying to
support both builds is a needless headache.

> 
> Removing the dependency on IRQ_DOMAIN brings up these build errors
> in the twl-core code (that being the PMIC for OMAP CPUs):
> 
> drivers/mfd/twl-core.c: In function 'twl_probe':
> drivers/mfd/twl-core.c:1229: error: invalid use of undefined type 'struct irq_domain'
> drivers/mfd/twl-core.c:1230: error: invalid use of undefined type 'struct irq_domain'
> drivers/mfd/twl-core.c:1235: error: implicit declaration of function 'irq_domain_add'
> 
> That's a bit of a problem, because afaik there aren't the DT descriptions
> for the boards I have yet, so it's causing me to see regressions when
> building and booting kernels with CONFIG_OF=n.
> 
> The more core-code we end up with which requires DT, the worse this
> problem is going to become - and obviously saying "everyone must now
> convert to DT" is, even today, a mammoth task.
> 
> Now, here's the thing: I believe that IRQ domains - at least as far as
> the hwirq stuff - should be available irrespective of whether we have
> the rest of the IRQ domain support code in place, so that IRQ support
> code doesn't have to keep playing games to decode from the global
> space to the per-controller number space.
> 
> I believe that would certainly help the current OMAP problems, where
> the current lack of CONFIG_IRQ_DOMAIN basically makes the kernel oops
> on boot.
> 
> How we fix this regression for 3.4 I've no idea at present, I'm trying
> to work out what the real dependencies are for OMAP on this stuff.
> 
> Finally, do we need asm/irq.h in our asm/prom.h ?  That's causing
> fragility between DT and non-DT builds, because people are finding
> that their DT builds work without their mach/irqs.h includes but
> fail when built with non-DT.  The only thing which DT might need -
> at the most - is NR_IRQS, but I'd hope with things like irq domains
> it doesn't actually require it.

Doesn't look like it is needed.

Rob

> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss


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

* Re: [PATCH v3 21/25] irqdomain/powerpc: Replace custom xlate functions with library functions
  2012-01-27 21:36 ` [PATCH v3 21/25] irqdomain/powerpc: Replace custom xlate functions with library functions Grant Likely
@ 2012-02-06  5:22   ` Michael Neuling
  2012-02-06  6:00     ` Grant Likely
  0 siblings, 1 reply; 66+ messages in thread
From: Michael Neuling @ 2012-02-06  5:22 UTC (permalink / raw)
  To: Grant Likely
  Cc: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell, devicetree-discuss,
	linuxppc-dev, linux-arm-kernel

>  static const struct irq_domain_ops pmac_pic_host_ops = {
>  	.match = pmac_pic_host_match,
>  	.map = pmac_pic_host_map,
> -	.xlate = pmac_pic_host_xlate,
> +	.xlate = irq_domain_xlate_onecell;
>  };
>  

This causes a compile fail (in next-20120206):
  arch/powerpc/platforms/powermac/pic.c:294: error: expected '}' before ';' token
Trivial fix below:



irqdomain/powerpc: Fix compile error in powermac/pic.c

Error introduced in:
  commit 72d6b477675374eafd206720d6c9146520df18ce
  Author: Grant Likely <grant.likely@secretlab.ca>
  irqdomain/powerpc: Replace custom xlate functions with library functions

Signed-off-by: Michael Neuling <mikey@neuling.org>

diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 3af29d1..92afc38 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -291,7 +291,7 @@ static int pmac_pic_host_map(struct irq_domain *h, unsigned int virq,
 static const struct irq_domain_ops pmac_pic_host_ops = {
 	.match = pmac_pic_host_match,
 	.map = pmac_pic_host_map,
-	.xlate = irq_domain_xlate_onecell;
+	.xlate = irq_domain_xlate_onecell,
 };
 
 static void __init pmac_pic_probe_oldstyle(void)

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

* Re: [PATCH v3 00/25] irq_domain generalization and refinement
  2012-02-04 22:17 ` Russell King - ARM Linux
                     ` (2 preceding siblings ...)
  2012-02-06  0:51   ` Rob Herring
@ 2012-02-06  5:56   ` Grant Likely
  3 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-02-06  5:56 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell, devicetree-discuss,
	linuxppc-dev, linux-arm-kernel

On Sat, Feb 04, 2012 at 10:17:48PM +0000, Russell King - ARM Linux wrote:
> On Fri, Jan 27, 2012 at 02:35:54PM -0700, Grant Likely wrote:
> > Hey everyone,
> > 
> > This patch series is ready for much wider consumption now.  I'd like
> > to get it into linux-next ASAP because there will be ARM board support
> > depending on it.  I'll wait a few days before I ask Stephen to pull
> > this in.
> 
> Grant,
> 
> Can you answer me this: does this irqdomain support require DT?

No, it should not.  Any situation where it does is a bug.

> Now, here's the thing: I believe that IRQ domains - at least as far as
> the hwirq stuff - should be available irrespective of whether we have
> the rest of the IRQ domain support code in place, so that IRQ support
> code doesn't have to keep playing games to decode from the global
> space to the per-controller number space.

Correct.  That's the intent.  My new series flushes out irq_domain quite a
bit better and gets all architectures doing the same thing if they use
irq_domains.  I've done some testing on both CONFIG_OF and !CONFIG_OF builds,
but I'm going to do some more to make sure I've not missed anything.

> I believe that would certainly help the current OMAP problems, where
> the current lack of CONFIG_IRQ_DOMAIN basically makes the kernel oops
> on boot.
> 
> How we fix this regression for 3.4 I've no idea at present, I'm trying
> to work out what the real dependencies are for OMAP on this stuff.
> 
> Finally, do we need asm/irq.h in our asm/prom.h ?  That's causing
> fragility between DT and non-DT builds, because people are finding
> that their DT builds work without their mach/irqs.h includes but
> fail when built with non-DT.  The only thing which DT might need -
> at the most - is NR_IRQS, but I'd hope with things like irq domains
> it doesn't actually require it.

I don't think so.  There may be a file or two that break because they're
not including everything they need, but I don't think anything in the
header requires it.

The irq_domain code is well isolated.  The header file doesn't need to
be including it.

g.

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

* Re: [PATCH v3 21/25] irqdomain/powerpc: Replace custom xlate functions with library functions
  2012-02-06  5:22   ` Michael Neuling
@ 2012-02-06  6:00     ` Grant Likely
  0 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-02-06  6:00 UTC (permalink / raw)
  To: Michael Neuling
  Cc: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell, devicetree-discuss,
	linuxppc-dev, linux-arm-kernel

On Mon, Feb 06, 2012 at 04:22:41PM +1100, Michael Neuling wrote:
> >  static const struct irq_domain_ops pmac_pic_host_ops = {
> >  	.match = pmac_pic_host_match,
> >  	.map = pmac_pic_host_map,
> > -	.xlate = pmac_pic_host_xlate,
> > +	.xlate = irq_domain_xlate_onecell;
> >  };
> >  
> 
> This causes a compile fail (in next-20120206):
>   arch/powerpc/platforms/powermac/pic.c:294: error: expected '}' before ';' token
> Trivial fix below:

fixed, thanks.

g.

> 
> 
> 
> irqdomain/powerpc: Fix compile error in powermac/pic.c
> 
> Error introduced in:
>   commit 72d6b477675374eafd206720d6c9146520df18ce
>   Author: Grant Likely <grant.likely@secretlab.ca>
>   irqdomain/powerpc: Replace custom xlate functions with library functions
> 
> Signed-off-by: Michael Neuling <mikey@neuling.org>
> 
> diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
> index 3af29d1..92afc38 100644
> --- a/arch/powerpc/platforms/powermac/pic.c
> +++ b/arch/powerpc/platforms/powermac/pic.c
> @@ -291,7 +291,7 @@ static int pmac_pic_host_map(struct irq_domain *h, unsigned int virq,
>  static const struct irq_domain_ops pmac_pic_host_ops = {
>  	.match = pmac_pic_host_match,
>  	.map = pmac_pic_host_map,
> -	.xlate = irq_domain_xlate_onecell;
> +	.xlate = irq_domain_xlate_onecell,
>  };
>  
>  static void __init pmac_pic_probe_oldstyle(void)

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

* Re: [PATCH v3 00/25] irq_domain generalization and refinement
  2012-02-05 16:13       ` Russell King - ARM Linux
@ 2012-02-07 15:26         ` Mark Brown
  2012-02-15 20:33           ` Grant Likely
  0 siblings, 1 reply; 66+ messages in thread
From: Mark Brown @ 2012-02-07 15:26 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Tony Lindgren, Stephen Rothwell, devicetree-discuss,
	linux-kernel, Rob Herring, Milton Miller, Thomas Gleixner,
	linuxppc-dev, linux-arm-kernel

On Sun, Feb 05, 2012 at 04:13:48PM +0000, Russell King - ARM Linux wrote:

> It's not quite correct, because OMAP4 has issues in this area as well
> (which does select IRQ_DOMAIN but can be without OF.)  The result is
> an oops from irq_domain_add() because domain->ops is NULL.

> The right solution is three fold:

> 1. Wrap the bits of code in CONFIG_IRQ_DOMAIN
> 2. Get rid of the #ifdef CONFIG_OF there, so the 'ops' member can be
>    initialized.
> 3. Fix the OMAP vp code not to oops when voltdm->pmic is NULL

> which I have in my combined patch for fixing OMAP so far.

It'd also help if we supported null ops, I sent patches for that a few
times over the 3.3 cycle since I was running into it on my systems but
apparently to /dev/null and further changes in this area have made the
patches not apply any more.

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

* Re: [PATCH v3 24/25] irq_domain: remove "hint" when allocating irq numbers
  2012-01-27 21:36 ` [PATCH v3 24/25] irq_domain: remove "hint" when allocating irq numbers Grant Likely
@ 2012-02-07 18:07   ` Nicolas Ferre
  2012-02-15 15:04     ` Nicolas Ferre
  0 siblings, 1 reply; 66+ messages in thread
From: Nicolas Ferre @ 2012-02-07 18:07 UTC (permalink / raw)
  To: Grant Likely
  Cc: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell, devicetree-discuss,
	linuxppc-dev, linux-arm-kernel

On 01/27/2012 10:36 PM, Grant Likely :
> The 'hint' used to try and line up irq numbers with hw irq numbers is
> rather a hack and not very useful.  Now that /proc/interrupts also outputs
> the hwirq number, it is even less useful to keep around the 'hint' heuristic.
> 
> This patch removes it.

Grant,

While trying your patch series in conjunction with Rob one, I do not
find this patch in your irqdomain/next branch (and a couple of others).
Can you tell me if this v3 series is available as a git tree?

Thanks, best regards,
-- 
Nicolas Ferre

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

* Re: [PATCH v3 24/25] irq_domain: remove "hint" when allocating irq numbers
  2012-02-07 18:07   ` Nicolas Ferre
@ 2012-02-15 15:04     ` Nicolas Ferre
  2012-02-15 20:21       ` Grant Likely
  0 siblings, 1 reply; 66+ messages in thread
From: Nicolas Ferre @ 2012-02-15 15:04 UTC (permalink / raw)
  To: Grant Likely, devicetree-discuss, Rob Herring
  Cc: Stephen Rothwell, linux-kernel, Milton Miller, Thomas Gleixner,
	linuxppc-dev, linux-arm-kernel

On 02/07/2012 07:07 PM, Nicolas Ferre :
> On 01/27/2012 10:36 PM, Grant Likely :
>> The 'hint' used to try and line up irq numbers with hw irq numbers is
>> rather a hack and not very useful.  Now that /proc/interrupts also outputs
>> the hwirq number, it is even less useful to keep around the 'hint' heuristic.
>>
>> This patch removes it.
> 
> Grant,
> 
> While trying your patch series in conjunction with Rob one, I do not
> find this patch in your irqdomain/next branch (and a couple of others).
> Can you tell me if this v3 series is available as a git tree?

I am still interested by patch 24-25 of this series but still cannot
find them in your irqdomain/next branch:
Are they also expected to join the 3.4 merge window material?

Bye,
-- 
Nicolas Ferre

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

* Re: [PATCH v3 25/25] irq_domain: mostly eliminate slow-path revmap lookups
  2012-01-27 21:36 ` [PATCH v3 25/25] irq_domain: mostly eliminate slow-path revmap lookups Grant Likely
@ 2012-02-15 16:36   ` Nicolas Ferre
  2012-02-15 20:29     ` Grant Likely
  0 siblings, 1 reply; 66+ messages in thread
From: Nicolas Ferre @ 2012-02-15 16:36 UTC (permalink / raw)
  To: Grant Likely, devicetree-discuss
  Cc: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell, linuxppc-dev,
	linux-arm-kernel

Grant,

I do not know if it is the latest revision but I have identified some
issues on error/slow paths...


On 01/27/2012 10:36 PM, Grant Likely :
> With the current state of irq_domain, the reverse map is always used when
> new IRQs get mapped.  This means that the irq_find_mapping() function
> can be simplified to always call out to the revmap-specific lookup function.
> 
> This patch adds lookup functions for the revmaps that don't yet have one
> and removes the slow path lookup from most of the code paths.  The only
> place where the slow path legitimately remains is when the linear map
> is used with a hwirq number larger than the revmap size.
> 
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Milton Miller <miltonm@bga.com>
> ---
>  arch/powerpc/sysdev/xics/xics-common.c |    3 -
>  include/linux/irqdomain.h              |    3 +-
>  kernel/irq/irqdomain.c                 |   94 +++++++++++++++++---------------
>  3 files changed, 51 insertions(+), 49 deletions(-)
> 
> diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
> index ea5e204..1d7067d 100644
> --- a/arch/powerpc/sysdev/xics/xics-common.c
> +++ b/arch/powerpc/sysdev/xics/xics-common.c
> @@ -330,9 +330,6 @@ static int xics_host_map(struct irq_domain *h, unsigned int virq,
>  
>  	pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hw);
>  
> -	/* Insert the interrupt mapping into the radix tree for fast lookup */
> -	irq_radix_revmap_insert(xics_host, virq, hw);
> -
>  	/* They aren't all level sensitive but we just don't really know */
>  	irq_set_status_flags(virq, IRQ_LEVEL);
>  
> diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
> index 0b00f83..38314f2 100644
> --- a/include/linux/irqdomain.h
> +++ b/include/linux/irqdomain.h
> @@ -93,6 +93,7 @@ struct irq_domain {
>  	struct list_head link;
>  
>  	/* type of reverse mapping_technique */
> +	unsigned int (*revmap)(struct irq_domain *host, irq_hw_number_t hwirq);
>  	unsigned int revmap_type;
>  	union {
>  		struct {
> @@ -155,8 +156,6 @@ extern void irq_dispose_mapping(unsigned int virq);
>  extern unsigned int irq_find_mapping(struct irq_domain *host,
>  				     irq_hw_number_t hwirq);
>  extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
> -extern void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq,
> -				    irq_hw_number_t hwirq);
>  extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
>  					    irq_hw_number_t hwirq);
>  extern unsigned int irq_linear_revmap(struct irq_domain *host,
> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> index 5b4fc4d..91c1cb7 100644
> --- a/kernel/irq/irqdomain.c
> +++ b/kernel/irq/irqdomain.c
> @@ -104,6 +104,7 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
>  	domain->revmap_data.legacy.first_irq = first_irq;
>  	domain->revmap_data.legacy.first_hwirq = first_hwirq;
>  	domain->revmap_data.legacy.size = size;
> +	domain->revmap = irq_domain_legacy_revmap;
>  
>  	mutex_lock(&irq_domain_mutex);
>  	/* Verify that all the irqs are available */
> @@ -174,18 +175,35 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
>  	}
>  	domain->revmap_data.linear.size = size;
>  	domain->revmap_data.linear.revmap = revmap;
> +	domain->revmap = irq_linear_revmap;
>  	irq_domain_add(domain);
>  	return domain;
>  }
>  
> +static unsigned int irq_domain_nomap_revmap(struct irq_domain *domain,
> +					    irq_hw_number_t hwirq)
> +{
> +	struct irq_data *data = irq_get_irq_data(hwirq);
> +
> +	if (WARN_ON_ONCE(domain->revmap_type != IRQ_DOMAIN_MAP_NOMAP))
> +		return irq_find_mapping(domain, hwirq);

Should be:
		return irq_find_mapping_slow(domain, hwirq);

Recursion otherwise...


> +
> +	/* Verify that the map has actually been established */
> +	if (data && (data->domain == domain) && (data->hwirq == hwirq))
> +		return hwirq;
> +	return 0;
> +}
> +
>  struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
>  					 const struct irq_domain_ops *ops,
>  					 void *host_data)
>  {
>  	struct irq_domain *domain = irq_domain_alloc(of_node,
>  					IRQ_DOMAIN_MAP_NOMAP, ops, host_data);
> -	if (domain)
> +	if (domain) {
> +		domain->revmap = irq_domain_nomap_revmap;
>  		irq_domain_add(domain);
> +	}
>  	return domain;
>  }
>  
> @@ -205,6 +223,7 @@ struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
>  					IRQ_DOMAIN_MAP_TREE, ops, host_data);
>  	if (domain) {
>  		INIT_RADIX_TREE(&domain->revmap_data.tree, GFP_KERNEL);
> +		domain->revmap = irq_radix_revmap_lookup;
>  		irq_domain_add(domain);
>  	}
>  	return domain;
> @@ -378,6 +397,19 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
>  		return 0;
>  	}
>  
> +	switch(domain->revmap_type) {
> +	case IRQ_DOMAIN_MAP_LINEAR:
> +		if (hwirq < domain->revmap_data.linear.size)
> +			domain->revmap_data.linear.revmap[hwirq] = irq;
> +		break;
> +	case IRQ_DOMAIN_MAP_TREE:
> +		mutex_lock(&revmap_trees_mutex);
> +		radix_tree_insert(&domain->revmap_data.tree, hwirq,
> +				  irq_get_irq_data(irq));
> +		mutex_unlock(&revmap_trees_mutex);
> +
> +		break;
> +	}
>  	pr_debug("irq: irq %lu on domain %s mapped to virtual irq %u\n",
>  		hwirq, domain->of_node ? domain->of_node->full_name : "null", virq);
>  
> @@ -478,25 +510,27 @@ EXPORT_SYMBOL_GPL(irq_dispose_mapping);
>   * irq_find_mapping() - Find a linux irq from an hw irq number.
>   * @domain: domain owning this hardware interrupt
>   * @hwirq: hardware irq number in that domain space
> - *
> - * This is a slow path, for use by generic code. It's expected that an
> - * irq controller implementation directly calls the appropriate low level
> - * mapping function.
>   */
>  unsigned int irq_find_mapping(struct irq_domain *domain,
>  			      irq_hw_number_t hwirq)
>  {
> -	unsigned int i;
> -
> -	/* Look for default domain if nececssary */
> -	if (domain == NULL)
> +	if (!domain)
>  		domain = irq_default_domain;
> -	if (domain == NULL)
> -		return 0;
> +	return domain ? domain->revmap(domain, hwirq) : 0;
> +}
> +EXPORT_SYMBOL_GPL(irq_find_mapping);
>  
> -	/* legacy -> bail early */
> -	if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
> -		return irq_domain_legacy_revmap(domain, hwirq);
> +/**
> + * irq_find_mapping_slow() - slow path for finding the irq mapped to a hwirq
> + *
> + * This is the failsafe slow path for finding an irq mapping.  The only time
> + * this will reasonably get called is when the linear map is used with a
> + * hwirq number larger than the size of the reverse map.
> + */
> +static unsigned int irq_find_mapping_slow(struct irq_domain *domain,
> +					  irq_hw_number_t hwirq)
> +{
> +	int i;
>  
>  	/* Slow path does a linear search of the map */
>  	for (i = 0; i < irq_virq_count; i++)  {
> @@ -506,7 +540,6 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
>  	}
>  	return 0;
>  }
> -EXPORT_SYMBOL_GPL(irq_find_mapping);
>  
>  /**
>   * irq_radix_revmap_lookup() - Find a linux irq from a hw irq number.
> @@ -537,31 +570,7 @@ unsigned int irq_radix_revmap_lookup(struct irq_domain *domain,
>  	 * Else fallback to linear lookup - this should not happen in practice
>  	 * as it means that we failed to insert the node in the radix tree.
>  	 */
> -	return irq_data ? irq_data->irq : irq_find_mapping(domain, hwirq);
> -}
> -
> -/**
> - * irq_radix_revmap_insert() - Insert a hw irq to linux irq number mapping.
> - * @domain: domain owning this hardware interrupt
> - * @virq: linux irq number
> - * @hwirq: hardware irq number in that domain space
> - *
> - * This is for use by irq controllers that use a radix tree reverse
> - * mapping for fast lookup.
> - */
> -void irq_radix_revmap_insert(struct irq_domain *domain, unsigned int virq,
> -			     irq_hw_number_t hwirq)
> -{
> -	struct irq_data *irq_data = irq_get_irq_data(virq);
> -
> -	if (WARN_ON(domain->revmap_type != IRQ_DOMAIN_MAP_TREE))
> -		return;
> -
> -	if (virq) {
> -		mutex_lock(&revmap_trees_mutex);
> -		radix_tree_insert(&domain->revmap_data.tree, hwirq, irq_data);
> -		mutex_unlock(&revmap_trees_mutex);
> -	}
> +	return irq_data ? irq_data->irq : irq_find_mapping_slow(domain, hwirq);
>  }
>  
>  /**
> @@ -585,14 +594,11 @@ unsigned int irq_linear_revmap(struct irq_domain *domain,
>  	if (unlikely(hwirq >= domain->revmap_data.linear.size))
>  		return irq_find_mapping(domain, hwirq);

Ditto here. And same whith previous one in same function. Check in
irq_radix_revmap_lookup() there is the same issue on the "WARN_ON_ONCE"
path...

>  
> -	/* Check if revmap was allocated */
>  	revmap = domain->revmap_data.linear.revmap;
> -	if (unlikely(revmap == NULL))
> -		return irq_find_mapping(domain, hwirq);
>  
>  	/* Fill up revmap with slow path if no mapping found */
>  	if (unlikely(!revmap[hwirq]))
> -		revmap[hwirq] = irq_find_mapping(domain, hwirq);
> +		revmap[hwirq] = irq_find_mapping_slow(domain, hwirq);
>  
>  	return revmap[hwirq];
>  }

Bye,
-- 
Nicolas Ferre

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

* Re: [PATCH v3 24/25] irq_domain: remove "hint" when allocating irq numbers
  2012-02-15 15:04     ` Nicolas Ferre
@ 2012-02-15 20:21       ` Grant Likely
  2012-02-15 21:50         ` Shawn Guo
  0 siblings, 1 reply; 66+ messages in thread
From: Grant Likely @ 2012-02-15 20:21 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: devicetree-discuss, Rob Herring, Stephen Rothwell, linux-kernel,
	Milton Miller, Thomas Gleixner, linuxppc-dev, linux-arm-kernel

On Wed, Feb 15, 2012 at 04:04:28PM +0100, Nicolas Ferre wrote:
> On 02/07/2012 07:07 PM, Nicolas Ferre :
> > On 01/27/2012 10:36 PM, Grant Likely :
> >> The 'hint' used to try and line up irq numbers with hw irq numbers is
> >> rather a hack and not very useful.  Now that /proc/interrupts also outputs
> >> the hwirq number, it is even less useful to keep around the 'hint' heuristic.
> >>
> >> This patch removes it.
> > 
> > Grant,
> > 
> > While trying your patch series in conjunction with Rob one, I do not
> > find this patch in your irqdomain/next branch (and a couple of others).
> > Can you tell me if this v3 series is available as a git tree?
> 
> I am still interested by patch 24-25 of this series but still cannot
> find them in your irqdomain/next branch:
> Are they also expected to join the 3.4 merge window material?

I've held off on putting them in irqdomain/next because they are a bit more
risky than the other patches, and I want an explicit ack from Ben for patches
24 & 25.  However, that shouldn't really cause any issues since the changes
in 24 & 25 don't impact the irq_domain functionality or API.  They are just
optimizations.

Also on 25, I'm not yet convinced that breaking out the revmap functions
into ops is the right thing to do.  It actually makes the .text size quite
a bit larger.  I may very well rewrite it.

g.


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

* Re: [PATCH v3 25/25] irq_domain: mostly eliminate slow-path revmap lookups
  2012-02-15 16:36   ` Nicolas Ferre
@ 2012-02-15 20:29     ` Grant Likely
  0 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-02-15 20:29 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: devicetree-discuss, linux-kernel, Benjamin Herrenschmidt,
	Thomas Gleixner, Milton Miller, Rob Herring, Stephen Rothwell,
	linuxppc-dev, linux-arm-kernel

On Wed, Feb 15, 2012 at 05:36:46PM +0100, Nicolas Ferre wrote:
> Grant,
> 
> I do not know if it is the latest revision but I have identified some
> issues on error/slow paths...
> 
> 
> On 01/27/2012 10:36 PM, Grant Likely :
> > With the current state of irq_domain, the reverse map is always used when
> > new IRQs get mapped.  This means that the irq_find_mapping() function
> > can be simplified to always call out to the revmap-specific lookup function.
> > 
> > This patch adds lookup functions for the revmaps that don't yet have one
> > and removes the slow path lookup from most of the code paths.  The only
> > place where the slow path legitimately remains is when the linear map
> > is used with a hwirq number larger than the revmap size.
> > 
> > Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > Cc: Milton Miller <miltonm@bga.com>
> > ---
> >  arch/powerpc/sysdev/xics/xics-common.c |    3 -
> >  include/linux/irqdomain.h              |    3 +-
> >  kernel/irq/irqdomain.c                 |   94 +++++++++++++++++---------------
> >  3 files changed, 51 insertions(+), 49 deletions(-)
> > 
> > diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
> > index ea5e204..1d7067d 100644
> > --- a/arch/powerpc/sysdev/xics/xics-common.c
> > +++ b/arch/powerpc/sysdev/xics/xics-common.c
> > @@ -330,9 +330,6 @@ static int xics_host_map(struct irq_domain *h, unsigned int virq,
> >  
> >  	pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hw);
> >  
> > -	/* Insert the interrupt mapping into the radix tree for fast lookup */
> > -	irq_radix_revmap_insert(xics_host, virq, hw);
> > -
> >  	/* They aren't all level sensitive but we just don't really know */
> >  	irq_set_status_flags(virq, IRQ_LEVEL);
> >  
> > diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
> > index 0b00f83..38314f2 100644
> > --- a/include/linux/irqdomain.h
> > +++ b/include/linux/irqdomain.h
> > @@ -93,6 +93,7 @@ struct irq_domain {
> >  	struct list_head link;
> >  
> >  	/* type of reverse mapping_technique */
> > +	unsigned int (*revmap)(struct irq_domain *host, irq_hw_number_t hwirq);
> >  	unsigned int revmap_type;
> >  	union {
> >  		struct {
> > @@ -155,8 +156,6 @@ extern void irq_dispose_mapping(unsigned int virq);
> >  extern unsigned int irq_find_mapping(struct irq_domain *host,
> >  				     irq_hw_number_t hwirq);
> >  extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
> > -extern void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq,
> > -				    irq_hw_number_t hwirq);
> >  extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
> >  					    irq_hw_number_t hwirq);
> >  extern unsigned int irq_linear_revmap(struct irq_domain *host,
> > diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> > index 5b4fc4d..91c1cb7 100644
> > --- a/kernel/irq/irqdomain.c
> > +++ b/kernel/irq/irqdomain.c
> > @@ -104,6 +104,7 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
> >  	domain->revmap_data.legacy.first_irq = first_irq;
> >  	domain->revmap_data.legacy.first_hwirq = first_hwirq;
> >  	domain->revmap_data.legacy.size = size;
> > +	domain->revmap = irq_domain_legacy_revmap;
> >  
> >  	mutex_lock(&irq_domain_mutex);
> >  	/* Verify that all the irqs are available */
> > @@ -174,18 +175,35 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
> >  	}
> >  	domain->revmap_data.linear.size = size;
> >  	domain->revmap_data.linear.revmap = revmap;
> > +	domain->revmap = irq_linear_revmap;
> >  	irq_domain_add(domain);
> >  	return domain;
> >  }
> >  
> > +static unsigned int irq_domain_nomap_revmap(struct irq_domain *domain,
> > +					    irq_hw_number_t hwirq)
> > +{
> > +	struct irq_data *data = irq_get_irq_data(hwirq);
> > +
> > +	if (WARN_ON_ONCE(domain->revmap_type != IRQ_DOMAIN_MAP_NOMAP))
> > +		return irq_find_mapping(domain, hwirq);
> 
> Should be:
> 		return irq_find_mapping_slow(domain, hwirq);
> 
> Recursion otherwise...

Good catch; but it's not the whole story.  Part of the problem when looking
at the other revmap functions is that the revmaps can be called by external
code and there is the possibility that the wrong revmap got called.  In that
case, calling the normal path is the right thing to do.  However, it is also
possible (but unlikely) to have a ->revmap() and ->revmap_type mismatch where
calling the normal path would indeed cause a recursion.

So, the whole ->revmap thing is a weak design and needs to be rethought.

However, for the time being, I'll change all the revmaps to use the slow
path because it is safer.

g.

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

* Re: [PATCH v3 00/25] irq_domain generalization and refinement
  2012-02-07 15:26         ` Mark Brown
@ 2012-02-15 20:33           ` Grant Likely
  0 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-02-15 20:33 UTC (permalink / raw)
  To: Mark Brown
  Cc: Russell King - ARM Linux, Tony Lindgren, Stephen Rothwell,
	devicetree-discuss, linux-kernel, Rob Herring, Milton Miller,
	Thomas Gleixner, linuxppc-dev, linux-arm-kernel

On Tue, Feb 07, 2012 at 03:26:27PM +0000, Mark Brown wrote:
> On Sun, Feb 05, 2012 at 04:13:48PM +0000, Russell King - ARM Linux wrote:
> 
> > It's not quite correct, because OMAP4 has issues in this area as well
> > (which does select IRQ_DOMAIN but can be without OF.)  The result is
> > an oops from irq_domain_add() because domain->ops is NULL.
> 
> > The right solution is three fold:
> 
> > 1. Wrap the bits of code in CONFIG_IRQ_DOMAIN
> > 2. Get rid of the #ifdef CONFIG_OF there, so the 'ops' member can be
> >    initialized.
> > 3. Fix the OMAP vp code not to oops when voltdm->pmic is NULL
> 
> > which I have in my combined patch for fixing OMAP so far.
> 
> It'd also help if we supported null ops, I sent patches for that a few
> times over the 3.3 cycle since I was running into it on my systems but
> apparently to /dev/null and further changes in this area have made the
> patches not apply any more.

I've avoided allowing null ops so that the drivers are forced to be explicit
about what they want, and it makes for (IMHO) simpler to follow code in the
core.

Sorry I missed your patches though.

g.

> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

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

* Re: [PATCH v3 24/25] irq_domain: remove "hint" when allocating irq numbers
  2012-02-15 20:21       ` Grant Likely
@ 2012-02-15 21:50         ` Shawn Guo
  2012-02-16  5:32           ` Grant Likely
  0 siblings, 1 reply; 66+ messages in thread
From: Shawn Guo @ 2012-02-15 21:50 UTC (permalink / raw)
  To: Grant Likely
  Cc: Nicolas Ferre, devicetree-discuss, Rob Herring, Stephen Rothwell,
	linux-kernel, Milton Miller, Thomas Gleixner, linuxppc-dev,
	linux-arm-kernel

On Wed, Feb 15, 2012 at 01:21:45PM -0700, Grant Likely wrote:
> On Wed, Feb 15, 2012 at 04:04:28PM +0100, Nicolas Ferre wrote:
> > On 02/07/2012 07:07 PM, Nicolas Ferre :
> > > On 01/27/2012 10:36 PM, Grant Likely :
> > >> The 'hint' used to try and line up irq numbers with hw irq numbers is
> > >> rather a hack and not very useful.  Now that /proc/interrupts also outputs
> > >> the hwirq number, it is even less useful to keep around the 'hint' heuristic.
> > >>
> > >> This patch removes it.
> > > 
> > > Grant,
> > > 
> > > While trying your patch series in conjunction with Rob one, I do not
> > > find this patch in your irqdomain/next branch (and a couple of others).
> > > Can you tell me if this v3 series is available as a git tree?
> > 
> > I am still interested by patch 24-25 of this series but still cannot
> > find them in your irqdomain/next branch:
> > Are they also expected to join the 3.4 merge window material?
> 
> I've held off on putting them in irqdomain/next because they are a bit more
> risky than the other patches, and I want an explicit ack from Ben for patches
> 24 & 25.  However, that shouldn't really cause any issues since the changes
> in 24 & 25 don't impact the irq_domain functionality or API.  They are just
> optimizations.
> 
I'm seeing that patch 24 does impact on irq_domain functionality
a little bit.  On next tree which has no this patch yet,
irq_create_mapping can reasonably create virq in range 1..15, while
irq_find_mapping will only try to find the virq from 16
(NUM_ISA_INTERRUPTS).  This will result in that any hwirq that is < 16
gets multiple entries in the mapping table with different virq numbers
mapped to the same one hwirq.

That's why I have to apply patch #24 (with one line change below) on
top of next tree to get my imx irqdomain series work properly.

@@ -371,7 +371,7 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
                return irq_domain_legacy_revmap(domain, hwirq);
 
        /* Allocate a virtual interrupt number */
-       virq = irq_alloc_desc(0);
+       virq = irq_alloc_desc_from(1, 0);
        if (!virq) {
                pr_debug("irq: -> virq allocation failed\n");
                return 0;

I need this line of change, because the first call on irq_alloc_desc
will always return 0 to virq and in turn irq_create_mapping fails.
On imx, that's the mapping for timer irq.  Hence, the system will hang
there due to irq mapping failure.

-- 
Regards,
Shawn

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

* Re: [PATCH v3 24/25] irq_domain: remove "hint" when allocating irq numbers
  2012-02-15 21:50         ` Shawn Guo
@ 2012-02-16  5:32           ` Grant Likely
  2012-02-16  6:03             ` Shawn Guo
  0 siblings, 1 reply; 66+ messages in thread
From: Grant Likely @ 2012-02-16  5:32 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Nicolas Ferre, devicetree-discuss, Rob Herring, Stephen Rothwell,
	linux-kernel, Milton Miller, Thomas Gleixner, linuxppc-dev,
	linux-arm-kernel

On Wed, Feb 15, 2012 at 01:50:02PM -0800, Shawn Guo wrote:
> On Wed, Feb 15, 2012 at 01:21:45PM -0700, Grant Likely wrote:
> > On Wed, Feb 15, 2012 at 04:04:28PM +0100, Nicolas Ferre wrote:
> > > On 02/07/2012 07:07 PM, Nicolas Ferre :
> > > > On 01/27/2012 10:36 PM, Grant Likely :
> > > >> The 'hint' used to try and line up irq numbers with hw irq numbers is
> > > >> rather a hack and not very useful.  Now that /proc/interrupts also outputs
> > > >> the hwirq number, it is even less useful to keep around the 'hint' heuristic.
> > > >>
> > > >> This patch removes it.
> > > > 
> > > > Grant,
> > > > 
> > > > While trying your patch series in conjunction with Rob one, I do not
> > > > find this patch in your irqdomain/next branch (and a couple of others).
> > > > Can you tell me if this v3 series is available as a git tree?
> > > 
> > > I am still interested by patch 24-25 of this series but still cannot
> > > find them in your irqdomain/next branch:
> > > Are they also expected to join the 3.4 merge window material?
> > 
> > I've held off on putting them in irqdomain/next because they are a bit more
> > risky than the other patches, and I want an explicit ack from Ben for patches
> > 24 & 25.  However, that shouldn't really cause any issues since the changes
> > in 24 & 25 don't impact the irq_domain functionality or API.  They are just
> > optimizations.
> > 
> I'm seeing that patch 24 does impact on irq_domain functionality
> a little bit.  On next tree which has no this patch yet,
> irq_create_mapping can reasonably create virq in range 1..15, while
> irq_find_mapping will only try to find the virq from 16
> (NUM_ISA_INTERRUPTS).  This will result in that any hwirq that is < 16
> gets multiple entries in the mapping table with different virq numbers
> mapped to the same one hwirq.

That's a bug then.  The implementation should work without patch 24.  Does
this patch fix it?

---

diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 2c1d6f8..2d3dfff 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -516,8 +516,8 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
 		return irq_domain_legacy_revmap(domain, hwirq);
 
 	/* Slow path does a linear search of the map */
-	if (hint < NUM_ISA_INTERRUPTS)
-		hint = NUM_ISA_INTERRUPTS;
+	if (hint == 0)
+		hint = 1;
 	i = hint;
 	do {
 		struct irq_data *data = irq_get_irq_data(i);
@@ -525,7 +525,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
 			return i;
 		i++;
 		if (i >= irq_virq_count)
-			i = NUM_ISA_INTERRUPTS;
+			i = 1
 	} while(i != hint);
 	return 0;
 }


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

* Re: [PATCH v3 24/25] irq_domain: remove "hint" when allocating irq numbers
  2012-02-16  5:32           ` Grant Likely
@ 2012-02-16  6:03             ` Shawn Guo
  0 siblings, 0 replies; 66+ messages in thread
From: Shawn Guo @ 2012-02-16  6:03 UTC (permalink / raw)
  To: Grant Likely
  Cc: Nicolas Ferre, devicetree-discuss, Rob Herring, Stephen Rothwell,
	linux-kernel, Milton Miller, Thomas Gleixner, linuxppc-dev,
	linux-arm-kernel

On Wed, Feb 15, 2012 at 10:32:43PM -0700, Grant Likely wrote:
...
> That's a bug then.  The implementation should work without patch 24.  Does
> this patch fix it?
> 
Yes, it fixes the problem for me.

Regards,
Shawn

> ---
> 
> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> index 2c1d6f8..2d3dfff 100644
> --- a/kernel/irq/irqdomain.c
> +++ b/kernel/irq/irqdomain.c
> @@ -516,8 +516,8 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
>  		return irq_domain_legacy_revmap(domain, hwirq);
>  
>  	/* Slow path does a linear search of the map */
> -	if (hint < NUM_ISA_INTERRUPTS)
> -		hint = NUM_ISA_INTERRUPTS;
> +	if (hint == 0)
> +		hint = 1;
>  	i = hint;
>  	do {
>  		struct irq_data *data = irq_get_irq_data(i);
> @@ -525,7 +525,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
>  			return i;
>  		i++;
>  		if (i >= irq_virq_count)
> -			i = NUM_ISA_INTERRUPTS;
> +			i = 1
>  	} while(i != hint);
>  	return 0;
>  }
> 

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

* Re: [PATCH v3 22/25] irq_domain/x86: Convert x86 (embedded) to use common irq_domain
  2012-02-01 18:06         ` Grant Likely
@ 2012-02-23 19:56           ` Grant Likely
  2012-02-23 21:22             ` Sebastian Andrzej Siewior
  0 siblings, 1 reply; 66+ messages in thread
From: Grant Likely @ 2012-02-23 19:56 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell, devicetree-discuss,
	linux-arm-kernel, linuxppc-dev

On Wed, Feb 1, 2012 at 11:06 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
> On Wed, Feb 1, 2012 at 7:17 AM, Sebastian Andrzej Siewior
> <bigeasy@linutronix.de> wrote:
>> * Grant Likely | 2012-01-30 12:58:42 [-0700]:
>>
>>>Ugh.  This isn't easy.  The legacy mapping really needs all the
>>
>> Feel free to merge this patch. I don't have the time to look at this now
>> so I take a look at the ioapic later.
>
> There's no rush here.  I can leave it as-is with IRQ_DOMAIN turned off
> for x86 for now.

Turns out I have to enable IRQ_DOMAIN for x86 because the TI TWL4030
driver needs it.  I do need to apply this patch.  Until something
better can be implemented, can I change ioapic_add_ofnode() so that it
allocates all irq_descs immediately.  It's not ideal, but every other
approach I've looked at results in nasty hacks.

Looking at the ioapic code, it appears to handle preallocated
irq_descs gracefully.

Does adding this loop help (apologies if it is whitespace damaged, I
cut&paste it):

diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index 3ae2ced..89c1310 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -345,7 +345,7 @@ const struct irq_domain_ops ioapic_irq_domain_ops = {
 static void __init ioapic_add_ofnode(struct device_node *np)
 {
 	struct resource r;
-	int i, ret;
+	int i, j, ret;

 	ret = of_address_to_resource(np, 0, &r);
 	if (ret) {
@@ -361,6 +361,14 @@ static void __init ioapic_add_ofnode(struct
device_node *np)

 			gsi_cfg = mp_ioapic_gsi_routing(i);

+			/*
+			 * Preallocate irq_descs so that the legacy mapping
+			 * works, but don't set them up.
+			 * io_apic_setup_irq_pin_once() will finish the set up.
+			 */
+			for (j = 0; j < 32; j++)
+				irq_alloc_desc_at(gsi_cfg->gsi_base + j,
+						  cpu_to_node(0));
 			id = irq_domain_add_legacy(np, 32, gsi_cfg->gsi_base, 0,
 						   &ioapic_irq_domain_ops,
 						   (void*)i);


g.

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

* Re: [PATCH v3 22/25] irq_domain/x86: Convert x86 (embedded) to use common irq_domain
  2012-02-23 19:56           ` Grant Likely
@ 2012-02-23 21:22             ` Sebastian Andrzej Siewior
  2012-02-23 21:39               ` Grant Likely
  0 siblings, 1 reply; 66+ messages in thread
From: Sebastian Andrzej Siewior @ 2012-02-23 21:22 UTC (permalink / raw)
  To: Grant Likely
  Cc: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell, devicetree-discuss,
	linux-arm-kernel, linuxppc-dev

On 02/23/2012 08:56 PM, Grant Likely wrote:
> On Wed, Feb 1, 2012 at 11:06 AM, Grant Likely<grant.likely@secretlab.ca>  wrote:
>> On Wed, Feb 1, 2012 at 7:17 AM, Sebastian Andrzej Siewior
>> <bigeasy@linutronix.de>  wrote:
>>> * Grant Likely | 2012-01-30 12:58:42 [-0700]:
>>>
>>>> Ugh.  This isn't easy.  The legacy mapping really needs all the
>>>
>>> Feel free to merge this patch. I don't have the time to look at this now
>>> so I take a look at the ioapic later.
>>
>> There's no rush here.  I can leave it as-is with IRQ_DOMAIN turned off
>> for x86 for now.
>
> Turns out I have to enable IRQ_DOMAIN for x86 because the TI TWL4030
> driver needs it.  I do need to apply this patch.  Until something
> better can be implemented, can I change ioapic_add_ofnode() so that it
> allocates all irq_descs immediately.  It's not ideal, but every other
> approach I've looked at results in nasty hacks.
>
> Looking at the ioapic code, it appears to handle preallocated
> irq_descs gracefully.

Please merge your initial patch as-it.

> Does adding this loop help (apologies if it is whitespace damaged, I
> cut&paste it):
>
> diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
> index 3ae2ced..89c1310 100644
> --- a/arch/x86/kernel/devicetree.c
> +++ b/arch/x86/kernel/devicetree.c
> @@ -345,7 +345,7 @@ const struct irq_domain_ops ioapic_irq_domain_ops = {
>   static void __init ioapic_add_ofnode(struct device_node *np)
>   {
>   	struct resource r;
> -	int i, ret;
> +	int i, j, ret;
>
>   	ret = of_address_to_resource(np, 0,&r);
>   	if (ret) {
> @@ -361,6 +361,14 @@ static void __init ioapic_add_ofnode(struct
> device_node *np)
>
>   			gsi_cfg = mp_ioapic_gsi_routing(i);
>
> +			/*
> +			 * Preallocate irq_descs so that the legacy mapping
> +			 * works, but don't set them up.
> +			 * io_apic_setup_irq_pin_once() will finish the set up.
> +			 */
> +			for (j = 0; j<  32; j++)

It is not 32. If I remember correctly the first ioapic had 24 pins so
did the second. This is ioapic specifc.


>
> g.

Sebastian

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

* Re: [PATCH v3 22/25] irq_domain/x86: Convert x86 (embedded) to use common irq_domain
  2012-02-23 21:22             ` Sebastian Andrzej Siewior
@ 2012-02-23 21:39               ` Grant Likely
  0 siblings, 0 replies; 66+ messages in thread
From: Grant Likely @ 2012-02-23 21:39 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
	Milton Miller, Rob Herring, Stephen Rothwell, devicetree-discuss,
	linux-arm-kernel, linuxppc-dev

On Thu, Feb 23, 2012 at 10:22:15PM +0100, Sebastian Andrzej Siewior wrote:
> On 02/23/2012 08:56 PM, Grant Likely wrote:
> >On Wed, Feb 1, 2012 at 11:06 AM, Grant Likely<grant.likely@secretlab.ca>  wrote:
> >>On Wed, Feb 1, 2012 at 7:17 AM, Sebastian Andrzej Siewior
> >><bigeasy@linutronix.de>  wrote:
> >>>* Grant Likely | 2012-01-30 12:58:42 [-0700]:
> >>>
> >>>>Ugh.  This isn't easy.  The legacy mapping really needs all the
> >>>
> >>>Feel free to merge this patch. I don't have the time to look at this now
> >>>so I take a look at the ioapic later.
> >>
> >>There's no rush here.  I can leave it as-is with IRQ_DOMAIN turned off
> >>for x86 for now.
> >
> >Turns out I have to enable IRQ_DOMAIN for x86 because the TI TWL4030
> >driver needs it.  I do need to apply this patch.  Until something
> >better can be implemented, can I change ioapic_add_ofnode() so that it
> >allocates all irq_descs immediately.  It's not ideal, but every other
> >approach I've looked at results in nasty hacks.
> >
> >Looking at the ioapic code, it appears to handle preallocated
> >irq_descs gracefully.
> 
> Please merge your initial patch as-it.

Okay, will do.

> >Does adding this loop help (apologies if it is whitespace damaged, I
> >cut&paste it):
> >
> >diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
> >index 3ae2ced..89c1310 100644
> >--- a/arch/x86/kernel/devicetree.c
> >+++ b/arch/x86/kernel/devicetree.c
> >@@ -345,7 +345,7 @@ const struct irq_domain_ops ioapic_irq_domain_ops = {
> >  static void __init ioapic_add_ofnode(struct device_node *np)
> >  {
> >  	struct resource r;
> >-	int i, ret;
> >+	int i, j, ret;
> >
> >  	ret = of_address_to_resource(np, 0,&r);
> >  	if (ret) {
> >@@ -361,6 +361,14 @@ static void __init ioapic_add_ofnode(struct
> >device_node *np)
> >
> >  			gsi_cfg = mp_ioapic_gsi_routing(i);
> >
> >+			/*
> >+			 * Preallocate irq_descs so that the legacy mapping
> >+			 * works, but don't set them up.
> >+			 * io_apic_setup_irq_pin_once() will finish the set up.
> >+			 */
> >+			for (j = 0; j<  32; j++)
> 
> It is not 32. If I remember correctly the first ioapic had 24 pins so
> did the second. This is ioapic specifc.

Is this better (bigger diffstat, but mostly due to renaming a local varable):

---

diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index 3ae2ced..4028dc6 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -345,7 +345,7 @@ const struct irq_domain_ops ioapic_irq_domain_ops = {
 static void __init ioapic_add_ofnode(struct device_node *np)
 {
 	struct resource r;
-	int i, ret;
+	int i, irq, ret;
 
 	ret = of_address_to_resource(np, 0, &r);
 	if (ret) {
@@ -357,13 +357,22 @@ static void __init ioapic_add_ofnode(struct device_node *np)
 	for (i = 0; i < nr_ioapics; i++) {
 		if (r.start == mpc_ioapic_addr(i)) {
 			struct irq_domain *id;
-			struct mp_ioapic_gsi *gsi_cfg;
-
-			gsi_cfg = mp_ioapic_gsi_routing(i);
-
-			id = irq_domain_add_legacy(np, 32, gsi_cfg->gsi_base, 0,
-						   &ioapic_irq_domain_ops,
-						   (void*)i);
+			struct mp_ioapic_gsi *cfg;
+
+			cfg = mp_ioapic_gsi_routing(i);
+
+			/*
+			 * Preallocate irq_descs so that the legacy mapping
+			 * works, but don't set them up.
+			 * io_apic_setup_irq_pin_once() will finish the set up.
+			 */
+			for (irq = cfg->gsi_base; irq <= cfg->gsi_end; irq++)
+				irq_alloc_desc_at(irq, cpu_to_node(0));
+
+			id = irq_domain_add_legacy(np,
+					cfg->gsi_end - cfg->gsi_base + 1,
+					cfg->gsi_base, 0,
+					&ioapic_irq_domain_ops, (void*)i);
 			BUG_ON(!id);
 			return;
 		}

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

end of thread, other threads:[~2012-02-23 21:39 UTC | newest]

Thread overview: 66+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
2012-01-27 21:35 ` [PATCH v3 01/25] irq_domain: add documentation and MAINTAINERS entry Grant Likely
2012-01-28 18:23   ` Randy Dunlap
2012-01-27 21:35 ` [PATCH v3 02/25] dt: Make irqdomain less verbose Grant Likely
2012-01-27 21:35 ` [PATCH v3 03/25] irq_domain: Make irq_domain structure match powerpc's irq_host Grant Likely
2012-01-27 21:35 ` [PATCH v3 04/25] irq_domain: convert microblaze from irq_host to irq_domain Grant Likely
2012-01-27 21:35 ` [PATCH v3 05/25] irq_domain/powerpc: Use common irq_domain structure instead of irq_host Grant Likely
2012-01-27 21:36 ` [PATCH v3 06/25] irq_domain/powerpc: eliminate irq_map; use irq_alloc_desc() instead Grant Likely
2012-01-27 21:36 ` [PATCH v3 07/25] irq_domain/powerpc: Eliminate virq_is_host() Grant Likely
2012-01-27 21:36 ` [PATCH v3 08/25] irq_domain: Move irq_domain code from powerpc to kernel/irq Grant Likely
2012-01-27 21:36 ` [PATCH v3 09/25] irqdomain: remove NO_IRQ from irq domain code Grant Likely
2012-01-27 21:36 ` [PATCH v3 10/25] irq_domain: Remove references to old irq_host names Grant Likely
2012-01-27 21:36 ` [PATCH v3 11/25] irq_domain: Replace irq_alloc_host() with revmap-specific initializers Grant Likely
2012-01-27 21:36 ` [PATCH v3 12/25] irq_domain: Add support for base irq and hwirq in legacy mappings Grant Likely
2012-01-27 21:36 ` [PATCH v3 13/25] irq_domain: Remove 'new' irq_domain in favour of the ppc one Grant Likely
2012-02-03 14:48   ` Cousson, Benoit
2012-02-03 16:42     ` Grant Likely
2012-01-27 21:36 ` [PATCH v3 14/25] irq_domain: Remove irq_domain_add_simple() Grant Likely
2012-01-31 12:45   ` Shawn Guo
2012-01-31 13:15     ` Rob Herring
2012-01-31 13:58       ` Shawn Guo
2012-02-01  0:08         ` Grant Likely
2012-02-01  5:46   ` [PATCH] irq_domain: fix the irq number of imx5 tzic Shawn Guo
2012-02-02  4:58     ` Grant Likely
2012-01-27 21:36 ` [PATCH v3 15/25] irq_domain: Create common xlate functions that device drivers can use Grant Likely
2012-01-27 21:36 ` [PATCH v3 16/25] irq_domain: constify irq_domain_ops Grant Likely
2012-01-27 21:36 ` [PATCH v3 17/25] irq_domain/c6x: Convert c6x to use generic irq_domain support Grant Likely
2012-01-27 21:36 ` [PATCH v3 18/25] irq_domain/c6x: constify irq_domain structures Grant Likely
2012-01-27 21:36 ` [PATCH v3 19/25] irq_domain/c6x: Use library of xlate functions Grant Likely
2012-01-27 21:36 ` [PATCH v3 20/25] irq_domain/powerpc: constify irq_domain_ops Grant Likely
2012-01-27 21:36 ` [PATCH v3 21/25] irqdomain/powerpc: Replace custom xlate functions with library functions Grant Likely
2012-02-06  5:22   ` Michael Neuling
2012-02-06  6:00     ` Grant Likely
2012-01-27 21:36 ` [PATCH v3 22/25] irq_domain/x86: Convert x86 (embedded) to use common irq_domain Grant Likely
2012-01-28 16:44   ` Sebastian Andrzej Siewior
2012-01-29  0:35     ` Grant Likely
2012-01-29  0:39       ` Grant Likely
2012-01-30 19:58     ` Grant Likely
2012-02-01 14:17       ` Sebastian Andrzej Siewior
2012-02-01 18:06         ` Grant Likely
2012-02-23 19:56           ` Grant Likely
2012-02-23 21:22             ` Sebastian Andrzej Siewior
2012-02-23 21:39               ` Grant Likely
2012-01-27 21:36 ` [PATCH v3 23/25] irq_domain: Include hwirq number in /proc/interrupts Grant Likely
2012-01-27 21:36 ` [PATCH v3 24/25] irq_domain: remove "hint" when allocating irq numbers Grant Likely
2012-02-07 18:07   ` Nicolas Ferre
2012-02-15 15:04     ` Nicolas Ferre
2012-02-15 20:21       ` Grant Likely
2012-02-15 21:50         ` Shawn Guo
2012-02-16  5:32           ` Grant Likely
2012-02-16  6:03             ` Shawn Guo
2012-01-27 21:36 ` [PATCH v3 25/25] irq_domain: mostly eliminate slow-path revmap lookups Grant Likely
2012-02-15 16:36   ` Nicolas Ferre
2012-02-15 20:29     ` Grant Likely
2012-01-28 18:38 ` [PATCH v3 00/25] irq_domain generalization and refinement Rob Herring
2012-01-31  4:53 ` Olof Johansson
2012-02-01  0:07   ` Grant Likely
2012-02-04 22:17 ` Russell King - ARM Linux
2012-02-04 22:31   ` Russell King - ARM Linux
2012-02-05  1:38     ` Tony Lindgren
2012-02-05 16:13       ` Russell King - ARM Linux
2012-02-07 15:26         ` Mark Brown
2012-02-15 20:33           ` Grant Likely
2012-02-05  0:01   ` Benjamin Herrenschmidt
2012-02-06  0:51   ` Rob Herring
2012-02-06  5:56   ` Grant Likely

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).