diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-09-02 00:33:35 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-09-02 00:33:35 +0300 |
commit | 17e6b00ac422b49d44a0b8d98402a211f726282d (patch) | |
tree | c7e9143030d20625a0bd94e12ddaf9421890c375 /drivers/irqchip/irq-dw-apb-ictl.c | |
parent | 5e359bf2219d8622eb0931701e45af55db323228 (diff) | |
parent | e324c4dc4a5991d5b1171f434884a4026345e4b4 (diff) | |
download | linux-17e6b00ac422b49d44a0b8d98402a211f726282d.tar.xz |
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq updates from Thomas Gleixner:
"This updated pull request does not contain the last few GIC related
patches which were reported to cause a regression. There is a fix
available, but I let it breed for a couple of days first.
The irq departement provides:
- new infrastructure to support non PCI based MSI interrupts
- a couple of new irq chip drivers
- the usual pile of fixlets and updates to irq chip drivers
- preparatory changes for removal of the irq argument from interrupt
flow handlers
- preparatory changes to remove IRQF_VALID"
* 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (129 commits)
irqchip/imx-gpcv2: IMX GPCv2 driver for wakeup sources
irqchip: Add bcm2836 interrupt controller for Raspberry Pi 2
irqchip: Add documentation for the bcm2836 interrupt controller
irqchip/bcm2835: Add support for being used as a second level controller
irqchip/bcm2835: Refactor handle_IRQ() calls out of MAKE_HWIRQ
PCI: xilinx: Fix typo in function name
irqchip/gic: Ensure gic_cpu_if_up/down() programs correct GIC instance
irqchip/gic: Only allow the primary GIC to set the CPU map
PCI/MSI: pci-xgene-msi: Consolidate chained IRQ handler install/remove
unicore32/irq: Prepare puv3_gpio_handler for irq argument removal
tile/pci_gx: Prepare trio_handle_level_irq for irq argument removal
m68k/irq: Prepare irq handlers for irq argument removal
C6X/megamode-pic: Prepare megamod_irq_cascade for irq argument removal
blackfin: Prepare irq handlers for irq argument removal
arc/irq: Prepare idu_cascade_isr for irq argument removal
sparc/irq: Use access helper irq_data_get_affinity_mask()
sparc/irq: Use helper irq_data_get_irq_handler_data()
parisc/irq: Use access helper irq_data_get_affinity_mask()
mn10300/irq: Use access helper irq_data_get_affinity_mask()
irqchip/i8259: Prepare i8259_irq_dispatch for irq argument removal
...
Diffstat (limited to 'drivers/irqchip/irq-dw-apb-ictl.c')
-rw-r--r-- | drivers/irqchip/irq-dw-apb-ictl.c | 56 |
1 files changed, 23 insertions, 33 deletions
diff --git a/drivers/irqchip/irq-dw-apb-ictl.c b/drivers/irqchip/irq-dw-apb-ictl.c index 53bb7326a60a..efd95d9955e7 100644 --- a/drivers/irqchip/irq-dw-apb-ictl.c +++ b/drivers/irqchip/irq-dw-apb-ictl.c @@ -13,36 +13,36 @@ #include <linux/io.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/irqchip/chained_irq.h> #include <linux/of_address.h> #include <linux/of_irq.h> -#include "irqchip.h" - #define APB_INT_ENABLE_L 0x00 #define APB_INT_ENABLE_H 0x04 #define APB_INT_MASK_L 0x08 #define APB_INT_MASK_H 0x0c #define APB_INT_FINALSTATUS_L 0x30 #define APB_INT_FINALSTATUS_H 0x34 +#define APB_INT_BASE_OFFSET 0x04 static void dw_apb_ictl_handler(unsigned int irq, struct irq_desc *desc) { - struct irq_chip *chip = irq_get_chip(irq); - struct irq_chip_generic *gc = irq_get_handler_data(irq); - struct irq_domain *d = gc->private; - u32 stat; + struct irq_domain *d = irq_desc_get_handler_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); int n; chained_irq_enter(chip, desc); - for (n = 0; n < gc->num_ct; n++) { - stat = readl_relaxed(gc->reg_base + - APB_INT_FINALSTATUS_L + 4 * n); + for (n = 0; n < d->revmap_size; n += 32) { + struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, n); + u32 stat = readl_relaxed(gc->reg_base + APB_INT_FINALSTATUS_L); + while (stat) { u32 hwirq = ffs(stat) - 1; - generic_handle_irq(irq_find_mapping(d, - gc->irq_base + hwirq + 32 * n)); + u32 virq = irq_find_mapping(d, gc->irq_base + hwirq); + + generic_handle_irq(virq); stat &= ~(1 << hwirq); } } @@ -73,7 +73,7 @@ static int __init dw_apb_ictl_init(struct device_node *np, struct irq_domain *domain; struct irq_chip_generic *gc; void __iomem *iobase; - int ret, nrirqs, irq; + int ret, nrirqs, irq, i; u32 reg; /* Map the parent interrupt for the chained handler */ @@ -128,35 +128,25 @@ static int __init dw_apb_ictl_init(struct device_node *np, goto err_unmap; } - ret = irq_alloc_domain_generic_chips(domain, 32, (nrirqs > 32) ? 2 : 1, - np->name, handle_level_irq, clr, 0, - IRQ_GC_MASK_CACHE_PER_TYPE | + ret = irq_alloc_domain_generic_chips(domain, 32, 1, np->name, + handle_level_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE); if (ret) { pr_err("%s: unable to alloc irq domain gc\n", np->full_name); goto err_unmap; } - gc = irq_get_domain_generic_chip(domain, 0); - gc->private = domain; - gc->reg_base = iobase; - - gc->chip_types[0].regs.mask = APB_INT_MASK_L; - gc->chip_types[0].regs.enable = APB_INT_ENABLE_L; - gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit; - gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit; - gc->chip_types[0].chip.irq_resume = dw_apb_ictl_resume; - - if (nrirqs > 32) { - gc->chip_types[1].regs.mask = APB_INT_MASK_H; - gc->chip_types[1].regs.enable = APB_INT_ENABLE_H; - gc->chip_types[1].chip.irq_mask = irq_gc_mask_set_bit; - gc->chip_types[1].chip.irq_unmask = irq_gc_mask_clr_bit; - gc->chip_types[1].chip.irq_resume = dw_apb_ictl_resume; + for (i = 0; i < DIV_ROUND_UP(nrirqs, 32); i++) { + gc = irq_get_domain_generic_chip(domain, i * 32); + gc->reg_base = iobase + i * APB_INT_BASE_OFFSET; + gc->chip_types[0].regs.mask = APB_INT_MASK_L; + gc->chip_types[0].regs.enable = APB_INT_ENABLE_L; + gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit; + gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit; + gc->chip_types[0].chip.irq_resume = dw_apb_ictl_resume; } - irq_set_handler_data(irq, gc); - irq_set_chained_handler(irq, dw_apb_ictl_handler); + irq_set_chained_handler_and_data(irq, dw_apb_ictl_handler, domain); return 0; |