linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/5] Add an optional device_node pointer to the irq_host
@ 2007-07-25 12:24 Michael Ellerman
  0 siblings, 0 replies; 7+ messages in thread
From: Michael Ellerman @ 2007-07-25 12:24 UTC (permalink / raw)
  To: linuxppc-dev

The majority of irq_host implementations (3 out of 4) are associated
with a device_node, and need to stash it somewhere. Rather than having
it somewhere different for each host, add an optional device_node pointer
to the irq_host structure.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/kernel/irq.c                 |    4 +++-
 arch/powerpc/platforms/52xx/mpc52xx_pic.c |    5 ++---
 arch/powerpc/platforms/82xx/mpc82xx_ads.c |    7 ++-----
 arch/powerpc/platforms/cell/axon_msi.c    |   14 +++++---------
 arch/powerpc/platforms/cell/interrupt.c   |    2 +-
 arch/powerpc/platforms/cell/spider-pic.c  |   18 +++++++-----------
 arch/powerpc/platforms/celleb/interrupt.c |    2 +-
 arch/powerpc/platforms/iseries/irq.c      |    3 ++-
 arch/powerpc/platforms/powermac/pic.c     |    2 +-
 arch/powerpc/platforms/ps3/interrupt.c    |    2 +-
 arch/powerpc/platforms/pseries/xics.c     |    2 +-
 arch/powerpc/sysdev/commproc.c            |    8 +++-----
 arch/powerpc/sysdev/cpm2_pic.c            |    7 +++----
 arch/powerpc/sysdev/i8259.c               |    8 +++-----
 arch/powerpc/sysdev/ipic.c                |    7 ++-----
 arch/powerpc/sysdev/ipic.h                |    3 ---
 arch/powerpc/sysdev/mpc8xx_pic.c          |   19 ++++++++++---------
 arch/powerpc/sysdev/mpic.c                |   11 ++++-------
 arch/powerpc/sysdev/mpic_msi.c            |    7 ++++---
 arch/powerpc/sysdev/mv64x60_pic.c         |    8 +++-----
 arch/powerpc/sysdev/qe_lib/qe_ic.c        |    7 ++-----
 arch/powerpc/sysdev/qe_lib/qe_ic.h        |    3 ---
 arch/powerpc/sysdev/tsi108_pci.c          |    8 ++++----
 arch/powerpc/sysdev/uic.c                 |   11 +++--------
 include/asm-powerpc/irq.h                 |    8 ++++++--
 include/asm-powerpc/mpic.h                |    3 ---
 26 files changed, 73 insertions(+), 106 deletions(-)

diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 2fc8786..31d1de7 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -418,7 +418,8 @@ irq_hw_number_t virq_to_hw(unsigned int virq)
 }
 EXPORT_SYMBOL_GPL(virq_to_hw);
 
-struct irq_host *irq_alloc_host(unsigned int revmap_type,
+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)
@@ -446,6 +447,7 @@ struct irq_host *irq_alloc_host(unsigned int revmap_type,
 	host->revmap_type = revmap_type;
 	host->inval_irq = inval_irq;
 	host->ops = ops;
+	host->of_node = of_node;
 
 	spin_lock_irqsave(&irq_big_lock, flags);
 
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index fbfff95..6332940 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -245,7 +245,7 @@ static struct irq_chip mpc52xx_sdma_irqchip = {
 static int mpc52xx_irqhost_match(struct irq_host *h, struct device_node *node)
 {
 	pr_debug("%s: node=%p\n", __func__, node);
-	return mpc52xx_irqhost->host_data == node;
+	return h->of_node == node;
 }
 
 static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
@@ -420,14 +420,13 @@ void __init mpc52xx_init_irq(void)
 	 * hw irq information provided by the ofw to linux virq
 	 */
 
-	mpc52xx_irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR,
+	mpc52xx_irqhost = irq_alloc_host(picnode, IRQ_HOST_MAP_LINEAR,
 	                                 MPC52xx_IRQ_HIGHTESTHWIRQ,
 	                                 &mpc52xx_irqhost_ops, -1);
 
 	if (!mpc52xx_irqhost)
 		panic(__FILE__ ": Cannot allocate the IRQ host\n");
 
-	mpc52xx_irqhost->host_data = picnode;
 	printk(KERN_INFO "MPC52xx PIC is up and running!\n");
 }
 
diff --git a/arch/powerpc/platforms/82xx/mpc82xx_ads.c b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
index da20832..65721bf 100644
--- a/arch/powerpc/platforms/82xx/mpc82xx_ads.c
+++ b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
@@ -62,7 +62,6 @@ static struct {
 
 static unsigned long pci_int_base;
 static struct irq_host *pci_pic_host;
-static struct device_node *pci_pic_node;
 #endif
 
 static void __init mpc82xx_ads_pic_init(void)
@@ -402,7 +401,7 @@ m82xx_pci_irq_demux(unsigned int irq, struct irq_desc *desc)
 
 static int pci_pic_host_match(struct irq_host *h, struct device_node *node)
 {
-	return node == pci_pic_node;
+	return h->of_node == node;
 }
 
 static int pci_pic_host_map(struct irq_host *h, unsigned int virq,
@@ -479,7 +478,6 @@ void m82xx_pci_init_irq(void)
 		iounmap(immap);
 		return;
 	}
-	pci_pic_node = of_node_get(np);
 	/* PCI interrupt controller registers: status and mask */
 	regs = of_get_property(np, "reg", &size);
 	if ((!regs) || (size <= 2)) {
@@ -491,7 +489,6 @@ void m82xx_pci_init_irq(void)
 	    ioremap(regs[0], sizeof(*pci_regs.pci_int_stat_reg));
 	pci_regs.pci_int_mask_reg =
 	    ioremap(regs[1], sizeof(*pci_regs.pci_int_mask_reg));
-	of_node_put(np);
 	/* configure chip select for PCI interrupt controller */
 	immap->im_memctl.memc_br3 = regs[0] | 0x00001801;
 	immap->im_memctl.memc_or3 = 0xffff8010;
@@ -502,7 +499,7 @@ void m82xx_pci_init_irq(void)
 	*pci_regs.pci_int_mask_reg |= 0xfff00000;
 	iounmap(immap);
 	pci_pic_host =
-	    irq_alloc_host(IRQ_HOST_MAP_LINEAR, irq_max - irq_min + 1,
+	    irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, irq_max - irq_min + 1,
 			   &pci_pic_host_ops, irq_max + 1);
 	return;
 }
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 4c9ab5b..bdd97bb 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -64,7 +64,6 @@
 
 
 struct axon_msic {
-	struct device_node *dn;
 	struct irq_host *irq_host;
 	__le32 *fifo;
 	dcr_host_t dcr_host;
@@ -297,9 +296,7 @@ static int msic_host_map(struct irq_host *h, unsigned int virq,
 
 static int msic_host_match(struct irq_host *host, struct device_node *dn)
 {
-	struct axon_msic *msic = host->host_data;
-
-	return msic->dn == dn;
+	return host->of_node == dn;
 }
 
 static struct irq_host_ops msic_host_ops = {
@@ -314,7 +311,8 @@ static int axon_msi_notify_reboot(struct notifier_block *nb,
 	u32 tmp;
 
 	list_for_each_entry(msic, &axon_msic_list, list) {
-		pr_debug("axon_msi: disabling %s\n", msic->dn->full_name);
+		pr_debug("axon_msi: disabling %s\n",
+			  msic->irq_host->of_node->full_name);
 		tmp  = msic_dcr_read(msic, MSIC_CTRL_REG);
 		tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE;
 		msic_dcr_write(msic, MSIC_CTRL_REG, tmp);
@@ -370,8 +368,8 @@ static int axon_msi_setup_one(struct device_node *dn)
 
 	msic->fifo = page_address(page);
 
-	msic->irq_host = irq_alloc_host(IRQ_HOST_MAP_NOMAP, NR_IRQS,
-					&msic_host_ops, 0);
+	msic->irq_host = irq_alloc_host(of_node_get(dn), IRQ_HOST_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",
 		       dn->full_name);
@@ -387,8 +385,6 @@ static int axon_msi_setup_one(struct device_node *dn)
 		goto out_free_host;
 	}
 
-	msic->dn = of_node_get(dn);
-
 	set_irq_data(virq, msic);
 	set_irq_chained_handler(virq, axon_msi_cascade);
 	pr_debug("axon_msi: irq 0x%x setup for axon_msi\n", virq);
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 47264e7..c29e634 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -381,7 +381,7 @@ static int __init setup_iic(void)
 void __init iic_init_IRQ(void)
 {
 	/* Setup an irq host data structure */
-	iic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, IIC_SOURCE_COUNT,
+	iic_host = irq_alloc_host(NULL, IRQ_HOST_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 05f4b3d..4309c2c 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -63,7 +63,6 @@ enum {
 
 struct spider_pic {
 	struct irq_host		*host;
-	struct device_node	*of_node;
 	void __iomem		*regs;
 	unsigned int		node_id;
 };
@@ -178,8 +177,7 @@ static struct irq_chip spider_pic = {
 
 static int spider_host_match(struct irq_host *h, struct device_node *node)
 {
-	struct spider_pic *pic = h->host_data;
-	return node == pic->of_node;
+	return h->of_node == node;
 }
 
 static int spider_host_map(struct irq_host *h, unsigned int virq,
@@ -247,18 +245,18 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
 	 * tree in case the device-tree is ever fixed
 	 */
 	struct of_irq oirq;
-	if (of_irq_map_one(pic->of_node, 0, &oirq) == 0) {
+	if (of_irq_map_one(pic->host->of_node, 0, &oirq) == 0) {
 		virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
 					     oirq.size);
 		return virq;
 	}
 
 	/* Now do the horrible hacks */
-	tmp = of_get_property(pic->of_node, "#interrupt-cells", NULL);
+	tmp = of_get_property(pic->host->of_node, "#interrupt-cells", NULL);
 	if (tmp == NULL)
 		return NO_IRQ;
 	intsize = *tmp;
-	imap = of_get_property(pic->of_node, "interrupt-map", &imaplen);
+	imap = of_get_property(pic->host->of_node, "interrupt-map", &imaplen);
 	if (imap == NULL || imaplen < (intsize + 1))
 		return NO_IRQ;
 	iic = of_find_node_by_phandle(imap[intsize]);
@@ -308,15 +306,13 @@ 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(IRQ_HOST_MAP_LINEAR, SPIDER_SRC_COUNT,
-				   &spider_host_ops, SPIDER_IRQ_INVALID);
+	pic->host = irq_alloc_host(of_node_get(of_node), IRQ_HOST_MAP_LINEAR,
+				   SPIDER_SRC_COUNT, &spider_host_ops,
+				   SPIDER_IRQ_INVALID);
 	if (pic->host == NULL)
 		panic("spider_pic: can't allocate irq host !");
 	pic->host->host_data = pic;
 
-	/* Fill out other bits */
-	pic->of_node = of_node_get(of_node);
-
 	/* Go through all sources and disable them */
 	for (i = 0; i < SPIDER_SRC_COUNT; i++) {
 		void __iomem *cfg = pic->regs + TIR_CFGA + 8 * i;
diff --git a/arch/powerpc/platforms/celleb/interrupt.c b/arch/powerpc/platforms/celleb/interrupt.c
index 98e6665..4ecdf06 100644
--- a/arch/powerpc/platforms/celleb/interrupt.c
+++ b/arch/powerpc/platforms/celleb/interrupt.c
@@ -242,7 +242,7 @@ void __init beatic_init_IRQ(void)
 	ppc_md.get_irq = beatic_get_irq;
 
 	/* Allocate an irq host */
-	beatic_host = irq_alloc_host(IRQ_HOST_MAP_NOMAP, 0,
+	beatic_host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0,
 					 &beatic_pic_host_ops,
 					 0);
 	BUG_ON(beatic_host == NULL);
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index 63b3367..3666746 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -369,7 +369,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(IRQ_HOST_MAP_NOMAP, 0, &iseries_irq_host_ops, 0);
+	host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0,
+			      &iseries_irq_host_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 87cd680..999f5e1 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -384,7 +384,7 @@ static void __init pmac_pic_probe_oldstyle(void)
 	/*
 	 * Allocate an irq host
 	 */
-	pmac_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, max_irqs,
+	pmac_pic_host = irq_alloc_host(master, IRQ_HOST_MAP_LINEAR, max_irqs,
 				       &pmac_pic_host_ops,
 				       max_irqs);
 	BUG_ON(pmac_pic_host == NULL);
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 67e32ec..30b9f4c 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -726,7 +726,7 @@ void __init ps3_init_IRQ(void)
 	unsigned cpu;
 	struct irq_host *host;
 
-	host = irq_alloc_host(IRQ_HOST_MAP_NOMAP, 0, &ps3_host_ops,
+	host = irq_alloc_host(NULL, IRQ_HOST_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/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 5bd90a7..5ddb025 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -540,7 +540,7 @@ static void __init xics_init_host(void)
 		ops = &xics_host_lpar_ops;
 	else
 		ops = &xics_host_direct_ops;
-	xics_host = irq_alloc_host(IRQ_HOST_MAP_TREE, 0, ops,
+	xics_host = irq_alloc_host(NULL, IRQ_HOST_MAP_TREE, 0, ops,
 				   XICS_IRQ_SPURIOUS);
 	BUG_ON(xics_host == NULL);
 	irq_set_default_host(xics_host);
diff --git a/arch/powerpc/sysdev/commproc.c b/arch/powerpc/sysdev/commproc.c
index 4f67b89..ed5f77a 100644
--- a/arch/powerpc/sysdev/commproc.c
+++ b/arch/powerpc/sysdev/commproc.c
@@ -50,7 +50,6 @@ static	uint	host_end;	/* end + 1 */
 cpm8xx_t	*cpmp;		/* Pointer to comm processor space */
 cpic8xx_t	*cpic_reg;
 
-static struct device_node *cpm_pic_node;
 static struct irq_host *cpm_pic_host;
 
 static void cpm_mask_irq(unsigned int irq)
@@ -97,7 +96,7 @@ int cpm_get_irq(void)
 
 static int cpm_pic_host_match(struct irq_host *h, struct device_node *node)
 {
-	return cpm_pic_node == node;
+	return h->of_node == node;
 }
 
 static int cpm_pic_host_map(struct irq_host *h, unsigned int virq,
@@ -165,9 +164,8 @@ unsigned int cpm_pic_init(void)
 
 	out_be32(&cpic_reg->cpic_cimr, 0);
 
-	cpm_pic_node = of_node_get(np);
-
-	cpm_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 64, &cpm_pic_host_ops, 64);
+	cpm_pic_host = irq_alloc_host(of_node_get(np), IRQ_HOST_MAP_LINEAR,
+				      64, &cpm_pic_host_ops, 64);
 	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 eabfe06..d9ab30c 100644
--- a/arch/powerpc/sysdev/cpm2_pic.c
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -50,7 +50,6 @@
 
 static intctl_cpm2_t *cpm2_intctl;
 
-static struct device_node *cpm2_pic_node;
 static struct irq_host *cpm2_pic_host;
 #define NR_MASK_WORDS   ((NR_IRQS + 31) / 32)
 static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
@@ -208,7 +207,7 @@ unsigned int cpm2_get_irq(void)
 
 static int cpm2_pic_host_match(struct irq_host *h, struct device_node *node)
 {
-	return cpm2_pic_node == node;
+	return h->of_node == node;
 }
 
 static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq,
@@ -273,8 +272,8 @@ void cpm2_pic_init(struct device_node *node)
 	out_be32(&cpm2_intctl->ic_scprrl, 0x05309770);
 
 	/* create a legacy host */
-	cpm2_pic_node = of_node_get(node);
-	cpm2_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 64, &cpm2_pic_host_ops, 64);
+	cpm2_pic_host = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LINEAR,
+				       64, &cpm2_pic_host_ops, 64);
 	if (cpm2_pic_host == NULL) {
 		printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
 		return;
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index ad87adc..7c1b27a 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -25,7 +25,6 @@ static unsigned char cached_8259[2] = { 0xff, 0xff };
 
 static DEFINE_SPINLOCK(i8259_lock);
 
-static struct device_node *i8259_node;
 static struct irq_host *i8259_host;
 
 /*
@@ -165,7 +164,7 @@ static struct resource pic_edgectrl_iores = {
 
 static int i8259_host_match(struct irq_host *h, struct device_node *node)
 {
-	return i8259_node == NULL || i8259_node == node;
+	return h->of_node == NULL || h->of_node == node;
 }
 
 static int i8259_host_map(struct irq_host *h, unsigned int virq,
@@ -276,9 +275,8 @@ void i8259_init(struct device_node *node, unsigned long intack_addr)
 	spin_unlock_irqrestore(&i8259_lock, flags);
 
 	/* create a legacy host */
-	if (node)
-		i8259_node = of_node_get(node);
-	i8259_host = irq_alloc_host(IRQ_HOST_MAP_LEGACY, 0, &i8259_host_ops, 0);
+	i8259_host = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LEGACY,
+				    0, &i8259_host_ops, 0);
 	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 473c415..05a56e5 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -511,10 +511,8 @@ static struct irq_chip ipic_irq_chip = {
 
 static int ipic_host_match(struct irq_host *h, struct device_node *node)
 {
-	struct ipic *ipic = h->host_data;
-
 	/* Exact match, unless ipic node is NULL */
-	return ipic->of_node == NULL || ipic->of_node == node;
+	return h->of_node == NULL || h->of_node == node;
 }
 
 static int ipic_host_map(struct irq_host *h, unsigned int virq,
@@ -568,9 +566,8 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
 		return NULL;
 
 	memset(ipic, 0, sizeof(struct ipic));
-	ipic->of_node = of_node_get(node);
 
-	ipic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR,
+	ipic->irqhost = irq_alloc_host(of_node_get(node), IRQ_HOST_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 c28e589..bb309a5 100644
--- a/arch/powerpc/sysdev/ipic.h
+++ b/arch/powerpc/sysdev/ipic.h
@@ -48,9 +48,6 @@ struct ipic {
 
 	/* The "linux" controller struct */
 	struct irq_chip		hc_irq;
-
-	/* The device node of the interrupt controller */
-	struct device_node	*of_node;
 };
 
 struct ipic_info {
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c
index 2fc2bcd..f20a4d4 100644
--- a/arch/powerpc/sysdev/mpc8xx_pic.c
+++ b/arch/powerpc/sysdev/mpc8xx_pic.c
@@ -19,7 +19,6 @@
 
 extern int cpm_get_irq(struct pt_regs *regs);
 
-static struct device_node *mpc8xx_pic_node;
 static struct irq_host *mpc8xx_pic_host;
 #define NR_MASK_WORDS   ((NR_IRQS + 31) / 32)
 static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
@@ -122,7 +121,7 @@ unsigned int mpc8xx_get_irq(void)
 
 static int mpc8xx_pic_host_match(struct irq_host *h, struct device_node *node)
 {
-	return mpc8xx_pic_node == node;
+	return h->of_node == node;
 }
 
 static int mpc8xx_pic_host_map(struct irq_host *h, unsigned int virq,
@@ -176,22 +175,24 @@ int mpc8xx_pic_init(void)
 		return -ENOMEM;
 	}
 
-	mpc8xx_pic_node = of_node_get(np);
-
 	ret = of_address_to_resource(np, 0, &res);
-	of_node_put(np);
 	if (ret)
-		return ret;
+		goto out;
 
 	siu_reg = (void *)ioremap(res.start, res.end - res.start + 1);
-	if (siu_reg == NULL)
-		return -EINVAL;
+	if (siu_reg == NULL) {
+		ret = -EINVAL;
+		goto out;
+	}
 
-	mpc8xx_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 64, &mpc8xx_pic_host_ops, 64);
+	mpc8xx_pic_host = irq_alloc_host(of_node_get(np), IRQ_HOST_MAP_LINEAR,
+					 64, &mpc8xx_pic_host_ops, 64);
 	if (mpc8xx_pic_host == NULL) {
 		printk(KERN_ERR "MPC8xx PIC: failed to allocate irq host!\n");
 		ret = -ENOMEM;
 	}
 
+out:
+	of_node_put(np);
 	return ret;
 }
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 74c64c0..25a81f7 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -271,7 +271,7 @@ static void _mpic_map_dcr(struct mpic *mpic, struct mpic_reg_bank *rb,
 {
 	rb->dbase = mpic->dcr_base;
 	rb->doff = offset;
-	rb->dhost = dcr_map(mpic->of_node, rb->dbase + rb->doff, size);
+	rb->dhost = dcr_map(mpic->irqhost->of_node, rb->dbase + rb->doff, size);
 	BUG_ON(!DCR_MAP_OK(rb->dhost));
 }
 
@@ -861,10 +861,8 @@ static struct irq_chip mpic_irq_ht_chip = {
 
 static int mpic_host_match(struct irq_host *h, struct device_node *node)
 {
-	struct mpic *mpic = h->host_data;
-
 	/* Exact match, unless mpic node is NULL */
-	return mpic->of_node == NULL || mpic->of_node == node;
+	return h->of_node == NULL || h->of_node == node;
 }
 
 static int mpic_host_map(struct irq_host *h, unsigned int virq,
@@ -985,10 +983,9 @@ struct mpic * __init mpic_alloc(struct device_node *node,
 	
 	memset(mpic, 0, sizeof(struct mpic));
 	mpic->name = name;
-	mpic->of_node = of_node_get(node);
 
-	mpic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, isu_size,
-				       &mpic_host_ops,
+	mpic->irqhost = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LINEAR,
+				       isu_size, &mpic_host_ops,
 				       flags & MPIC_LARGE_VECTORS ? 2048 : 256);
 	if (mpic->irqhost == NULL) {
 		of_node_put(node);
diff --git a/arch/powerpc/sysdev/mpic_msi.c b/arch/powerpc/sysdev/mpic_msi.c
index b076793..9ca4d8f 100644
--- a/arch/powerpc/sysdev/mpic_msi.c
+++ b/arch/powerpc/sysdev/mpic_msi.c
@@ -117,16 +117,17 @@ static int mpic_msi_reserve_dt_hwirqs(struct mpic *mpic)
 	int i, len;
 	const u32 *p;
 
-	p = of_get_property(mpic->of_node, "msi-available-ranges", &len);
+	p = of_get_property(mpic->irqhost->of_node,
+			    "msi-available-ranges", &len);
 	if (!p) {
 		pr_debug("mpic: no msi-available-ranges property found on %s\n",
-			  mpic->of_node->full_name);
+			  mpic->irqhost->of_node->full_name);
 		return -ENODEV;
 	}
 
 	if (len % 8 != 0) {
 		printk(KERN_WARNING "mpic: Malformed msi-available-ranges "
-		       "property on %s\n", mpic->of_node->full_name);
+		       "property on %s\n", mpic->irqhost->of_node->full_name);
 		return -EINVAL;
 	}
 
diff --git a/arch/powerpc/sysdev/mv64x60_pic.c b/arch/powerpc/sysdev/mv64x60_pic.c
index 01d3162..a145bfd 100644
--- a/arch/powerpc/sysdev/mv64x60_pic.c
+++ b/arch/powerpc/sysdev/mv64x60_pic.c
@@ -204,7 +204,7 @@ static struct irq_chip mv64x60_chip_gpp = {
 
 static int mv64x60_host_match(struct irq_host *h, struct device_node *np)
 {
-	return mv64x60_irq_host->host_data == np;
+	return h->of_node == np;
 }
 
 static struct irq_chip *mv64x60_chips[] = {
@@ -253,14 +253,12 @@ void __init mv64x60_init_irq(void)
 	np = of_find_compatible_node(NULL, NULL, "marvell,mv64x60-pic");
 	reg = of_get_property(np, "reg", &size);
 	paddr = of_translate_address(np, reg);
-	of_node_put(np);
 	mv64x60_irq_reg_base = ioremap(paddr, reg[1]);
 
-	mv64x60_irq_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, MV64x60_NUM_IRQS,
+	mv64x60_irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
+					  MV64x60_NUM_IRQS,
 					  &mv64x60_host_ops, MV64x60_NUM_IRQS);
 
-	mv64x60_irq_host->host_data = np;
-
 	spin_lock_irqsave(&mv64x60_lock, flags);
 	out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
 		 mv64x60_cached_gpp_mask);
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index 4d1dcb4..55e6f39 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -245,10 +245,8 @@ static struct irq_chip qe_ic_irq_chip = {
 
 static int qe_ic_host_match(struct irq_host *h, struct device_node *node)
 {
-	struct qe_ic *qe_ic = h->host_data;
-
 	/* Exact match, unless qe_ic node is NULL */
-	return qe_ic->of_node == NULL || qe_ic->of_node == node;
+	return h->of_node == NULL || h->of_node == node;
 }
 
 static int qe_ic_host_map(struct irq_host *h, unsigned int virq,
@@ -352,9 +350,8 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags)
 		return;
 
 	memset(qe_ic, 0, sizeof(struct qe_ic));
-	qe_ic->of_node = of_node_get(node);
 
-	qe_ic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR,
+	qe_ic->irqhost = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LINEAR,
 					NR_QE_IC_INTS, &qe_ic_host_ops, 0);
 	if (qe_ic->irqhost == NULL) {
 		of_node_put(node);
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.h b/arch/powerpc/sysdev/qe_lib/qe_ic.h
index 9a631ad..c1361d0 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.h
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.h
@@ -84,9 +84,6 @@ struct qe_ic {
 	/* The "linux" controller struct */
 	struct irq_chip hc_irq;
 
-	/* The device node of the interrupt controller */
-	struct device_node *of_node;
-
 	/* VIRQ numbers of QE high/low irqs */
 	unsigned int virq_high;
 	unsigned int virq_low;
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 90db8a7..f57dc0f 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -52,7 +52,6 @@
 u32 tsi108_pci_cfg_base;
 static u32 tsi108_pci_cfg_phys;
 u32 tsi108_csr_vir_base;
-static struct device_node *pci_irq_node;
 static struct irq_host *pci_irq_host;
 
 extern u32 get_vir_csrbase(void);
@@ -407,7 +406,7 @@ static int pci_irq_host_map(struct irq_host *h, unsigned int virq,
 
 static int pci_irq_host_match(struct irq_host *h, struct device_node *node)
 {
-	return pci_irq_node == node;
+	return h->of_node == node;
 }
 
 static struct irq_host_ops pci_irq_host_ops = {
@@ -433,10 +432,11 @@ void __init tsi108_pci_int_init(struct device_node *node)
 {
 	DBG("Tsi108_pci_int_init: initializing PCI interrupts\n");
 
-	pci_irq_node = of_node_get(node);
-	pci_irq_host = irq_alloc_host(IRQ_HOST_MAP_LEGACY, 0, &pci_irq_host_ops, 0);
+	pci_irq_host = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LEGACY,
+				      0, &pci_irq_host_ops, 0);
 	if (pci_irq_host == NULL) {
 		printk(KERN_ERR "pci_irq_host: failed to allocate irq host !\n");
+		of_node_put(node);
 		return;
 	}
 
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
index 8905989..3d8ebc7 100644
--- a/arch/powerpc/sysdev/uic.c
+++ b/arch/powerpc/sysdev/uic.c
@@ -55,9 +55,6 @@ struct uic {
 
 	/* For secondary UICs, the cascade interrupt's irqaction */
 	struct irqaction cascade;
-
-	/* The device node of the interrupt controller */
-	struct device_node *of_node;
 };
 
 static void uic_unmask_irq(unsigned int virq)
@@ -161,8 +158,7 @@ static struct irq_chip uic_irq_chip = {
 
 static int uic_host_match(struct irq_host *h, struct device_node *node)
 {
-	struct uic *uic = h->host_data;
-	return uic->of_node == node;
+	return h->of_node == node;
 }
 
 static int uic_host_map(struct irq_host *h, unsigned int virq,
@@ -229,7 +225,6 @@ static struct uic * __init uic_init_one(struct device_node *node)
 
 	memset(uic, 0, sizeof(*uic));
 	spin_lock_init(&uic->lock);
-	uic->of_node = of_node_get(node);
 	indexp = of_get_property(node, "cell-index", &len);
 	if (!indexp || (len != sizeof(u32))) {
 		printk(KERN_ERR "uic: Device node %s has missing or invalid "
@@ -246,8 +241,8 @@ static struct uic * __init uic_init_one(struct device_node *node)
 	}
 	uic->dcrbase = *dcrreg;
 
-	uic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, NR_UIC_INTS,
-				      &uic_host_ops, -1);
+	uic->irqhost = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LINEAR,
+				      NR_UIC_INTS, &uic_host_ops, -1);
 	if (! uic->irqhost) {
 		of_node_put(node);
 		return NULL; /* FIXME: panic? */
diff --git a/include/asm-powerpc/irq.h b/include/asm-powerpc/irq.h
index 0485c53..1392db4 100644
--- a/include/asm-powerpc/irq.h
+++ b/include/asm-powerpc/irq.h
@@ -124,6 +124,9 @@ struct irq_host {
 	struct irq_host_ops	*ops;
 	void			*host_data;
 	irq_hw_number_t		inval_irq;
+
+	/* Optional device node pointer */
+	struct device_node	*of_node;
 };
 
 /* The main irq map itself is an array of NR_IRQ entries containing the
@@ -142,7 +145,7 @@ extern irq_hw_number_t virq_to_hw(unsigned int virq);
 
 /**
  * irq_alloc_host - Allocate a new irq_host data structure
- * @node: device-tree node of the interrupt controller
+ * @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
@@ -156,7 +159,8 @@ extern irq_hw_number_t virq_to_hw(unsigned int virq);
  * later during boot automatically (the reverse mapping will use the slow path
  * until that happens).
  */
-extern struct irq_host *irq_alloc_host(unsigned int revmap_type,
+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);
diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h
index 262db6b..0eb3ab9 100644
--- a/include/asm-powerpc/mpic.h
+++ b/include/asm-powerpc/mpic.h
@@ -240,9 +240,6 @@ struct mpic_irq_save {
 /* The instance data of a given MPIC */
 struct mpic
 {
-	/* The device node of the interrupt controller */
-	struct device_node	*of_node;
-
 	/* The remapper for this MPIC */
 	struct irq_host		*irqhost;
 
-- 
1.5.1.3.g7a33b

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

* [PATCH 1/5] Add an optional device_node pointer to the irq_host
@ 2007-08-28  8:47 Michael Ellerman
  2007-08-28  8:47 ` [PATCH 3/5] Provide a default irq_host match, which matches on an exact of_node Michael Ellerman
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Michael Ellerman @ 2007-08-28  8:47 UTC (permalink / raw)
  To: linuxppc-dev

The majority of irq_host implementations (3 out of 4) are associated
with a device_node, and need to stash it somewhere. Rather than having
it somewhere different for each host, add an optional device_node pointer
to the irq_host structure.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/kernel/irq.c                 |   10 ++++++----
 arch/powerpc/platforms/52xx/mpc52xx_pic.c |    5 ++---
 arch/powerpc/platforms/82xx/mpc82xx_ads.c |    7 ++-----
 arch/powerpc/platforms/cell/axon_msi.c    |   14 +++++---------
 arch/powerpc/platforms/cell/interrupt.c   |    2 +-
 arch/powerpc/platforms/cell/spider-pic.c  |   18 +++++++-----------
 arch/powerpc/platforms/celleb/interrupt.c |    2 +-
 arch/powerpc/platforms/iseries/irq.c      |    3 ++-
 arch/powerpc/platforms/powermac/pic.c     |    2 +-
 arch/powerpc/platforms/ps3/interrupt.c    |    2 +-
 arch/powerpc/platforms/pseries/xics.c     |    2 +-
 arch/powerpc/sysdev/commproc.c            |    8 +++-----
 arch/powerpc/sysdev/cpm2_pic.c            |    7 +++----
 arch/powerpc/sysdev/i8259.c               |    8 +++-----
 arch/powerpc/sysdev/ipic.c                |    7 ++-----
 arch/powerpc/sysdev/ipic.h                |    3 ---
 arch/powerpc/sysdev/mpc8xx_pic.c          |   19 ++++++++++---------
 arch/powerpc/sysdev/mpic.c                |   11 ++++-------
 arch/powerpc/sysdev/mpic_msi.c            |    7 ++++---
 arch/powerpc/sysdev/mv64x60_pic.c         |    8 +++-----
 arch/powerpc/sysdev/qe_lib/qe_ic.c        |    7 ++-----
 arch/powerpc/sysdev/qe_lib/qe_ic.h        |    3 ---
 arch/powerpc/sysdev/tsi108_pci.c          |    8 ++++----
 arch/powerpc/sysdev/uic.c                 |   11 +++--------
 include/asm-powerpc/irq.h                 |    8 ++++++--
 include/asm-powerpc/mpic.h                |    3 ---
 26 files changed, 76 insertions(+), 109 deletions(-)

diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index dfad0e4..79b4512 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -418,10 +418,11 @@ irq_hw_number_t virq_to_hw(unsigned int virq)
 }
 EXPORT_SYMBOL_GPL(virq_to_hw);
 
-__init_refok struct irq_host *irq_alloc_host(unsigned int revmap_type,
-						unsigned int revmap_arg,
-						struct irq_host_ops *ops,
-						irq_hw_number_t inval_irq)
+__init_refok 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);
@@ -446,6 +447,7 @@ __init_refok struct irq_host *irq_alloc_host(unsigned int revmap_type,
 	host->revmap_type = revmap_type;
 	host->inval_irq = inval_irq;
 	host->ops = ops;
+	host->of_node = of_node;
 
 	spin_lock_irqsave(&irq_big_lock, flags);
 
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 8c464c5..1d793e4 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -244,7 +244,7 @@ static struct irq_chip mpc52xx_sdma_irqchip = {
 static int mpc52xx_irqhost_match(struct irq_host *h, struct device_node *node)
 {
 	pr_debug("%s: node=%p\n", __func__, node);
-	return mpc52xx_irqhost->host_data == node;
+	return h->of_node == node;
 }
 
 static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
@@ -419,14 +419,13 @@ void __init mpc52xx_init_irq(void)
 	 * hw irq information provided by the ofw to linux virq
 	 */
 
-	mpc52xx_irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR,
+	mpc52xx_irqhost = irq_alloc_host(picnode, IRQ_HOST_MAP_LINEAR,
 	                                 MPC52xx_IRQ_HIGHTESTHWIRQ,
 	                                 &mpc52xx_irqhost_ops, -1);
 
 	if (!mpc52xx_irqhost)
 		panic(__FILE__ ": Cannot allocate the IRQ host\n");
 
-	mpc52xx_irqhost->host_data = picnode;
 	printk(KERN_INFO "MPC52xx PIC is up and running!\n");
 }
 
diff --git a/arch/powerpc/platforms/82xx/mpc82xx_ads.c b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
index c0a0c56..91ddbd2 100644
--- a/arch/powerpc/platforms/82xx/mpc82xx_ads.c
+++ b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
@@ -61,7 +61,6 @@ static struct {
 
 static unsigned long pci_int_base;
 static struct irq_host *pci_pic_host;
-static struct device_node *pci_pic_node;
 #endif
 
 static void __init mpc82xx_ads_pic_init(void)
@@ -401,7 +400,7 @@ m82xx_pci_irq_demux(unsigned int irq, struct irq_desc *desc)
 
 static int pci_pic_host_match(struct irq_host *h, struct device_node *node)
 {
-	return node == pci_pic_node;
+	return h->of_node == node;
 }
 
 static int pci_pic_host_map(struct irq_host *h, unsigned int virq,
@@ -478,7 +477,6 @@ void m82xx_pci_init_irq(void)
 		iounmap(immap);
 		return;
 	}
-	pci_pic_node = of_node_get(np);
 	/* PCI interrupt controller registers: status and mask */
 	regs = of_get_property(np, "reg", &size);
 	if ((!regs) || (size <= 2)) {
@@ -490,7 +488,6 @@ void m82xx_pci_init_irq(void)
 	    ioremap(regs[0], sizeof(*pci_regs.pci_int_stat_reg));
 	pci_regs.pci_int_mask_reg =
 	    ioremap(regs[1], sizeof(*pci_regs.pci_int_mask_reg));
-	of_node_put(np);
 	/* configure chip select for PCI interrupt controller */
 	immap->im_memctl.memc_br3 = regs[0] | 0x00001801;
 	immap->im_memctl.memc_or3 = 0xffff8010;
@@ -501,7 +498,7 @@ void m82xx_pci_init_irq(void)
 	*pci_regs.pci_int_mask_reg |= 0xfff00000;
 	iounmap(immap);
 	pci_pic_host =
-	    irq_alloc_host(IRQ_HOST_MAP_LINEAR, irq_max - irq_min + 1,
+	    irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, irq_max - irq_min + 1,
 			   &pci_pic_host_ops, irq_max + 1);
 	return;
 }
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 4c9ab5b..bdd97bb 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -64,7 +64,6 @@
 
 
 struct axon_msic {
-	struct device_node *dn;
 	struct irq_host *irq_host;
 	__le32 *fifo;
 	dcr_host_t dcr_host;
@@ -297,9 +296,7 @@ static int msic_host_map(struct irq_host *h, unsigned int virq,
 
 static int msic_host_match(struct irq_host *host, struct device_node *dn)
 {
-	struct axon_msic *msic = host->host_data;
-
-	return msic->dn == dn;
+	return host->of_node == dn;
 }
 
 static struct irq_host_ops msic_host_ops = {
@@ -314,7 +311,8 @@ static int axon_msi_notify_reboot(struct notifier_block *nb,
 	u32 tmp;
 
 	list_for_each_entry(msic, &axon_msic_list, list) {
-		pr_debug("axon_msi: disabling %s\n", msic->dn->full_name);
+		pr_debug("axon_msi: disabling %s\n",
+			  msic->irq_host->of_node->full_name);
 		tmp  = msic_dcr_read(msic, MSIC_CTRL_REG);
 		tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE;
 		msic_dcr_write(msic, MSIC_CTRL_REG, tmp);
@@ -370,8 +368,8 @@ static int axon_msi_setup_one(struct device_node *dn)
 
 	msic->fifo = page_address(page);
 
-	msic->irq_host = irq_alloc_host(IRQ_HOST_MAP_NOMAP, NR_IRQS,
-					&msic_host_ops, 0);
+	msic->irq_host = irq_alloc_host(of_node_get(dn), IRQ_HOST_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",
 		       dn->full_name);
@@ -387,8 +385,6 @@ static int axon_msi_setup_one(struct device_node *dn)
 		goto out_free_host;
 	}
 
-	msic->dn = of_node_get(dn);
-
 	set_irq_data(virq, msic);
 	set_irq_chained_handler(virq, axon_msi_cascade);
 	pr_debug("axon_msi: irq 0x%x setup for axon_msi\n", virq);
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 47264e7..c29e634 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -381,7 +381,7 @@ static int __init setup_iic(void)
 void __init iic_init_IRQ(void)
 {
 	/* Setup an irq host data structure */
-	iic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, IIC_SOURCE_COUNT,
+	iic_host = irq_alloc_host(NULL, IRQ_HOST_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 05f4b3d..4309c2c 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -63,7 +63,6 @@ enum {
 
 struct spider_pic {
 	struct irq_host		*host;
-	struct device_node	*of_node;
 	void __iomem		*regs;
 	unsigned int		node_id;
 };
@@ -178,8 +177,7 @@ static struct irq_chip spider_pic = {
 
 static int spider_host_match(struct irq_host *h, struct device_node *node)
 {
-	struct spider_pic *pic = h->host_data;
-	return node == pic->of_node;
+	return h->of_node == node;
 }
 
 static int spider_host_map(struct irq_host *h, unsigned int virq,
@@ -247,18 +245,18 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
 	 * tree in case the device-tree is ever fixed
 	 */
 	struct of_irq oirq;
-	if (of_irq_map_one(pic->of_node, 0, &oirq) == 0) {
+	if (of_irq_map_one(pic->host->of_node, 0, &oirq) == 0) {
 		virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
 					     oirq.size);
 		return virq;
 	}
 
 	/* Now do the horrible hacks */
-	tmp = of_get_property(pic->of_node, "#interrupt-cells", NULL);
+	tmp = of_get_property(pic->host->of_node, "#interrupt-cells", NULL);
 	if (tmp == NULL)
 		return NO_IRQ;
 	intsize = *tmp;
-	imap = of_get_property(pic->of_node, "interrupt-map", &imaplen);
+	imap = of_get_property(pic->host->of_node, "interrupt-map", &imaplen);
 	if (imap == NULL || imaplen < (intsize + 1))
 		return NO_IRQ;
 	iic = of_find_node_by_phandle(imap[intsize]);
@@ -308,15 +306,13 @@ 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(IRQ_HOST_MAP_LINEAR, SPIDER_SRC_COUNT,
-				   &spider_host_ops, SPIDER_IRQ_INVALID);
+	pic->host = irq_alloc_host(of_node_get(of_node), IRQ_HOST_MAP_LINEAR,
+				   SPIDER_SRC_COUNT, &spider_host_ops,
+				   SPIDER_IRQ_INVALID);
 	if (pic->host == NULL)
 		panic("spider_pic: can't allocate irq host !");
 	pic->host->host_data = pic;
 
-	/* Fill out other bits */
-	pic->of_node = of_node_get(of_node);
-
 	/* Go through all sources and disable them */
 	for (i = 0; i < SPIDER_SRC_COUNT; i++) {
 		void __iomem *cfg = pic->regs + TIR_CFGA + 8 * i;
diff --git a/arch/powerpc/platforms/celleb/interrupt.c b/arch/powerpc/platforms/celleb/interrupt.c
index 98e6665..4ecdf06 100644
--- a/arch/powerpc/platforms/celleb/interrupt.c
+++ b/arch/powerpc/platforms/celleb/interrupt.c
@@ -242,7 +242,7 @@ void __init beatic_init_IRQ(void)
 	ppc_md.get_irq = beatic_get_irq;
 
 	/* Allocate an irq host */
-	beatic_host = irq_alloc_host(IRQ_HOST_MAP_NOMAP, 0,
+	beatic_host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0,
 					 &beatic_pic_host_ops,
 					 0);
 	BUG_ON(beatic_host == NULL);
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index 63b3367..3666746 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -369,7 +369,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(IRQ_HOST_MAP_NOMAP, 0, &iseries_irq_host_ops, 0);
+	host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0,
+			      &iseries_irq_host_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 87cd680..999f5e1 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -384,7 +384,7 @@ static void __init pmac_pic_probe_oldstyle(void)
 	/*
 	 * Allocate an irq host
 	 */
-	pmac_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, max_irqs,
+	pmac_pic_host = irq_alloc_host(master, IRQ_HOST_MAP_LINEAR, max_irqs,
 				       &pmac_pic_host_ops,
 				       max_irqs);
 	BUG_ON(pmac_pic_host == NULL);
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 67e32ec..30b9f4c 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -726,7 +726,7 @@ void __init ps3_init_IRQ(void)
 	unsigned cpu;
 	struct irq_host *host;
 
-	host = irq_alloc_host(IRQ_HOST_MAP_NOMAP, 0, &ps3_host_ops,
+	host = irq_alloc_host(NULL, IRQ_HOST_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/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 5bd90a7..5ddb025 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -540,7 +540,7 @@ static void __init xics_init_host(void)
 		ops = &xics_host_lpar_ops;
 	else
 		ops = &xics_host_direct_ops;
-	xics_host = irq_alloc_host(IRQ_HOST_MAP_TREE, 0, ops,
+	xics_host = irq_alloc_host(NULL, IRQ_HOST_MAP_TREE, 0, ops,
 				   XICS_IRQ_SPURIOUS);
 	BUG_ON(xics_host == NULL);
 	irq_set_default_host(xics_host);
diff --git a/arch/powerpc/sysdev/commproc.c b/arch/powerpc/sysdev/commproc.c
index e8e79f8..05dc30b 100644
--- a/arch/powerpc/sysdev/commproc.c
+++ b/arch/powerpc/sysdev/commproc.c
@@ -50,7 +50,6 @@ static uint host_end;    /* end + 1 */
 cpm8xx_t *cpmp;          /* Pointer to comm processor space */
 cpic8xx_t *cpic_reg;
 
-static struct device_node *cpm_pic_node;
 static struct irq_host *cpm_pic_host;
 
 static void cpm_mask_irq(unsigned int irq)
@@ -97,7 +96,7 @@ int cpm_get_irq(void)
 
 static int cpm_pic_host_match(struct irq_host *h, struct device_node *node)
 {
-	return cpm_pic_node == node;
+	return h->of_node == node;
 }
 
 static int cpm_pic_host_map(struct irq_host *h, unsigned int virq,
@@ -165,9 +164,8 @@ unsigned int cpm_pic_init(void)
 
 	out_be32(&cpic_reg->cpic_cimr, 0);
 
-	cpm_pic_node = of_node_get(np);
-
-	cpm_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 64, &cpm_pic_host_ops, 64);
+	cpm_pic_host = irq_alloc_host(of_node_get(np), IRQ_HOST_MAP_LINEAR,
+				      64, &cpm_pic_host_ops, 64);
 	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 eabfe06..d9ab30c 100644
--- a/arch/powerpc/sysdev/cpm2_pic.c
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -50,7 +50,6 @@
 
 static intctl_cpm2_t *cpm2_intctl;
 
-static struct device_node *cpm2_pic_node;
 static struct irq_host *cpm2_pic_host;
 #define NR_MASK_WORDS   ((NR_IRQS + 31) / 32)
 static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
@@ -208,7 +207,7 @@ unsigned int cpm2_get_irq(void)
 
 static int cpm2_pic_host_match(struct irq_host *h, struct device_node *node)
 {
-	return cpm2_pic_node == node;
+	return h->of_node == node;
 }
 
 static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq,
@@ -273,8 +272,8 @@ void cpm2_pic_init(struct device_node *node)
 	out_be32(&cpm2_intctl->ic_scprrl, 0x05309770);
 
 	/* create a legacy host */
-	cpm2_pic_node = of_node_get(node);
-	cpm2_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 64, &cpm2_pic_host_ops, 64);
+	cpm2_pic_host = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LINEAR,
+				       64, &cpm2_pic_host_ops, 64);
 	if (cpm2_pic_host == NULL) {
 		printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
 		return;
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index ad87adc..7c1b27a 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -25,7 +25,6 @@ static unsigned char cached_8259[2] = { 0xff, 0xff };
 
 static DEFINE_SPINLOCK(i8259_lock);
 
-static struct device_node *i8259_node;
 static struct irq_host *i8259_host;
 
 /*
@@ -165,7 +164,7 @@ static struct resource pic_edgectrl_iores = {
 
 static int i8259_host_match(struct irq_host *h, struct device_node *node)
 {
-	return i8259_node == NULL || i8259_node == node;
+	return h->of_node == NULL || h->of_node == node;
 }
 
 static int i8259_host_map(struct irq_host *h, unsigned int virq,
@@ -276,9 +275,8 @@ void i8259_init(struct device_node *node, unsigned long intack_addr)
 	spin_unlock_irqrestore(&i8259_lock, flags);
 
 	/* create a legacy host */
-	if (node)
-		i8259_node = of_node_get(node);
-	i8259_host = irq_alloc_host(IRQ_HOST_MAP_LEGACY, 0, &i8259_host_ops, 0);
+	i8259_host = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LEGACY,
+				    0, &i8259_host_ops, 0);
 	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 473c415..05a56e5 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -511,10 +511,8 @@ static struct irq_chip ipic_irq_chip = {
 
 static int ipic_host_match(struct irq_host *h, struct device_node *node)
 {
-	struct ipic *ipic = h->host_data;
-
 	/* Exact match, unless ipic node is NULL */
-	return ipic->of_node == NULL || ipic->of_node == node;
+	return h->of_node == NULL || h->of_node == node;
 }
 
 static int ipic_host_map(struct irq_host *h, unsigned int virq,
@@ -568,9 +566,8 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
 		return NULL;
 
 	memset(ipic, 0, sizeof(struct ipic));
-	ipic->of_node = of_node_get(node);
 
-	ipic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR,
+	ipic->irqhost = irq_alloc_host(of_node_get(node), IRQ_HOST_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 c28e589..bb309a5 100644
--- a/arch/powerpc/sysdev/ipic.h
+++ b/arch/powerpc/sysdev/ipic.h
@@ -48,9 +48,6 @@ struct ipic {
 
 	/* The "linux" controller struct */
 	struct irq_chip		hc_irq;
-
-	/* The device node of the interrupt controller */
-	struct device_node	*of_node;
 };
 
 struct ipic_info {
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c
index 2fc2bcd..f20a4d4 100644
--- a/arch/powerpc/sysdev/mpc8xx_pic.c
+++ b/arch/powerpc/sysdev/mpc8xx_pic.c
@@ -19,7 +19,6 @@
 
 extern int cpm_get_irq(struct pt_regs *regs);
 
-static struct device_node *mpc8xx_pic_node;
 static struct irq_host *mpc8xx_pic_host;
 #define NR_MASK_WORDS   ((NR_IRQS + 31) / 32)
 static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
@@ -122,7 +121,7 @@ unsigned int mpc8xx_get_irq(void)
 
 static int mpc8xx_pic_host_match(struct irq_host *h, struct device_node *node)
 {
-	return mpc8xx_pic_node == node;
+	return h->of_node == node;
 }
 
 static int mpc8xx_pic_host_map(struct irq_host *h, unsigned int virq,
@@ -176,22 +175,24 @@ int mpc8xx_pic_init(void)
 		return -ENOMEM;
 	}
 
-	mpc8xx_pic_node = of_node_get(np);
-
 	ret = of_address_to_resource(np, 0, &res);
-	of_node_put(np);
 	if (ret)
-		return ret;
+		goto out;
 
 	siu_reg = (void *)ioremap(res.start, res.end - res.start + 1);
-	if (siu_reg == NULL)
-		return -EINVAL;
+	if (siu_reg == NULL) {
+		ret = -EINVAL;
+		goto out;
+	}
 
-	mpc8xx_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 64, &mpc8xx_pic_host_ops, 64);
+	mpc8xx_pic_host = irq_alloc_host(of_node_get(np), IRQ_HOST_MAP_LINEAR,
+					 64, &mpc8xx_pic_host_ops, 64);
 	if (mpc8xx_pic_host == NULL) {
 		printk(KERN_ERR "MPC8xx PIC: failed to allocate irq host!\n");
 		ret = -ENOMEM;
 	}
 
+out:
+	of_node_put(np);
 	return ret;
 }
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 74c64c0..25a81f7 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -271,7 +271,7 @@ static void _mpic_map_dcr(struct mpic *mpic, struct mpic_reg_bank *rb,
 {
 	rb->dbase = mpic->dcr_base;
 	rb->doff = offset;
-	rb->dhost = dcr_map(mpic->of_node, rb->dbase + rb->doff, size);
+	rb->dhost = dcr_map(mpic->irqhost->of_node, rb->dbase + rb->doff, size);
 	BUG_ON(!DCR_MAP_OK(rb->dhost));
 }
 
@@ -861,10 +861,8 @@ static struct irq_chip mpic_irq_ht_chip = {
 
 static int mpic_host_match(struct irq_host *h, struct device_node *node)
 {
-	struct mpic *mpic = h->host_data;
-
 	/* Exact match, unless mpic node is NULL */
-	return mpic->of_node == NULL || mpic->of_node == node;
+	return h->of_node == NULL || h->of_node == node;
 }
 
 static int mpic_host_map(struct irq_host *h, unsigned int virq,
@@ -985,10 +983,9 @@ struct mpic * __init mpic_alloc(struct device_node *node,
 	
 	memset(mpic, 0, sizeof(struct mpic));
 	mpic->name = name;
-	mpic->of_node = of_node_get(node);
 
-	mpic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, isu_size,
-				       &mpic_host_ops,
+	mpic->irqhost = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LINEAR,
+				       isu_size, &mpic_host_ops,
 				       flags & MPIC_LARGE_VECTORS ? 2048 : 256);
 	if (mpic->irqhost == NULL) {
 		of_node_put(node);
diff --git a/arch/powerpc/sysdev/mpic_msi.c b/arch/powerpc/sysdev/mpic_msi.c
index b076793..9ca4d8f 100644
--- a/arch/powerpc/sysdev/mpic_msi.c
+++ b/arch/powerpc/sysdev/mpic_msi.c
@@ -117,16 +117,17 @@ static int mpic_msi_reserve_dt_hwirqs(struct mpic *mpic)
 	int i, len;
 	const u32 *p;
 
-	p = of_get_property(mpic->of_node, "msi-available-ranges", &len);
+	p = of_get_property(mpic->irqhost->of_node,
+			    "msi-available-ranges", &len);
 	if (!p) {
 		pr_debug("mpic: no msi-available-ranges property found on %s\n",
-			  mpic->of_node->full_name);
+			  mpic->irqhost->of_node->full_name);
 		return -ENODEV;
 	}
 
 	if (len % 8 != 0) {
 		printk(KERN_WARNING "mpic: Malformed msi-available-ranges "
-		       "property on %s\n", mpic->of_node->full_name);
+		       "property on %s\n", mpic->irqhost->of_node->full_name);
 		return -EINVAL;
 	}
 
diff --git a/arch/powerpc/sysdev/mv64x60_pic.c b/arch/powerpc/sysdev/mv64x60_pic.c
index 01d3162..a145bfd 100644
--- a/arch/powerpc/sysdev/mv64x60_pic.c
+++ b/arch/powerpc/sysdev/mv64x60_pic.c
@@ -204,7 +204,7 @@ static struct irq_chip mv64x60_chip_gpp = {
 
 static int mv64x60_host_match(struct irq_host *h, struct device_node *np)
 {
-	return mv64x60_irq_host->host_data == np;
+	return h->of_node == np;
 }
 
 static struct irq_chip *mv64x60_chips[] = {
@@ -253,14 +253,12 @@ void __init mv64x60_init_irq(void)
 	np = of_find_compatible_node(NULL, NULL, "marvell,mv64x60-pic");
 	reg = of_get_property(np, "reg", &size);
 	paddr = of_translate_address(np, reg);
-	of_node_put(np);
 	mv64x60_irq_reg_base = ioremap(paddr, reg[1]);
 
-	mv64x60_irq_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, MV64x60_NUM_IRQS,
+	mv64x60_irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
+					  MV64x60_NUM_IRQS,
 					  &mv64x60_host_ops, MV64x60_NUM_IRQS);
 
-	mv64x60_irq_host->host_data = np;
-
 	spin_lock_irqsave(&mv64x60_lock, flags);
 	out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
 		 mv64x60_cached_gpp_mask);
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index 4d1dcb4..55e6f39 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -245,10 +245,8 @@ static struct irq_chip qe_ic_irq_chip = {
 
 static int qe_ic_host_match(struct irq_host *h, struct device_node *node)
 {
-	struct qe_ic *qe_ic = h->host_data;
-
 	/* Exact match, unless qe_ic node is NULL */
-	return qe_ic->of_node == NULL || qe_ic->of_node == node;
+	return h->of_node == NULL || h->of_node == node;
 }
 
 static int qe_ic_host_map(struct irq_host *h, unsigned int virq,
@@ -352,9 +350,8 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags)
 		return;
 
 	memset(qe_ic, 0, sizeof(struct qe_ic));
-	qe_ic->of_node = of_node_get(node);
 
-	qe_ic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR,
+	qe_ic->irqhost = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LINEAR,
 					NR_QE_IC_INTS, &qe_ic_host_ops, 0);
 	if (qe_ic->irqhost == NULL) {
 		of_node_put(node);
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.h b/arch/powerpc/sysdev/qe_lib/qe_ic.h
index 9a631ad..c1361d0 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.h
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.h
@@ -84,9 +84,6 @@ struct qe_ic {
 	/* The "linux" controller struct */
 	struct irq_chip hc_irq;
 
-	/* The device node of the interrupt controller */
-	struct device_node *of_node;
-
 	/* VIRQ numbers of QE high/low irqs */
 	unsigned int virq_high;
 	unsigned int virq_low;
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index cf0bfbd..b41492a 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -52,7 +52,6 @@
 u32 tsi108_pci_cfg_base;
 static u32 tsi108_pci_cfg_phys;
 u32 tsi108_csr_vir_base;
-static struct device_node *pci_irq_node;
 static struct irq_host *pci_irq_host;
 
 extern u32 get_vir_csrbase(void);
@@ -407,7 +406,7 @@ static int pci_irq_host_map(struct irq_host *h, unsigned int virq,
 
 static int pci_irq_host_match(struct irq_host *h, struct device_node *node)
 {
-	return pci_irq_node == node;
+	return h->of_node == node;
 }
 
 static struct irq_host_ops pci_irq_host_ops = {
@@ -433,10 +432,11 @@ void __init tsi108_pci_int_init(struct device_node *node)
 {
 	DBG("Tsi108_pci_int_init: initializing PCI interrupts\n");
 
-	pci_irq_node = of_node_get(node);
-	pci_irq_host = irq_alloc_host(IRQ_HOST_MAP_LEGACY, 0, &pci_irq_host_ops, 0);
+	pci_irq_host = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LEGACY,
+				      0, &pci_irq_host_ops, 0);
 	if (pci_irq_host == NULL) {
 		printk(KERN_ERR "pci_irq_host: failed to allocate irq host !\n");
+		of_node_put(node);
 		return;
 	}
 
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
index 47180b3..bf37667 100644
--- a/arch/powerpc/sysdev/uic.c
+++ b/arch/powerpc/sysdev/uic.c
@@ -56,9 +56,6 @@ struct uic {
 
 	/* For secondary UICs, the cascade interrupt's irqaction */
 	struct irqaction cascade;
-
-	/* The device node of the interrupt controller */
-	struct device_node *of_node;
 };
 
 static void uic_unmask_irq(unsigned int virq)
@@ -220,8 +217,7 @@ out_unlock:
 
 static int uic_host_match(struct irq_host *h, struct device_node *node)
 {
-	struct uic *uic = h->host_data;
-	return uic->of_node == node;
+	return h->of_node == node;
 }
 
 static int uic_host_map(struct irq_host *h, unsigned int virq,
@@ -291,7 +287,6 @@ static struct uic * __init uic_init_one(struct device_node *node)
 
 	memset(uic, 0, sizeof(*uic));
 	spin_lock_init(&uic->lock);
-	uic->of_node = of_node_get(node);
 	indexp = of_get_property(node, "cell-index", &len);
 	if (!indexp || (len != sizeof(u32))) {
 		printk(KERN_ERR "uic: Device node %s has missing or invalid "
@@ -308,8 +303,8 @@ static struct uic * __init uic_init_one(struct device_node *node)
 	}
 	uic->dcrbase = *dcrreg;
 
-	uic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, NR_UIC_INTS,
-				      &uic_host_ops, -1);
+	uic->irqhost = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LINEAR,
+				      NR_UIC_INTS, &uic_host_ops, -1);
 	if (! uic->irqhost) {
 		of_node_put(node);
 		return NULL; /* FIXME: panic? */
diff --git a/include/asm-powerpc/irq.h b/include/asm-powerpc/irq.h
index 0485c53..1392db4 100644
--- a/include/asm-powerpc/irq.h
+++ b/include/asm-powerpc/irq.h
@@ -124,6 +124,9 @@ struct irq_host {
 	struct irq_host_ops	*ops;
 	void			*host_data;
 	irq_hw_number_t		inval_irq;
+
+	/* Optional device node pointer */
+	struct device_node	*of_node;
 };
 
 /* The main irq map itself is an array of NR_IRQ entries containing the
@@ -142,7 +145,7 @@ extern irq_hw_number_t virq_to_hw(unsigned int virq);
 
 /**
  * irq_alloc_host - Allocate a new irq_host data structure
- * @node: device-tree node of the interrupt controller
+ * @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
@@ -156,7 +159,8 @@ extern irq_hw_number_t virq_to_hw(unsigned int virq);
  * later during boot automatically (the reverse mapping will use the slow path
  * until that happens).
  */
-extern struct irq_host *irq_alloc_host(unsigned int revmap_type,
+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);
diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h
index 262db6b..0eb3ab9 100644
--- a/include/asm-powerpc/mpic.h
+++ b/include/asm-powerpc/mpic.h
@@ -240,9 +240,6 @@ struct mpic_irq_save {
 /* The instance data of a given MPIC */
 struct mpic
 {
-	/* The device node of the interrupt controller */
-	struct device_node	*of_node;
-
 	/* The remapper for this MPIC */
 	struct irq_host		*irqhost;
 
-- 
1.5.1.3.g7a33b

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

* [PATCH 2/5] Invert null match behaviour for irq_hosts
  2007-08-28  8:47 [PATCH 1/5] Add an optional device_node pointer to the irq_host Michael Ellerman
  2007-08-28  8:47 ` [PATCH 3/5] Provide a default irq_host match, which matches on an exact of_node Michael Ellerman
@ 2007-08-28  8:47 ` Michael Ellerman
  2007-08-28  8:47 ` [PATCH 4/5] Initialise hwirq for legacy irqs Michael Ellerman
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Michael Ellerman @ 2007-08-28  8:47 UTC (permalink / raw)
  To: linuxppc-dev

Currently if you don't specify a match callback for your irq_host it's
assumed you match everything. This is a kind of opt-out approach, and
turns out to be the exception rather than the rule.

So change the semantics to be opt-in, ie. you don't match anything unless
you provide a match callback. This in itself isn't very useful, but will
allow us to provide a default match implementation in a subsequent patch.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/kernel/irq.c                 |    2 +-
 arch/powerpc/platforms/celleb/interrupt.c |    7 +++++++
 arch/powerpc/platforms/iseries/irq.c      |    7 +++++++
 arch/powerpc/platforms/ps3/interrupt.c    |    7 +++++++
 4 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 79b4512..30fb8e2 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -523,7 +523,7 @@ struct irq_host *irq_find_host(struct device_node *node)
 	 */
 	spin_lock_irqsave(&irq_big_lock, flags);
 	list_for_each_entry(h, &irq_hosts, link)
-		if (h->ops->match == NULL || h->ops->match(h, node)) {
+		if (h->ops->match != NULL && h->ops->match(h, node)) {
 			found = h;
 			break;
 		}
diff --git a/arch/powerpc/platforms/celleb/interrupt.c b/arch/powerpc/platforms/celleb/interrupt.c
index 4ecdf06..c7c68ca 100644
--- a/arch/powerpc/platforms/celleb/interrupt.c
+++ b/arch/powerpc/platforms/celleb/interrupt.c
@@ -175,11 +175,18 @@ 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)
+{
+	/* Match all */
+	return 1;
+}
+
 static struct irq_host_ops beatic_pic_host_ops = {
 	.map = beatic_pic_host_map,
 	.remap = beatic_pic_host_remap,
 	.unmap = beatic_pic_host_unmap,
 	.xlate = beatic_pic_host_xlate,
+	.match = beatic_pic_host_match,
 };
 
 /*
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index 3666746..701d929 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -346,8 +346,15 @@ 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)
+{
+	/* Match all */
+	return 1;
+}
+
 static struct irq_host_ops iseries_irq_host_ops = {
 	.map = iseries_irq_host_map,
+	.match = iseries_irq_host_match,
 };
 
 /*
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 30b9f4c..3a6db04 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -673,9 +673,16 @@ 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)
+{
+	/* Match all */
+	return 1;
+}
+
 static struct irq_host_ops ps3_host_ops = {
 	.map = ps3_host_map,
 	.unmap = ps3_host_unmap,
+	.match = ps3_host_match,
 };
 
 void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq)
-- 
1.5.1.3.g7a33b

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

* [PATCH 3/5] Provide a default irq_host match, which matches on an exact of_node
  2007-08-28  8:47 [PATCH 1/5] Add an optional device_node pointer to the irq_host Michael Ellerman
@ 2007-08-28  8:47 ` Michael Ellerman
  2007-08-28  8:47 ` [PATCH 2/5] Invert null match behaviour for irq_hosts Michael Ellerman
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Michael Ellerman @ 2007-08-28  8:47 UTC (permalink / raw)
  To: linuxppc-dev

The most common match semantic is an exact match based on the device node.
So provide a default implementation that does this, and hook it up if no
match routine is specified.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/kernel/irq.c                 |   10 +++++++++-
 arch/powerpc/platforms/52xx/mpc52xx_pic.c |    7 -------
 arch/powerpc/platforms/82xx/mpc82xx_ads.c |    6 ------
 arch/powerpc/platforms/cell/axon_msi.c    |    6 ------
 arch/powerpc/platforms/cell/spider-pic.c  |    6 ------
 arch/powerpc/sysdev/commproc.c            |    6 ------
 arch/powerpc/sysdev/cpm2_pic.c            |    6 ------
 arch/powerpc/sysdev/mpc8xx_pic.c          |    6 ------
 arch/powerpc/sysdev/mv64x60_pic.c         |    6 ------
 arch/powerpc/sysdev/tsi108_pci.c          |    6 ------
 arch/powerpc/sysdev/uic.c                 |    6 ------
 11 files changed, 9 insertions(+), 62 deletions(-)

diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 30fb8e2..d5c7e4c 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -418,6 +418,11 @@ irq_hw_number_t virq_to_hw(unsigned int virq)
 }
 EXPORT_SYMBOL_GPL(virq_to_hw);
 
+static int default_irq_host_match(struct irq_host *h, struct device_node *np)
+{
+	return h->of_node != NULL && h->of_node == np;
+}
+
 __init_refok struct irq_host *irq_alloc_host(struct device_node *of_node,
 				unsigned int revmap_type,
 				unsigned int revmap_arg,
@@ -449,6 +454,9 @@ __init_refok struct irq_host *irq_alloc_host(struct device_node *of_node,
 	host->ops = ops;
 	host->of_node = of_node;
 
+	if (host->ops->match == NULL)
+		host->ops->match = default_irq_host_match;
+
 	spin_lock_irqsave(&irq_big_lock, flags);
 
 	/* If it's a legacy controller, check for duplicates and
@@ -523,7 +531,7 @@ struct irq_host *irq_find_host(struct device_node *node)
 	 */
 	spin_lock_irqsave(&irq_big_lock, flags);
 	list_for_each_entry(h, &irq_hosts, link)
-		if (h->ops->match != NULL && h->ops->match(h, node)) {
+		if (h->ops->match(h, node)) {
 			found = h;
 			break;
 		}
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 1d793e4..0f4ca8a 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -241,12 +241,6 @@ static struct irq_chip mpc52xx_sdma_irqchip = {
  * irq_host
 */
 
-static int mpc52xx_irqhost_match(struct irq_host *h, struct device_node *node)
-{
-	pr_debug("%s: node=%p\n", __func__, node);
-	return h->of_node == node;
-}
-
 static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
 				 u32 * intspec, unsigned int intsize,
 				 irq_hw_number_t * out_hwirq,
@@ -367,7 +361,6 @@ static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
 }
 
 static struct irq_host_ops mpc52xx_irqhost_ops = {
-	.match = mpc52xx_irqhost_match,
 	.xlate = mpc52xx_irqhost_xlate,
 	.map = mpc52xx_irqhost_map,
 };
diff --git a/arch/powerpc/platforms/82xx/mpc82xx_ads.c b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
index 91ddbd2..4008795 100644
--- a/arch/powerpc/platforms/82xx/mpc82xx_ads.c
+++ b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
@@ -398,11 +398,6 @@ m82xx_pci_irq_demux(unsigned int irq, struct irq_desc *desc)
 	}
 }
 
-static int pci_pic_host_match(struct irq_host *h, struct device_node *node)
-{
-	return h->of_node == node;
-}
-
 static int pci_pic_host_map(struct irq_host *h, unsigned int virq,
 			    irq_hw_number_t hw)
 {
@@ -418,7 +413,6 @@ static void pci_host_unmap(struct irq_host *h, unsigned int virq)
 }
 
 static struct irq_host_ops pci_pic_host_ops = {
-	.match = pci_pic_host_match,
 	.map = pci_pic_host_map,
 	.unmap = pci_host_unmap,
 };
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index bdd97bb..74407af 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -294,13 +294,7 @@ static int msic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int msic_host_match(struct irq_host *host, struct device_node *dn)
-{
-	return host->of_node == dn;
-}
-
 static struct irq_host_ops msic_host_ops = {
-	.match	= msic_host_match,
 	.map	= msic_host_map,
 };
 
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 4309c2c..3f4b4ae 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -175,11 +175,6 @@ static struct irq_chip spider_pic = {
 	.set_type = spider_set_irq_type,
 };
 
-static int spider_host_match(struct irq_host *h, struct device_node *node)
-{
-	return h->of_node == node;
-}
-
 static int spider_host_map(struct irq_host *h, unsigned int virq,
 			irq_hw_number_t hw)
 {
@@ -206,7 +201,6 @@ static int spider_host_xlate(struct irq_host *h, struct device_node *ct,
 }
 
 static struct irq_host_ops spider_host_ops = {
-	.match = spider_host_match,
 	.map = spider_host_map,
 	.xlate = spider_host_xlate,
 };
diff --git a/arch/powerpc/sysdev/commproc.c b/arch/powerpc/sysdev/commproc.c
index 05dc30b..b562afc 100644
--- a/arch/powerpc/sysdev/commproc.c
+++ b/arch/powerpc/sysdev/commproc.c
@@ -94,11 +94,6 @@ int cpm_get_irq(void)
 	return irq_linear_revmap(cpm_pic_host, cpm_vec);
 }
 
-static int cpm_pic_host_match(struct irq_host *h, struct device_node *node)
-{
-	return h->of_node == node;
-}
-
 static int cpm_pic_host_map(struct irq_host *h, unsigned int virq,
 			  irq_hw_number_t hw)
 {
@@ -126,7 +121,6 @@ static struct irqaction cpm_error_irqaction = {
 };
 
 static struct irq_host_ops cpm_pic_host_ops = {
-	.match = cpm_pic_host_match,
 	.map = cpm_pic_host_map,
 };
 
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
index d9ab30c..d5b36e0 100644
--- a/arch/powerpc/sysdev/cpm2_pic.c
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -205,11 +205,6 @@ unsigned int cpm2_get_irq(void)
 	return irq_linear_revmap(cpm2_pic_host, irq);
 }
 
-static int cpm2_pic_host_match(struct irq_host *h, struct device_node *node)
-{
-	return h->of_node == node;
-}
-
 static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq,
 			  irq_hw_number_t hw)
 {
@@ -233,7 +228,6 @@ static int cpm2_pic_host_xlate(struct irq_host *h, struct device_node *ct,
 }
 
 static struct irq_host_ops cpm2_pic_host_ops = {
-	.match = cpm2_pic_host_match,
 	.map = cpm2_pic_host_map,
 	.xlate = cpm2_pic_host_xlate,
 };
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c
index f20a4d4..565156a 100644
--- a/arch/powerpc/sysdev/mpc8xx_pic.c
+++ b/arch/powerpc/sysdev/mpc8xx_pic.c
@@ -119,11 +119,6 @@ unsigned int mpc8xx_get_irq(void)
 
 }
 
-static int mpc8xx_pic_host_match(struct irq_host *h, struct device_node *node)
-{
-	return h->of_node == node;
-}
-
 static int mpc8xx_pic_host_map(struct irq_host *h, unsigned int virq,
 			  irq_hw_number_t hw)
 {
@@ -157,7 +152,6 @@ static int mpc8xx_pic_host_xlate(struct irq_host *h, struct device_node *ct,
 
 
 static struct irq_host_ops mpc8xx_pic_host_ops = {
-	.match = mpc8xx_pic_host_match,
 	.map = mpc8xx_pic_host_map,
 	.xlate = mpc8xx_pic_host_xlate,
 };
diff --git a/arch/powerpc/sysdev/mv64x60_pic.c b/arch/powerpc/sysdev/mv64x60_pic.c
index a145bfd..19e6ef2 100644
--- a/arch/powerpc/sysdev/mv64x60_pic.c
+++ b/arch/powerpc/sysdev/mv64x60_pic.c
@@ -202,11 +202,6 @@ static struct irq_chip mv64x60_chip_gpp = {
  * mv64x60_host_ops functions
  */
 
-static int mv64x60_host_match(struct irq_host *h, struct device_node *np)
-{
-	return h->of_node == np;
-}
-
 static struct irq_chip *mv64x60_chips[] = {
 	[MV64x60_LEVEL1_LOW]  = &mv64x60_chip_low,
 	[MV64x60_LEVEL1_HIGH] = &mv64x60_chip_high,
@@ -228,7 +223,6 @@ static int mv64x60_host_map(struct irq_host *h, unsigned int virq,
 }
 
 static struct irq_host_ops mv64x60_host_ops = {
-	.match = mv64x60_host_match,
 	.map   = mv64x60_host_map,
 };
 
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index b41492a..31d3d33 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -404,13 +404,7 @@ static int pci_irq_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int pci_irq_host_match(struct irq_host *h, struct device_node *node)
-{
-	return h->of_node == node;
-}
-
 static struct irq_host_ops pci_irq_host_ops = {
-	.match = pci_irq_host_match,
 	.map = pci_irq_host_map,
 	.xlate = pci_irq_host_xlate,
 };
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
index bf37667..5149716 100644
--- a/arch/powerpc/sysdev/uic.c
+++ b/arch/powerpc/sysdev/uic.c
@@ -215,11 +215,6 @@ out_unlock:
 	spin_unlock(&desc->lock);
 }
 
-static int uic_host_match(struct irq_host *h, struct device_node *node)
-{
-	return h->of_node == node;
-}
-
 static int uic_host_map(struct irq_host *h, unsigned int virq,
 			irq_hw_number_t hw)
 {
@@ -249,7 +244,6 @@ static int uic_host_xlate(struct irq_host *h, struct device_node *ct,
 }
 
 static struct irq_host_ops uic_host_ops = {
-	.match	= uic_host_match,
 	.map	= uic_host_map,
 	.xlate	= uic_host_xlate,
 };
-- 
1.5.1.3.g7a33b

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

* [PATCH 4/5] Initialise hwirq for legacy irqs
  2007-08-28  8:47 [PATCH 1/5] Add an optional device_node pointer to the irq_host Michael Ellerman
  2007-08-28  8:47 ` [PATCH 3/5] Provide a default irq_host match, which matches on an exact of_node Michael Ellerman
  2007-08-28  8:47 ` [PATCH 2/5] Invert null match behaviour for irq_hosts Michael Ellerman
@ 2007-08-28  8:47 ` Michael Ellerman
  2007-08-28  8:47 ` [PATCH 5/5] Export virq mapping via debugfs Michael Ellerman
  2007-08-28  8:50 ` [PATCH 1/5] Add an optional device_node pointer to the irq_host Michael Ellerman
  4 siblings, 0 replies; 7+ messages in thread
From: Michael Ellerman @ 2007-08-28  8:47 UTC (permalink / raw)
  To: linuxppc-dev

Although no one uses the hwirq value for legacy irqs at the moment, we
should really setup the correct value in the irq_map.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/kernel/irq.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index d5c7e4c..1339f32 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -487,7 +487,7 @@ __init_refok struct irq_host *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 = 0;
+			irq_map[i].hwirq = i;
 			smp_wmb();
 			irq_map[i].host = host;
 			smp_wmb();
-- 
1.5.1.3.g7a33b

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

* [PATCH 5/5] Export virq mapping via debugfs
  2007-08-28  8:47 [PATCH 1/5] Add an optional device_node pointer to the irq_host Michael Ellerman
                   ` (2 preceding siblings ...)
  2007-08-28  8:47 ` [PATCH 4/5] Initialise hwirq for legacy irqs Michael Ellerman
@ 2007-08-28  8:47 ` Michael Ellerman
  2007-08-28  8:50 ` [PATCH 1/5] Add an optional device_node pointer to the irq_host Michael Ellerman
  4 siblings, 0 replies; 7+ messages in thread
From: Michael Ellerman @ 2007-08-28  8:47 UTC (permalink / raw)
  To: linuxppc-dev

This patch adds a debugfs file "powerpc/virq_mapping", which shows the virtual
to real mapping of irq numbers. Enable it with CONFIG_VIRQ_DEBUG.

Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
Signed-off-by: Chen Gong <G.Chen@freescale.com>
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/Kconfig.debug |   10 +++++++
 arch/powerpc/kernel/irq.c  |   63 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 22acece..c38bc22 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -124,6 +124,16 @@ config IRQSTACKS
 	  for handling hard and soft interrupts.  This can help avoid
 	  overflowing the process kernel stacks.
 
+config VIRQ_DEBUG
+	bool "Expose hardware/virtual IRQ mapping via debugfs"
+	depends on DEBUG_FS && PPC_MERGE
+	help
+	  This option will show the mapping relationship between hardware irq
+	  numbers and virtual irq numbers. The mapping is exposed via debugfs
+	  in the file powerpc/virq_mapping.
+
+	  If you don't know what this means you don't need it.
+
 config BDI_SWITCH
 	bool "Include BDI-2000 user context switcher"
 	depends on DEBUG_KERNEL && PPC32
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 1339f32..0e47c8c 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -52,6 +52,7 @@
 #include <linux/mutex.h>
 #include <linux/bootmem.h>
 #include <linux/pci.h>
+#include <linux/debugfs.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -1006,6 +1007,68 @@ static int irq_late_init(void)
 }
 arch_initcall(irq_late_init);
 
+#ifdef CONFIG_VIRQ_DEBUG
+static int virq_debug_show(struct seq_file *m, void *private)
+{
+	unsigned long flags;
+	irq_desc_t *desc;
+	const char *p;
+	char none[] = "none";
+	int i;
+
+	seq_printf(m, "%-5s  %-7s  %-15s  %s\n", "virq", "hwirq",
+		      "chip name", "host name");
+
+	for (i = 1; i < NR_IRQS; i++) {
+		desc = get_irq_desc(i);
+		spin_lock_irqsave(&desc->lock, flags);
+
+		if (desc->action && desc->action->handler) {
+			seq_printf(m, "%5d  ", i);
+			seq_printf(m, "0x%05lx  ", virq_to_hw(i));
+
+			if (desc->chip && desc->chip->typename)
+				p = desc->chip->typename;
+			else
+				p = none;
+			seq_printf(m, "%-15s  ", p);
+
+			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);
+		}
+
+		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))
+		return -ENOMEM;
+
+	return 0;
+}
+__initcall(irq_debugfs_init);
+#endif /* CONFIG_VIRQ_DEBUG */
+
 #endif /* CONFIG_PPC_MERGE */
 
 #ifdef CONFIG_PPC64
-- 
1.5.1.3.g7a33b

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

* Re: [PATCH 1/5] Add an optional device_node pointer to the irq_host
  2007-08-28  8:47 [PATCH 1/5] Add an optional device_node pointer to the irq_host Michael Ellerman
                   ` (3 preceding siblings ...)
  2007-08-28  8:47 ` [PATCH 5/5] Export virq mapping via debugfs Michael Ellerman
@ 2007-08-28  8:50 ` Michael Ellerman
  4 siblings, 0 replies; 7+ messages in thread
From: Michael Ellerman @ 2007-08-28  8:50 UTC (permalink / raw)
  To: linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 759 bytes --]

On Tue, 2007-08-28 at 18:47 +1000, Michael Ellerman wrote:
> The majority of irq_host implementations (3 out of 4) are associated
> with a device_node, and need to stash it somewhere. Rather than having
> it somewhere different for each host, add an optional device_node pointer
> to the irq_host structure.
> 
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>

This series is basically unchanged since I last sent it, but applies
cleanly now onto the powerpc-for-2.6.24 branch.

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

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

end of thread, other threads:[~2007-08-28  8:50 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-28  8:47 [PATCH 1/5] Add an optional device_node pointer to the irq_host Michael Ellerman
2007-08-28  8:47 ` [PATCH 3/5] Provide a default irq_host match, which matches on an exact of_node Michael Ellerman
2007-08-28  8:47 ` [PATCH 2/5] Invert null match behaviour for irq_hosts Michael Ellerman
2007-08-28  8:47 ` [PATCH 4/5] Initialise hwirq for legacy irqs Michael Ellerman
2007-08-28  8:47 ` [PATCH 5/5] Export virq mapping via debugfs Michael Ellerman
2007-08-28  8:50 ` [PATCH 1/5] Add an optional device_node pointer to the irq_host Michael Ellerman
  -- strict thread matches above, loose matches on Subject: below --
2007-07-25 12:24 Michael Ellerman

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