[Patch V7 4/4] irqchip/qeic: remove PPCisms for QEIC

2016-12-26 Thread Zhao Qiang
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

2016-12-26 Thread Zhao Qiang
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

2016-12-26 Thread Zhao Qiang
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

2016-12-26 Thread Zhao Qiang
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,
+