aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2012-02-14 16:06:54 -0500
committerGrant Likely <grant.likely@secretlab.ca>2012-02-16 08:11:22 -0500
commita8db8cf0d894df5f1dcfd4bce9894e0dbcc01c96 (patch)
treef9f2c53c57eeb04e5df60671951bcf4f2ca4966e
parent68700650e71b6bb6636673f4f9c8ec807353d8d6 (diff)
irq_domain: Replace irq_alloc_host() with revmap-specific initializers
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> Tested-by: Olof Johansson <olof@lixom.net>
-rw-r--r--arch/powerpc/platforms/512x/mpc5121_ads_cpld.c3
-rw-r--r--arch/powerpc/platforms/52xx/media5200.c7
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_gpt.c6
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pic.c4
-rw-r--r--arch/powerpc/platforms/82xx/pq2ads-pci-pic.c6
-rw-r--r--arch/powerpc/platforms/85xx/socrates_fpga_pic.c5
-rw-r--r--arch/powerpc/platforms/86xx/gef_pic.c5
-rw-r--r--arch/powerpc/platforms/cell/axon_msi.c5
-rw-r--r--arch/powerpc/platforms/cell/beat_interrupt.c4
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c4
-rw-r--r--arch/powerpc/platforms/cell/spider-pic.c6
-rw-r--r--arch/powerpc/platforms/embedded6xx/flipper-pic.c6
-rw-r--r--arch/powerpc/platforms/embedded6xx/hlwd-pic.c5
-rw-r--r--arch/powerpc/platforms/iseries/irq.c3
-rw-r--r--arch/powerpc/platforms/powermac/pic.c5
-rw-r--r--arch/powerpc/platforms/powermac/smp.c3
-rw-r--r--arch/powerpc/platforms/ps3/interrupt.c3
-rw-r--r--arch/powerpc/platforms/wsp/opb_pic.c7
-rw-r--r--arch/powerpc/sysdev/cpm1.c3
-rw-r--r--arch/powerpc/sysdev/cpm2_pic.c3
-rw-r--r--arch/powerpc/sysdev/ehv_pic.c6
-rw-r--r--arch/powerpc/sysdev/fsl_msi.c6
-rw-r--r--arch/powerpc/sysdev/i8259.c3
-rw-r--r--arch/powerpc/sysdev/ipic.c7
-rw-r--r--arch/powerpc/sysdev/mpc8xx_pic.c3
-rw-r--r--arch/powerpc/sysdev/mpic.c7
-rw-r--r--arch/powerpc/sysdev/mv64x60_pic.c5
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe_ic.c5
-rw-r--r--arch/powerpc/sysdev/tsi108_pci.c3
-rw-r--r--arch/powerpc/sysdev/uic.c6
-rw-r--r--arch/powerpc/sysdev/xics/xics-common.c3
-rw-r--r--arch/powerpc/sysdev/xilinx_intc.c5
-rw-r--r--drivers/gpio/gpio-mpc8xxx.c7
-rw-r--r--include/linux/irqdomain.h24
-rw-r--r--kernel/irq/irqdomain.c200
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 fefa7977fa9f..291d61c94718 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)
190 190
191 cpld_pic_node = of_node_get(np); 191 cpld_pic_node = of_node_get(np);
192 192
193 cpld_pic_host = 193 cpld_pic_host = irq_domain_add_linear(np, 16, &cpld_pic_host_ops, NULL);
194 irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, 16, &cpld_pic_host_ops, 16);
195 if (!cpld_pic_host) { 194 if (!cpld_pic_host) {
196 printk(KERN_ERR "CPLD PIC: failed to allocate irq host!\n"); 195 printk(KERN_ERR "CPLD PIC: failed to allocate irq host!\n");
197 goto end; 196 goto end;
diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c
index a746415c4242..5db5cfb6a4ff 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)
173 173
174 spin_lock_init(&media5200_irq.lock); 174 spin_lock_init(&media5200_irq.lock);
175 175
176 media5200_irq.irqhost = irq_alloc_host(fpga_np, IRQ_DOMAIN_MAP_LINEAR, 176 media5200_irq.irqhost = irq_domain_add_linear(fpga_np,
177 MEDIA5200_NUM_IRQS, 177 MEDIA5200_NUM_IRQS, &media5200_irq_ops, &media5200_irq);
178 &media5200_irq_ops, -1);
179 if (!media5200_irq.irqhost) 178 if (!media5200_irq.irqhost)
180 goto out; 179 goto out;
181 pr_debug("%s: allocated irqhost\n", __func__); 180 pr_debug("%s: allocated irqhost\n", __func__);
182 181
183 media5200_irq.irqhost->host_data = &media5200_irq;
184
185 irq_set_handler_data(cascade_virq, &media5200_irq); 182 irq_set_handler_data(cascade_virq, &media5200_irq);
186 irq_set_chained_handler(cascade_virq, media5200_irq_cascade); 183 irq_set_chained_handler(cascade_virq, media5200_irq_cascade);
187 184
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index e90af8fd8413..b53275d12727 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)
252 if (!cascade_virq) 252 if (!cascade_virq)
253 return; 253 return;
254 254
255 gpt->irqhost = irq_alloc_host(node, IRQ_DOMAIN_MAP_LINEAR, 1, 255 gpt->irqhost = irq_domain_add_linear(node, 1, &mpc52xx_gpt_irq_ops, gpt);
256 &mpc52xx_gpt_irq_ops, -1);
257 if (!gpt->irqhost) { 256 if (!gpt->irqhost) {
258 dev_err(gpt->dev, "irq_alloc_host() failed\n"); 257 dev_err(gpt->dev, "irq_domain_add_linear() failed\n");
259 return; 258 return;
260 } 259 }
261 260
262 gpt->irqhost->host_data = gpt;
263 irq_set_handler_data(cascade_virq, gpt); 261 irq_set_handler_data(cascade_virq, gpt);
264 irq_set_chained_handler(cascade_virq, mpc52xx_gpt_irq_cascade); 262 irq_set_chained_handler(cascade_virq, mpc52xx_gpt_irq_cascade);
265 263
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 8c997f1a9122..41fa67126c44 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)
444 * As last step, add an irq host to translate the real 444 * As last step, add an irq host to translate the real
445 * hw irq information provided by the ofw to linux virq 445 * hw irq information provided by the ofw to linux virq
446 */ 446 */
447 mpc52xx_irqhost = irq_alloc_host(picnode, IRQ_DOMAIN_MAP_LINEAR, 447 mpc52xx_irqhost = irq_domain_add_linear(picnode,
448 MPC52xx_IRQ_HIGHTESTHWIRQ, 448 MPC52xx_IRQ_HIGHTESTHWIRQ,
449 &mpc52xx_irqhost_ops, -1); 449 &mpc52xx_irqhost_ops, NULL);
450 450
451 if (!mpc52xx_irqhost) 451 if (!mpc52xx_irqhost)
452 panic(__FILE__ ": Cannot allocate the IRQ host\n"); 452 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 bdba174e7b3a..4ef9d6918e23 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)
156 out_be32(&priv->regs->mask, ~0); 156 out_be32(&priv->regs->mask, ~0);
157 mb(); 157 mb();
158 158
159 host = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, NUM_IRQS, 159 host = irq_domain_add_linear(np, NUM_IRQS, &pci_pic_host_ops, priv);
160 &pci_pic_host_ops, NUM_IRQS);
161 if (!host) { 160 if (!host) {
162 ret = -ENOMEM; 161 ret = -ENOMEM;
163 goto out_unmap_regs; 162 goto out_unmap_regs;
164 } 163 }
165 164
166 host->host_data = priv;
167
168 priv->host = host; 165 priv->host = host;
169 host->host_data = priv;
170 irq_set_handler_data(irq, priv); 166 irq_set_handler_data(irq, priv);
171 irq_set_chained_handler(irq, pq2ads_pci_irq_demux); 167 irq_set_chained_handler(irq, pq2ads_pci_irq_demux);
172 168
diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
index e3ef7c9ed7b1..1092c121adf3 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)
280 int i; 280 int i;
281 281
282 /* Setup an irq_domain structure */ 282 /* Setup an irq_domain structure */
283 socrates_fpga_pic_irq_host = irq_alloc_host(pic, IRQ_DOMAIN_MAP_LINEAR, 283 socrates_fpga_pic_irq_host = irq_domain_add_linear(pic,
284 SOCRATES_FPGA_NUM_IRQS, &socrates_fpga_pic_host_ops, 284 SOCRATES_FPGA_NUM_IRQS, &socrates_fpga_pic_host_ops, NULL);
285 SOCRATES_FPGA_NUM_IRQS);
286 if (socrates_fpga_pic_irq_host == NULL) { 285 if (socrates_fpga_pic_irq_host == NULL) {
287 pr_err("FPGA PIC: Unable to allocate host\n"); 286 pr_err("FPGA PIC: Unable to allocate host\n");
288 return; 287 return;
diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c
index 0cf8af230bcf..126a94b530e4 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)
212 } 212 }
213 213
214 /* Setup an irq_domain structure */ 214 /* Setup an irq_domain structure */
215 gef_pic_irq_host = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, 215 gef_pic_irq_host = irq_domain_add_linear(np, GEF_PIC_NUM_IRQS,
216 GEF_PIC_NUM_IRQS, 216 &gef_pic_host_ops, NULL);
217 &gef_pic_host_ops, NO_IRQ);
218 if (gef_pic_irq_host == NULL) 217 if (gef_pic_irq_host == NULL)
219 return; 218 return;
220 219
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 1bfd18a48a7f..cf9fd3c8a9b9 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)
392 } 392 }
393 memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES); 393 memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES);
394 394
395 msic->irq_domain = irq_alloc_host(dn, IRQ_DOMAIN_MAP_NOMAP, 395 msic->irq_domain = irq_domain_add_nomap(dn, &msic_host_ops, msic);
396 NR_IRQS, &msic_host_ops, 0);
397 if (!msic->irq_domain) { 396 if (!msic->irq_domain) {
398 printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n", 397 printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n",
399 dn->full_name); 398 dn->full_name);
400 goto out_free_fifo; 399 goto out_free_fifo;
401 } 400 }
402 401
403 msic->irq_domain->host_data = msic;
404
405 irq_set_handler_data(virq, msic); 402 irq_set_handler_data(virq, msic);
406 irq_set_chained_handler(virq, axon_msi_cascade); 403 irq_set_chained_handler(virq, axon_msi_cascade);
407 pr_devel("axon_msi: irq 0x%x setup for axon_msi\n", virq); 404 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 21b64cfef5e5..bbdf57440cd5 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)
239 ppc_md.get_irq = beatic_get_irq; 239 ppc_md.get_irq = beatic_get_irq;
240 240
241 /* Allocate an irq host */ 241 /* Allocate an irq host */
242 beatic_host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_NOMAP, 0, 242 beatic_host = irq_domain_add_nomap(NULL, &beatic_pic_host_ops, NULL);
243 &beatic_pic_host_ops,
244 0);
245 BUG_ON(beatic_host == NULL); 243 BUG_ON(beatic_host == NULL);
246 irq_set_default_host(beatic_host); 244 irq_set_default_host(beatic_host);
247} 245}
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 6888475e7c62..c844797a6898 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)
378void __init iic_init_IRQ(void) 378void __init iic_init_IRQ(void)
379{ 379{
380 /* Setup an irq host data structure */ 380 /* Setup an irq host data structure */
381 iic_host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_LINEAR, IIC_SOURCE_COUNT, 381 iic_host = irq_domain_add_linear(NULL, IIC_SOURCE_COUNT, &iic_host_ops,
382 &iic_host_ops, IIC_IRQ_INVALID); 382 NULL);
383 BUG_ON(iic_host == NULL); 383 BUG_ON(iic_host == NULL);
384 irq_set_default_host(iic_host); 384 irq_set_default_host(iic_host);
385 385
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 1f935a772ef8..6521d202284a 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,
299 panic("spider_pic: can't map registers !"); 299 panic("spider_pic: can't map registers !");
300 300
301 /* Allocate a host */ 301 /* Allocate a host */
302 pic->host = irq_alloc_host(of_node, IRQ_DOMAIN_MAP_LINEAR, 302 pic->host = irq_domain_add_linear(of_node, SPIDER_SRC_COUNT,
303 SPIDER_SRC_COUNT, &spider_host_ops, 303 &spider_host_ops, pic);
304 SPIDER_IRQ_INVALID);
305 if (pic->host == NULL) 304 if (pic->host == NULL)
306 panic("spider_pic: can't allocate irq host !"); 305 panic("spider_pic: can't allocate irq host !");
307 pic->host->host_data = pic;
308 306
309 /* Go through all sources and disable them */ 307 /* Go through all sources and disable them */
310 for (i = 0; i < SPIDER_SRC_COUNT; i++) { 308 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 f862361730fb..434597166ca4 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)
159 159
160 __flipper_quiesce(io_base); 160 __flipper_quiesce(io_base);
161 161
162 irq_domain = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, FLIPPER_NR_IRQS, 162 irq_domain = irq_domain_add_linear(np, FLIPPER_NR_IRQS,
163 &flipper_irq_domain_ops, -1); 163 &flipper_irq_domain_ops, io_base);
164 if (!irq_domain) { 164 if (!irq_domain) {
165 pr_err("failed to allocate irq_domain\n"); 165 pr_err("failed to allocate irq_domain\n");
166 return NULL; 166 return NULL;
167 } 167 }
168 168
169 irq_domain->host_data = io_base;
170
171out: 169out:
172 return irq_domain; 170 return irq_domain;
173} 171}
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
index 2d4a5d48fbbd..499d410b95fa 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)
177 177
178 __hlwd_quiesce(io_base); 178 __hlwd_quiesce(io_base);
179 179
180 irq_domain = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, HLWD_NR_IRQS, 180 irq_domain = irq_domain_add_linear(np, HLWD_NR_IRQS,
181 &hlwd_irq_domain_ops, -1); 181 &hlwd_irq_domain_ops, io_base);
182 if (!irq_domain) { 182 if (!irq_domain) {
183 pr_err("failed to allocate irq_domain\n"); 183 pr_err("failed to allocate irq_domain\n");
184 return NULL; 184 return NULL;
185 } 185 }
186 irq_domain->host_data = io_base;
187 186
188 return irq_domain; 187 return irq_domain;
189} 188}
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index b07d4f2e0155..5538b593079d 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)
380 /* Create irq host. No need for a revmap since HV will give us 380 /* Create irq host. No need for a revmap since HV will give us
381 * back our virtual irq number 381 * back our virtual irq number
382 */ 382 */
383 host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_NOMAP, 0, 383 host = irq_domain_add_nomap(NULL, &iseries_irq_domain_ops, NULL);
384 &iseries_irq_domain_ops, 0);
385 BUG_ON(host == NULL); 384 BUG_ON(host == NULL);
386 irq_set_default_host(host); 385 irq_set_default_host(host);
387 386
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index cff326ab8ef2..646fdf3b9c0c 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)
352 /* 352 /*
353 * Allocate an irq host 353 * Allocate an irq host
354 */ 354 */
355 pmac_pic_host = irq_alloc_host(master, IRQ_DOMAIN_MAP_LINEAR, max_irqs, 355 pmac_pic_host = irq_domain_add_linear(master, max_irqs,
356 &pmac_pic_host_ops, 356 &pmac_pic_host_ops, NULL);
357 max_irqs);
358 BUG_ON(pmac_pic_host == NULL); 357 BUG_ON(pmac_pic_host == NULL);
359 irq_set_default_host(pmac_pic_host); 358 irq_set_default_host(pmac_pic_host);
360 359
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 6b1ef2d4dea0..09afd704f07a 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)
192{ 192{
193 int rc = -ENOMEM; 193 int rc = -ENOMEM;
194 194
195 psurge_host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_NOMAP, 0, 195 psurge_host = irq_domain_add_nomap(NULL, &psurge_host_ops, NULL);
196 &psurge_host_ops, 0);
197 196
198 if (psurge_host) 197 if (psurge_host)
199 psurge_secondary_virq = irq_create_direct_mapping(psurge_host); 198 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 c5980e422dc6..c05808f21015 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)
753 unsigned cpu; 753 unsigned cpu;
754 struct irq_domain *host; 754 struct irq_domain *host;
755 755
756 host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_NOMAP, 0, &ps3_host_ops, 756 host = irq_domain_add_nomap(NULL, &ps3_host_ops, NULL);
757 PS3_INVALID_OUTLET);
758 irq_set_default_host(host); 757 irq_set_default_host(host);
759 irq_set_virq_count(PS3_PLUG_MAX + 1); 758 irq_set_virq_count(PS3_PLUG_MAX + 1);
760 759
diff --git a/arch/powerpc/platforms/wsp/opb_pic.c b/arch/powerpc/platforms/wsp/opb_pic.c
index 76b33bc36116..4837515c2826 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)
263 goto free_opb; 263 goto free_opb;
264 } 264 }
265 265
266 /* Allocate an irq host so that Linux knows that despite only 266 /* Allocate an irq domain so that Linux knows that despite only
267 * having one interrupt to issue, we're the controller for multiple 267 * having one interrupt to issue, we're the controller for multiple
268 * hardware IRQs, so later we can lookup their virtual IRQs. */ 268 * hardware IRQs, so later we can lookup their virtual IRQs. */
269 269
270 opb->host = irq_alloc_host(dn, IRQ_DOMAIN_MAP_LINEAR, 270 opb->host = irq_domain_add_linear(dn, OPB_NR_IRQS, &opb_host_ops, opb);
271 OPB_NR_IRQS, &opb_host_ops, -1);
272
273 if (!opb->host) { 271 if (!opb->host) {
274 printk(KERN_ERR "opb: Failed to allocate IRQ host!\n"); 272 printk(KERN_ERR "opb: Failed to allocate IRQ host!\n");
275 goto free_regs; 273 goto free_regs;
@@ -277,7 +275,6 @@ struct opb_pic *opb_pic_init_one(struct device_node *dn)
277 275
278 opb->index = opb_index++; 276 opb->index = opb_index++;
279 spin_lock_init(&opb->lock); 277 spin_lock_init(&opb->lock);
280 opb->host->host_data = opb;
281 278
282 /* Disable all interrupts by default */ 279 /* Disable all interrupts by default */
283 opb_out(opb, OPB_MLSASIER, 0); 280 opb_out(opb, OPB_MLSASIER, 0);
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
index 0877a757c209..53f39dbbfb97 100644
--- a/arch/powerpc/sysdev/cpm1.c
+++ b/arch/powerpc/sysdev/cpm1.c
@@ -164,8 +164,7 @@ unsigned int cpm_pic_init(void)
164 164
165 out_be32(&cpic_reg->cpic_cimr, 0); 165 out_be32(&cpic_reg->cpic_cimr, 0);
166 166
167 cpm_pic_host = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, 167 cpm_pic_host = irq_domain_add_linear(np, 64, &cpm_pic_host_ops, NULL);
168 64, &cpm_pic_host_ops, 64);
169 if (cpm_pic_host == NULL) { 168 if (cpm_pic_host == NULL) {
170 printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n"); 169 printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
171 sirq = NO_IRQ; 170 sirq = NO_IRQ;
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
index b149baae5d33..b3643322c528 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)
275 out_be32(&cpm2_intctl->ic_scprrl, 0x05309770); 275 out_be32(&cpm2_intctl->ic_scprrl, 0x05309770);
276 276
277 /* create a legacy host */ 277 /* create a legacy host */
278 cpm2_pic_host = irq_alloc_host(node, IRQ_DOMAIN_MAP_LINEAR, 278 cpm2_pic_host = irq_domain_add_linear(node, 64, &cpm2_pic_host_ops, NULL);
279 64, &cpm2_pic_host_ops, 64);
280 if (cpm2_pic_host == NULL) { 279 if (cpm2_pic_host == NULL) {
281 printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n"); 280 printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
282 return; 281 return;
diff --git a/arch/powerpc/sysdev/ehv_pic.c b/arch/powerpc/sysdev/ehv_pic.c
index 48d3ba1220d3..adea322ea18f 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)
275 return; 275 return;
276 } 276 }
277 277
278 ehv_pic->irqhost = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, 278 ehv_pic->irqhost = irq_domain_add_linear(np, NR_EHV_PIC_INTS,
279 NR_EHV_PIC_INTS, &ehv_pic_host_ops, 0); 279 &ehv_pic_host_ops, ehv_pic);
280
281 if (!ehv_pic->irqhost) { 280 if (!ehv_pic->irqhost) {
282 of_node_put(np); 281 of_node_put(np);
283 kfree(ehv_pic); 282 kfree(ehv_pic);
@@ -293,7 +292,6 @@ void __init ehv_pic_init(void)
293 of_node_put(np2); 292 of_node_put(np2);
294 } 293 }
295 294
296 ehv_pic->irqhost->host_data = ehv_pic;
297 ehv_pic->hc_irq = ehv_pic_irq_chip; 295 ehv_pic->hc_irq = ehv_pic_irq_chip;
298 ehv_pic->hc_irq.irq_set_affinity = ehv_pic_set_affinity; 296 ehv_pic->hc_irq.irq_set_affinity = ehv_pic_set_affinity;
299 ehv_pic->coreint_flag = coreint_flag; 297 ehv_pic->coreint_flag = coreint_flag;
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 3f9a301c4550..f4fd95bc1278 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)
387 } 387 }
388 platform_set_drvdata(dev, msi); 388 platform_set_drvdata(dev, msi);
389 389
390 msi->irqhost = irq_alloc_host(dev->dev.of_node, IRQ_DOMAIN_MAP_LINEAR, 390 msi->irqhost = irq_domain_add_linear(dev->dev.of_node,
391 NR_MSI_IRQS, &fsl_msi_host_ops, 0); 391 NR_MSI_IRQS, &fsl_msi_host_ops, msi);
392 392
393 if (msi->irqhost == NULL) { 393 if (msi->irqhost == NULL) {
394 dev_err(&dev->dev, "No memory for MSI irqhost\n"); 394 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)
420 420
421 msi->feature = features->fsl_pic_ip; 421 msi->feature = features->fsl_pic_ip;
422 422
423 msi->irqhost->host_data = msi;
424
425 /* 423 /*
426 * Remember the phandle, so that we can match with any PCI nodes 424 * Remember the phandle, so that we can match with any PCI nodes
427 * that have an "fsl,msi" property. 425 * that have an "fsl,msi" property.
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index 7e67890b8fc2..573a73bd954a 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)
263 raw_spin_unlock_irqrestore(&i8259_lock, flags); 263 raw_spin_unlock_irqrestore(&i8259_lock, flags);
264 264
265 /* create a legacy host */ 265 /* create a legacy host */
266 i8259_host = irq_alloc_host(node, IRQ_DOMAIN_MAP_LEGACY, 266 i8259_host = irq_domain_add_legacy(node, &i8259_host_ops, NULL);
267 0, &i8259_host_ops, 0);
268 if (i8259_host == NULL) { 267 if (i8259_host == NULL) {
269 printk(KERN_ERR "i8259: failed to allocate irq host !\n"); 268 printk(KERN_ERR "i8259: failed to allocate irq host !\n");
270 return; 269 return;
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 9abed3760545..0eaaa01c11b3 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)
728 if (ipic == NULL) 728 if (ipic == NULL)
729 return NULL; 729 return NULL;
730 730
731 ipic->irqhost = irq_alloc_host(node, IRQ_DOMAIN_MAP_LINEAR, 731 ipic->irqhost = irq_domain_add_linear(node, NR_IPIC_INTS,
732 NR_IPIC_INTS, 732 &ipic_host_ops, ipic);
733 &ipic_host_ops, 0);
734 if (ipic->irqhost == NULL) { 733 if (ipic->irqhost == NULL) {
735 kfree(ipic); 734 kfree(ipic);
736 return NULL; 735 return NULL;
@@ -738,8 +737,6 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
738 737
739 ipic->regs = ioremap(res.start, resource_size(&res)); 738 ipic->regs = ioremap(res.start, resource_size(&res));
740 739
741 ipic->irqhost->host_data = ipic;
742
743 /* init hw */ 740 /* init hw */
744 ipic_write(ipic->regs, IPIC_SICNR, 0x0); 741 ipic_write(ipic->regs, IPIC_SICNR, 0x0);
745 742
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c
index 978dfc4c3120..d5f5416be310 100644
--- a/arch/powerpc/sysdev/mpc8xx_pic.c
+++ b/arch/powerpc/sysdev/mpc8xx_pic.c
@@ -171,8 +171,7 @@ int mpc8xx_pic_init(void)
171 goto out; 171 goto out;
172 } 172 }
173 173
174 mpc8xx_pic_host = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, 174 mpc8xx_pic_host = irq_domain_add_linear(np, 64, &mpc8xx_pic_host_ops, NULL);
175 64, &mpc8xx_pic_host_ops, 64);
176 if (mpc8xx_pic_host == NULL) { 175 if (mpc8xx_pic_host == NULL) {
177 printk(KERN_ERR "MPC8xx PIC: failed to allocate irq host!\n"); 176 printk(KERN_ERR "MPC8xx PIC: failed to allocate irq host!\n");
178 ret = -ENOMEM; 177 ret = -ENOMEM;
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index c844d343bf32..c83a512fa175 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,
1345 mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1); 1345 mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
1346 mpic->isu_mask = (1 << mpic->isu_shift) - 1; 1346 mpic->isu_mask = (1 << mpic->isu_shift) - 1;
1347 1347
1348 mpic->irqhost = irq_alloc_host(mpic->node, IRQ_DOMAIN_MAP_LINEAR, 1348 mpic->irqhost = irq_domain_add_linear(mpic->node,
1349 isu_size ? isu_size : mpic->num_sources, 1349 isu_size ? isu_size : mpic->num_sources,
1350 &mpic_host_ops, 1350 &mpic_host_ops, mpic);
1351 flags & MPIC_LARGE_VECTORS ? 2048 : 256);
1352 1351
1353 /* 1352 /*
1354 * FIXME: The code leaks the MPIC object and mappings here; this 1353 * FIXME: The code leaks the MPIC object and mappings here; this
@@ -1357,8 +1356,6 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1357 if (mpic->irqhost == NULL) 1356 if (mpic->irqhost == NULL)
1358 return NULL; 1357 return NULL;
1359 1358
1360 mpic->irqhost->host_data = mpic;
1361
1362 /* Display version */ 1359 /* Display version */
1363 switch (greg_feature & MPIC_GREG_FEATURE_VERSION_MASK) { 1360 switch (greg_feature & MPIC_GREG_FEATURE_VERSION_MASK) {
1364 case 1: 1361 case 1:
diff --git a/arch/powerpc/sysdev/mv64x60_pic.c b/arch/powerpc/sysdev/mv64x60_pic.c
index 45124a1959d0..8848e99a83f2 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)
250 paddr = of_translate_address(np, reg); 250 paddr = of_translate_address(np, reg);
251 mv64x60_irq_reg_base = ioremap(paddr, reg[1]); 251 mv64x60_irq_reg_base = ioremap(paddr, reg[1]);
252 252
253 mv64x60_irq_host = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, 253 mv64x60_irq_host = irq_domain_add_linear(np, MV64x60_NUM_IRQS,
254 MV64x60_NUM_IRQS, 254 &mv64x60_host_ops, NULL);
255 &mv64x60_host_ops, MV64x60_NUM_IRQS);
256 255
257 spin_lock_irqsave(&mv64x60_lock, flags); 256 spin_lock_irqsave(&mv64x60_lock, flags);
258 out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK, 257 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 78e90192c343..e9b3d5cc65d3 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,
339 if (qe_ic == NULL) 339 if (qe_ic == NULL)
340 return; 340 return;
341 341
342 qe_ic->irqhost = irq_alloc_host(node, IRQ_DOMAIN_MAP_LINEAR, 342 qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS,
343 NR_QE_IC_INTS, &qe_ic_host_ops, 0); 343 &qe_ic_host_ops, qe_ic);
344 if (qe_ic->irqhost == NULL) { 344 if (qe_ic->irqhost == NULL) {
345 kfree(qe_ic); 345 kfree(qe_ic);
346 return; 346 return;
@@ -348,7 +348,6 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags,
348 348
349 qe_ic->regs = ioremap(res.start, resource_size(&res)); 349 qe_ic->regs = ioremap(res.start, resource_size(&res));
350 350
351 qe_ic->irqhost->host_data = qe_ic;
352 qe_ic->hc_irq = qe_ic_irq_chip; 351 qe_ic->hc_irq = qe_ic_irq_chip;
353 352
354 qe_ic->virq_high = irq_of_parse_and_map(node, 0); 353 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 f3757236e666..1be26f4b9c96 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)
419{ 419{
420 DBG("Tsi108_pci_int_init: initializing PCI interrupts\n"); 420 DBG("Tsi108_pci_int_init: initializing PCI interrupts\n");
421 421
422 pci_irq_host = irq_alloc_host(node, IRQ_DOMAIN_MAP_LEGACY, 422 pci_irq_host = irq_domain_add_legacy(node, &pci_irq_domain_ops, NULL);
423 0, &pci_irq_domain_ops, 0);
424 if (pci_irq_host == NULL) { 423 if (pci_irq_host == NULL) {
425 printk(KERN_ERR "pci_irq_host: failed to allocate irq domain!\n"); 424 printk(KERN_ERR "pci_irq_host: failed to allocate irq domain!\n");
426 return; 425 return;
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
index 7eea3a64bdf7..84e59c97391f 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)
270 } 270 }
271 uic->dcrbase = *dcrreg; 271 uic->dcrbase = *dcrreg;
272 272
273 uic->irqhost = irq_alloc_host(node, IRQ_DOMAIN_MAP_LINEAR, 273 uic->irqhost = irq_domain_add_linear(node, NR_UIC_INTS, &uic_host_ops,
274 NR_UIC_INTS, &uic_host_ops, -1); 274 uic);
275 if (! uic->irqhost) 275 if (! uic->irqhost)
276 return NULL; /* FIXME: panic? */ 276 return NULL; /* FIXME: panic? */
277 277
278 uic->irqhost->host_data = uic;
279
280 /* Start with all interrupts disabled, level and non-critical */ 278 /* Start with all interrupts disabled, level and non-critical */
281 mtdcr(uic->dcrbase + UIC_ER, 0); 279 mtdcr(uic->dcrbase + UIC_ER, 0);
282 mtdcr(uic->dcrbase + UIC_CR, 0); 280 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 fb2e303d25fb..ea5e204e3450 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 = {
374 374
375static void __init xics_init_host(void) 375static void __init xics_init_host(void)
376{ 376{
377 xics_host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_TREE, 0, &xics_host_ops, 377 xics_host = irq_domain_add_tree(NULL, &xics_host_ops, NULL);
378 XICS_IRQ_SPURIOUS);
379 BUG_ON(xics_host == NULL); 378 BUG_ON(xics_host == NULL);
380 irq_set_default_host(xics_host); 379 irq_set_default_host(xics_host);
381} 380}
diff --git a/arch/powerpc/sysdev/xilinx_intc.c b/arch/powerpc/sysdev/xilinx_intc.c
index 92e7d4db9fde..8d73c3c0bee6 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)
201 out_be32(regs + XINTC_MER, 0x3UL); /* Turn on the Master Enable. */ 201 out_be32(regs + XINTC_MER, 0x3UL); /* Turn on the Master Enable. */
202 202
203 /* Allocate and initialize an irq_domain structure. */ 203 /* Allocate and initialize an irq_domain structure. */
204 irq = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, XILINX_INTC_MAXIRQS, 204 irq = irq_domain_add_linear(np, XILINX_INTC_MAXIRQS, &xilinx_intc_ops,
205 &xilinx_intc_ops, -1); 205 regs);
206 if (!irq) 206 if (!irq)
207 panic(__FILE__ ": Cannot allocate IRQ host\n"); 207 panic(__FILE__ ": Cannot allocate IRQ host\n");
208 irq->host_data = regs;
209 208
210 return irq; 209 return irq;
211} 210}
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
index 9efd59732eeb..149d9876fca8 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)
364 if (hwirq == NO_IRQ) 364 if (hwirq == NO_IRQ)
365 goto skip_irq; 365 goto skip_irq;
366 366
367 mpc8xxx_gc->irq = 367 mpc8xxx_gc->irq = irq_domain_add_linear(np, MPC8XXX_GPIO_PINS,
368 irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, MPC8XXX_GPIO_PINS, 368 &mpc8xxx_gpio_irq_ops, mpc8xxx_gc);
369 &mpc8xxx_gpio_irq_ops, MPC8XXX_GPIO_PINS);
370 if (!mpc8xxx_gc->irq) 369 if (!mpc8xxx_gc->irq)
371 goto skip_irq; 370 goto skip_irq;
372 371
@@ -374,8 +373,6 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
374 if (id) 373 if (id)
375 mpc8xxx_gc->of_dev_id_data = id->data; 374 mpc8xxx_gc->of_dev_id_data = id->data;
376 375
377 mpc8xxx_gc->irq->host_data = mpc8xxx_gc;
378
379 /* ack and mask all irqs */ 376 /* ack and mask all irqs */
380 out_be32(mm_gc->regs + GPIO_IER, 0xffffffff); 377 out_be32(mm_gc->regs + GPIO_IER, 0xffffffff);
381 out_be32(mm_gc->regs + GPIO_IMR, 0); 378 out_be32(mm_gc->regs + GPIO_IMR, 0);
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 18f4ab002d2e..f95553fa6872 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -95,10 +95,6 @@ struct irq_domain {
95 95
96 /* type of reverse mapping_technique */ 96 /* type of reverse mapping_technique */
97 unsigned int revmap_type; 97 unsigned int revmap_type;
98#define IRQ_DOMAIN_MAP_LEGACY 0 /* legacy 8259, gets irqs 1..15 */
99#define IRQ_DOMAIN_MAP_NOMAP 1 /* no fast reverse mapping */
100#define IRQ_DOMAIN_MAP_LINEAR 2 /* linear map of interrupts */
101#define IRQ_DOMAIN_MAP_TREE 3 /* radix tree */
102 union { 98 union {
103 struct { 99 struct {
104 unsigned int size; 100 unsigned int size;
@@ -120,11 +116,21 @@ struct irq_domain {
120 116
121#ifdef CONFIG_IRQ_DOMAIN 117#ifdef CONFIG_IRQ_DOMAIN
122#ifdef CONFIG_PPC 118#ifdef CONFIG_PPC
123extern struct irq_domain *irq_alloc_host(struct device_node *of_node, 119struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
124 unsigned int revmap_type, 120 struct irq_domain_ops *ops,
125 unsigned int revmap_arg, 121 void *host_data);
126 struct irq_domain_ops *ops, 122struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
127 irq_hw_number_t inval_irq); 123 unsigned int size,
124 struct irq_domain_ops *ops,
125 void *host_data);
126struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
127 struct irq_domain_ops *ops,
128 void *host_data);
129struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
130 struct irq_domain_ops *ops,
131 void *host_data);
132
133
128extern struct irq_domain *irq_find_host(struct device_node *node); 134extern struct irq_domain *irq_find_host(struct device_node *node);
129extern void irq_set_default_host(struct irq_domain *host); 135extern void irq_set_default_host(struct irq_domain *host);
130extern void irq_set_virq_count(unsigned int count); 136extern void irq_set_virq_count(unsigned int count);
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 432d292b33f8..acedba1a2651 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -13,6 +13,11 @@
13#include <linux/smp.h> 13#include <linux/smp.h>
14#include <linux/fs.h> 14#include <linux/fs.h>
15 15
16#define IRQ_DOMAIN_MAP_LEGACY 0 /* legacy 8259, gets irqs 1..15 */
17#define IRQ_DOMAIN_MAP_NOMAP 1 /* no fast reverse mapping */
18#define IRQ_DOMAIN_MAP_LINEAR 2 /* linear map of interrupts */
19#define IRQ_DOMAIN_MAP_TREE 3 /* radix tree */
20
16static LIST_HEAD(irq_domain_list); 21static LIST_HEAD(irq_domain_list);
17static DEFINE_MUTEX(irq_domain_mutex); 22static DEFINE_MUTEX(irq_domain_mutex);
18 23
@@ -27,100 +32,158 @@ static int default_irq_domain_match(struct irq_domain *d, struct device_node *np
27} 32}
28 33
29/** 34/**
30 * irq_alloc_host() - Allocate a new irq_domain data structure 35 * irq_domain_alloc() - Allocate a new irq_domain data structure
31 * @of_node: optional device-tree node of the interrupt controller 36 * @of_node: optional device-tree node of the interrupt controller
32 * @revmap_type: type of reverse mapping to use 37 * @revmap_type: type of reverse mapping to use
33 * @revmap_arg: for IRQ_DOMAIN_MAP_LINEAR linear only: size of the map
34 * @ops: map/unmap domain callbacks 38 * @ops: map/unmap domain callbacks
35 * @inval_irq: provide a hw number in that domain space that is always invalid 39 * @host_data: Controller private data pointer
36 * 40 *
37 * Allocates and initialize and irq_domain structure. Note that in the case of 41 * Allocates and initialize and irq_domain structure. Caller is expected to
38 * IRQ_DOMAIN_MAP_LEGACY, the map() callback will be called before this returns 42 * register allocated irq_domain with irq_domain_register(). Returns pointer
39 * for all legacy interrupts except 0 (which is always the invalid irq for 43 * to IRQ domain, or NULL on failure.
40 * a legacy controller). For a IRQ_DOMAIN_MAP_LINEAR, the map is allocated by
41 * this call as well. For a IRQ_DOMAIN_MAP_TREE, the radix tree will be
42 * allocated later during boot automatically (the reverse mapping will use the
43 * slow path until that happens).
44 */ 44 */
45struct irq_domain *irq_alloc_host(struct device_node *of_node, 45static struct irq_domain *irq_domain_alloc(struct device_node *of_node,
46 unsigned int revmap_type, 46 unsigned int revmap_type,
47 unsigned int revmap_arg, 47 struct irq_domain_ops *ops,
48 struct irq_domain_ops *ops, 48 void *host_data)
49 irq_hw_number_t inval_irq)
50{ 49{
51 struct irq_domain *domain, *h; 50 struct irq_domain *domain;
52 unsigned int size = sizeof(struct irq_domain);
53 unsigned int i;
54 unsigned int *rmap;
55 51
56 /* Allocate structure and revmap table if using linear mapping */ 52 domain = kzalloc(sizeof(*domain), GFP_KERNEL);
57 if (revmap_type == IRQ_DOMAIN_MAP_LINEAR) 53 if (WARN_ON(!domain))
58 size += revmap_arg * sizeof(unsigned int);
59 domain = kzalloc(size, GFP_KERNEL);
60 if (domain == NULL)
61 return NULL; 54 return NULL;
62 55
63 /* Fill structure */ 56 /* Fill structure */
64 domain->revmap_type = revmap_type; 57 domain->revmap_type = revmap_type;
65 domain->inval_irq = inval_irq;
66 domain->ops = ops; 58 domain->ops = ops;
59 domain->host_data = host_data;
67 domain->of_node = of_node_get(of_node); 60 domain->of_node = of_node_get(of_node);
68 61
69 if (domain->ops->match == NULL) 62 if (domain->ops->match == NULL)
70 domain->ops->match = default_irq_domain_match; 63 domain->ops->match = default_irq_domain_match;
71 64
65 return domain;
66}
67
68static void irq_domain_add(struct irq_domain *domain)
69{
70 mutex_lock(&irq_domain_mutex);
71 list_add(&domain->link, &irq_domain_list);
72 mutex_unlock(&irq_domain_mutex);
73 pr_debug("irq: Allocated domain of type %d @0x%p\n",
74 domain->revmap_type, domain);
75}
76
77/**
78 * irq_domain_add_legacy() - Allocate and register a legacy revmap irq_domain.
79 * @of_node: pointer to interrupt controller's device tree node.
80 * @ops: map/unmap domain callbacks
81 * @host_data: Controller private data pointer
82 *
83 * Note: the map() callback will be called before this function returns
84 * for all legacy interrupts except 0 (which is always the invalid irq for
85 * a legacy controller).
86 */
87struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
88 struct irq_domain_ops *ops,
89 void *host_data)
90{
91 struct irq_domain *domain, *h;
92 unsigned int i;
93
94 domain = irq_domain_alloc(of_node, IRQ_DOMAIN_MAP_LEGACY, ops, host_data);
95 if (!domain)
96 return NULL;
97
72 mutex_lock(&irq_domain_mutex); 98 mutex_lock(&irq_domain_mutex);
73 /* Make sure only one legacy controller can be created */ 99 /* Make sure only one legacy controller can be created */
74 if (revmap_type == IRQ_DOMAIN_MAP_LEGACY) { 100 list_for_each_entry(h, &irq_domain_list, link) {
75 list_for_each_entry(h, &irq_domain_list, link) { 101 if (WARN_ON(h->revmap_type == IRQ_DOMAIN_MAP_LEGACY)) {
76 if (WARN_ON(h->revmap_type == IRQ_DOMAIN_MAP_LEGACY)) { 102 mutex_unlock(&irq_domain_mutex);
77 mutex_unlock(&irq_domain_mutex); 103 of_node_put(domain->of_node);
78 of_node_put(domain->of_node); 104 kfree(domain);
79 kfree(domain); 105 return NULL;
80 return NULL;
81 }
82 } 106 }
83 } 107 }
84 list_add(&domain->link, &irq_domain_list); 108 list_add(&domain->link, &irq_domain_list);
85 mutex_unlock(&irq_domain_mutex); 109 mutex_unlock(&irq_domain_mutex);
86 110
87 /* Additional setups per revmap type */ 111 /* setup us as the domain for all legacy interrupts */
88 switch(revmap_type) { 112 for (i = 1; i < NUM_ISA_INTERRUPTS; i++) {
89 case IRQ_DOMAIN_MAP_LEGACY: 113 struct irq_data *irq_data = irq_get_irq_data(i);
90 /* 0 is always the invalid number for legacy */ 114 irq_data->hwirq = i;
91 domain->inval_irq = 0; 115 irq_data->domain = domain;
92 /* setup us as the domain for all legacy interrupts */ 116
93 for (i = 1; i < NUM_ISA_INTERRUPTS; i++) { 117 /* Legacy flags are left to default at this point,
94 struct irq_data *irq_data = irq_get_irq_data(i); 118 * one can then use irq_create_mapping() to
95 irq_data->hwirq = i; 119 * explicitly change them
96 irq_data->domain = domain; 120 */
97 121 ops->map(domain, i, i);
98 /* Legacy flags are left to default at this point, 122
99 * one can then use irq_create_mapping() to 123 /* Clear norequest flags */
100 * explicitly change them 124 irq_clear_status_flags(i, IRQ_NOREQUEST);
101 */
102 ops->map(domain, i, i);
103
104 /* Clear norequest flags */
105 irq_clear_status_flags(i, IRQ_NOREQUEST);
106 }
107 break;
108 case IRQ_DOMAIN_MAP_LINEAR:
109 rmap = (unsigned int *)(domain + 1);
110 for (i = 0; i < revmap_arg; i++)
111 rmap[i] = 0;
112 domain->revmap_data.linear.size = revmap_arg;
113 domain->revmap_data.linear.revmap = rmap;
114 break;
115 case IRQ_DOMAIN_MAP_TREE:
116 INIT_RADIX_TREE(&domain->revmap_data.tree, GFP_KERNEL);
117 break;
118 default:
119 break;
120 } 125 }
126 return domain;
127}
121 128
122 pr_debug("irq: Allocated domain of type %d @0x%p\n", revmap_type, domain); 129/**
130 * irq_domain_add_linear() - Allocate and register a legacy revmap irq_domain.
131 * @of_node: pointer to interrupt controller's device tree node.
132 * @ops: map/unmap domain callbacks
133 * @host_data: Controller private data pointer
134 */
135struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
136 unsigned int size,
137 struct irq_domain_ops *ops,
138 void *host_data)
139{
140 struct irq_domain *domain;
141 unsigned int *revmap;
142
143 revmap = kzalloc(sizeof(*revmap) * size, GFP_KERNEL);
144 if (WARN_ON(!revmap))
145 return NULL;
123 146
147 domain = irq_domain_alloc(of_node, IRQ_DOMAIN_MAP_LINEAR, ops, host_data);
148 if (!domain) {
149 kfree(revmap);
150 return NULL;
151 }
152 domain->revmap_data.linear.size = size;
153 domain->revmap_data.linear.revmap = revmap;
154 irq_domain_add(domain);
155 return domain;
156}
157
158struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
159 struct irq_domain_ops *ops,
160 void *host_data)
161{
162 struct irq_domain *domain = irq_domain_alloc(of_node,
163 IRQ_DOMAIN_MAP_NOMAP, ops, host_data);
164 if (domain)
165 irq_domain_add(domain);
166 return domain;
167}
168
169/**
170 * irq_domain_add_tree()
171 * @of_node: pointer to interrupt controller's device tree node.
172 * @ops: map/unmap domain callbacks
173 *
174 * Note: The radix tree will be allocated later during boot automatically
175 * (the reverse mapping will use the slow path until that happens).
176 */
177struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
178 struct irq_domain_ops *ops,
179 void *host_data)
180{
181 struct irq_domain *domain = irq_domain_alloc(of_node,
182 IRQ_DOMAIN_MAP_TREE, ops, host_data);
183 if (domain) {
184 INIT_RADIX_TREE(&domain->revmap_data.tree, GFP_KERNEL);
185 irq_domain_add(domain);
186 }
124 return domain; 187 return domain;
125} 188}
126 189
@@ -393,9 +456,6 @@ void irq_dispose_mapping(unsigned int virq)
393 break; 456 break;
394 } 457 }
395 458
396 /* Destroy map */
397 irq_data->hwirq = domain->inval_irq;
398
399 irq_free_desc(virq); 459 irq_free_desc(virq);
400} 460}
401EXPORT_SYMBOL_GPL(irq_dispose_mapping); 461EXPORT_SYMBOL_GPL(irq_dispose_mapping);