irqchip/mxs: Add support for ASM9260 interrupt controller
Subsystems (2)
cover irqchip/mxs: Add support for ASM9260 interrupt controller
I'm reposting this series from Oleksij before I apply it to give Shawn and Sascha an opportunity to review and test it on imx.
I moved the irqdomain panic part of Oleksij's patch 2 to patch 1 because it clearly belongs there. Other than that I merily massaged the changelogs a bit.
Timely feedback would be appreciated so the lot can bake in next.
Thanks,
tglx
PATCH 1/3 irqchip/mxs: Panic if ioremap or domain creation fails
From: Oleksij Rempel <[email protected]>
Current code will only warn and then dereference the NULL pointer or continue, which results in a fatal NULL pointer dereference later.
If the initialization fails, the machine is unusable, so panic right away.
[ tglx: Massaged changelog and picked the irqdomain panic from the
next patch]
--- drivers/irqchip/irq-mxs.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/irqchip/irq-mxs.c +6 -2
@@ -97,7 +97,8 @@ static int __init icoll_of_init(struct d struct device_node *interrupt_parent) { icoll_base =of_iomap (np,0 ); -WARN_ON (!icoll_base); +if (!icoll_base) +panic ("%s: unable to map resource" , np->full_name);/* * Interrupt Collector reset, which initializes the priority
@@ -107,6 +108,9 @@ static int __init icoll_of_init(struct d icoll_domain =irq_domain_add_linear (np,ICOLL_NUM_IRQS , &icoll_irq_domain_ops,NULL ); -return icoll_domain ?0 : -ENODEV ; +if (!icoll_domain) +panic ("%s: unable to create irqdomain" , np->full_name); + +return 0 ; }IRQCHIP_DECLARE (mxs,"fsl,icoll" , icoll_of_init);
PATCH 2/3 irqchip/mxs: Prepare driver for hardware with different offsets
In reply to Thomas GleixnerFrom: Oleksij Rempel <[email protected]>
Alphascale asm9260 has similar functionality but different register offsets. To support asm9260 in the mxs driver we need to rework the hardcoded access mechanisms.
- Define SET_REG and CLR_REG. These controllers support seperate CLR and SET offsets for each register.
- Reimplement HW_ICOLL_INTERRUPT with SET_REG and CLR_REG to make it usable for both cases.
- Instead of using icoll_base and adding the offsets at runtime, create a new data structure which contains base pointers to all required regitsters and use it.
- Split out functionality, which is required for the init code of mxs and asm9260, into helper functions
[ tglx: Massaged changelog and moved the return value change to the
previous patch ]
--- drivers/irqchip/irq-mxs.c | 78 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 59 insertions(+), 19 deletions(-)
drivers/irqchip/irq-mxs.c +59 -19
@@ -28,18 +28,36 @@#include <linux/stmp_device.h> #include <asm/exception.h> +/* +* this device provide 4 offsets for each register: +* 0x0 - plain read write mode +* 0x4 - set mode, OR logic. +* 0x8 - clr mode, XOR logic. +* 0xc - togle mode. +*/ +#define SET_REG 4 +#define CLR_REG 8 +#define HW_ICOLL_VECTOR 0x0000#define HW_ICOLL_LEVELACK 0x0010#define HW_ICOLL_CTRL 0x0020#define HW_ICOLL_STAT_OFFSET 0x0070 -#define HW_ICOLL_INTERRUPTn_SET (n) (0x0124 + (n) * 0x10) -#define HW_ICOLL_INTERRUPTn_CLR (n) (0x0128 + (n) * 0x10) -#define BM_ICOLL_INTERRUPTn_ENABLE 0x00000004 +#define HW_ICOLL_INTERRUPT0 0x0120 +#define HW_ICOLL_INTERRUPTn (n) ((n) * 0x10) +#define BM_ICOLL_INTR_ENABLE BIT(2)#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 0x1#define ICOLL_NUM_IRQS 128 -static void __iomem *icoll_base; +struct icoll_priv { +void __iomem *vector; +void __iomem *levelack; +void __iomem *ctrl; +void __iomem *stat; +void __iomem *intr; +}; + +static struct icoll_priv icoll_priv;static struct irq_domain *icoll_domain;static void icoll_ack_irq (struct irq_data *d)
@@ -50,19 +68,19 @@ static void icoll_ack_irq(struct irq_dat* BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 unconditionally. */ __raw_writel (BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 , - icoll_base +HW_ICOLL_LEVELACK ); + icoll_priv.levelack); }static void icoll_mask_irq (struct irq_data *d) { -__raw_writel (BM_ICOLL_INTERRUPTn_ENABLE, - icoll_base +HW_ICOLL_INTERRUPTn_CLR (d->hwirq)); +__raw_writel (BM_ICOLL_INTR_ENABLE , + icoll_priv.intr +CLR_REG +HW_ICOLL_INTERRUPTn (d->hwirq)); }static void icoll_unmask_irq (struct irq_data *d) { -__raw_writel (BM_ICOLL_INTERRUPTn_ENABLE, - icoll_base +HW_ICOLL_INTERRUPTn_SET (d->hwirq)); +__raw_writel (BM_ICOLL_INTR_ENABLE , + icoll_priv.intr +SET_REG +HW_ICOLL_INTERRUPTn (d->hwirq)); }static struct irq_chip mxs_icoll_chip = {
@@ -75,8 +93,8 @@ asmlinkage void __exception_irq_entry ic {u32 irqnr; - irqnr =__raw_readl (icoll_base +HW_ICOLL_STAT_OFFSET ); -__raw_writel (irqnr, icoll_base +HW_ICOLL_VECTOR ); + irqnr =__raw_readl (icoll_priv.stat); +__raw_writel (irqnr, icoll_priv.vector);handle_domain_irq (icoll_domain, irqnr, regs); }
@@ -93,23 +111,45 @@ static const struct irq_domain_ops icoll .xlate = irq_domain_xlate_onecell, }; -static int __init icoll_of_init (struct device_node *np, -struct device_node *interrupt_parent) +static void __init icoll_add_domain (struct device_node *np, +int num) +{ + icoll_domain =irq_domain_add_linear (np, num, + &icoll_irq_domain_ops,NULL ); + +if (!icoll_domain) +panic ("%s: unable to create irq domain" , np->full_name); +} + +static void __iomem *__init icoll_init_iobase (struct device_node *np) { - icoll_base =of_iomap (np,0 ); +void __iomem *icoll_base; + + icoll_base =of_io_request_and_map (np,0 , np->name);if (!icoll_base)panic ("%s: unable to map resource" , np->full_name); +return icoll_base; +} + +static int __init icoll_of_init (struct device_node *np, +struct device_node *interrupt_parent) +{ +void __iomem *icoll_base; + + icoll_base =icoll_init_iobase (np); + icoll_priv.vector = icoll_base +HW_ICOLL_VECTOR ; + icoll_priv.levelack = icoll_base +HW_ICOLL_LEVELACK ; + icoll_priv.ctrl = icoll_base +HW_ICOLL_CTRL ; + icoll_priv.stat = icoll_base +HW_ICOLL_STAT_OFFSET ; + icoll_priv.intr = icoll_base +HW_ICOLL_INTERRUPT0 ;/* * Interrupt Collector reset, which initializes the priority * for each irq to level 0. */ -stmp_reset_block (icoll_base +HW_ICOLL_CTRL ); +stmp_reset_block (icoll_priv.ctrl); - icoll_domain =irq_domain_add_linear (np,ICOLL_NUM_IRQS , - &icoll_irq_domain_ops,NULL ); -if (!icoll_domain) -panic ("%s: unable to create irqdomain" , np->full_name); +icoll_add_domain (np,ICOLL_NUM_IRQS );return 0 ; }
PATCH 3/3 irqchip/mxs: Add Alphascale ASM9260 support
In reply to Thomas GleixnerFrom: Oleksij Rempel <[email protected]>
Freescale iMX23/iMX28 and Alphascale ASM9260 have similar interrupt collectors. We already prepared the mxs driver to handle a different register layout. Add the actual ASM9260 support.
Differences between these devices:
- Different register offsets
- Different count of interupt lines per register
- ASM9260 does not provide reset bit
- ASM9260 does not support FIQ.
--- drivers/irqchip/Kconfig | 5 + drivers/irqchip/Makefile | 2 drivers/irqchip/alphascale_asm9260-icoll.h | 109 +++++++++++++++++++++++++++++ drivers/irqchip/irq-mxs.c | 93 ++++++++++++++++++++++++ 4 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 drivers/irqchip/alphascale_asm9260-icoll.h
drivers/irqchip/Kconfig +5 -0
@@ -188,3 +188,8 @@ config IMX_GPCV2 select IRQ_DOMAIN help Enables the wakeup IRQs for IMX platforms with GPCv2 block + +config IRQ_MXS + def_bool y if MACH_ASM9260 || ARCH_MXS + select IRQ_DOMAIN + select STMP_DEVICE
drivers/irqchip/Makefile +1 -1
@@ -6,7 +6,7 @@ obj-$(CONFIG_ARCH_EXYNOS) += exynos-com obj-$(CONFIG_ARCH_HIP04) += irq-hip04.o obj-$(CONFIG_ARCH_MMP) += irq-mmp.o obj-$(CONFIG_ARCH_MVEBU) += irq-armada-370-xp.o -obj-$(CONFIG_ARCH_MXS) += irq-mxs.o +obj-$(CONFIG_IRQ_MXS) += irq-mxs.o obj-$(CONFIG_ARCH_TEGRA) += irq-tegra.o obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o obj-$(CONFIG_DW_APB_ICTL) += irq-dw-apb-ictl.o
drivers/irqchip/alphascale_asm9260-icoll.h new file +109 -0
109 lines not on this page · raw message
drivers/irqchip/irq-mxs.c +92 -1
154 lines not on this page · raw message
Quoted 2 lines · Thomas Gleixner
I'm reposting this series from Oleksij before I apply it to give Shawn and Sascha an opportunity to review and test it on imx.
I tested the series on imx28-evk board with v4.3-rc5, and it works fine.