mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 02:32:09 -04:00
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq core updates from Thomas Gleixner:
"This is the first (boring) part of irq updates:
- support for big endian I/O accessors in the generic irq chip
- cleanup of brcmstb/bcm7120 drivers so they can be reused for non
ARM SoCs
- the usual pile of fixes and updates for the various ARM irq chips"
* 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (25 commits)
irqchip: dw-apb-ictl: Add PM support
irqchip: dw-apb-ictl: Enable IRQ_GC_MASK_CACHE_PER_TYPE
irqchip: dw-apb-ictl: Always use use {readl|writel}_relaxed
ARM: orion: convert the irq_reg_{readl,writel} calls to the new API
irqchip: atmel-aic: Add missing entry for rm9200 irq fixups
irqchip: atmel-aic: Rename at91sam9_aic_irq_fixup for naming consistency
irqchip: atmel-aic: Add specific irq fixup function for sam9g45 and sam9rl
irqchip: atmel-aic: Add irq fixups for at91sam926x SoCs
irqchip: atmel-aic: Add irq fixup for RTT block
irqchip: brcmstb-l2: Convert driver to use irq_reg_{readl,writel}
irqchip: bcm7120-l2: Convert driver to use irq_reg_{readl,writel}
irqchip: bcm7120-l2: Decouple driver from brcmstb-l2
irqchip: bcm7120-l2: Extend driver to support 64+ bit controllers
irqchip: bcm7120-l2: Use gc->mask_cache to simplify suspend/resume functions
irqchip: bcm7120-l2: Fix missing nibble in gc->unused mask
irqchip: bcm7120-l2: Make sure all register accesses use base+offset
irqchip: bcm7120-l2, brcmstb-l2: Remove ARM Kconfig dependency
irqchip: bcm7120-l2: Eliminate bad IRQ check
irqchip: brcmstb-l2: Eliminate dependency on ARM code
genirq: Generic chip: Add big endian I/O accessors
...
This commit is contained in:
commit
ecb50f0afd
18 changed files with 345 additions and 188 deletions
|
|
@ -48,14 +48,19 @@ config ATMEL_AIC5_IRQ
|
|||
select MULTI_IRQ_HANDLER
|
||||
select SPARSE_IRQ
|
||||
|
||||
config BCM7120_L2_IRQ
|
||||
bool
|
||||
select GENERIC_IRQ_CHIP
|
||||
select IRQ_DOMAIN
|
||||
|
||||
config BRCMSTB_L2_IRQ
|
||||
bool
|
||||
depends on ARM
|
||||
select GENERIC_IRQ_CHIP
|
||||
select IRQ_DOMAIN
|
||||
|
||||
config DW_APB_ICTL
|
||||
bool
|
||||
select GENERIC_IRQ_CHIP
|
||||
select IRQ_DOMAIN
|
||||
|
||||
config IMGPDC_IRQ
|
||||
|
|
|
|||
|
|
@ -35,6 +35,6 @@ obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o
|
|||
obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o
|
||||
obj-$(CONFIG_XTENSA_MX) += irq-xtensa-mx.o
|
||||
obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o
|
||||
obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o \
|
||||
irq-bcm7120-l2.o
|
||||
obj-$(CONFIG_BCM7120_L2_IRQ) += irq-bcm7120-l2.o
|
||||
obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o
|
||||
obj-$(CONFIG_KEYSTONE_IRQ) += irq-keystone.o
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ static int armada_xp_set_affinity(struct irq_data *d,
|
|||
writel(reg, main_int_base + ARMADA_370_XP_INT_SOURCE_CTL(hwirq));
|
||||
raw_spin_unlock(&irq_controller_lock);
|
||||
|
||||
return 0;
|
||||
return IRQ_SET_MASK_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -167,6 +167,32 @@ void __init aic_common_rtc_irq_fixup(struct device_node *root)
|
|||
iounmap(regs);
|
||||
}
|
||||
|
||||
#define AT91_RTT_MR 0x00 /* Real-time Mode Register */
|
||||
#define AT91_RTT_ALMIEN (1 << 16) /* Alarm Interrupt Enable */
|
||||
#define AT91_RTT_RTTINCIEN (1 << 17) /* Real Time Timer Increment Interrupt Enable */
|
||||
|
||||
void __init aic_common_rtt_irq_fixup(struct device_node *root)
|
||||
{
|
||||
struct device_node *np;
|
||||
void __iomem *regs;
|
||||
|
||||
/*
|
||||
* The at91sam9263 SoC has 2 instances of the RTT block, hence we
|
||||
* iterate over the DT to find each occurrence.
|
||||
*/
|
||||
for_each_compatible_node(np, NULL, "atmel,at91sam9260-rtt") {
|
||||
regs = of_iomap(np, 0);
|
||||
if (!regs)
|
||||
continue;
|
||||
|
||||
writel(readl(regs + AT91_RTT_MR) &
|
||||
~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN),
|
||||
regs + AT91_RTT_MR);
|
||||
|
||||
iounmap(regs);
|
||||
}
|
||||
}
|
||||
|
||||
void __init aic_common_irq_fixup(const struct of_device_id *matches)
|
||||
{
|
||||
struct device_node *root = of_find_node_by_path("/");
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ struct irq_domain *__init aic_common_of_init(struct device_node *node,
|
|||
|
||||
void __init aic_common_rtc_irq_fixup(struct device_node *root);
|
||||
|
||||
void __init aic_common_rtt_irq_fixup(struct device_node *root);
|
||||
|
||||
void __init aic_common_irq_fixup(const struct of_device_id *matches);
|
||||
|
||||
#endif /* __IRQ_ATMEL_AIC_COMMON_H */
|
||||
|
|
|
|||
|
|
@ -65,11 +65,11 @@ aic_handle(struct pt_regs *regs)
|
|||
u32 irqnr;
|
||||
u32 irqstat;
|
||||
|
||||
irqnr = irq_reg_readl(gc->reg_base + AT91_AIC_IVR);
|
||||
irqstat = irq_reg_readl(gc->reg_base + AT91_AIC_ISR);
|
||||
irqnr = irq_reg_readl(gc, AT91_AIC_IVR);
|
||||
irqstat = irq_reg_readl(gc, AT91_AIC_ISR);
|
||||
|
||||
if (!irqstat)
|
||||
irq_reg_writel(0, gc->reg_base + AT91_AIC_EOICR);
|
||||
irq_reg_writel(gc, 0, AT91_AIC_EOICR);
|
||||
else
|
||||
handle_domain_irq(aic_domain, irqnr, regs);
|
||||
}
|
||||
|
|
@ -80,7 +80,7 @@ static int aic_retrigger(struct irq_data *d)
|
|||
|
||||
/* Enable interrupt on AIC5 */
|
||||
irq_gc_lock(gc);
|
||||
irq_reg_writel(d->mask, gc->reg_base + AT91_AIC_ISCR);
|
||||
irq_reg_writel(gc, d->mask, AT91_AIC_ISCR);
|
||||
irq_gc_unlock(gc);
|
||||
|
||||
return 0;
|
||||
|
|
@ -92,12 +92,12 @@ static int aic_set_type(struct irq_data *d, unsigned type)
|
|||
unsigned int smr;
|
||||
int ret;
|
||||
|
||||
smr = irq_reg_readl(gc->reg_base + AT91_AIC_SMR(d->hwirq));
|
||||
smr = irq_reg_readl(gc, AT91_AIC_SMR(d->hwirq));
|
||||
ret = aic_common_set_type(d, type, &smr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
irq_reg_writel(smr, gc->reg_base + AT91_AIC_SMR(d->hwirq));
|
||||
irq_reg_writel(gc, smr, AT91_AIC_SMR(d->hwirq));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -108,8 +108,8 @@ static void aic_suspend(struct irq_data *d)
|
|||
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
|
||||
|
||||
irq_gc_lock(gc);
|
||||
irq_reg_writel(gc->mask_cache, gc->reg_base + AT91_AIC_IDCR);
|
||||
irq_reg_writel(gc->wake_active, gc->reg_base + AT91_AIC_IECR);
|
||||
irq_reg_writel(gc, gc->mask_cache, AT91_AIC_IDCR);
|
||||
irq_reg_writel(gc, gc->wake_active, AT91_AIC_IECR);
|
||||
irq_gc_unlock(gc);
|
||||
}
|
||||
|
||||
|
|
@ -118,8 +118,8 @@ static void aic_resume(struct irq_data *d)
|
|||
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
|
||||
|
||||
irq_gc_lock(gc);
|
||||
irq_reg_writel(gc->wake_active, gc->reg_base + AT91_AIC_IDCR);
|
||||
irq_reg_writel(gc->mask_cache, gc->reg_base + AT91_AIC_IECR);
|
||||
irq_reg_writel(gc, gc->wake_active, AT91_AIC_IDCR);
|
||||
irq_reg_writel(gc, gc->mask_cache, AT91_AIC_IECR);
|
||||
irq_gc_unlock(gc);
|
||||
}
|
||||
|
||||
|
|
@ -128,8 +128,8 @@ static void aic_pm_shutdown(struct irq_data *d)
|
|||
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
|
||||
|
||||
irq_gc_lock(gc);
|
||||
irq_reg_writel(0xffffffff, gc->reg_base + AT91_AIC_IDCR);
|
||||
irq_reg_writel(0xffffffff, gc->reg_base + AT91_AIC_ICCR);
|
||||
irq_reg_writel(gc, 0xffffffff, AT91_AIC_IDCR);
|
||||
irq_reg_writel(gc, 0xffffffff, AT91_AIC_ICCR);
|
||||
irq_gc_unlock(gc);
|
||||
}
|
||||
#else
|
||||
|
|
@ -148,24 +148,24 @@ static void __init aic_hw_init(struct irq_domain *domain)
|
|||
* will not Lock out nIRQ
|
||||
*/
|
||||
for (i = 0; i < 8; i++)
|
||||
irq_reg_writel(0, gc->reg_base + AT91_AIC_EOICR);
|
||||
irq_reg_writel(gc, 0, AT91_AIC_EOICR);
|
||||
|
||||
/*
|
||||
* Spurious Interrupt ID in Spurious Vector Register.
|
||||
* When there is no current interrupt, the IRQ Vector Register
|
||||
* reads the value stored in AIC_SPU
|
||||
*/
|
||||
irq_reg_writel(0xffffffff, gc->reg_base + AT91_AIC_SPU);
|
||||
irq_reg_writel(gc, 0xffffffff, AT91_AIC_SPU);
|
||||
|
||||
/* No debugging in AIC: Debug (Protect) Control Register */
|
||||
irq_reg_writel(0, gc->reg_base + AT91_AIC_DCR);
|
||||
irq_reg_writel(gc, 0, AT91_AIC_DCR);
|
||||
|
||||
/* Disable and clear all interrupts initially */
|
||||
irq_reg_writel(0xffffffff, gc->reg_base + AT91_AIC_IDCR);
|
||||
irq_reg_writel(0xffffffff, gc->reg_base + AT91_AIC_ICCR);
|
||||
irq_reg_writel(gc, 0xffffffff, AT91_AIC_IDCR);
|
||||
irq_reg_writel(gc, 0xffffffff, AT91_AIC_ICCR);
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
irq_reg_writel(i, gc->reg_base + AT91_AIC_SVR(i));
|
||||
irq_reg_writel(gc, i, AT91_AIC_SVR(i));
|
||||
}
|
||||
|
||||
static int aic_irq_domain_xlate(struct irq_domain *d,
|
||||
|
|
@ -195,10 +195,10 @@ static int aic_irq_domain_xlate(struct irq_domain *d,
|
|||
gc = dgc->gc[idx];
|
||||
|
||||
irq_gc_lock(gc);
|
||||
smr = irq_reg_readl(gc->reg_base + AT91_AIC_SMR(*out_hwirq));
|
||||
smr = irq_reg_readl(gc, AT91_AIC_SMR(*out_hwirq));
|
||||
ret = aic_common_set_priority(intspec[2], &smr);
|
||||
if (!ret)
|
||||
irq_reg_writel(smr, gc->reg_base + AT91_AIC_SMR(*out_hwirq));
|
||||
irq_reg_writel(gc, smr, AT91_AIC_SMR(*out_hwirq));
|
||||
irq_gc_unlock(gc);
|
||||
|
||||
return ret;
|
||||
|
|
@ -209,16 +209,32 @@ static const struct irq_domain_ops aic_irq_ops = {
|
|||
.xlate = aic_irq_domain_xlate,
|
||||
};
|
||||
|
||||
static void __init at91sam9_aic_irq_fixup(struct device_node *root)
|
||||
static void __init at91rm9200_aic_irq_fixup(struct device_node *root)
|
||||
{
|
||||
aic_common_rtc_irq_fixup(root);
|
||||
}
|
||||
|
||||
static void __init at91sam9260_aic_irq_fixup(struct device_node *root)
|
||||
{
|
||||
aic_common_rtt_irq_fixup(root);
|
||||
}
|
||||
|
||||
static void __init at91sam9g45_aic_irq_fixup(struct device_node *root)
|
||||
{
|
||||
aic_common_rtc_irq_fixup(root);
|
||||
aic_common_rtt_irq_fixup(root);
|
||||
}
|
||||
|
||||
static const struct of_device_id __initdata aic_irq_fixups[] = {
|
||||
{ .compatible = "atmel,at91sam9g45", .data = at91sam9_aic_irq_fixup },
|
||||
{ .compatible = "atmel,at91sam9n12", .data = at91sam9_aic_irq_fixup },
|
||||
{ .compatible = "atmel,at91sam9rl", .data = at91sam9_aic_irq_fixup },
|
||||
{ .compatible = "atmel,at91sam9x5", .data = at91sam9_aic_irq_fixup },
|
||||
{ .compatible = "atmel,at91rm9200", .data = at91rm9200_aic_irq_fixup },
|
||||
{ .compatible = "atmel,at91sam9g45", .data = at91sam9g45_aic_irq_fixup },
|
||||
{ .compatible = "atmel,at91sam9n12", .data = at91rm9200_aic_irq_fixup },
|
||||
{ .compatible = "atmel,at91sam9rl", .data = at91sam9g45_aic_irq_fixup },
|
||||
{ .compatible = "atmel,at91sam9x5", .data = at91rm9200_aic_irq_fixup },
|
||||
{ .compatible = "atmel,at91sam9260", .data = at91sam9260_aic_irq_fixup },
|
||||
{ .compatible = "atmel,at91sam9261", .data = at91sam9260_aic_irq_fixup },
|
||||
{ .compatible = "atmel,at91sam9263", .data = at91sam9260_aic_irq_fixup },
|
||||
{ .compatible = "atmel,at91sam9g20", .data = at91sam9260_aic_irq_fixup },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -75,11 +75,11 @@ aic5_handle(struct pt_regs *regs)
|
|||
u32 irqnr;
|
||||
u32 irqstat;
|
||||
|
||||
irqnr = irq_reg_readl(gc->reg_base + AT91_AIC5_IVR);
|
||||
irqstat = irq_reg_readl(gc->reg_base + AT91_AIC5_ISR);
|
||||
irqnr = irq_reg_readl(gc, AT91_AIC5_IVR);
|
||||
irqstat = irq_reg_readl(gc, AT91_AIC5_ISR);
|
||||
|
||||
if (!irqstat)
|
||||
irq_reg_writel(0, gc->reg_base + AT91_AIC5_EOICR);
|
||||
irq_reg_writel(gc, 0, AT91_AIC5_EOICR);
|
||||
else
|
||||
handle_domain_irq(aic5_domain, irqnr, regs);
|
||||
}
|
||||
|
|
@ -92,8 +92,8 @@ static void aic5_mask(struct irq_data *d)
|
|||
|
||||
/* Disable interrupt on AIC5 */
|
||||
irq_gc_lock(gc);
|
||||
irq_reg_writel(d->hwirq, gc->reg_base + AT91_AIC5_SSR);
|
||||
irq_reg_writel(1, gc->reg_base + AT91_AIC5_IDCR);
|
||||
irq_reg_writel(gc, d->hwirq, AT91_AIC5_SSR);
|
||||
irq_reg_writel(gc, 1, AT91_AIC5_IDCR);
|
||||
gc->mask_cache &= ~d->mask;
|
||||
irq_gc_unlock(gc);
|
||||
}
|
||||
|
|
@ -106,8 +106,8 @@ static void aic5_unmask(struct irq_data *d)
|
|||
|
||||
/* Enable interrupt on AIC5 */
|
||||
irq_gc_lock(gc);
|
||||
irq_reg_writel(d->hwirq, gc->reg_base + AT91_AIC5_SSR);
|
||||
irq_reg_writel(1, gc->reg_base + AT91_AIC5_IECR);
|
||||
irq_reg_writel(gc, d->hwirq, AT91_AIC5_SSR);
|
||||
irq_reg_writel(gc, 1, AT91_AIC5_IECR);
|
||||
gc->mask_cache |= d->mask;
|
||||
irq_gc_unlock(gc);
|
||||
}
|
||||
|
|
@ -120,8 +120,8 @@ static int aic5_retrigger(struct irq_data *d)
|
|||
|
||||
/* Enable interrupt on AIC5 */
|
||||
irq_gc_lock(gc);
|
||||
irq_reg_writel(d->hwirq, gc->reg_base + AT91_AIC5_SSR);
|
||||
irq_reg_writel(1, gc->reg_base + AT91_AIC5_ISCR);
|
||||
irq_reg_writel(gc, d->hwirq, AT91_AIC5_SSR);
|
||||
irq_reg_writel(gc, 1, AT91_AIC5_ISCR);
|
||||
irq_gc_unlock(gc);
|
||||
|
||||
return 0;
|
||||
|
|
@ -136,11 +136,11 @@ static int aic5_set_type(struct irq_data *d, unsigned type)
|
|||
int ret;
|
||||
|
||||
irq_gc_lock(gc);
|
||||
irq_reg_writel(d->hwirq, gc->reg_base + AT91_AIC5_SSR);
|
||||
smr = irq_reg_readl(gc->reg_base + AT91_AIC5_SMR);
|
||||
irq_reg_writel(gc, d->hwirq, AT91_AIC5_SSR);
|
||||
smr = irq_reg_readl(gc, AT91_AIC5_SMR);
|
||||
ret = aic_common_set_type(d, type, &smr);
|
||||
if (!ret)
|
||||
irq_reg_writel(smr, gc->reg_base + AT91_AIC5_SMR);
|
||||
irq_reg_writel(gc, smr, AT91_AIC5_SMR);
|
||||
irq_gc_unlock(gc);
|
||||
|
||||
return ret;
|
||||
|
|
@ -162,12 +162,11 @@ static void aic5_suspend(struct irq_data *d)
|
|||
if ((mask & gc->mask_cache) == (mask & gc->wake_active))
|
||||
continue;
|
||||
|
||||
irq_reg_writel(i + gc->irq_base,
|
||||
bgc->reg_base + AT91_AIC5_SSR);
|
||||
irq_reg_writel(bgc, i + gc->irq_base, AT91_AIC5_SSR);
|
||||
if (mask & gc->wake_active)
|
||||
irq_reg_writel(1, bgc->reg_base + AT91_AIC5_IECR);
|
||||
irq_reg_writel(bgc, 1, AT91_AIC5_IECR);
|
||||
else
|
||||
irq_reg_writel(1, bgc->reg_base + AT91_AIC5_IDCR);
|
||||
irq_reg_writel(bgc, 1, AT91_AIC5_IDCR);
|
||||
}
|
||||
irq_gc_unlock(bgc);
|
||||
}
|
||||
|
|
@ -187,12 +186,11 @@ static void aic5_resume(struct irq_data *d)
|
|||
if ((mask & gc->mask_cache) == (mask & gc->wake_active))
|
||||
continue;
|
||||
|
||||
irq_reg_writel(i + gc->irq_base,
|
||||
bgc->reg_base + AT91_AIC5_SSR);
|
||||
irq_reg_writel(bgc, i + gc->irq_base, AT91_AIC5_SSR);
|
||||
if (mask & gc->mask_cache)
|
||||
irq_reg_writel(1, bgc->reg_base + AT91_AIC5_IECR);
|
||||
irq_reg_writel(bgc, 1, AT91_AIC5_IECR);
|
||||
else
|
||||
irq_reg_writel(1, bgc->reg_base + AT91_AIC5_IDCR);
|
||||
irq_reg_writel(bgc, 1, AT91_AIC5_IDCR);
|
||||
}
|
||||
irq_gc_unlock(bgc);
|
||||
}
|
||||
|
|
@ -207,10 +205,9 @@ static void aic5_pm_shutdown(struct irq_data *d)
|
|||
|
||||
irq_gc_lock(bgc);
|
||||
for (i = 0; i < dgc->irqs_per_chip; i++) {
|
||||
irq_reg_writel(i + gc->irq_base,
|
||||
bgc->reg_base + AT91_AIC5_SSR);
|
||||
irq_reg_writel(1, bgc->reg_base + AT91_AIC5_IDCR);
|
||||
irq_reg_writel(1, bgc->reg_base + AT91_AIC5_ICCR);
|
||||
irq_reg_writel(bgc, i + gc->irq_base, AT91_AIC5_SSR);
|
||||
irq_reg_writel(bgc, 1, AT91_AIC5_IDCR);
|
||||
irq_reg_writel(bgc, 1, AT91_AIC5_ICCR);
|
||||
}
|
||||
irq_gc_unlock(bgc);
|
||||
}
|
||||
|
|
@ -230,24 +227,24 @@ static void __init aic5_hw_init(struct irq_domain *domain)
|
|||
* will not Lock out nIRQ
|
||||
*/
|
||||
for (i = 0; i < 8; i++)
|
||||
irq_reg_writel(0, gc->reg_base + AT91_AIC5_EOICR);
|
||||
irq_reg_writel(gc, 0, AT91_AIC5_EOICR);
|
||||
|
||||
/*
|
||||
* Spurious Interrupt ID in Spurious Vector Register.
|
||||
* When there is no current interrupt, the IRQ Vector Register
|
||||
* reads the value stored in AIC_SPU
|
||||
*/
|
||||
irq_reg_writel(0xffffffff, gc->reg_base + AT91_AIC5_SPU);
|
||||
irq_reg_writel(gc, 0xffffffff, AT91_AIC5_SPU);
|
||||
|
||||
/* No debugging in AIC: Debug (Protect) Control Register */
|
||||
irq_reg_writel(0, gc->reg_base + AT91_AIC5_DCR);
|
||||
irq_reg_writel(gc, 0, AT91_AIC5_DCR);
|
||||
|
||||
/* Disable and clear all interrupts initially */
|
||||
for (i = 0; i < domain->revmap_size; i++) {
|
||||
irq_reg_writel(i, gc->reg_base + AT91_AIC5_SSR);
|
||||
irq_reg_writel(i, gc->reg_base + AT91_AIC5_SVR);
|
||||
irq_reg_writel(1, gc->reg_base + AT91_AIC5_IDCR);
|
||||
irq_reg_writel(1, gc->reg_base + AT91_AIC5_ICCR);
|
||||
irq_reg_writel(gc, i, AT91_AIC5_SSR);
|
||||
irq_reg_writel(gc, i, AT91_AIC5_SVR);
|
||||
irq_reg_writel(gc, 1, AT91_AIC5_IDCR);
|
||||
irq_reg_writel(gc, 1, AT91_AIC5_ICCR);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -273,11 +270,11 @@ static int aic5_irq_domain_xlate(struct irq_domain *d,
|
|||
gc = dgc->gc[0];
|
||||
|
||||
irq_gc_lock(gc);
|
||||
irq_reg_writel(*out_hwirq, gc->reg_base + AT91_AIC5_SSR);
|
||||
smr = irq_reg_readl(gc->reg_base + AT91_AIC5_SMR);
|
||||
irq_reg_writel(gc, *out_hwirq, AT91_AIC5_SSR);
|
||||
smr = irq_reg_readl(gc, AT91_AIC5_SMR);
|
||||
ret = aic_common_set_priority(intspec[2], &smr);
|
||||
if (!ret)
|
||||
irq_reg_writel(intspec[2] | smr, gc->reg_base + AT91_AIC5_SMR);
|
||||
irq_reg_writel(gc, intspec[2] | smr, AT91_AIC5_SMR);
|
||||
irq_gc_unlock(gc);
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_irq.h>
|
||||
|
|
@ -23,47 +24,52 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/irqchip/chained_irq.h>
|
||||
|
||||
#include "irqchip.h"
|
||||
|
||||
#include <asm/mach/irq.h>
|
||||
|
||||
/* Register offset in the L2 interrupt controller */
|
||||
#define IRQEN 0x00
|
||||
#define IRQSTAT 0x04
|
||||
|
||||
#define MAX_WORDS 4
|
||||
#define IRQS_PER_WORD 32
|
||||
|
||||
struct bcm7120_l2_intc_data {
|
||||
void __iomem *base;
|
||||
unsigned int n_words;
|
||||
void __iomem *base[MAX_WORDS];
|
||||
struct irq_domain *domain;
|
||||
bool can_wake;
|
||||
u32 irq_fwd_mask;
|
||||
u32 irq_map_mask;
|
||||
u32 saved_mask;
|
||||
u32 irq_fwd_mask[MAX_WORDS];
|
||||
u32 irq_map_mask[MAX_WORDS];
|
||||
};
|
||||
|
||||
static void bcm7120_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
struct bcm7120_l2_intc_data *b = irq_desc_get_handler_data(desc);
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
u32 status;
|
||||
unsigned int idx;
|
||||
|
||||
chained_irq_enter(chip, desc);
|
||||
|
||||
status = __raw_readl(b->base + IRQSTAT);
|
||||
for (idx = 0; idx < b->n_words; idx++) {
|
||||
int base = idx * IRQS_PER_WORD;
|
||||
struct irq_chip_generic *gc =
|
||||
irq_get_domain_generic_chip(b->domain, base);
|
||||
unsigned long pending;
|
||||
int hwirq;
|
||||
|
||||
if (status == 0) {
|
||||
do_bad_IRQ(irq, desc);
|
||||
goto out;
|
||||
irq_gc_lock(gc);
|
||||
pending = irq_reg_readl(gc, IRQSTAT) & gc->mask_cache;
|
||||
irq_gc_unlock(gc);
|
||||
|
||||
for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) {
|
||||
generic_handle_irq(irq_find_mapping(b->domain,
|
||||
base + hwirq));
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
irq = ffs(status) - 1;
|
||||
status &= ~(1 << irq);
|
||||
generic_handle_irq(irq_find_mapping(b->domain, irq));
|
||||
} while (status);
|
||||
|
||||
out:
|
||||
chained_irq_exit(chip, desc);
|
||||
}
|
||||
|
||||
|
|
@ -71,26 +77,20 @@ static void bcm7120_l2_intc_suspend(struct irq_data *d)
|
|||
{
|
||||
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
|
||||
struct bcm7120_l2_intc_data *b = gc->private;
|
||||
u32 reg;
|
||||
|
||||
irq_gc_lock(gc);
|
||||
/* Save the current mask and the interrupt forward mask */
|
||||
b->saved_mask = __raw_readl(b->base) | b->irq_fwd_mask;
|
||||
if (b->can_wake) {
|
||||
reg = b->saved_mask | gc->wake_active;
|
||||
__raw_writel(reg, b->base);
|
||||
}
|
||||
if (b->can_wake)
|
||||
irq_reg_writel(gc, gc->mask_cache | gc->wake_active, IRQEN);
|
||||
irq_gc_unlock(gc);
|
||||
}
|
||||
|
||||
static void bcm7120_l2_intc_resume(struct irq_data *d)
|
||||
{
|
||||
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
|
||||
struct bcm7120_l2_intc_data *b = gc->private;
|
||||
|
||||
/* Restore the saved mask */
|
||||
irq_gc_lock(gc);
|
||||
__raw_writel(b->saved_mask, b->base);
|
||||
irq_reg_writel(gc, gc->mask_cache, IRQEN);
|
||||
irq_gc_unlock(gc);
|
||||
}
|
||||
|
||||
|
|
@ -99,6 +99,7 @@ static int bcm7120_l2_intc_init_one(struct device_node *dn,
|
|||
int irq, const __be32 *map_mask)
|
||||
{
|
||||
int parent_irq;
|
||||
unsigned int idx;
|
||||
|
||||
parent_irq = irq_of_parse_and_map(dn, irq);
|
||||
if (!parent_irq) {
|
||||
|
|
@ -106,7 +107,12 @@ static int bcm7120_l2_intc_init_one(struct device_node *dn,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
data->irq_map_mask |= be32_to_cpup(map_mask + irq);
|
||||
/* For multiple parent IRQs with multiple words, this looks like:
|
||||
* <irq0_w0 irq0_w1 irq1_w0 irq1_w1 ...>
|
||||
*/
|
||||
for (idx = 0; idx < data->n_words; idx++)
|
||||
data->irq_map_mask[idx] |=
|
||||
be32_to_cpup(map_mask + irq * data->n_words + idx);
|
||||
|
||||
irq_set_handler_data(parent_irq, data);
|
||||
irq_set_chained_handler(parent_irq, bcm7120_l2_intc_irq_handle);
|
||||
|
|
@ -123,26 +129,41 @@ int __init bcm7120_l2_intc_of_init(struct device_node *dn,
|
|||
struct irq_chip_type *ct;
|
||||
const __be32 *map_mask;
|
||||
int num_parent_irqs;
|
||||
int ret = 0, len, irq;
|
||||
int ret = 0, len;
|
||||
unsigned int idx, irq, flags;
|
||||
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
data->base = of_iomap(dn, 0);
|
||||
if (!data->base) {
|
||||
for (idx = 0; idx < MAX_WORDS; idx++) {
|
||||
data->base[idx] = of_iomap(dn, idx);
|
||||
if (!data->base[idx])
|
||||
break;
|
||||
data->n_words = idx + 1;
|
||||
}
|
||||
if (!data->n_words) {
|
||||
pr_err("failed to remap intc L2 registers\n");
|
||||
ret = -ENOMEM;
|
||||
goto out_free;
|
||||
goto out_unmap;
|
||||
}
|
||||
|
||||
if (of_property_read_u32(dn, "brcm,int-fwd-mask", &data->irq_fwd_mask))
|
||||
data->irq_fwd_mask = 0;
|
||||
|
||||
/* Enable all interrupt specified in the interrupt forward mask and have
|
||||
* the other disabled
|
||||
/* Enable all interrupts specified in the interrupt forward mask;
|
||||
* disable all others. If the property doesn't exist (-EINVAL),
|
||||
* assume all zeroes.
|
||||
*/
|
||||
__raw_writel(data->irq_fwd_mask, data->base + IRQEN);
|
||||
ret = of_property_read_u32_array(dn, "brcm,int-fwd-mask",
|
||||
data->irq_fwd_mask, data->n_words);
|
||||
if (ret == 0 || ret == -EINVAL) {
|
||||
for (idx = 0; idx < data->n_words; idx++)
|
||||
__raw_writel(data->irq_fwd_mask[idx],
|
||||
data->base[idx] + IRQEN);
|
||||
} else {
|
||||
/* property exists but has the wrong number of words */
|
||||
pr_err("invalid int-fwd-mask property\n");
|
||||
ret = -EINVAL;
|
||||
goto out_unmap;
|
||||
}
|
||||
|
||||
num_parent_irqs = of_irq_count(dn);
|
||||
if (num_parent_irqs <= 0) {
|
||||
|
|
@ -152,7 +173,8 @@ int __init bcm7120_l2_intc_of_init(struct device_node *dn,
|
|||
}
|
||||
|
||||
map_mask = of_get_property(dn, "brcm,int-map-mask", &len);
|
||||
if (!map_mask || (len != (sizeof(*map_mask) * num_parent_irqs))) {
|
||||
if (!map_mask ||
|
||||
(len != (sizeof(*map_mask) * num_parent_irqs * data->n_words))) {
|
||||
pr_err("invalid brcm,int-map-mask property\n");
|
||||
ret = -EINVAL;
|
||||
goto out_unmap;
|
||||
|
|
@ -164,56 +186,70 @@ int __init bcm7120_l2_intc_of_init(struct device_node *dn,
|
|||
goto out_unmap;
|
||||
}
|
||||
|
||||
data->domain = irq_domain_add_linear(dn, 32,
|
||||
&irq_generic_chip_ops, NULL);
|
||||
data->domain = irq_domain_add_linear(dn, IRQS_PER_WORD * data->n_words,
|
||||
&irq_generic_chip_ops, NULL);
|
||||
if (!data->domain) {
|
||||
ret = -ENOMEM;
|
||||
goto out_unmap;
|
||||
}
|
||||
|
||||
ret = irq_alloc_domain_generic_chips(data->domain, 32, 1,
|
||||
dn->full_name, handle_level_irq, clr, 0,
|
||||
IRQ_GC_INIT_MASK_CACHE);
|
||||
/* MIPS chips strapped for BE will automagically configure the
|
||||
* peripheral registers for CPU-native byte order.
|
||||
*/
|
||||
flags = IRQ_GC_INIT_MASK_CACHE;
|
||||
if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
|
||||
flags |= IRQ_GC_BE_IO;
|
||||
|
||||
ret = irq_alloc_domain_generic_chips(data->domain, IRQS_PER_WORD, 1,
|
||||
dn->full_name, handle_level_irq, clr, 0, flags);
|
||||
if (ret) {
|
||||
pr_err("failed to allocate generic irq chip\n");
|
||||
goto out_free_domain;
|
||||
}
|
||||
|
||||
gc = irq_get_domain_generic_chip(data->domain, 0);
|
||||
gc->unused = 0xfffffff & ~data->irq_map_mask;
|
||||
gc->reg_base = data->base;
|
||||
gc->private = data;
|
||||
ct = gc->chip_types;
|
||||
|
||||
ct->regs.mask = IRQEN;
|
||||
ct->chip.irq_mask = irq_gc_mask_clr_bit;
|
||||
ct->chip.irq_unmask = irq_gc_mask_set_bit;
|
||||
ct->chip.irq_ack = irq_gc_noop;
|
||||
ct->chip.irq_suspend = bcm7120_l2_intc_suspend;
|
||||
ct->chip.irq_resume = bcm7120_l2_intc_resume;
|
||||
|
||||
if (of_property_read_bool(dn, "brcm,irq-can-wake")) {
|
||||
if (of_property_read_bool(dn, "brcm,irq-can-wake"))
|
||||
data->can_wake = true;
|
||||
/* This IRQ chip can wake the system, set all relevant child
|
||||
* interupts in wake_enabled mask
|
||||
*/
|
||||
gc->wake_enabled = 0xffffffff;
|
||||
gc->wake_enabled &= ~gc->unused;
|
||||
ct->chip.irq_set_wake = irq_gc_set_wake;
|
||||
|
||||
for (idx = 0; idx < data->n_words; idx++) {
|
||||
irq = idx * IRQS_PER_WORD;
|
||||
gc = irq_get_domain_generic_chip(data->domain, irq);
|
||||
|
||||
gc->unused = 0xffffffff & ~data->irq_map_mask[idx];
|
||||
gc->reg_base = data->base[idx];
|
||||
gc->private = data;
|
||||
ct = gc->chip_types;
|
||||
|
||||
ct->regs.mask = IRQEN;
|
||||
ct->chip.irq_mask = irq_gc_mask_clr_bit;
|
||||
ct->chip.irq_unmask = irq_gc_mask_set_bit;
|
||||
ct->chip.irq_ack = irq_gc_noop;
|
||||
ct->chip.irq_suspend = bcm7120_l2_intc_suspend;
|
||||
ct->chip.irq_resume = bcm7120_l2_intc_resume;
|
||||
|
||||
if (data->can_wake) {
|
||||
/* This IRQ chip can wake the system, set all
|
||||
* relevant child interupts in wake_enabled mask
|
||||
*/
|
||||
gc->wake_enabled = 0xffffffff;
|
||||
gc->wake_enabled &= ~gc->unused;
|
||||
ct->chip.irq_set_wake = irq_gc_set_wake;
|
||||
}
|
||||
}
|
||||
|
||||
pr_info("registered BCM7120 L2 intc (mem: 0x%p, parent IRQ(s): %d)\n",
|
||||
data->base, num_parent_irqs);
|
||||
data->base[0], num_parent_irqs);
|
||||
|
||||
return 0;
|
||||
|
||||
out_free_domain:
|
||||
irq_domain_remove(data->domain);
|
||||
out_unmap:
|
||||
iounmap(data->base);
|
||||
out_free:
|
||||
for (idx = 0; idx < MAX_WORDS; idx++) {
|
||||
if (data->base[idx])
|
||||
iounmap(data->base[idx]);
|
||||
}
|
||||
kfree(data);
|
||||
return ret;
|
||||
}
|
||||
IRQCHIP_DECLARE(brcmstb_l2_intc, "brcm,bcm7120-l2-intc",
|
||||
IRQCHIP_DECLARE(bcm7120_l2_intc, "brcm,bcm7120-l2-intc",
|
||||
bcm7120_l2_intc_of_init);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_address.h>
|
||||
|
|
@ -30,8 +32,6 @@
|
|||
#include <linux/irqchip.h>
|
||||
#include <linux/irqchip/chained_irq.h>
|
||||
|
||||
#include <asm/mach/irq.h>
|
||||
|
||||
#include "irqchip.h"
|
||||
|
||||
/* Register offsets in the L2 interrupt controller */
|
||||
|
|
@ -54,23 +54,26 @@ struct brcmstb_l2_intc_data {
|
|||
static void brcmstb_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
struct brcmstb_l2_intc_data *b = irq_desc_get_handler_data(desc);
|
||||
struct irq_chip_generic *gc = irq_get_domain_generic_chip(b->domain, 0);
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
u32 status;
|
||||
|
||||
chained_irq_enter(chip, desc);
|
||||
|
||||
status = __raw_readl(b->base + CPU_STATUS) &
|
||||
~(__raw_readl(b->base + CPU_MASK_STATUS));
|
||||
status = irq_reg_readl(gc, CPU_STATUS) &
|
||||
~(irq_reg_readl(gc, CPU_MASK_STATUS));
|
||||
|
||||
if (status == 0) {
|
||||
do_bad_IRQ(irq, desc);
|
||||
raw_spin_lock(&desc->lock);
|
||||
handle_bad_irq(irq, desc);
|
||||
raw_spin_unlock(&desc->lock);
|
||||
goto out;
|
||||
}
|
||||
|
||||
do {
|
||||
irq = ffs(status) - 1;
|
||||
/* ack at our level */
|
||||
__raw_writel(1 << irq, b->base + CPU_CLEAR);
|
||||
irq_reg_writel(gc, 1 << irq, CPU_CLEAR);
|
||||
status &= ~(1 << irq);
|
||||
generic_handle_irq(irq_find_mapping(b->domain, irq));
|
||||
} while (status);
|
||||
|
|
@ -85,12 +88,12 @@ static void brcmstb_l2_intc_suspend(struct irq_data *d)
|
|||
|
||||
irq_gc_lock(gc);
|
||||
/* Save the current mask */
|
||||
b->saved_mask = __raw_readl(b->base + CPU_MASK_STATUS);
|
||||
b->saved_mask = irq_reg_readl(gc, CPU_MASK_STATUS);
|
||||
|
||||
if (b->can_wake) {
|
||||
/* Program the wakeup mask */
|
||||
__raw_writel(~gc->wake_active, b->base + CPU_MASK_SET);
|
||||
__raw_writel(gc->wake_active, b->base + CPU_MASK_CLEAR);
|
||||
irq_reg_writel(gc, ~gc->wake_active, CPU_MASK_SET);
|
||||
irq_reg_writel(gc, gc->wake_active, CPU_MASK_CLEAR);
|
||||
}
|
||||
irq_gc_unlock(gc);
|
||||
}
|
||||
|
|
@ -102,11 +105,11 @@ static void brcmstb_l2_intc_resume(struct irq_data *d)
|
|||
|
||||
irq_gc_lock(gc);
|
||||
/* Clear unmasked non-wakeup interrupts */
|
||||
__raw_writel(~b->saved_mask & ~gc->wake_active, b->base + CPU_CLEAR);
|
||||
irq_reg_writel(gc, ~b->saved_mask & ~gc->wake_active, CPU_CLEAR);
|
||||
|
||||
/* Restore the saved mask */
|
||||
__raw_writel(b->saved_mask, b->base + CPU_MASK_SET);
|
||||
__raw_writel(~b->saved_mask, b->base + CPU_MASK_CLEAR);
|
||||
irq_reg_writel(gc, b->saved_mask, CPU_MASK_SET);
|
||||
irq_reg_writel(gc, ~b->saved_mask, CPU_MASK_CLEAR);
|
||||
irq_gc_unlock(gc);
|
||||
}
|
||||
|
||||
|
|
@ -118,6 +121,7 @@ int __init brcmstb_l2_intc_of_init(struct device_node *np,
|
|||
struct irq_chip_generic *gc;
|
||||
struct irq_chip_type *ct;
|
||||
int ret;
|
||||
unsigned int flags;
|
||||
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
|
|
@ -131,8 +135,8 @@ int __init brcmstb_l2_intc_of_init(struct device_node *np,
|
|||
}
|
||||
|
||||
/* Disable all interrupts by default */
|
||||
__raw_writel(0xffffffff, data->base + CPU_MASK_SET);
|
||||
__raw_writel(0xffffffff, data->base + CPU_CLEAR);
|
||||
writel(0xffffffff, data->base + CPU_MASK_SET);
|
||||
writel(0xffffffff, data->base + CPU_CLEAR);
|
||||
|
||||
data->parent_irq = irq_of_parse_and_map(np, 0);
|
||||
if (!data->parent_irq) {
|
||||
|
|
@ -148,9 +152,16 @@ int __init brcmstb_l2_intc_of_init(struct device_node *np,
|
|||
goto out_unmap;
|
||||
}
|
||||
|
||||
/* MIPS chips strapped for BE will automagically configure the
|
||||
* peripheral registers for CPU-native byte order.
|
||||
*/
|
||||
flags = 0;
|
||||
if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
|
||||
flags |= IRQ_GC_BE_IO;
|
||||
|
||||
/* Allocate a single Generic IRQ chip for this node */
|
||||
ret = irq_alloc_domain_generic_chips(data->domain, 32, 1,
|
||||
np->full_name, handle_edge_irq, clr, 0, 0);
|
||||
np->full_name, handle_edge_irq, clr, 0, flags);
|
||||
if (ret) {
|
||||
pr_err("failed to allocate generic irq chip\n");
|
||||
goto out_free_domain;
|
||||
|
|
|
|||
|
|
@ -50,6 +50,21 @@ static void dw_apb_ictl_handler(unsigned int irq, struct irq_desc *desc)
|
|||
chained_irq_exit(chip, desc);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static void dw_apb_ictl_resume(struct irq_data *d)
|
||||
{
|
||||
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
|
||||
struct irq_chip_type *ct = irq_data_get_chip_type(d);
|
||||
|
||||
irq_gc_lock(gc);
|
||||
writel_relaxed(~0, gc->reg_base + ct->regs.enable);
|
||||
writel_relaxed(*ct->mask_cache, gc->reg_base + ct->regs.mask);
|
||||
irq_gc_unlock(gc);
|
||||
}
|
||||
#else
|
||||
#define dw_apb_ictl_resume NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static int __init dw_apb_ictl_init(struct device_node *np,
|
||||
struct device_node *parent)
|
||||
{
|
||||
|
|
@ -94,16 +109,16 @@ static int __init dw_apb_ictl_init(struct device_node *np,
|
|||
*/
|
||||
|
||||
/* mask and enable all interrupts */
|
||||
writel(~0, iobase + APB_INT_MASK_L);
|
||||
writel(~0, iobase + APB_INT_MASK_H);
|
||||
writel(~0, iobase + APB_INT_ENABLE_L);
|
||||
writel(~0, iobase + APB_INT_ENABLE_H);
|
||||
writel_relaxed(~0, iobase + APB_INT_MASK_L);
|
||||
writel_relaxed(~0, iobase + APB_INT_MASK_H);
|
||||
writel_relaxed(~0, iobase + APB_INT_ENABLE_L);
|
||||
writel_relaxed(~0, iobase + APB_INT_ENABLE_H);
|
||||
|
||||
reg = readl(iobase + APB_INT_ENABLE_H);
|
||||
reg = readl_relaxed(iobase + APB_INT_ENABLE_H);
|
||||
if (reg)
|
||||
nrirqs = 32 + fls(reg);
|
||||
else
|
||||
nrirqs = fls(readl(iobase + APB_INT_ENABLE_L));
|
||||
nrirqs = fls(readl_relaxed(iobase + APB_INT_ENABLE_L));
|
||||
|
||||
domain = irq_domain_add_linear(np, nrirqs,
|
||||
&irq_generic_chip_ops, NULL);
|
||||
|
|
@ -115,6 +130,7 @@ static int __init dw_apb_ictl_init(struct device_node *np,
|
|||
|
||||
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 |
|
||||
IRQ_GC_INIT_MASK_CACHE);
|
||||
if (ret) {
|
||||
pr_err("%s: unable to alloc irq domain gc\n", np->full_name);
|
||||
|
|
@ -126,13 +142,17 @@ static int __init dw_apb_ictl_init(struct device_node *np,
|
|||
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;
|
||||
}
|
||||
|
||||
irq_set_handler_data(irq, gc);
|
||||
|
|
|
|||
|
|
@ -176,8 +176,7 @@ static void __exception_irq_entry hip04_handle_irq(struct pt_regs *regs)
|
|||
irqnr = irqstat & GICC_IAR_INT_ID_MASK;
|
||||
|
||||
if (likely(irqnr > 15 && irqnr <= HIP04_MAX_IRQS)) {
|
||||
irqnr = irq_find_mapping(hip04_data.domain, irqnr);
|
||||
handle_IRQ(irqnr, regs);
|
||||
handle_domain_irq(hip04_data.domain, irqnr, regs);
|
||||
continue;
|
||||
}
|
||||
if (irqnr < 16) {
|
||||
|
|
|
|||
|
|
@ -50,12 +50,12 @@ static struct sunxi_sc_nmi_reg_offs sun6i_reg_offs = {
|
|||
static inline void sunxi_sc_nmi_write(struct irq_chip_generic *gc, u32 off,
|
||||
u32 val)
|
||||
{
|
||||
irq_reg_writel(val, gc->reg_base + off);
|
||||
irq_reg_writel(gc, val, off);
|
||||
}
|
||||
|
||||
static inline u32 sunxi_sc_nmi_read(struct irq_chip_generic *gc, u32 off)
|
||||
{
|
||||
return irq_reg_readl(gc->reg_base + off);
|
||||
return irq_reg_readl(gc, off);
|
||||
}
|
||||
|
||||
static void sunxi_sc_nmi_handle_irq(unsigned int irq, struct irq_desc *desc)
|
||||
|
|
|
|||
|
|
@ -43,12 +43,12 @@
|
|||
static inline void ab_irqctl_writereg(struct irq_chip_generic *gc, u32 reg,
|
||||
u32 val)
|
||||
{
|
||||
irq_reg_writel(val, gc->reg_base + reg);
|
||||
irq_reg_writel(gc, val, reg);
|
||||
}
|
||||
|
||||
static inline u32 ab_irqctl_readreg(struct irq_chip_generic *gc, u32 reg)
|
||||
{
|
||||
return irq_reg_readl(gc->reg_base + reg);
|
||||
return irq_reg_readl(gc, reg);
|
||||
}
|
||||
|
||||
static int tb10x_irq_set_type(struct irq_data *data, unsigned int flow_type)
|
||||
|
|
|
|||
Loading…
Reference in a new issue