diff options
author | Rasmus Villemoes <linux@rasmusvillemoes.dk> | 2019-11-28 15:55:17 +0100 |
---|---|---|
committer | Li Yang <leoyang.li@nxp.com> | 2019-12-09 13:54:31 -0600 |
commit | 4e0e161d3cc403823159b2c15b6f4c9f642fd1d3 (patch) | |
tree | b600dcba860f1f083d4f4292b03daead67bf4135 /drivers/soc/fsl | |
parent | 273e66721e368764659dde52ee4702567c921f49 (diff) |
soc: fsl: qe: move calls of qe_ic_init out of arch/powerpc/
Having to call qe_ic_init() from platform-specific code makes it
awkward to allow building the QE drivers for ARM. It's also a needless
duplication of code, and slightly error-prone: Instead of the caller
needing to know the details of whether the QUICC Engine High and QUICC
Engine Low are actually the same interrupt (see e.g. the machine_is()
in mpc85xx_mds_qeic_init), just let the init function choose the
appropriate handlers after it has parsed the DT and figured it out. If
the two interrupts are distinct, use separate handlers, otherwise use
the handler which first checks the CHIVEC register (for the high
priority interrupts), then the CIVEC.
All existing callers pass 0 for flags, so continue to do that from the
new single caller. Later cleanups will remove that argument
from qe_ic_init and simplify the body, as well as make qe_ic_init into
a proper init function for an IRQCHIP_DECLARE, eliminating the need to
manually look up the fsl,qe-ic node.
Reviewed-by: Timur Tabi <timur@kernel.org>
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Signed-off-by: Li Yang <leoyang.li@nxp.com>
Diffstat (limited to 'drivers/soc/fsl')
-rw-r--r-- | drivers/soc/fsl/qe/qe_ic.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/drivers/soc/fsl/qe/qe_ic.c b/drivers/soc/fsl/qe/qe_ic.c index f170926ce4d1..a062efac398b 100644 --- a/drivers/soc/fsl/qe/qe_ic.c +++ b/drivers/soc/fsl/qe/qe_ic.c @@ -314,10 +314,10 @@ unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic) return irq_linear_revmap(qe_ic->irqhost, irq); } -void __init qe_ic_init(struct device_node *node, unsigned int flags, - void (*low_handler)(struct irq_desc *desc), - void (*high_handler)(struct irq_desc *desc)) +static void __init qe_ic_init(struct device_node *node, unsigned int flags) { + void (*low_handler)(struct irq_desc *desc); + void (*high_handler)(struct irq_desc *desc); struct qe_ic *qe_ic; struct resource res; u32 temp = 0, ret; @@ -349,6 +349,13 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags, kfree(qe_ic); return; } + if (qe_ic->virq_high != qe_ic->virq_low) { + low_handler = qe_ic_cascade_low_mpic; + high_handler = qe_ic_cascade_high_mpic; + } else { + low_handler = qe_ic_cascade_muxed_mpic; + high_handler = NULL; + } /* default priority scheme is grouped. If spread mode is */ /* required, configure cicr accordingly. */ @@ -381,6 +388,22 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags, } } +static int __init qe_ic_of_init(void) +{ + struct device_node *np; + + np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); + if (!np) { + np = of_find_node_by_type(NULL, "qeic"); + if (!np) + return -ENODEV; + } + qe_ic_init(np, 0); + of_node_put(np); + return 0; +} +subsys_initcall(qe_ic_of_init); + void qe_ic_set_highest_priority(unsigned int virq, int high) { struct qe_ic *qe_ic = qe_ic_from_irq(virq); |