irq_domain: Replace irq_alloc_host() with revmap-specific initializers
authorGrant Likely <grant.likely@secretlab.ca>
Tue, 14 Feb 2012 21:06:54 +0000 (14:06 -0700)
committerGrant Likely <grant.likely@secretlab.ca>
Thu, 16 Feb 2012 13:11:22 +0000 (06:11 -0700)
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>
35 files changed:
arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
arch/powerpc/platforms/52xx/media5200.c
arch/powerpc/platforms/52xx/mpc52xx_gpt.c
arch/powerpc/platforms/52xx/mpc52xx_pic.c
arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
arch/powerpc/platforms/85xx/socrates_fpga_pic.c
arch/powerpc/platforms/86xx/gef_pic.c
arch/powerpc/platforms/cell/axon_msi.c
arch/powerpc/platforms/cell/beat_interrupt.c
arch/powerpc/platforms/cell/interrupt.c
arch/powerpc/platforms/cell/spider-pic.c
arch/powerpc/platforms/embedded6xx/flipper-pic.c
arch/powerpc/platforms/embedded6xx/hlwd-pic.c
arch/powerpc/platforms/iseries/irq.c
arch/powerpc/platforms/powermac/pic.c
arch/powerpc/platforms/powermac/smp.c
arch/powerpc/platforms/ps3/interrupt.c
arch/powerpc/platforms/wsp/opb_pic.c
arch/powerpc/sysdev/cpm1.c
arch/powerpc/sysdev/cpm2_pic.c
arch/powerpc/sysdev/ehv_pic.c
arch/powerpc/sysdev/fsl_msi.c
arch/powerpc/sysdev/i8259.c
arch/powerpc/sysdev/ipic.c
arch/powerpc/sysdev/mpc8xx_pic.c
arch/powerpc/sysdev/mpic.c
arch/powerpc/sysdev/mv64x60_pic.c
arch/powerpc/sysdev/qe_lib/qe_ic.c
arch/powerpc/sysdev/tsi108_pci.c
arch/powerpc/sysdev/uic.c
arch/powerpc/sysdev/xics/xics-common.c
arch/powerpc/sysdev/xilinx_intc.c
drivers/gpio/gpio-mpc8xxx.c
include/linux/irqdomain.h
kernel/irq/irqdomain.c

index fefa7977fa9f1f46c9a07b48e2c144e11a395f7e..291d61c9471825b5083729a0d75befc8bbf9773e 100644 (file)
@@ -190,8 +190,7 @@ mpc5121_ads_cpld_pic_init(void)
 
        cpld_pic_node = of_node_get(np);
 
-       cpld_pic_host =
-           irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, 16, &cpld_pic_host_ops, 16);
+       cpld_pic_host = irq_domain_add_linear(np, 16, &cpld_pic_host_ops, NULL);
        if (!cpld_pic_host) {
                printk(KERN_ERR "CPLD PIC: failed to allocate irq host!\n");
                goto end;
index a746415c42423808496d0fedc02cdbbb42863a20..5db5cfb6a4ff69bfa594869f81cab82d68840b05 100644 (file)
@@ -173,15 +173,12 @@ static void __init media5200_init_irq(void)
 
        spin_lock_init(&media5200_irq.lock);
 
-       media5200_irq.irqhost = irq_alloc_host(fpga_np, IRQ_DOMAIN_MAP_LINEAR,
-                                              MEDIA5200_NUM_IRQS,
-                                              &media5200_irq_ops, -1);
+       media5200_irq.irqhost = irq_domain_add_linear(fpga_np,
+                       MEDIA5200_NUM_IRQS, &media5200_irq_ops, &media5200_irq);
        if (!media5200_irq.irqhost)
                goto out;
        pr_debug("%s: allocated irqhost\n", __func__);
 
-       media5200_irq.irqhost->host_data = &media5200_irq;
-
        irq_set_handler_data(cascade_virq, &media5200_irq);
        irq_set_chained_handler(cascade_virq, media5200_irq_cascade);
 
index e90af8fd8413051d9f84b98913f9581b21c8de41..b53275d127271075146c142e03279413b6652761 100644 (file)
@@ -252,14 +252,12 @@ mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
        if (!cascade_virq)
                return;
 
-       gpt->irqhost = irq_alloc_host(node, IRQ_DOMAIN_MAP_LINEAR, 1,
-                                     &mpc52xx_gpt_irq_ops, -1);
+       gpt->irqhost = irq_domain_add_linear(node, 1, &mpc52xx_gpt_irq_ops, gpt);
        if (!gpt->irqhost) {
-               dev_err(gpt->dev, "irq_alloc_host() failed\n");
+               dev_err(gpt->dev, "irq_domain_add_linear() failed\n");
                return;
        }
 
-       gpt->irqhost->host_data = gpt;
        irq_set_handler_data(cascade_virq, gpt);
        irq_set_chained_handler(cascade_virq, mpc52xx_gpt_irq_cascade);
 
index 8c997f1a912285f79e6a4e5187df4d6ee716c6be..41fa67126c443485fe96a9889dfa5484b5c1581f 100644 (file)
@@ -444,9 +444,9 @@ void __init mpc52xx_init_irq(void)
         * As last step, add an irq host to translate the real
         * hw irq information provided by the ofw to linux virq
         */
-       mpc52xx_irqhost = irq_alloc_host(picnode, IRQ_DOMAIN_MAP_LINEAR,
+       mpc52xx_irqhost = irq_domain_add_linear(picnode,
                                         MPC52xx_IRQ_HIGHTESTHWIRQ,
-                                        &mpc52xx_irqhost_ops, -1);
+                                        &mpc52xx_irqhost_ops, NULL);
 
        if (!mpc52xx_irqhost)
                panic(__FILE__ ": Cannot allocate the IRQ host\n");
index bdba174e7b3a6645eee092847631ae9da1df2635..4ef9d6918e23612ce82f87483f76a614eed4edc4 100644 (file)
@@ -156,17 +156,13 @@ int __init pq2ads_pci_init_irq(void)
        out_be32(&priv->regs->mask, ~0);
        mb();
 
-       host = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, NUM_IRQS,
-                             &pci_pic_host_ops, NUM_IRQS);
+       host = irq_domain_add_linear(np, NUM_IRQS, &pci_pic_host_ops, priv);
        if (!host) {
                ret = -ENOMEM;
                goto out_unmap_regs;
        }
 
-       host->host_data = priv;
-
        priv->host = host;
-       host->host_data = priv;
        irq_set_handler_data(irq, priv);
        irq_set_chained_handler(irq, pq2ads_pci_irq_demux);
 
index e3ef7c9ed7b1bb315152e53d78ed75cedac1ab48..1092c121adf3c32d5a78ddc5035938cbf4ecae97 100644 (file)
@@ -280,9 +280,8 @@ void socrates_fpga_pic_init(struct device_node *pic)
        int i;
 
        /* Setup an irq_domain structure */
-       socrates_fpga_pic_irq_host = irq_alloc_host(pic, IRQ_DOMAIN_MAP_LINEAR,
-                       SOCRATES_FPGA_NUM_IRQS, &socrates_fpga_pic_host_ops,
-                       SOCRATES_FPGA_NUM_IRQS);
+       socrates_fpga_pic_irq_host = irq_domain_add_linear(pic,
+                   SOCRATES_FPGA_NUM_IRQS, &socrates_fpga_pic_host_ops, NULL);
        if (socrates_fpga_pic_irq_host == NULL) {
                pr_err("FPGA PIC: Unable to allocate host\n");
                return;
index 0cf8af230bcf5199c888d390023fe718a6d72d60..126a94b530e4387409a24e0b32bca45f0977062a 100644 (file)
@@ -212,9 +212,8 @@ void __init gef_pic_init(struct device_node *np)
        }
 
        /* Setup an irq_domain structure */
-       gef_pic_irq_host = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR,
-                                         GEF_PIC_NUM_IRQS,
-                                         &gef_pic_host_ops, NO_IRQ);
+       gef_pic_irq_host = irq_domain_add_linear(np, GEF_PIC_NUM_IRQS,
+                                         &gef_pic_host_ops, NULL);
        if (gef_pic_irq_host == NULL)
                return;
 
index 1bfd18a48a7f54a7a5c3fbb4063a2b0440c69728..cf9fd3c8a9b90a76f72df4fa1e15da61b63f39ae 100644 (file)
@@ -392,16 +392,13 @@ static int axon_msi_probe(struct platform_device *device)
        }
        memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES);
 
-       msic->irq_domain = irq_alloc_host(dn, IRQ_DOMAIN_MAP_NOMAP,
-                                       NR_IRQS, &msic_host_ops, 0);
+       msic->irq_domain = irq_domain_add_nomap(dn, &msic_host_ops, msic);
        if (!msic->irq_domain) {
                printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n",
                       dn->full_name);
                goto out_free_fifo;
        }
 
-       msic->irq_domain->host_data = msic;
-
        irq_set_handler_data(virq, msic);
        irq_set_chained_handler(virq, axon_msi_cascade);
        pr_devel("axon_msi: irq 0x%x setup for axon_msi\n", virq);
index 21b64cfef5e5af8181e1efa4ccc9cd0f61c1a978..bbdf57440cd54a654ec20dbd08a404725d64c1fc 100644 (file)
@@ -239,9 +239,7 @@ void __init beatic_init_IRQ(void)
        ppc_md.get_irq = beatic_get_irq;
 
        /* Allocate an irq host */
-       beatic_host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_NOMAP, 0,
-                                    &beatic_pic_host_ops,
-                                        0);
+       beatic_host = irq_domain_add_nomap(NULL, &beatic_pic_host_ops, NULL);
        BUG_ON(beatic_host == NULL);
        irq_set_default_host(beatic_host);
 }
index 6888475e7c626137c1f4b0c7d0d06d0b80b3c544..c844797a6898ad68e6643d53a53b6d7228612d15 100644 (file)
@@ -378,8 +378,8 @@ static int __init setup_iic(void)
 void __init iic_init_IRQ(void)
 {
        /* Setup an irq host data structure */
-       iic_host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_LINEAR, IIC_SOURCE_COUNT,
-                                 &iic_host_ops, IIC_IRQ_INVALID);
+       iic_host = irq_domain_add_linear(NULL, IIC_SOURCE_COUNT, &iic_host_ops,
+                                        NULL);
        BUG_ON(iic_host == NULL);
        irq_set_default_host(iic_host);
 
index 1f935a772ef827f03b36bd9722a9475500721343..6521d202284aab29788829444c8c3480d432452d 100644 (file)
@@ -299,12 +299,10 @@ static void __init spider_init_one(struct device_node *of_node, int chip,
                panic("spider_pic: can't map registers !");
 
        /* Allocate a host */
-       pic->host = irq_alloc_host(of_node, IRQ_DOMAIN_MAP_LINEAR,
-                                  SPIDER_SRC_COUNT, &spider_host_ops,
-                                  SPIDER_IRQ_INVALID);
+       pic->host = irq_domain_add_linear(of_node, SPIDER_SRC_COUNT,
+                                         &spider_host_ops, pic);
        if (pic->host == NULL)
                panic("spider_pic: can't allocate irq host !");
-       pic->host->host_data = pic;
 
        /* Go through all sources and disable them */
        for (i = 0; i < SPIDER_SRC_COUNT; i++) {
index f862361730fb7e3d4154463a0b2f20e7f98d164e..434597166ca444a9bcb3c9214ff0abc7d14b556f 100644 (file)
@@ -159,15 +159,13 @@ struct irq_domain * __init flipper_pic_init(struct device_node *np)
 
        __flipper_quiesce(io_base);
 
-       irq_domain = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, FLIPPER_NR_IRQS,
-                                 &flipper_irq_domain_ops, -1);
+       irq_domain = irq_domain_add_linear(np, FLIPPER_NR_IRQS,
+                                 &flipper_irq_domain_ops, io_base);
        if (!irq_domain) {
                pr_err("failed to allocate irq_domain\n");
                return NULL;
        }
 
-       irq_domain->host_data = io_base;
-
 out:
        return irq_domain;
 }
index 2d4a5d48fbbd100a182938c517e8c6a893c99a0e..499d410b95fa43f6bc203a20ffa19fb347cfd970 100644 (file)
@@ -177,13 +177,12 @@ struct irq_domain *hlwd_pic_init(struct device_node *np)
 
        __hlwd_quiesce(io_base);
 
-       irq_domain = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, HLWD_NR_IRQS,
-                                 &hlwd_irq_domain_ops, -1);
+       irq_domain = irq_domain_add_linear(np, HLWD_NR_IRQS,
+                                          &hlwd_irq_domain_ops, io_base);
        if (!irq_domain) {
                pr_err("failed to allocate irq_domain\n");
                return NULL;
        }
-       irq_domain->host_data = io_base;
 
        return irq_domain;
 }
index b07d4f2e0155fb6a272ff46c2a8e4e762c51c4fa..5538b593079d4f736226a91e1b788acbea0f2231 100644 (file)
@@ -380,8 +380,7 @@ void __init iSeries_init_IRQ(void)
        /* Create irq host. No need for a revmap since HV will give us
         * back our virtual irq number
         */
-       host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_NOMAP, 0,
-                             &iseries_irq_domain_ops, 0);
+       host = irq_domain_add_nomap(NULL, &iseries_irq_domain_ops, NULL);
        BUG_ON(host == NULL);
        irq_set_default_host(host);
 
index cff326ab8ef2db943ab285fdd25e9101bd811323..646fdf3b9c0c4b9cf4cdfa8f640244da679e5cf9 100644 (file)
@@ -352,9 +352,8 @@ static void __init pmac_pic_probe_oldstyle(void)
        /*
         * Allocate an irq host
         */
-       pmac_pic_host = irq_alloc_host(master, IRQ_DOMAIN_MAP_LINEAR, max_irqs,
-                                      &pmac_pic_host_ops,
-                                      max_irqs);
+       pmac_pic_host = irq_domain_add_linear(master, max_irqs,
+                                             &pmac_pic_host_ops, NULL);
        BUG_ON(pmac_pic_host == NULL);
        irq_set_default_host(pmac_pic_host);
 
index 6b1ef2d4dea0b016924bc73956c70348b7694e1b..09afd704f07ae7cad49640964931f2b0ba7df313 100644 (file)
@@ -192,8 +192,7 @@ static int psurge_secondary_ipi_init(void)
 {
        int rc = -ENOMEM;
 
-       psurge_host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_NOMAP, 0,
-               &psurge_host_ops, 0);
+       psurge_host = irq_domain_add_nomap(NULL, &psurge_host_ops, NULL);
 
        if (psurge_host)
                psurge_secondary_virq = irq_create_direct_mapping(psurge_host);
index c5980e422dc656f62d78ad85eb85cdf166ff8614..c05808f21015c96532afae607ba49c03491575ce 100644 (file)
@@ -753,8 +753,7 @@ void __init ps3_init_IRQ(void)
        unsigned cpu;
        struct irq_domain *host;
 
-       host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_NOMAP, 0, &ps3_host_ops,
-               PS3_INVALID_OUTLET);
+       host = irq_domain_add_nomap(NULL, &ps3_host_ops, NULL);
        irq_set_default_host(host);
        irq_set_virq_count(PS3_PLUG_MAX + 1);
 
index 76b33bc3611608e0a3fe87e28c360412b9e61a58..4837515c282609860ee11d3a5418102c96ed85ab 100644 (file)
@@ -263,13 +263,11 @@ struct opb_pic *opb_pic_init_one(struct device_node *dn)
                goto free_opb;
        }
 
-       /* Allocate an irq host so that Linux knows that despite only
+       /* Allocate an irq domain so that Linux knows that despite only
         * having one interrupt to issue, we're the controller for multiple
         * hardware IRQs, so later we can lookup their virtual IRQs. */
 
-       opb->host = irq_alloc_host(dn, IRQ_DOMAIN_MAP_LINEAR,
-                       OPB_NR_IRQS, &opb_host_ops, -1);
-
+       opb->host = irq_domain_add_linear(dn, OPB_NR_IRQS, &opb_host_ops, opb);
        if (!opb->host) {
                printk(KERN_ERR "opb: Failed to allocate IRQ host!\n");
                goto free_regs;
@@ -277,7 +275,6 @@ struct opb_pic *opb_pic_init_one(struct device_node *dn)
 
        opb->index = opb_index++;
        spin_lock_init(&opb->lock);
-       opb->host->host_data = opb;
 
        /* Disable all interrupts by default */
        opb_out(opb, OPB_MLSASIER, 0);
index 0877a757c209c23a3a5bbdb418a15e30a88d7037..53f39dbbfb9720001e4b38072cfb0f04978df168 100644 (file)
@@ -164,8 +164,7 @@ unsigned int cpm_pic_init(void)
 
        out_be32(&cpic_reg->cpic_cimr, 0);
 
-       cpm_pic_host = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR,
-                                     64, &cpm_pic_host_ops, 64);
+       cpm_pic_host = irq_domain_add_linear(np, 64, &cpm_pic_host_ops, NULL);
        if (cpm_pic_host == NULL) {
                printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
                sirq = NO_IRQ;
index b149baae5d33e64def2dba8145b8efe8e2c1fb43..b3643322c528b9ebb862538bc357d4f65bb29834 100644 (file)
@@ -275,8 +275,7 @@ void cpm2_pic_init(struct device_node *node)
        out_be32(&cpm2_intctl->ic_scprrl, 0x05309770);
 
        /* create a legacy host */
-       cpm2_pic_host = irq_alloc_host(node, IRQ_DOMAIN_MAP_LINEAR,
-                                      64, &cpm2_pic_host_ops, 64);
+       cpm2_pic_host = irq_domain_add_linear(node, 64, &cpm2_pic_host_ops, NULL);
        if (cpm2_pic_host == NULL) {
                printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
                return;
index 48d3ba1220d3a01e0a5f4e3bbd394303621d054e..adea322ea18f0d81a3d1b5e692980feab5f6bc8d 100644 (file)
@@ -275,9 +275,8 @@ void __init ehv_pic_init(void)
                return;
        }
 
-       ehv_pic->irqhost = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR,
-               NR_EHV_PIC_INTS, &ehv_pic_host_ops, 0);
-
+       ehv_pic->irqhost = irq_domain_add_linear(np, NR_EHV_PIC_INTS,
+                                                &ehv_pic_host_ops, ehv_pic);
        if (!ehv_pic->irqhost) {
                of_node_put(np);
                kfree(ehv_pic);
@@ -293,7 +292,6 @@ void __init ehv_pic_init(void)
                of_node_put(np2);
        }
 
-       ehv_pic->irqhost->host_data = ehv_pic;
        ehv_pic->hc_irq = ehv_pic_irq_chip;
        ehv_pic->hc_irq.irq_set_affinity = ehv_pic_set_affinity;
        ehv_pic->coreint_flag = coreint_flag;
index 3f9a301c4550f255075f5bfdac23f89b81aa0dbb..f4fd95bc12789c42adb9df19fad6d29b62e2f725 100644 (file)
@@ -387,8 +387,8 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
        }
        platform_set_drvdata(dev, msi);
 
-       msi->irqhost = irq_alloc_host(dev->dev.of_node, IRQ_DOMAIN_MAP_LINEAR,
-                                     NR_MSI_IRQS, &fsl_msi_host_ops, 0);
+       msi->irqhost = irq_domain_add_linear(dev->dev.of_node,
+                                     NR_MSI_IRQS, &fsl_msi_host_ops, msi);
 
        if (msi->irqhost == NULL) {
                dev_err(&dev->dev, "No memory for MSI irqhost\n");
@@ -420,8 +420,6 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
 
        msi->feature = features->fsl_pic_ip;
 
-       msi->irqhost->host_data = msi;
-
        /*
         * Remember the phandle, so that we can match with any PCI nodes
         * that have an "fsl,msi" property.
index 7e67890b8fc29b6450bee34594641e7f31e398b8..573a73bd954a9e61a0591e5f1e63d39640b7cb2c 100644 (file)
@@ -263,8 +263,7 @@ void i8259_init(struct device_node *node, unsigned long intack_addr)
        raw_spin_unlock_irqrestore(&i8259_lock, flags);
 
        /* create a legacy host */
-       i8259_host = irq_alloc_host(node, IRQ_DOMAIN_MAP_LEGACY,
-                                   0, &i8259_host_ops, 0);
+       i8259_host = irq_domain_add_legacy(node, &i8259_host_ops, NULL);
        if (i8259_host == NULL) {
                printk(KERN_ERR "i8259: failed to allocate irq host !\n");
                return;
index 9abed376054519cb6f8eecca28f6923979fcecad..0eaaa01c11b3fa654e48fdd5a50396cad2e1492b 100644 (file)
@@ -728,9 +728,8 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
        if (ipic == NULL)
                return NULL;
 
-       ipic->irqhost = irq_alloc_host(node, IRQ_DOMAIN_MAP_LINEAR,
-                                      NR_IPIC_INTS,
-                                      &ipic_host_ops, 0);
+       ipic->irqhost = irq_domain_add_linear(node, NR_IPIC_INTS,
+                                             &ipic_host_ops, ipic);
        if (ipic->irqhost == NULL) {
                kfree(ipic);
                return NULL;
@@ -738,8 +737,6 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
 
        ipic->regs = ioremap(res.start, resource_size(&res));
 
-       ipic->irqhost->host_data = ipic;
-
        /* init hw */
        ipic_write(ipic->regs, IPIC_SICNR, 0x0);
 
index 978dfc4c3120808935c002886e5fec051b1f94a2..d5f5416be310b0fc5f78f7466cc5755b34a6f1cd 100644 (file)
@@ -171,8 +171,7 @@ int mpc8xx_pic_init(void)
                goto out;
        }
 
-       mpc8xx_pic_host = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR,
-                                        64, &mpc8xx_pic_host_ops, 64);
+       mpc8xx_pic_host = irq_domain_add_linear(np, 64, &mpc8xx_pic_host_ops, NULL);
        if (mpc8xx_pic_host == NULL) {
                printk(KERN_ERR "MPC8xx PIC: failed to allocate irq host!\n");
                ret = -ENOMEM;
index c844d343bf322e392b68456e93f4bd1c9594ab93..c83a512fa175c74b83b24eadb5ed9791b03351f1 100644 (file)
@@ -1345,10 +1345,9 @@ struct mpic * __init mpic_alloc(struct device_node *node,
        mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
        mpic->isu_mask = (1 << mpic->isu_shift) - 1;
 
-       mpic->irqhost = irq_alloc_host(mpic->node, IRQ_DOMAIN_MAP_LINEAR,
+       mpic->irqhost = irq_domain_add_linear(mpic->node,
                                       isu_size ? isu_size : mpic->num_sources,
-                                      &mpic_host_ops,
-                                      flags & MPIC_LARGE_VECTORS ? 2048 : 256);
+                                      &mpic_host_ops, mpic);
 
        /*
         * FIXME: The code leaks the MPIC object and mappings here; this
@@ -1357,8 +1356,6 @@ struct mpic * __init mpic_alloc(struct device_node *node,
        if (mpic->irqhost == NULL)
                return NULL;
 
-       mpic->irqhost->host_data = mpic;
-
        /* Display version */
        switch (greg_feature & MPIC_GREG_FEATURE_VERSION_MASK) {
        case 1:
index 45124a1959d03da3e7cdf497c7e45e849e1f25ab..8848e99a83f21a27779c0ea56e94876bfdfda400 100644 (file)
@@ -250,9 +250,8 @@ void __init mv64x60_init_irq(void)
        paddr = of_translate_address(np, reg);
        mv64x60_irq_reg_base = ioremap(paddr, reg[1]);
 
-       mv64x60_irq_host = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR,
-                                         MV64x60_NUM_IRQS,
-                                         &mv64x60_host_ops, MV64x60_NUM_IRQS);
+       mv64x60_irq_host = irq_domain_add_linear(np, MV64x60_NUM_IRQS,
+                                         &mv64x60_host_ops, NULL);
 
        spin_lock_irqsave(&mv64x60_lock, flags);
        out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
index 78e90192c34356222d539467959fbe84c020afdd..e9b3d5cc65d3d30d4cb285fcf660190979050b7a 100644 (file)
@@ -339,8 +339,8 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags,
        if (qe_ic == NULL)
                return;
 
-       qe_ic->irqhost = irq_alloc_host(node, IRQ_DOMAIN_MAP_LINEAR,
-                                       NR_QE_IC_INTS, &qe_ic_host_ops, 0);
+       qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS,
+                                              &qe_ic_host_ops, qe_ic);
        if (qe_ic->irqhost == NULL) {
                kfree(qe_ic);
                return;
@@ -348,7 +348,6 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags,
 
        qe_ic->regs = ioremap(res.start, resource_size(&res));
 
-       qe_ic->irqhost->host_data = qe_ic;
        qe_ic->hc_irq = qe_ic_irq_chip;
 
        qe_ic->virq_high = irq_of_parse_and_map(node, 0);
index f3757236e6662b3013cfbbb070da8796514d06f9..1be26f4b9c962a74dda8adae6f3c581418af7eb0 100644 (file)
@@ -419,8 +419,7 @@ void __init tsi108_pci_int_init(struct device_node *node)
 {
        DBG("Tsi108_pci_int_init: initializing PCI interrupts\n");
 
-       pci_irq_host = irq_alloc_host(node, IRQ_DOMAIN_MAP_LEGACY,
-                                     0, &pci_irq_domain_ops, 0);
+       pci_irq_host = irq_domain_add_legacy(node, &pci_irq_domain_ops, NULL);
        if (pci_irq_host == NULL) {
                printk(KERN_ERR "pci_irq_host: failed to allocate irq domain!\n");
                return;
index 7eea3a64bdf70d0a156ddb0e275e3b4facf9b03d..84e59c97391fe63970237453010fbdc4934f1a4c 100644 (file)
@@ -270,13 +270,11 @@ static struct uic * __init uic_init_one(struct device_node *node)
        }
        uic->dcrbase = *dcrreg;
 
-       uic->irqhost = irq_alloc_host(node, IRQ_DOMAIN_MAP_LINEAR,
-                                     NR_UIC_INTS, &uic_host_ops, -1);
+       uic->irqhost = irq_domain_add_linear(node, NR_UIC_INTS, &uic_host_ops,
+                                            uic);
        if (! uic->irqhost)
                return NULL; /* FIXME: panic? */
 
-       uic->irqhost->host_data = uic;
-
        /* Start with all interrupts disabled, level and non-critical */
        mtdcr(uic->dcrbase + UIC_ER, 0);
        mtdcr(uic->dcrbase + UIC_CR, 0);
index fb2e303d25fbd6f40f08ecd9aaf56330d87b63c8..ea5e204e345093cedfc320d06f23a804d3c8589e 100644 (file)
@@ -374,8 +374,7 @@ static struct irq_domain_ops xics_host_ops = {
 
 static void __init xics_init_host(void)
 {
-       xics_host = irq_alloc_host(NULL, IRQ_DOMAIN_MAP_TREE, 0, &xics_host_ops,
-                                  XICS_IRQ_SPURIOUS);
+       xics_host = irq_domain_add_tree(NULL, &xics_host_ops, NULL);
        BUG_ON(xics_host == NULL);
        irq_set_default_host(xics_host);
 }
index 92e7d4db9fde432b57920b0ccb5b2c86e2904328..8d73c3c0bee6a9062776e2820c8758eb96737a54 100644 (file)
@@ -201,11 +201,10 @@ xilinx_intc_init(struct device_node *np)
        out_be32(regs + XINTC_MER, 0x3UL); /* Turn on the Master Enable. */
 
        /* Allocate and initialize an irq_domain structure. */
-       irq = irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, XILINX_INTC_MAXIRQS,
-                            &xilinx_intc_ops, -1);
+       irq = irq_domain_add_linear(np, XILINX_INTC_MAXIRQS, &xilinx_intc_ops,
+                                   regs);
        if (!irq)
                panic(__FILE__ ": Cannot allocate IRQ host\n");
-       irq->host_data = regs;
 
        return irq;
 }
index 9efd59732eeba1a54727428f6560f5852672f5a9..149d9876fca8040ddf9bddf15b1aa7fa0a6473f9 100644 (file)
@@ -364,9 +364,8 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
        if (hwirq == NO_IRQ)
                goto skip_irq;
 
-       mpc8xxx_gc->irq =
-               irq_alloc_host(np, IRQ_DOMAIN_MAP_LINEAR, MPC8XXX_GPIO_PINS,
-                              &mpc8xxx_gpio_irq_ops, MPC8XXX_GPIO_PINS);
+       mpc8xxx_gc->irq = irq_domain_add_linear(np, MPC8XXX_GPIO_PINS,
+                                       &mpc8xxx_gpio_irq_ops, mpc8xxx_gc);
        if (!mpc8xxx_gc->irq)
                goto skip_irq;
 
@@ -374,8 +373,6 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
        if (id)
                mpc8xxx_gc->of_dev_id_data = id->data;
 
-       mpc8xxx_gc->irq->host_data = mpc8xxx_gc;
-
        /* ack and mask all irqs */
        out_be32(mm_gc->regs + GPIO_IER, 0xffffffff);
        out_be32(mm_gc->regs + GPIO_IMR, 0);
index 18f4ab002d2e161ceeafd125b16f3a9b6e3d978c..f95553fa687215ce899cc9b2c3daffc1641aedbf 100644 (file)
@@ -95,10 +95,6 @@ struct irq_domain {
 
        /* type of reverse mapping_technique */
        unsigned int revmap_type;
-#define IRQ_DOMAIN_MAP_LEGACY 0 /* legacy 8259, gets irqs 1..15 */
-#define IRQ_DOMAIN_MAP_NOMAP 1 /* no fast reverse mapping */
-#define IRQ_DOMAIN_MAP_LINEAR 2 /* linear map of interrupts */
-#define IRQ_DOMAIN_MAP_TREE 3 /* radix tree */
        union {
                struct {
                        unsigned int size;
@@ -120,11 +116,21 @@ struct irq_domain {
 
 #ifdef CONFIG_IRQ_DOMAIN
 #ifdef CONFIG_PPC
-extern struct irq_domain *irq_alloc_host(struct device_node *of_node,
-                                      unsigned int revmap_type,
-                                      unsigned int revmap_arg,
-                                      struct irq_domain_ops *ops,
-                                      irq_hw_number_t inval_irq);
+struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
+                                        struct irq_domain_ops *ops,
+                                        void *host_data);
+struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
+                                        unsigned int size,
+                                        struct irq_domain_ops *ops,
+                                        void *host_data);
+struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
+                                        struct irq_domain_ops *ops,
+                                        void *host_data);
+struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
+                                        struct irq_domain_ops *ops,
+                                        void *host_data);
+
+
 extern struct irq_domain *irq_find_host(struct device_node *node);
 extern void irq_set_default_host(struct irq_domain *host);
 extern void irq_set_virq_count(unsigned int count);
index 432d292b33f8c273a9b125567c0c708db09f062e..acedba1a2651b03fae055090afb22deccd2e8738 100644 (file)
 #include <linux/smp.h>
 #include <linux/fs.h>
 
+#define IRQ_DOMAIN_MAP_LEGACY 0 /* legacy 8259, gets irqs 1..15 */
+#define IRQ_DOMAIN_MAP_NOMAP 1 /* no fast reverse mapping */
+#define IRQ_DOMAIN_MAP_LINEAR 2 /* linear map of interrupts */
+#define IRQ_DOMAIN_MAP_TREE 3 /* radix tree */
+
 static LIST_HEAD(irq_domain_list);
 static DEFINE_MUTEX(irq_domain_mutex);
 
@@ -27,100 +32,158 @@ static int default_irq_domain_match(struct irq_domain *d, struct device_node *np
 }
 
 /**
- * irq_alloc_host() - Allocate a new irq_domain data structure
+ * irq_domain_alloc() - Allocate a new irq_domain data structure
  * @of_node: optional device-tree node of the interrupt controller
  * @revmap_type: type of reverse mapping to use
- * @revmap_arg: for IRQ_DOMAIN_MAP_LINEAR linear only: size of the map
  * @ops: map/unmap domain callbacks
- * @inval_irq: provide a hw number in that domain space that is always invalid
+ * @host_data: Controller private data pointer
  *
- * Allocates and initialize and irq_domain structure. Note that in the case of
- * IRQ_DOMAIN_MAP_LEGACY, the map() callback will be called before this returns
- * for all legacy interrupts except 0 (which is always the invalid irq for
- * a legacy controller). For a IRQ_DOMAIN_MAP_LINEAR, the map is allocated by
- * this call as well. For a IRQ_DOMAIN_MAP_TREE, the radix tree will be
- * allocated later during boot automatically (the reverse mapping will use the
- * slow path until that happens).
+ * Allocates and initialize and irq_domain structure.  Caller is expected to
+ * register allocated irq_domain with irq_domain_register().  Returns pointer
+ * to IRQ domain, or NULL on failure.
  */
-struct irq_domain *irq_alloc_host(struct device_node *of_node,
-                               unsigned int revmap_type,
-                               unsigned int revmap_arg,
-                               struct irq_domain_ops *ops,
-                               irq_hw_number_t inval_irq)
+static struct irq_domain *irq_domain_alloc(struct device_node *of_node,
+                                          unsigned int revmap_type,
+                                          struct irq_domain_ops *ops,
+                                          void *host_data)
 {
-       struct irq_domain *domain, *h;
-       unsigned int size = sizeof(struct irq_domain);
-       unsigned int i;
-       unsigned int *rmap;
+       struct irq_domain *domain;
 
-       /* Allocate structure and revmap table if using linear mapping */
-       if (revmap_type == IRQ_DOMAIN_MAP_LINEAR)
-               size += revmap_arg * sizeof(unsigned int);
-       domain = kzalloc(size, GFP_KERNEL);
-       if (domain == NULL)
+       domain = kzalloc(sizeof(*domain), GFP_KERNEL);
+       if (WARN_ON(!domain))
                return NULL;
 
        /* Fill structure */
        domain->revmap_type = revmap_type;
-       domain->inval_irq = inval_irq;
        domain->ops = ops;
+       domain->host_data = host_data;
        domain->of_node = of_node_get(of_node);
 
        if (domain->ops->match == NULL)
                domain->ops->match = default_irq_domain_match;
 
+       return domain;
+}
+
+static void irq_domain_add(struct irq_domain *domain)
+{
+       mutex_lock(&irq_domain_mutex);
+       list_add(&domain->link, &irq_domain_list);
+       mutex_unlock(&irq_domain_mutex);
+       pr_debug("irq: Allocated domain of type %d @0x%p\n",
+                domain->revmap_type, domain);
+}
+
+/**
+ * irq_domain_add_legacy() - Allocate and register a legacy revmap irq_domain.
+ * @of_node: pointer to interrupt controller's device tree node.
+ * @ops: map/unmap domain callbacks
+ * @host_data: Controller private data pointer
+ *
+ * Note: the map() callback will be called before this function returns
+ * for all legacy interrupts except 0 (which is always the invalid irq for
+ * a legacy controller).
+ */
+struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
+                                        struct irq_domain_ops *ops,
+                                        void *host_data)
+{
+       struct irq_domain *domain, *h;
+       unsigned int i;
+
+       domain = irq_domain_alloc(of_node, IRQ_DOMAIN_MAP_LEGACY, ops, host_data);
+       if (!domain)
+               return NULL;
+
        mutex_lock(&irq_domain_mutex);
        /* Make sure only one legacy controller can be created */
-       if (revmap_type == IRQ_DOMAIN_MAP_LEGACY) {
-               list_for_each_entry(h, &irq_domain_list, link) {
-                       if (WARN_ON(h->revmap_type == IRQ_DOMAIN_MAP_LEGACY)) {
-                               mutex_unlock(&irq_domain_mutex);
-                               of_node_put(domain->of_node);
-                               kfree(domain);
-                               return NULL;
-                       }
+       list_for_each_entry(h, &irq_domain_list, link) {
+               if (WARN_ON(h->revmap_type == IRQ_DOMAIN_MAP_LEGACY)) {
+                       mutex_unlock(&irq_domain_mutex);
+                       of_node_put(domain->of_node);
+                       kfree(domain);
+                       return NULL;
                }
        }
        list_add(&domain->link, &irq_domain_list);
        mutex_unlock(&irq_domain_mutex);
 
-       /* Additional setups per revmap type */
-       switch(revmap_type) {
-       case IRQ_DOMAIN_MAP_LEGACY:
-               /* 0 is always the invalid number for legacy */
-               domain->inval_irq = 0;
-               /* setup us as the domain for all legacy interrupts */
-               for (i = 1; i < NUM_ISA_INTERRUPTS; i++) {
-                       struct irq_data *irq_data = irq_get_irq_data(i);
-                       irq_data->hwirq = i;
-                       irq_data->domain = domain;
-
-                       /* Legacy flags are left to default at this point,
-                        * one can then use irq_create_mapping() to
-                        * explicitly change them
-                        */
-                       ops->map(domain, i, i);
-
-                       /* Clear norequest flags */
-                       irq_clear_status_flags(i, IRQ_NOREQUEST);
-               }
-               break;
-       case IRQ_DOMAIN_MAP_LINEAR:
-               rmap = (unsigned int *)(domain + 1);
-               for (i = 0; i < revmap_arg; i++)
-                       rmap[i] = 0;
-               domain->revmap_data.linear.size = revmap_arg;
-               domain->revmap_data.linear.revmap = rmap;
-               break;
-       case IRQ_DOMAIN_MAP_TREE:
-               INIT_RADIX_TREE(&domain->revmap_data.tree, GFP_KERNEL);
-               break;
-       default:
-               break;
+       /* setup us as the domain for all legacy interrupts */
+       for (i = 1; i < NUM_ISA_INTERRUPTS; i++) {
+               struct irq_data *irq_data = irq_get_irq_data(i);
+               irq_data->hwirq = i;
+               irq_data->domain = domain;
+
+               /* Legacy flags are left to default at this point,
+                * one can then use irq_create_mapping() to
+                * explicitly change them
+                */
+               ops->map(domain, i, i);
+
+               /* Clear norequest flags */
+               irq_clear_status_flags(i, IRQ_NOREQUEST);
        }
+       return domain;
+}
 
-       pr_debug("irq: Allocated domain of type %d @0x%p\n", revmap_type, domain);
+/**
+ * irq_domain_add_linear() - Allocate and register a legacy revmap irq_domain.
+ * @of_node: pointer to interrupt controller's device tree node.
+ * @ops: map/unmap domain callbacks
+ * @host_data: Controller private data pointer
+ */
+struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
+                                        unsigned int size,
+                                        struct irq_domain_ops *ops,
+                                        void *host_data)
+{
+       struct irq_domain *domain;
+       unsigned int *revmap;
+
+       revmap = kzalloc(sizeof(*revmap) * size, GFP_KERNEL);
+       if (WARN_ON(!revmap))
+               return NULL;
 
+       domain = irq_domain_alloc(of_node, IRQ_DOMAIN_MAP_LINEAR, ops, host_data);
+       if (!domain) {
+               kfree(revmap);
+               return NULL;
+       }
+       domain->revmap_data.linear.size = size;
+       domain->revmap_data.linear.revmap = revmap;
+       irq_domain_add(domain);
+       return domain;
+}
+
+struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
+                                        struct irq_domain_ops *ops,
+                                        void *host_data)
+{
+       struct irq_domain *domain = irq_domain_alloc(of_node,
+                                       IRQ_DOMAIN_MAP_NOMAP, ops, host_data);
+       if (domain)
+               irq_domain_add(domain);
+       return domain;
+}
+
+/**
+ * irq_domain_add_tree()
+ * @of_node: pointer to interrupt controller's device tree node.
+ * @ops: map/unmap domain callbacks
+ *
+ * Note: The radix tree will be allocated later during boot automatically
+ * (the reverse mapping will use the slow path until that happens).
+ */
+struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
+                                        struct irq_domain_ops *ops,
+                                        void *host_data)
+{
+       struct irq_domain *domain = irq_domain_alloc(of_node,
+                                       IRQ_DOMAIN_MAP_TREE, ops, host_data);
+       if (domain) {
+               INIT_RADIX_TREE(&domain->revmap_data.tree, GFP_KERNEL);
+               irq_domain_add(domain);
+       }
        return domain;
 }
 
@@ -393,9 +456,6 @@ void irq_dispose_mapping(unsigned int virq)
                break;
        }
 
-       /* Destroy map */
-       irq_data->hwirq = domain->inval_irq;
-
        irq_free_desc(virq);
 }
 EXPORT_SYMBOL_GPL(irq_dispose_mapping);