}
EXPORT_SYMBOL_GPL(virq_to_hw);
-__init_refok struct irq_host *irq_alloc_host(unsigned int revmap_type,
- unsigned int revmap_arg,
- struct irq_host_ops *ops,
- irq_hw_number_t inval_irq)
+__init_refok struct irq_host *irq_alloc_host(struct device_node *of_node,
+ unsigned int revmap_type,
+ unsigned int revmap_arg,
+ struct irq_host_ops *ops,
+ irq_hw_number_t inval_irq)
{
struct irq_host *host;
unsigned int size = sizeof(struct irq_host);
host->revmap_type = revmap_type;
host->inval_irq = inval_irq;
host->ops = ops;
+ host->of_node = of_node;
spin_lock_irqsave(&irq_big_lock, flags);
static int mpc52xx_irqhost_match(struct irq_host *h, struct device_node *node)
{
pr_debug("%s: node=%p\n", __func__, node);
- return mpc52xx_irqhost->host_data == node;
+ return h->of_node == node;
}
static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
* hw irq information provided by the ofw to linux virq
*/
- mpc52xx_irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR,
+ mpc52xx_irqhost = irq_alloc_host(picnode, IRQ_HOST_MAP_LINEAR,
MPC52xx_IRQ_HIGHTESTHWIRQ,
&mpc52xx_irqhost_ops, -1);
if (!mpc52xx_irqhost)
panic(__FILE__ ": Cannot allocate the IRQ host\n");
- mpc52xx_irqhost->host_data = picnode;
printk(KERN_INFO "MPC52xx PIC is up and running!\n");
}
static unsigned long pci_int_base;
static struct irq_host *pci_pic_host;
-static struct device_node *pci_pic_node;
#endif
static void __init mpc82xx_ads_pic_init(void)
static int pci_pic_host_match(struct irq_host *h, struct device_node *node)
{
- return node == pci_pic_node;
+ return h->of_node == node;
}
static int pci_pic_host_map(struct irq_host *h, unsigned int virq,
iounmap(immap);
return;
}
- pci_pic_node = of_node_get(np);
/* PCI interrupt controller registers: status and mask */
regs = of_get_property(np, "reg", &size);
if ((!regs) || (size <= 2)) {
ioremap(regs[0], sizeof(*pci_regs.pci_int_stat_reg));
pci_regs.pci_int_mask_reg =
ioremap(regs[1], sizeof(*pci_regs.pci_int_mask_reg));
- of_node_put(np);
/* configure chip select for PCI interrupt controller */
immap->im_memctl.memc_br3 = regs[0] | 0x00001801;
immap->im_memctl.memc_or3 = 0xffff8010;
*pci_regs.pci_int_mask_reg |= 0xfff00000;
iounmap(immap);
pci_pic_host =
- irq_alloc_host(IRQ_HOST_MAP_LINEAR, irq_max - irq_min + 1,
+ irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, irq_max - irq_min + 1,
&pci_pic_host_ops, irq_max + 1);
return;
}
struct axon_msic {
- struct device_node *dn;
struct irq_host *irq_host;
__le32 *fifo;
dcr_host_t dcr_host;
static int msic_host_match(struct irq_host *host, struct device_node *dn)
{
- struct axon_msic *msic = host->host_data;
-
- return msic->dn == dn;
+ return host->of_node == dn;
}
static struct irq_host_ops msic_host_ops = {
u32 tmp;
list_for_each_entry(msic, &axon_msic_list, list) {
- pr_debug("axon_msi: disabling %s\n", msic->dn->full_name);
+ pr_debug("axon_msi: disabling %s\n",
+ msic->irq_host->of_node->full_name);
tmp = msic_dcr_read(msic, MSIC_CTRL_REG);
tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE;
msic_dcr_write(msic, MSIC_CTRL_REG, tmp);
msic->fifo = page_address(page);
- msic->irq_host = irq_alloc_host(IRQ_HOST_MAP_NOMAP, NR_IRQS,
- &msic_host_ops, 0);
+ msic->irq_host = irq_alloc_host(of_node_get(dn), IRQ_HOST_MAP_NOMAP,
+ NR_IRQS, &msic_host_ops, 0);
if (!msic->irq_host) {
printk(KERN_ERR "axon_msi: couldn't allocate irq_host for %s\n",
dn->full_name);
goto out_free_host;
}
- msic->dn = of_node_get(dn);
-
set_irq_data(virq, msic);
set_irq_chained_handler(virq, axon_msi_cascade);
pr_debug("axon_msi: irq 0x%x setup for axon_msi\n", virq);
void __init iic_init_IRQ(void)
{
/* Setup an irq host data structure */
- iic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, IIC_SOURCE_COUNT,
+ iic_host = irq_alloc_host(NULL, IRQ_HOST_MAP_LINEAR, IIC_SOURCE_COUNT,
&iic_host_ops, IIC_IRQ_INVALID);
BUG_ON(iic_host == NULL);
irq_set_default_host(iic_host);
struct spider_pic {
struct irq_host *host;
- struct device_node *of_node;
void __iomem *regs;
unsigned int node_id;
};
static int spider_host_match(struct irq_host *h, struct device_node *node)
{
- struct spider_pic *pic = h->host_data;
- return node == pic->of_node;
+ return h->of_node == node;
}
static int spider_host_map(struct irq_host *h, unsigned int virq,
* tree in case the device-tree is ever fixed
*/
struct of_irq oirq;
- if (of_irq_map_one(pic->of_node, 0, &oirq) == 0) {
+ if (of_irq_map_one(pic->host->of_node, 0, &oirq) == 0) {
virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
oirq.size);
return virq;
}
/* Now do the horrible hacks */
- tmp = of_get_property(pic->of_node, "#interrupt-cells", NULL);
+ tmp = of_get_property(pic->host->of_node, "#interrupt-cells", NULL);
if (tmp == NULL)
return NO_IRQ;
intsize = *tmp;
- imap = of_get_property(pic->of_node, "interrupt-map", &imaplen);
+ imap = of_get_property(pic->host->of_node, "interrupt-map", &imaplen);
if (imap == NULL || imaplen < (intsize + 1))
return NO_IRQ;
iic = of_find_node_by_phandle(imap[intsize]);
panic("spider_pic: can't map registers !");
/* Allocate a host */
- pic->host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, SPIDER_SRC_COUNT,
- &spider_host_ops, SPIDER_IRQ_INVALID);
+ pic->host = irq_alloc_host(of_node_get(of_node), IRQ_HOST_MAP_LINEAR,
+ SPIDER_SRC_COUNT, &spider_host_ops,
+ SPIDER_IRQ_INVALID);
if (pic->host == NULL)
panic("spider_pic: can't allocate irq host !");
pic->host->host_data = pic;
- /* Fill out other bits */
- pic->of_node = of_node_get(of_node);
-
/* Go through all sources and disable them */
for (i = 0; i < SPIDER_SRC_COUNT; i++) {
void __iomem *cfg = pic->regs + TIR_CFGA + 8 * i;
ppc_md.get_irq = beatic_get_irq;
/* Allocate an irq host */
- beatic_host = irq_alloc_host(IRQ_HOST_MAP_NOMAP, 0,
+ beatic_host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0,
&beatic_pic_host_ops,
0);
BUG_ON(beatic_host == NULL);
/* Create irq host. No need for a revmap since HV will give us
* back our virtual irq number
*/
- host = irq_alloc_host(IRQ_HOST_MAP_NOMAP, 0, &iseries_irq_host_ops, 0);
+ host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0,
+ &iseries_irq_host_ops, 0);
BUG_ON(host == NULL);
irq_set_default_host(host);
/*
* Allocate an irq host
*/
- pmac_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, max_irqs,
+ pmac_pic_host = irq_alloc_host(master, IRQ_HOST_MAP_LINEAR, max_irqs,
&pmac_pic_host_ops,
max_irqs);
BUG_ON(pmac_pic_host == NULL);
unsigned cpu;
struct irq_host *host;
- host = irq_alloc_host(IRQ_HOST_MAP_NOMAP, 0, &ps3_host_ops,
+ host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0, &ps3_host_ops,
PS3_INVALID_OUTLET);
irq_set_default_host(host);
irq_set_virq_count(PS3_PLUG_MAX + 1);
ops = &xics_host_lpar_ops;
else
ops = &xics_host_direct_ops;
- xics_host = irq_alloc_host(IRQ_HOST_MAP_TREE, 0, ops,
+ xics_host = irq_alloc_host(NULL, IRQ_HOST_MAP_TREE, 0, ops,
XICS_IRQ_SPURIOUS);
BUG_ON(xics_host == NULL);
irq_set_default_host(xics_host);
cpm8xx_t *cpmp; /* Pointer to comm processor space */
cpic8xx_t *cpic_reg;
-static struct device_node *cpm_pic_node;
static struct irq_host *cpm_pic_host;
static void cpm_mask_irq(unsigned int irq)
static int cpm_pic_host_match(struct irq_host *h, struct device_node *node)
{
- return cpm_pic_node == node;
+ return h->of_node == node;
}
static int cpm_pic_host_map(struct irq_host *h, unsigned int virq,
out_be32(&cpic_reg->cpic_cimr, 0);
- cpm_pic_node = of_node_get(np);
-
- cpm_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 64, &cpm_pic_host_ops, 64);
+ cpm_pic_host = irq_alloc_host(of_node_get(np), IRQ_HOST_MAP_LINEAR,
+ 64, &cpm_pic_host_ops, 64);
if (cpm_pic_host == NULL) {
printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
sirq = NO_IRQ;
static intctl_cpm2_t *cpm2_intctl;
-static struct device_node *cpm2_pic_node;
static struct irq_host *cpm2_pic_host;
#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
static int cpm2_pic_host_match(struct irq_host *h, struct device_node *node)
{
- return cpm2_pic_node == node;
+ return h->of_node == node;
}
static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq,
out_be32(&cpm2_intctl->ic_scprrl, 0x05309770);
/* create a legacy host */
- cpm2_pic_node = of_node_get(node);
- cpm2_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 64, &cpm2_pic_host_ops, 64);
+ cpm2_pic_host = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LINEAR,
+ 64, &cpm2_pic_host_ops, 64);
if (cpm2_pic_host == NULL) {
printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
return;
static DEFINE_SPINLOCK(i8259_lock);
-static struct device_node *i8259_node;
static struct irq_host *i8259_host;
/*
static int i8259_host_match(struct irq_host *h, struct device_node *node)
{
- return i8259_node == NULL || i8259_node == node;
+ return h->of_node == NULL || h->of_node == node;
}
static int i8259_host_map(struct irq_host *h, unsigned int virq,
spin_unlock_irqrestore(&i8259_lock, flags);
/* create a legacy host */
- if (node)
- i8259_node = of_node_get(node);
- i8259_host = irq_alloc_host(IRQ_HOST_MAP_LEGACY, 0, &i8259_host_ops, 0);
+ i8259_host = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LEGACY,
+ 0, &i8259_host_ops, 0);
if (i8259_host == NULL) {
printk(KERN_ERR "i8259: failed to allocate irq host !\n");
return;
static int ipic_host_match(struct irq_host *h, struct device_node *node)
{
- struct ipic *ipic = h->host_data;
-
/* Exact match, unless ipic node is NULL */
- return ipic->of_node == NULL || ipic->of_node == node;
+ return h->of_node == NULL || h->of_node == node;
}
static int ipic_host_map(struct irq_host *h, unsigned int virq,
return NULL;
memset(ipic, 0, sizeof(struct ipic));
- ipic->of_node = of_node_get(node);
- ipic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR,
+ ipic->irqhost = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LINEAR,
NR_IPIC_INTS,
&ipic_host_ops, 0);
if (ipic->irqhost == NULL) {
/* The "linux" controller struct */
struct irq_chip hc_irq;
-
- /* The device node of the interrupt controller */
- struct device_node *of_node;
};
struct ipic_info {
extern int cpm_get_irq(struct pt_regs *regs);
-static struct device_node *mpc8xx_pic_node;
static struct irq_host *mpc8xx_pic_host;
#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
static int mpc8xx_pic_host_match(struct irq_host *h, struct device_node *node)
{
- return mpc8xx_pic_node == node;
+ return h->of_node == node;
}
static int mpc8xx_pic_host_map(struct irq_host *h, unsigned int virq,
return -ENOMEM;
}
- mpc8xx_pic_node = of_node_get(np);
-
ret = of_address_to_resource(np, 0, &res);
- of_node_put(np);
if (ret)
- return ret;
+ goto out;
siu_reg = (void *)ioremap(res.start, res.end - res.start + 1);
- if (siu_reg == NULL)
- return -EINVAL;
+ if (siu_reg == NULL) {
+ ret = -EINVAL;
+ goto out;
+ }
- mpc8xx_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 64, &mpc8xx_pic_host_ops, 64);
+ mpc8xx_pic_host = irq_alloc_host(of_node_get(np), IRQ_HOST_MAP_LINEAR,
+ 64, &mpc8xx_pic_host_ops, 64);
if (mpc8xx_pic_host == NULL) {
printk(KERN_ERR "MPC8xx PIC: failed to allocate irq host!\n");
ret = -ENOMEM;
}
+out:
+ of_node_put(np);
return ret;
}
{
rb->dbase = mpic->dcr_base;
rb->doff = offset;
- rb->dhost = dcr_map(mpic->of_node, rb->dbase + rb->doff, size);
+ rb->dhost = dcr_map(mpic->irqhost->of_node, rb->dbase + rb->doff, size);
BUG_ON(!DCR_MAP_OK(rb->dhost));
}
static int mpic_host_match(struct irq_host *h, struct device_node *node)
{
- struct mpic *mpic = h->host_data;
-
/* Exact match, unless mpic node is NULL */
- return mpic->of_node == NULL || mpic->of_node == node;
+ return h->of_node == NULL || h->of_node == node;
}
static int mpic_host_map(struct irq_host *h, unsigned int virq,
memset(mpic, 0, sizeof(struct mpic));
mpic->name = name;
- mpic->of_node = of_node_get(node);
- mpic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, isu_size,
- &mpic_host_ops,
+ mpic->irqhost = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LINEAR,
+ isu_size, &mpic_host_ops,
flags & MPIC_LARGE_VECTORS ? 2048 : 256);
if (mpic->irqhost == NULL) {
of_node_put(node);
int i, len;
const u32 *p;
- p = of_get_property(mpic->of_node, "msi-available-ranges", &len);
+ p = of_get_property(mpic->irqhost->of_node,
+ "msi-available-ranges", &len);
if (!p) {
pr_debug("mpic: no msi-available-ranges property found on %s\n",
- mpic->of_node->full_name);
+ mpic->irqhost->of_node->full_name);
return -ENODEV;
}
if (len % 8 != 0) {
printk(KERN_WARNING "mpic: Malformed msi-available-ranges "
- "property on %s\n", mpic->of_node->full_name);
+ "property on %s\n", mpic->irqhost->of_node->full_name);
return -EINVAL;
}
static int mv64x60_host_match(struct irq_host *h, struct device_node *np)
{
- return mv64x60_irq_host->host_data == np;
+ return h->of_node == np;
}
static struct irq_chip *mv64x60_chips[] = {
np = of_find_compatible_node(NULL, NULL, "marvell,mv64x60-pic");
reg = of_get_property(np, "reg", &size);
paddr = of_translate_address(np, reg);
- of_node_put(np);
mv64x60_irq_reg_base = ioremap(paddr, reg[1]);
- mv64x60_irq_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, MV64x60_NUM_IRQS,
+ mv64x60_irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
+ MV64x60_NUM_IRQS,
&mv64x60_host_ops, MV64x60_NUM_IRQS);
- mv64x60_irq_host->host_data = np;
-
spin_lock_irqsave(&mv64x60_lock, flags);
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
mv64x60_cached_gpp_mask);
static int qe_ic_host_match(struct irq_host *h, struct device_node *node)
{
- struct qe_ic *qe_ic = h->host_data;
-
/* Exact match, unless qe_ic node is NULL */
- return qe_ic->of_node == NULL || qe_ic->of_node == node;
+ return h->of_node == NULL || h->of_node == node;
}
static int qe_ic_host_map(struct irq_host *h, unsigned int virq,
return;
memset(qe_ic, 0, sizeof(struct qe_ic));
- qe_ic->of_node = of_node_get(node);
- qe_ic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR,
+ qe_ic->irqhost = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LINEAR,
NR_QE_IC_INTS, &qe_ic_host_ops, 0);
if (qe_ic->irqhost == NULL) {
of_node_put(node);
/* The "linux" controller struct */
struct irq_chip hc_irq;
- /* The device node of the interrupt controller */
- struct device_node *of_node;
-
/* VIRQ numbers of QE high/low irqs */
unsigned int virq_high;
unsigned int virq_low;
u32 tsi108_pci_cfg_base;
static u32 tsi108_pci_cfg_phys;
u32 tsi108_csr_vir_base;
-static struct device_node *pci_irq_node;
static struct irq_host *pci_irq_host;
extern u32 get_vir_csrbase(void);
static int pci_irq_host_match(struct irq_host *h, struct device_node *node)
{
- return pci_irq_node == node;
+ return h->of_node == node;
}
static struct irq_host_ops pci_irq_host_ops = {
{
DBG("Tsi108_pci_int_init: initializing PCI interrupts\n");
- pci_irq_node = of_node_get(node);
- pci_irq_host = irq_alloc_host(IRQ_HOST_MAP_LEGACY, 0, &pci_irq_host_ops, 0);
+ pci_irq_host = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LEGACY,
+ 0, &pci_irq_host_ops, 0);
if (pci_irq_host == NULL) {
printk(KERN_ERR "pci_irq_host: failed to allocate irq host !\n");
+ of_node_put(node);
return;
}
/* For secondary UICs, the cascade interrupt's irqaction */
struct irqaction cascade;
-
- /* The device node of the interrupt controller */
- struct device_node *of_node;
};
static void uic_unmask_irq(unsigned int virq)
static int uic_host_match(struct irq_host *h, struct device_node *node)
{
- struct uic *uic = h->host_data;
- return uic->of_node == node;
+ return h->of_node == node;
}
static int uic_host_map(struct irq_host *h, unsigned int virq,
memset(uic, 0, sizeof(*uic));
spin_lock_init(&uic->lock);
- uic->of_node = of_node_get(node);
indexp = of_get_property(node, "cell-index", &len);
if (!indexp || (len != sizeof(u32))) {
printk(KERN_ERR "uic: Device node %s has missing or invalid "
}
uic->dcrbase = *dcrreg;
- uic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, NR_UIC_INTS,
- &uic_host_ops, -1);
+ uic->irqhost = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LINEAR,
+ NR_UIC_INTS, &uic_host_ops, -1);
if (! uic->irqhost) {
of_node_put(node);
return NULL; /* FIXME: panic? */
struct irq_host_ops *ops;
void *host_data;
irq_hw_number_t inval_irq;
+
+ /* Optional device node pointer */
+ struct device_node *of_node;
};
/* The main irq map itself is an array of NR_IRQ entries containing the
/**
* irq_alloc_host - Allocate a new irq_host data structure
- * @node: device-tree node of the interrupt controller
+ * @of_node: optional device-tree node of the interrupt controller
* @revmap_type: type of reverse mapping to use
* @revmap_arg: for IRQ_HOST_MAP_LINEAR linear only: size of the map
* @ops: map/unmap host callbacks
* later during boot automatically (the reverse mapping will use the slow path
* until that happens).
*/
-extern struct irq_host *irq_alloc_host(unsigned int revmap_type,
+extern struct irq_host *irq_alloc_host(struct device_node *of_node,
+ unsigned int revmap_type,
unsigned int revmap_arg,
struct irq_host_ops *ops,
irq_hw_number_t inval_irq);
/* The instance data of a given MPIC */
struct mpic
{
- /* The device node of the interrupt controller */
- struct device_node *of_node;
-
/* The remapper for this MPIC */
struct irq_host *irqhost;