aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);