Message ID | 20181206073125.7255-6-andrew.smirnov@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | i.MX8MQ support for GPCv2 irqchip driver | expand |
Am Mittwoch, den 05.12.2018, 23:31 -0800 schrieb Andrey Smirnov: > Add code needed to support i.MX8MQ. > > > Cc: Thomas Gleixner <tglx@linutronix.de> > > Cc: Jason Cooper <jason@lakedaemon.net> > > Cc: Marc Zyngier <marc.zyngier@arm.com> > Cc: cphealy@gmail.com > Cc: l.stach@pengutronix.de > > Cc: Leonard Crestez <leonard.crestez@nxp.com> > > Cc: "A.s. Dong" <aisheng.dong@nxp.com> > > Cc: Richard Zhu <hongxing.zhu@nxp.com> > Cc: linux-imx@nxp.com > Cc: linux-arm-kernel@lists.infradead.org > Cc: linux-kernel@vger.kernel.org > Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> > --- > drivers/irqchip/irq-imx-gpcv2.c | 31 +++++++++++++++++++++++++++++-- > 1 file changed, 29 insertions(+), 2 deletions(-) > > diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c > index c2b2b3128ddd..17a2dad2d4c2 100644 > --- a/drivers/irqchip/irq-imx-gpcv2.c > +++ b/drivers/irqchip/irq-imx-gpcv2.c > @@ -17,6 +17,9 @@ > > > #define GPC_IMR1_CORE0 0x30 > > #define GPC_IMR1_CORE1 0x40 > > +#define GPC_IMR1_CORE2 0x1c0 > > +#define GPC_IMR1_CORE3 0x1d0 > + > > struct gpcv2_irqchip_data { > > > struct raw_spinlock rlock; > @@ -192,11 +195,19 @@ static const struct irq_domain_ops gpcv2_irqchip_data_domain_ops = { > > > .free = irq_domain_free_irqs_common, > }; > > +static const struct of_device_id gpcv2_of_match[] = { > > + { .compatible = "fsl,imx7d-gpc", .data = (const void *) 2 }, > > + { .compatible = "fsl,imx8mq-gpc", .data = (const void *) 4 }, > > + { /* END */ } > +}; > + > static int __init imx_gpcv2_irqchip_init(struct device_node *node, > > struct device_node *parent) > { > > struct irq_domain *parent_domain, *domain; > > struct gpcv2_irqchip_data *cd; > > + const struct of_device_id *id; > > + unsigned long core_num; > > int i; > > > if (!parent) { > @@ -204,6 +215,14 @@ static int __init imx_gpcv2_irqchip_init(struct device_node *node, > > return -ENODEV; > > } > > > + id = of_match_node(gpcv2_of_match, node); > > + if (!id) { > > + pr_err("%pOF: unknown compatibility string\n", node); > > + return -ENODEV; > > + } > + > > + core_num = (unsigned long)id->data; > + > > parent_domain = irq_find_host(parent); > > if (!parent_domain) { > > pr_err("%pOF: unable to get parent domain\n", node); > @@ -236,8 +255,16 @@ static int __init imx_gpcv2_irqchip_init(struct device_node *node, > > > /* Initially mask all interrupts */ > > for (i = 0; i < IMR_NUM; i++) { > > - writel_relaxed(~0, cd->gpc_base + GPC_IMR1_CORE0 + i * 4); > > - writel_relaxed(~0, cd->gpc_base + GPC_IMR1_CORE1 + i * 4); > > + void __iomem *reg = cd->gpc_base + i * 4; > + > > + switch (core_num) { > > + case 4: > > + writel_relaxed(~0, reg + GPC_IMR1_CORE2); > > + writel_relaxed(~0, reg + GPC_IMR1_CORE3); > > > + case 2: /* FALLTHROUGH */ > > + writel_relaxed(~0, reg + GPC_IMR1_CORE0); > > + writel_relaxed(~0, reg + GPC_IMR1_CORE1); > + } The writes being not being in linear descending core order does trigger something in me, but obviously this doesn't has any effect on the code, so: Reviewed-by: Lucas Stach <l.stach@pengutronix.de> > cd->wakeup_sources[i] = ~0; > > } >
diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c index c2b2b3128ddd..17a2dad2d4c2 100644 --- a/drivers/irqchip/irq-imx-gpcv2.c +++ b/drivers/irqchip/irq-imx-gpcv2.c @@ -17,6 +17,9 @@ #define GPC_IMR1_CORE0 0x30 #define GPC_IMR1_CORE1 0x40 +#define GPC_IMR1_CORE2 0x1c0 +#define GPC_IMR1_CORE3 0x1d0 + struct gpcv2_irqchip_data { struct raw_spinlock rlock; @@ -192,11 +195,19 @@ static const struct irq_domain_ops gpcv2_irqchip_data_domain_ops = { .free = irq_domain_free_irqs_common, }; +static const struct of_device_id gpcv2_of_match[] = { + { .compatible = "fsl,imx7d-gpc", .data = (const void *) 2 }, + { .compatible = "fsl,imx8mq-gpc", .data = (const void *) 4 }, + { /* END */ } +}; + static int __init imx_gpcv2_irqchip_init(struct device_node *node, struct device_node *parent) { struct irq_domain *parent_domain, *domain; struct gpcv2_irqchip_data *cd; + const struct of_device_id *id; + unsigned long core_num; int i; if (!parent) { @@ -204,6 +215,14 @@ static int __init imx_gpcv2_irqchip_init(struct device_node *node, return -ENODEV; } + id = of_match_node(gpcv2_of_match, node); + if (!id) { + pr_err("%pOF: unknown compatibility string\n", node); + return -ENODEV; + } + + core_num = (unsigned long)id->data; + parent_domain = irq_find_host(parent); if (!parent_domain) { pr_err("%pOF: unable to get parent domain\n", node); @@ -236,8 +255,16 @@ static int __init imx_gpcv2_irqchip_init(struct device_node *node, /* Initially mask all interrupts */ for (i = 0; i < IMR_NUM; i++) { - writel_relaxed(~0, cd->gpc_base + GPC_IMR1_CORE0 + i * 4); - writel_relaxed(~0, cd->gpc_base + GPC_IMR1_CORE1 + i * 4); + void __iomem *reg = cd->gpc_base + i * 4; + + switch (core_num) { + case 4: + writel_relaxed(~0, reg + GPC_IMR1_CORE2); + writel_relaxed(~0, reg + GPC_IMR1_CORE3); + case 2: /* FALLTHROUGH */ + writel_relaxed(~0, reg + GPC_IMR1_CORE0); + writel_relaxed(~0, reg + GPC_IMR1_CORE1); + } cd->wakeup_sources[i] = ~0; }
Add code needed to support i.MX8MQ. Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Jason Cooper <jason@lakedaemon.net> Cc: Marc Zyngier <marc.zyngier@arm.com> Cc: cphealy@gmail.com Cc: l.stach@pengutronix.de Cc: Leonard Crestez <leonard.crestez@nxp.com> Cc: "A.s. Dong" <aisheng.dong@nxp.com> Cc: Richard Zhu <hongxing.zhu@nxp.com> Cc: linux-imx@nxp.com Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> --- drivers/irqchip/irq-imx-gpcv2.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-)