[Patch V7 4/4] irqchip/qeic: remove PPCisms for QEIC
QEIC was supported on PowerPC, and dependent on PPC, Now it is supported on other platforms, so remove PPCisms. Signed-off-by: Zhao Qiang--- Changes for v6: - new added Changes for v7: - fix warning drivers/irqchip/irq-qeic.c | 34 -- include/soc/fsl/qe/qe_ic.h | 12 ++-- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/drivers/irqchip/irq-qeic.c b/drivers/irqchip/irq-qeic.c index 4f49d4b..957ea5b 100644 --- a/drivers/irqchip/irq-qeic.c +++ b/drivers/irqchip/irq-qeic.c @@ -18,7 +18,10 @@ #include #include #include +#include #include +#include +#include #include #include #include @@ -88,7 +91,7 @@ struct qe_ic { /* Control registers offset */ - volatile u32 __iomem *regs; + u32 __iomem *regs; /* The remapper for this QEIC */ struct irq_domain *irqhost; @@ -264,15 +267,15 @@ static struct qe_ic_info qe_ic_info[] = { }, }; -static inline u32 qe_ic_read(volatile __be32 __iomem * base, unsigned int reg) +static inline u32 qe_ic_read(__be32 __iomem * base, unsigned int reg) { - return in_be32(base + (reg >> 2)); + return ioread32be(base + (reg >> 2)); } -static inline void qe_ic_write(volatile __be32 __iomem * base, unsigned int reg, +static inline void qe_ic_write(__be32 __iomem * base, unsigned int reg, u32 value) { - out_be32(base + (reg >> 2), value); + iowrite32be(value, base + (reg >> 2)); } static inline struct qe_ic *qe_ic_from_irq(unsigned int virq) @@ -374,7 +377,7 @@ static const struct irq_domain_ops qe_ic_host_ops = { .xlate = irq_domain_xlate_onetwocell, }; -/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */ +/* Return an interrupt vector or 0 if no interrupt is pending. */ unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic) { int irq; @@ -385,12 +388,12 @@ unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic) irq = qe_ic_read(qe_ic->regs, QEIC_CIVEC) >> 26; if (irq == 0) - return NO_IRQ; + return 0; return irq_linear_revmap(qe_ic->irqhost, irq); } -/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */ +/* Return an interrupt vector or 0 if no interrupt is pending. */ unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic) { int irq; @@ -401,7 +404,7 @@ unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic) irq = qe_ic_read(qe_ic->regs, QEIC_CHIVEC) >> 26; if (irq == 0) - return NO_IRQ; + return 0; return irq_linear_revmap(qe_ic->irqhost, irq); } @@ -447,7 +450,7 @@ static int __init qe_ic_init(unsigned int flags) qe_ic->virq_high = irq_of_parse_and_map(node, 0); qe_ic->virq_low = irq_of_parse_and_map(node, 1); - if (qe_ic->virq_low == NO_IRQ) { + if (qe_ic->virq_low == 0) { pr_err("Failed to map QE_IC low IRQ\n"); ret = -ENOMEM; goto err_domain_remove; @@ -479,7 +482,7 @@ static int __init qe_ic_init(unsigned int flags) irq_set_handler_data(qe_ic->virq_low, qe_ic); irq_set_chained_handler(qe_ic->virq_low, qe_ic_cascade_low_mpic); - if (qe_ic->virq_high != NO_IRQ && + if (qe_ic->virq_high != 0 && qe_ic->virq_high != qe_ic->virq_low) { irq_set_handler_data(qe_ic->virq_high, qe_ic); irq_set_chained_handler(qe_ic->virq_high, @@ -500,7 +503,8 @@ err_put_node: void qe_ic_set_highest_priority(unsigned int virq, int high) { struct qe_ic *qe_ic = qe_ic_from_irq(virq); - unsigned int src = virq_to_hw(virq); + struct irq_data *irq_data = irq_get_irq_data(virq); + irq_hw_number_t src = WARN_ON(!irq_data) ? 0 : irq_data->hwirq; u32 temp = 0; temp = qe_ic_read(qe_ic->regs, QEIC_CICR); @@ -518,7 +522,8 @@ void qe_ic_set_highest_priority(unsigned int virq, int high) int qe_ic_set_priority(unsigned int virq, unsigned int priority) { struct qe_ic *qe_ic = qe_ic_from_irq(virq); - unsigned int src = virq_to_hw(virq); + struct irq_data *irq_data = irq_get_irq_data(virq); + irq_hw_number_t src = WARN_ON(!irq_data) ? 0 : irq_data->hwirq; u32 temp; if (priority > 8 || priority == 0) @@ -548,7 +553,8 @@ int qe_ic_set_priority(unsigned int virq, unsigned int priority) int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high) { struct qe_ic *qe_ic = qe_ic_from_irq(virq); - unsigned int src = virq_to_hw(virq); + struct irq_data *irq_data = irq_get_irq_data(virq); + irq_hw_number_t src = WARN_ON(!irq_data) ? 0 : irq_data->hwirq; u32 temp, control_reg = QEIC_CICNR, shift = 0; if (priority > 2 || priority == 0) diff --git a/include/soc/fsl/qe/qe_ic.h b/include/soc/fsl/qe/qe_ic.h index
[Patch V7 3/4] irqchip/qeic: merge qeic_of_init into qe_ic_init
qeic_of_init just get device_node of qeic from dtb and call qe_ic_init, pass the device_node to qe_ic_init. So merge qeic_of_init into qe_ic_init to get the qeic node in qe_ic_init. Signed-off-by: Zhao Qiang--- Changes for v2: - modify subject and commit msg - return 0 and add put node when return in qe_ic_init Changes for v3: - na Changes for v4: - na Changes for v5: - na Changes for v6: - rebase Changes for v6: - na drivers/irqchip/irq-qeic.c | 91 +- include/soc/fsl/qe/qe_ic.h | 7 2 files changed, 50 insertions(+), 48 deletions(-) diff --git a/drivers/irqchip/irq-qeic.c b/drivers/irqchip/irq-qeic.c index 1463731..4f49d4b 100644 --- a/drivers/irqchip/irq-qeic.c +++ b/drivers/irqchip/irq-qeic.c @@ -406,27 +406,38 @@ 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 int __init qe_ic_init(unsigned int flags) { + struct device_node *node; struct qe_ic *qe_ic; struct resource res; - u32 temp = 0, ret, high_active = 0; + u32 temp = 0, high_active = 0; + int ret = 0; + + node = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); + if (!node) { + node = of_find_node_by_type(NULL, "qeic"); + if (!node) + return -ENODEV; + } ret = of_address_to_resource(node, 0, ); - if (ret) - return; + if (ret) { + ret = -ENODEV; + goto err_put_node; + } qe_ic = kzalloc(sizeof(*qe_ic), GFP_KERNEL); - if (qe_ic == NULL) - return; + if (qe_ic == NULL) { + ret = -ENOMEM; + goto err_put_node; + } qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS, _ic_host_ops, qe_ic); if (qe_ic->irqhost == NULL) { - kfree(qe_ic); - return; + ret = -ENOMEM; + goto err_free_qe_ic; } qe_ic->regs = ioremap(res.start, resource_size()); @@ -437,9 +448,9 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags, qe_ic->virq_low = irq_of_parse_and_map(node, 1); if (qe_ic->virq_low == NO_IRQ) { - printk(KERN_ERR "Failed to map QE_IC low IRQ\n"); - kfree(qe_ic); - return; + pr_err("Failed to map QE_IC low IRQ\n"); + ret = -ENOMEM; + goto err_domain_remove; } /* default priority scheme is grouped. If spread mode is*/ @@ -466,13 +477,24 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags, qe_ic_write(qe_ic->regs, QEIC_CICR, temp); irq_set_handler_data(qe_ic->virq_low, qe_ic); - irq_set_chained_handler(qe_ic->virq_low, low_handler); + irq_set_chained_handler(qe_ic->virq_low, qe_ic_cascade_low_mpic); if (qe_ic->virq_high != NO_IRQ && qe_ic->virq_high != qe_ic->virq_low) { irq_set_handler_data(qe_ic->virq_high, qe_ic); - irq_set_chained_handler(qe_ic->virq_high, high_handler); + irq_set_chained_handler(qe_ic->virq_high, + qe_ic_cascade_high_mpic); } + of_node_put(node); + return 0; + +err_domain_remove: + irq_domain_remove(qe_ic->irqhost); +err_free_qe_ic: + kfree(qe_ic); +err_put_node: + of_node_put(node); + return ret; } void qe_ic_set_highest_priority(unsigned int virq, int high) @@ -579,39 +601,26 @@ static struct device device_qe_ic = { .bus = _ic_subsys, }; -static int __init init_qe_ic_sysfs(void) +static int __init init_qe_ic(void) { - int rc; + int ret; - printk(KERN_DEBUG "Registering qe_ic with sysfs...\n"); + ret = qe_ic_init(0); + if (ret) + return ret; - rc = subsys_system_register(_ic_subsys, NULL); - if (rc) { - printk(KERN_ERR "Failed registering qe_ic sys class\n"); + ret = subsys_system_register(_ic_subsys, NULL); + if (ret) { + pr_err("Failed registering qe_ic sys class\n"); return -ENODEV; } - rc = device_register(_qe_ic); - if (rc) { - printk(KERN_ERR "Failed registering qe_ic sys device\n"); + ret = device_register(_qe_ic); + if (ret) { + pr_err("Failed registering qe_ic sys device\n"); return -ENODEV; } - return 0; -} - -static int __init qeic_of_init(void) -{ - struct device_node *np;
[Patch V7 2/4] irqchip/qeic: merge qeic init code from platforms to a common function
The codes of qe_ic init from a variety of platforms are redundant, merge them to a common function and put it to irqchip/irq-qeic.c For non-p1021_mds mpc85xx_mds boards, use "qe_ic_init(np, 0, qe_ic_cascade_low_mpic, qe_ic_cascade_high_mpic);" instead of "qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL);". qe_ic_cascade_muxed_mpic was used for boards has the same interrupt number for low interrupt and high interrupt, qe_ic_init has checked if "low interrupt == high interrupt" Signed-off-by: Zhao Qiang--- Changes for v2: - modify subject and commit msg - add check for qeic by type Changes for v3: - na Changes for v4: - na Changes for v5: - na Changes for v6: - rebase Changes for v7: - na arch/powerpc/platforms/83xx/misc.c| 15 --- arch/powerpc/platforms/85xx/corenet_generic.c | 9 - arch/powerpc/platforms/85xx/mpc85xx_mds.c | 14 -- arch/powerpc/platforms/85xx/mpc85xx_rdb.c | 16 arch/powerpc/platforms/85xx/twr_p102x.c | 14 -- drivers/irqchip/irq-qeic.c| 16 6 files changed, 16 insertions(+), 68 deletions(-) diff --git a/arch/powerpc/platforms/83xx/misc.c b/arch/powerpc/platforms/83xx/misc.c index d75c981..c09a135 100644 --- a/arch/powerpc/platforms/83xx/misc.c +++ b/arch/powerpc/platforms/83xx/misc.c @@ -93,24 +93,9 @@ void __init mpc83xx_ipic_init_IRQ(void) } #ifdef CONFIG_QUICC_ENGINE -void __init mpc83xx_qe_init_IRQ(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; - } - qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic); - of_node_put(np); -} - void __init mpc83xx_ipic_and_qe_init_IRQ(void) { mpc83xx_ipic_init_IRQ(); - mpc83xx_qe_init_IRQ(); } #endif /* CONFIG_QUICC_ENGINE */ diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c index 1179115..1d96c3f 100644 --- a/arch/powerpc/platforms/85xx/corenet_generic.c +++ b/arch/powerpc/platforms/85xx/corenet_generic.c @@ -41,8 +41,6 @@ void __init corenet_gen_pic_init(void) unsigned int flags = MPIC_BIG_ENDIAN | MPIC_SINGLE_DEST_CPU | MPIC_NO_RESET; - struct device_node *np; - if (ppc_md.get_irq == mpic_get_coreint_irq) flags |= MPIC_ENABLE_COREINT; @@ -50,13 +48,6 @@ void __init corenet_gen_pic_init(void) BUG_ON(mpic == NULL); mpic_init(mpic); - - np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); - if (np) { - qe_ic_init(np, 0, qe_ic_cascade_low_mpic, - qe_ic_cascade_high_mpic); - of_node_put(np); - } } /* diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index d7e440e..06f34a9 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -283,20 +283,6 @@ static void __init mpc85xx_mds_qeic_init(void) of_node_put(np); return; } - - np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); - if (!np) { - np = of_find_node_by_type(NULL, "qeic"); - if (!np) - return; - } - - if (machine_is(p1021_mds)) - qe_ic_init(np, 0, qe_ic_cascade_low_mpic, - qe_ic_cascade_high_mpic); - else - qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL); - of_node_put(np); } #else static void __init mpc85xx_mds_qe_init(void) { } diff --git a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c index 1006950..000d385 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c @@ -48,10 +48,6 @@ void __init mpc85xx_rdb_pic_init(void) { struct mpic *mpic; -#ifdef CONFIG_QUICC_ENGINE - struct device_node *np; -#endif - if (of_machine_is_compatible("fsl,MPC85XXRDB-CAMP")) { mpic = mpic_alloc(NULL, 0, MPIC_NO_RESET | MPIC_BIG_ENDIAN | @@ -66,18 +62,6 @@ void __init mpc85xx_rdb_pic_init(void) BUG_ON(mpic == NULL); mpic_init(mpic); - -#ifdef CONFIG_QUICC_ENGINE - np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); - if (np) { - qe_ic_init(np, 0, qe_ic_cascade_low_mpic, - qe_ic_cascade_high_mpic); - of_node_put(np); - - } else - pr_err("%s: Could not find qe-ic node\n", __func__); -#endif - } /* diff --git a/arch/powerpc/platforms/85xx/twr_p102x.c b/arch/powerpc/platforms/85xx/twr_p102x.c index
[Patch V7 1/4] irqchip/qeic: move qeic driver from drivers/soc/fsl/qe
move the driver from drivers/soc/fsl/qe to drivers/irqchip, merge qe_ic.h and qe_ic.c into irq-qeic.c. Signed-off-by: Zhao Qiang--- Changes for v2: - modify the subject and commit msg Changes for v3: - merge .h file to .c, rename it with irq-qeic.c Changes for v4: - modify comments Changes for v5: - disable rename detection Changes for v6: - rebase Changes for v7: - na drivers/irqchip/Makefile| 1 + drivers/irqchip/irq-qeic.c | 601 drivers/soc/fsl/qe/Makefile | 2 +- drivers/soc/fsl/qe/qe_ic.c | 512 - drivers/soc/fsl/qe/qe_ic.h | 103 5 files changed, 603 insertions(+), 616 deletions(-) create mode 100644 drivers/irqchip/irq-qeic.c delete mode 100644 drivers/soc/fsl/qe/qe_ic.c delete mode 100644 drivers/soc/fsl/qe/qe_ic.h diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 4c203b6..face608 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -71,3 +71,4 @@ obj-$(CONFIG_MVEBU_ODMI) += irq-mvebu-odmi.o obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o obj-$(CONFIG_EZNPS_GIC)+= irq-eznps.o obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o +obj-$(CONFIG_QUICC_ENGINE) += irq-qeic.o diff --git a/drivers/irqchip/irq-qeic.c b/drivers/irqchip/irq-qeic.c new file mode 100644 index 000..48ceded --- /dev/null +++ b/drivers/irqchip/irq-qeic.c @@ -0,0 +1,601 @@ +/* + * drivers/irqchip/irq-qeic.c + * + * Copyright (C) 2016 Freescale Semiconductor, Inc. All rights reserved. + * + * Author: Li Yang + * Based on code from Shlomi Gridish + * + * QUICC ENGINE Interrupt Controller + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NR_QE_IC_INTS 64 + +/* QE IC registers offset */ +#define QEIC_CICR 0x00 +#define QEIC_CIVEC 0x04 +#define QEIC_CRIPNR0x08 +#define QEIC_CIPNR 0x0c +#define QEIC_CIPXCC0x10 +#define QEIC_CIPYCC0x14 +#define QEIC_CIPWCC0x18 +#define QEIC_CIPZCC0x1c +#define QEIC_CIMR 0x20 +#define QEIC_CRIMR 0x24 +#define QEIC_CICNR 0x28 +#define QEIC_CIPRTA0x30 +#define QEIC_CIPRTB0x34 +#define QEIC_CRICR 0x3c +#define QEIC_CHIVEC0x60 + +/* Interrupt priority registers */ +#define CIPCC_SHIFT_PRI0 29 +#define CIPCC_SHIFT_PRI1 26 +#define CIPCC_SHIFT_PRI2 23 +#define CIPCC_SHIFT_PRI3 20 +#define CIPCC_SHIFT_PRI4 13 +#define CIPCC_SHIFT_PRI5 10 +#define CIPCC_SHIFT_PRI6 7 +#define CIPCC_SHIFT_PRI7 4 + +/* CICR priority modes */ +#define CICR_GWCC 0x0004 +#define CICR_GXCC 0x0002 +#define CICR_GYCC 0x0001 +#define CICR_GZCC 0x0008 +#define CICR_GRTA 0x0020 +#define CICR_GRTB 0x0040 +#define CICR_HPIT_SHIFT8 +#define CICR_HPIT_MASK 0x0300 +#define CICR_HP_SHIFT 24 +#define CICR_HP_MASK 0x3f00 + +/* CICNR */ +#define CICNR_WCC1T_SHIFT 20 +#define CICNR_ZCC1T_SHIFT 28 +#define CICNR_YCC1T_SHIFT 12 +#define CICNR_XCC1T_SHIFT 4 + +/* CRICR */ +#define CRICR_RTA1T_SHIFT 20 +#define CRICR_RTB1T_SHIFT 28 + +/* Signal indicator */ +#define SIGNAL_MASK3 +#define SIGNAL_HIGH2 +#define SIGNAL_LOW 0 + +struct qe_ic { + /* Control registers offset */ + volatile u32 __iomem *regs; + + /* The remapper for this QEIC */ + struct irq_domain *irqhost; + + /* The "linux" controller struct */ + struct irq_chip hc_irq; + + /* VIRQ numbers of QE high/low irqs */ + unsigned int virq_high; + unsigned int virq_low; +}; + +/* + * QE interrupt controller internal structure + */ +struct qe_ic_info { + /* location of this source at the QIMR register. */ + u32 mask; + + /* Mask register offset */ + u32 mask_reg; + + /* +* for grouped interrupts sources - the interrupt +* code as appears at the group priority register +*/ + u8 pri_code; + + /* Group priority register offset */ + u32 pri_reg; +}; + +static DEFINE_RAW_SPINLOCK(qe_ic_lock); + +static struct qe_ic_info qe_ic_info[] = { + [1] = { + .mask = 0x8000, +