layerscape: add patches-5.4
[openwrt/staging/wigyori.git] / target / linux / layerscape / patches-5.4 / 814-qe-0001-irqchip-qeic-move-qeic-driver-from-drivers-soc-fsl-q.patch
diff --git a/target/linux/layerscape/patches-5.4/814-qe-0001-irqchip-qeic-move-qeic-driver-from-drivers-soc-fsl-q.patch b/target/linux/layerscape/patches-5.4/814-qe-0001-irqchip-qeic-move-qeic-driver-from-drivers-soc-fsl-q.patch
new file mode 100644 (file)
index 0000000..bedc902
--- /dev/null
@@ -0,0 +1,1243 @@
+From 0172b31512827b9fd735df47751c7aa88b6aa5f6 Mon Sep 17 00:00:00 2001
+From: Zhao Qiang <qiang.zhao@nxp.com>
+Date: Thu, 27 Apr 2017 09:52:54 +0800
+Subject: [PATCH] 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 <qiang.zhao@nxp.com>
+---
+ drivers/irqchip/irq-qeic.c  | 597 ++++++++++++++++++++++++++++++++++++++++++++
+ drivers/soc/fsl/qe/Makefile |   2 +-
+ drivers/soc/fsl/qe/qe_ic.c  | 508 -------------------------------------
+ drivers/soc/fsl/qe/qe_ic.h  |  99 --------
+ 4 files changed, 598 insertions(+), 608 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
+
+--- /dev/null
++++ b/drivers/irqchip/irq-qeic.c
+@@ -0,0 +1,597 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * drivers/irqchip/irq-qeic.c
++ *
++ * Copyright (C) 2016 Freescale Semiconductor, Inc.  All rights reserved.
++ *
++ * Author: Li Yang <leoli@freescale.com>
++ * Based on code from Shlomi Gridish <gridish@freescale.com>
++ *
++ * QUICC ENGINE Interrupt Controller
++ */
++
++#include <linux/of_irq.h>
++#include <linux/of_address.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/errno.h>
++#include <linux/reboot.h>
++#include <linux/slab.h>
++#include <linux/stddef.h>
++#include <linux/sched.h>
++#include <linux/signal.h>
++#include <linux/device.h>
++#include <linux/spinlock.h>
++#include <asm/irq.h>
++#include <asm/io.h>
++#include <soc/fsl/qe/qe_ic.h>
++
++#define NR_QE_IC_INTS         64
++
++/* QE IC registers offset */
++#define QEIC_CICR             0x00
++#define QEIC_CIVEC            0x04
++#define QEIC_CRIPNR           0x08
++#define QEIC_CIPNR            0x0c
++#define QEIC_CIPXCC           0x10
++#define QEIC_CIPYCC           0x14
++#define QEIC_CIPWCC           0x18
++#define QEIC_CIPZCC           0x1c
++#define QEIC_CIMR             0x20
++#define QEIC_CRIMR            0x24
++#define QEIC_CICNR            0x28
++#define QEIC_CIPRTA           0x30
++#define QEIC_CIPRTB           0x34
++#define QEIC_CRICR            0x3c
++#define QEIC_CHIVEC           0x60
++
++/* 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             0x00040000
++#define CICR_GXCC             0x00020000
++#define CICR_GYCC             0x00010000
++#define CICR_GZCC             0x00080000
++#define CICR_GRTA             0x00200000
++#define CICR_GRTB             0x00400000
++#define CICR_HPIT_SHIFT               8
++#define CICR_HPIT_MASK                0x00000300
++#define CICR_HP_SHIFT         24
++#define CICR_HP_MASK          0x3f000000
++
++/* 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_MASK           3
++#define SIGNAL_HIGH           2
++#define SIGNAL_LOW            0
++
++struct qe_ic {
++      /* Control registers offset */
++      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 = 0x00008000,
++             .mask_reg = QEIC_CIMR,
++             .pri_code = 0,
++             .pri_reg = QEIC_CIPWCC,
++             },
++      [2] = {
++             .mask = 0x00004000,
++             .mask_reg = QEIC_CIMR,
++             .pri_code = 1,
++             .pri_reg = QEIC_CIPWCC,
++             },
++      [3] = {
++             .mask = 0x00002000,
++             .mask_reg = QEIC_CIMR,
++             .pri_code = 2,
++             .pri_reg = QEIC_CIPWCC,
++             },
++      [10] = {
++              .mask = 0x00000040,
++              .mask_reg = QEIC_CIMR,
++              .pri_code = 1,
++              .pri_reg = QEIC_CIPZCC,
++              },
++      [11] = {
++              .mask = 0x00000020,
++              .mask_reg = QEIC_CIMR,
++              .pri_code = 2,
++              .pri_reg = QEIC_CIPZCC,
++              },
++      [12] = {
++              .mask = 0x00000010,
++              .mask_reg = QEIC_CIMR,
++              .pri_code = 3,
++              .pri_reg = QEIC_CIPZCC,
++              },
++      [13] = {
++              .mask = 0x00000008,
++              .mask_reg = QEIC_CIMR,
++              .pri_code = 4,
++              .pri_reg = QEIC_CIPZCC,
++              },
++      [14] = {
++              .mask = 0x00000004,
++              .mask_reg = QEIC_CIMR,
++              .pri_code = 5,
++              .pri_reg = QEIC_CIPZCC,
++              },
++      [15] = {
++              .mask = 0x00000002,
++              .mask_reg = QEIC_CIMR,
++              .pri_code = 6,
++              .pri_reg = QEIC_CIPZCC,
++              },
++      [20] = {
++              .mask = 0x10000000,
++              .mask_reg = QEIC_CRIMR,
++              .pri_code = 3,
++              .pri_reg = QEIC_CIPRTA,
++              },
++      [25] = {
++              .mask = 0x00800000,
++              .mask_reg = QEIC_CRIMR,
++              .pri_code = 0,
++              .pri_reg = QEIC_CIPRTB,
++              },
++      [26] = {
++              .mask = 0x00400000,
++              .mask_reg = QEIC_CRIMR,
++              .pri_code = 1,
++              .pri_reg = QEIC_CIPRTB,
++              },
++      [27] = {
++              .mask = 0x00200000,
++              .mask_reg = QEIC_CRIMR,
++              .pri_code = 2,
++              .pri_reg = QEIC_CIPRTB,
++              },
++      [28] = {
++              .mask = 0x00100000,
++              .mask_reg = QEIC_CRIMR,
++              .pri_code = 3,
++              .pri_reg = QEIC_CIPRTB,
++              },
++      [32] = {
++              .mask = 0x80000000,
++              .mask_reg = QEIC_CIMR,
++              .pri_code = 0,
++              .pri_reg = QEIC_CIPXCC,
++              },
++      [33] = {
++              .mask = 0x40000000,
++              .mask_reg = QEIC_CIMR,
++              .pri_code = 1,
++              .pri_reg = QEIC_CIPXCC,
++              },
++      [34] = {
++              .mask = 0x20000000,
++              .mask_reg = QEIC_CIMR,
++              .pri_code = 2,
++              .pri_reg = QEIC_CIPXCC,
++              },
++      [35] = {
++              .mask = 0x10000000,
++              .mask_reg = QEIC_CIMR,
++              .pri_code = 3,
++              .pri_reg = QEIC_CIPXCC,
++              },
++      [36] = {
++              .mask = 0x08000000,
++              .mask_reg = QEIC_CIMR,
++              .pri_code = 4,
++              .pri_reg = QEIC_CIPXCC,
++              },
++      [40] = {
++              .mask = 0x00800000,
++              .mask_reg = QEIC_CIMR,
++              .pri_code = 0,
++              .pri_reg = QEIC_CIPYCC,
++              },
++      [41] = {
++              .mask = 0x00400000,
++              .mask_reg = QEIC_CIMR,
++              .pri_code = 1,
++              .pri_reg = QEIC_CIPYCC,
++              },
++      [42] = {
++              .mask = 0x00200000,
++              .mask_reg = QEIC_CIMR,
++              .pri_code = 2,
++              .pri_reg = QEIC_CIPYCC,
++              },
++      [43] = {
++              .mask = 0x00100000,
++              .mask_reg = QEIC_CIMR,
++              .pri_code = 3,
++              .pri_reg = QEIC_CIPYCC,
++              },
++};
++
++static inline u32 qe_ic_read(volatile __be32  __iomem * base, unsigned int reg)
++{
++      return in_be32(base + (reg >> 2));
++}
++
++static inline void qe_ic_write(volatile __be32  __iomem * base, unsigned int reg,
++                             u32 value)
++{
++      out_be32(base + (reg >> 2), value);
++}
++
++static inline struct qe_ic *qe_ic_from_irq(unsigned int virq)
++{
++      return irq_get_chip_data(virq);
++}
++
++static inline struct qe_ic *qe_ic_from_irq_data(struct irq_data *d)
++{
++      return irq_data_get_irq_chip_data(d);
++}
++
++static void qe_ic_unmask_irq(struct irq_data *d)
++{
++      struct qe_ic *qe_ic = qe_ic_from_irq_data(d);
++      unsigned int src = irqd_to_hwirq(d);
++      unsigned long flags;
++      u32 temp;
++
++      raw_spin_lock_irqsave(&qe_ic_lock, flags);
++
++      temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
++      qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
++                  temp | qe_ic_info[src].mask);
++
++      raw_spin_unlock_irqrestore(&qe_ic_lock, flags);
++}
++
++static void qe_ic_mask_irq(struct irq_data *d)
++{
++      struct qe_ic *qe_ic = qe_ic_from_irq_data(d);
++      unsigned int src = irqd_to_hwirq(d);
++      unsigned long flags;
++      u32 temp;
++
++      raw_spin_lock_irqsave(&qe_ic_lock, flags);
++
++      temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
++      qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
++                  temp & ~qe_ic_info[src].mask);
++
++      /* Flush the above write before enabling interrupts; otherwise,
++       * spurious interrupts will sometimes happen.  To be 100% sure
++       * that the write has reached the device before interrupts are
++       * enabled, the mask register would have to be read back; however,
++       * this is not required for correctness, only to avoid wasting
++       * time on a large number of spurious interrupts.  In testing,
++       * a sync reduced the observed spurious interrupts to zero.
++       */
++      mb();
++
++      raw_spin_unlock_irqrestore(&qe_ic_lock, flags);
++}
++
++static struct irq_chip qe_ic_irq_chip = {
++      .name = "QEIC",
++      .irq_unmask = qe_ic_unmask_irq,
++      .irq_mask = qe_ic_mask_irq,
++      .irq_mask_ack = qe_ic_mask_irq,
++};
++
++static int qe_ic_host_match(struct irq_domain *h, struct device_node *node,
++                          enum irq_domain_bus_token bus_token)
++{
++      /* Exact match, unless qe_ic node is NULL */
++      struct device_node *of_node = irq_domain_get_of_node(h);
++      return of_node == NULL || of_node == node;
++}
++
++static int qe_ic_host_map(struct irq_domain *h, unsigned int virq,
++                        irq_hw_number_t hw)
++{
++      struct qe_ic *qe_ic = h->host_data;
++      struct irq_chip *chip;
++
++      if (hw >= ARRAY_SIZE(qe_ic_info)) {
++              pr_err("%s: Invalid hw irq number for QEIC\n", __func__);
++              return -EINVAL;
++      }
++
++      if (qe_ic_info[hw].mask == 0) {
++              printk(KERN_ERR "Can't map reserved IRQ\n");
++              return -EINVAL;
++      }
++      /* Default chip */
++      chip = &qe_ic->hc_irq;
++
++      irq_set_chip_data(virq, qe_ic);
++      irq_set_status_flags(virq, IRQ_LEVEL);
++
++      irq_set_chip_and_handler(virq, chip, handle_level_irq);
++
++      return 0;
++}
++
++static const struct irq_domain_ops qe_ic_host_ops = {
++      .match = qe_ic_host_match,
++      .map = qe_ic_host_map,
++      .xlate = irq_domain_xlate_onetwocell,
++};
++
++/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
++unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic)
++{
++      int irq;
++
++      BUG_ON(qe_ic == NULL);
++
++      /* get the interrupt source vector. */
++      irq = qe_ic_read(qe_ic->regs, QEIC_CIVEC) >> 26;
++
++      if (irq == 0)
++              return NO_IRQ;
++
++      return irq_linear_revmap(qe_ic->irqhost, irq);
++}
++
++/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
++unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic)
++{
++      int irq;
++
++      BUG_ON(qe_ic == NULL);
++
++      /* get the interrupt source vector. */
++      irq = qe_ic_read(qe_ic->regs, QEIC_CHIVEC) >> 26;
++
++      if (irq == 0)
++              return NO_IRQ;
++
++      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))
++{
++      struct qe_ic *qe_ic;
++      struct resource res;
++      u32 temp = 0, ret, high_active = 0;
++
++      ret = of_address_to_resource(node, 0, &res);
++      if (ret)
++              return;
++
++      qe_ic = kzalloc(sizeof(*qe_ic), GFP_KERNEL);
++      if (qe_ic == NULL)
++              return;
++
++      qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS,
++                                             &qe_ic_host_ops, qe_ic);
++      if (qe_ic->irqhost == NULL) {
++              kfree(qe_ic);
++              return;
++      }
++
++      qe_ic->regs = ioremap(res.start, resource_size(&res));
++
++      qe_ic->hc_irq = qe_ic_irq_chip;
++
++      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) {
++              printk(KERN_ERR "Failed to map QE_IC low IRQ\n");
++              kfree(qe_ic);
++              return;
++      }
++
++      /* default priority scheme is grouped. If spread mode is    */
++      /* required, configure cicr accordingly.                    */
++      if (flags & QE_IC_SPREADMODE_GRP_W)
++              temp |= CICR_GWCC;
++      if (flags & QE_IC_SPREADMODE_GRP_X)
++              temp |= CICR_GXCC;
++      if (flags & QE_IC_SPREADMODE_GRP_Y)
++              temp |= CICR_GYCC;
++      if (flags & QE_IC_SPREADMODE_GRP_Z)
++              temp |= CICR_GZCC;
++      if (flags & QE_IC_SPREADMODE_GRP_RISCA)
++              temp |= CICR_GRTA;
++      if (flags & QE_IC_SPREADMODE_GRP_RISCB)
++              temp |= CICR_GRTB;
++
++      /* choose destination signal for highest priority interrupt */
++      if (flags & QE_IC_HIGH_SIGNAL) {
++              temp |= (SIGNAL_HIGH << CICR_HPIT_SHIFT);
++              high_active = 1;
++      }
++
++      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);
++
++      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);
++      }
++}
++
++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);
++      u32 temp = 0;
++
++      temp = qe_ic_read(qe_ic->regs, QEIC_CICR);
++
++      temp &= ~CICR_HP_MASK;
++      temp |= src << CICR_HP_SHIFT;
++
++      temp &= ~CICR_HPIT_MASK;
++      temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << CICR_HPIT_SHIFT;
++
++      qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
++}
++
++/* Set Priority level within its group, from 1 to 8 */
++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);
++      u32 temp;
++
++      if (priority > 8 || priority == 0)
++              return -EINVAL;
++      if (WARN_ONCE(src >= ARRAY_SIZE(qe_ic_info),
++                    "%s: Invalid hw irq number for QEIC\n", __func__))
++              return -EINVAL;
++      if (qe_ic_info[src].pri_reg == 0)
++              return -EINVAL;
++
++      temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].pri_reg);
++
++      if (priority < 4) {
++              temp &= ~(0x7 << (32 - priority * 3));
++              temp |= qe_ic_info[src].pri_code << (32 - priority * 3);
++      } else {
++              temp &= ~(0x7 << (24 - priority * 3));
++              temp |= qe_ic_info[src].pri_code << (24 - priority * 3);
++      }
++
++      qe_ic_write(qe_ic->regs, qe_ic_info[src].pri_reg, temp);
++
++      return 0;
++}
++
++/* Set a QE priority to use high irq, only priority 1~2 can use high irq */
++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);
++      u32 temp, control_reg = QEIC_CICNR, shift = 0;
++
++      if (priority > 2 || priority == 0)
++              return -EINVAL;
++      if (WARN_ONCE(src >= ARRAY_SIZE(qe_ic_info),
++                    "%s: Invalid hw irq number for QEIC\n", __func__))
++              return -EINVAL;
++
++      switch (qe_ic_info[src].pri_reg) {
++      case QEIC_CIPZCC:
++              shift = CICNR_ZCC1T_SHIFT;
++              break;
++      case QEIC_CIPWCC:
++              shift = CICNR_WCC1T_SHIFT;
++              break;
++      case QEIC_CIPYCC:
++              shift = CICNR_YCC1T_SHIFT;
++              break;
++      case QEIC_CIPXCC:
++              shift = CICNR_XCC1T_SHIFT;
++              break;
++      case QEIC_CIPRTA:
++              shift = CRICR_RTA1T_SHIFT;
++              control_reg = QEIC_CRICR;
++              break;
++      case QEIC_CIPRTB:
++              shift = CRICR_RTB1T_SHIFT;
++              control_reg = QEIC_CRICR;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      shift += (2 - priority) * 2;
++      temp = qe_ic_read(qe_ic->regs, control_reg);
++      temp &= ~(SIGNAL_MASK << shift);
++      temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << shift;
++      qe_ic_write(qe_ic->regs, control_reg, temp);
++
++      return 0;
++}
++
++static struct bus_type qe_ic_subsys = {
++      .name = "qe_ic",
++      .dev_name = "qe_ic",
++};
++
++static struct device device_qe_ic = {
++      .id = 0,
++      .bus = &qe_ic_subsys,
++};
++
++static int __init init_qe_ic_sysfs(void)
++{
++      int rc;
++
++      printk(KERN_DEBUG "Registering qe_ic with sysfs...\n");
++
++      rc = subsys_system_register(&qe_ic_subsys, NULL);
++      if (rc) {
++              printk(KERN_ERR "Failed registering qe_ic sys class\n");
++              return -ENODEV;
++      }
++      rc = device_register(&device_qe_ic);
++      if (rc) {
++              printk(KERN_ERR "Failed registering qe_ic sys device\n");
++              return -ENODEV;
++      }
++      return 0;
++}
++
++subsys_initcall(init_qe_ic_sysfs);
+--- a/drivers/soc/fsl/qe/Makefile
++++ b/drivers/soc/fsl/qe/Makefile
+@@ -2,7 +2,7 @@
+ #
+ # Makefile for the linux ppc-specific parts of QE
+ #
+-obj-$(CONFIG_QUICC_ENGINE)+= qe.o qe_common.o qe_ic.o qe_io.o
++obj-$(CONFIG_QUICC_ENGINE)+= qe.o qe_common.o qe_io.o
+ obj-$(CONFIG_CPM)     += qe_common.o
+ obj-$(CONFIG_UCC)     += ucc.o
+ obj-$(CONFIG_UCC_SLOW)        += ucc_slow.o
+--- a/drivers/soc/fsl/qe/qe_ic.c
++++ /dev/null
+@@ -1,508 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0-or-later
+-/*
+- * arch/powerpc/sysdev/qe_lib/qe_ic.c
+- *
+- * Copyright (C) 2006 Freescale Semiconductor, Inc.  All rights reserved.
+- *
+- * Author: Li Yang <leoli@freescale.com>
+- * Based on code from Shlomi Gridish <gridish@freescale.com>
+- *
+- * QUICC ENGINE Interrupt Controller
+- */
+-
+-#include <linux/of_irq.h>
+-#include <linux/of_address.h>
+-#include <linux/kernel.h>
+-#include <linux/init.h>
+-#include <linux/errno.h>
+-#include <linux/reboot.h>
+-#include <linux/slab.h>
+-#include <linux/stddef.h>
+-#include <linux/sched.h>
+-#include <linux/signal.h>
+-#include <linux/device.h>
+-#include <linux/spinlock.h>
+-#include <asm/irq.h>
+-#include <asm/io.h>
+-#include <soc/fsl/qe/qe_ic.h>
+-
+-#include "qe_ic.h"
+-
+-static DEFINE_RAW_SPINLOCK(qe_ic_lock);
+-
+-static struct qe_ic_info qe_ic_info[] = {
+-      [1] = {
+-             .mask = 0x00008000,
+-             .mask_reg = QEIC_CIMR,
+-             .pri_code = 0,
+-             .pri_reg = QEIC_CIPWCC,
+-             },
+-      [2] = {
+-             .mask = 0x00004000,
+-             .mask_reg = QEIC_CIMR,
+-             .pri_code = 1,
+-             .pri_reg = QEIC_CIPWCC,
+-             },
+-      [3] = {
+-             .mask = 0x00002000,
+-             .mask_reg = QEIC_CIMR,
+-             .pri_code = 2,
+-             .pri_reg = QEIC_CIPWCC,
+-             },
+-      [10] = {
+-              .mask = 0x00000040,
+-              .mask_reg = QEIC_CIMR,
+-              .pri_code = 1,
+-              .pri_reg = QEIC_CIPZCC,
+-              },
+-      [11] = {
+-              .mask = 0x00000020,
+-              .mask_reg = QEIC_CIMR,
+-              .pri_code = 2,
+-              .pri_reg = QEIC_CIPZCC,
+-              },
+-      [12] = {
+-              .mask = 0x00000010,
+-              .mask_reg = QEIC_CIMR,
+-              .pri_code = 3,
+-              .pri_reg = QEIC_CIPZCC,
+-              },
+-      [13] = {
+-              .mask = 0x00000008,
+-              .mask_reg = QEIC_CIMR,
+-              .pri_code = 4,
+-              .pri_reg = QEIC_CIPZCC,
+-              },
+-      [14] = {
+-              .mask = 0x00000004,
+-              .mask_reg = QEIC_CIMR,
+-              .pri_code = 5,
+-              .pri_reg = QEIC_CIPZCC,
+-              },
+-      [15] = {
+-              .mask = 0x00000002,
+-              .mask_reg = QEIC_CIMR,
+-              .pri_code = 6,
+-              .pri_reg = QEIC_CIPZCC,
+-              },
+-      [20] = {
+-              .mask = 0x10000000,
+-              .mask_reg = QEIC_CRIMR,
+-              .pri_code = 3,
+-              .pri_reg = QEIC_CIPRTA,
+-              },
+-      [25] = {
+-              .mask = 0x00800000,
+-              .mask_reg = QEIC_CRIMR,
+-              .pri_code = 0,
+-              .pri_reg = QEIC_CIPRTB,
+-              },
+-      [26] = {
+-              .mask = 0x00400000,
+-              .mask_reg = QEIC_CRIMR,
+-              .pri_code = 1,
+-              .pri_reg = QEIC_CIPRTB,
+-              },
+-      [27] = {
+-              .mask = 0x00200000,
+-              .mask_reg = QEIC_CRIMR,
+-              .pri_code = 2,
+-              .pri_reg = QEIC_CIPRTB,
+-              },
+-      [28] = {
+-              .mask = 0x00100000,
+-              .mask_reg = QEIC_CRIMR,
+-              .pri_code = 3,
+-              .pri_reg = QEIC_CIPRTB,
+-              },
+-      [32] = {
+-              .mask = 0x80000000,
+-              .mask_reg = QEIC_CIMR,
+-              .pri_code = 0,
+-              .pri_reg = QEIC_CIPXCC,
+-              },
+-      [33] = {
+-              .mask = 0x40000000,
+-              .mask_reg = QEIC_CIMR,
+-              .pri_code = 1,
+-              .pri_reg = QEIC_CIPXCC,
+-              },
+-      [34] = {
+-              .mask = 0x20000000,
+-              .mask_reg = QEIC_CIMR,
+-              .pri_code = 2,
+-              .pri_reg = QEIC_CIPXCC,
+-              },
+-      [35] = {
+-              .mask = 0x10000000,
+-              .mask_reg = QEIC_CIMR,
+-              .pri_code = 3,
+-              .pri_reg = QEIC_CIPXCC,
+-              },
+-      [36] = {
+-              .mask = 0x08000000,
+-              .mask_reg = QEIC_CIMR,
+-              .pri_code = 4,
+-              .pri_reg = QEIC_CIPXCC,
+-              },
+-      [40] = {
+-              .mask = 0x00800000,
+-              .mask_reg = QEIC_CIMR,
+-              .pri_code = 0,
+-              .pri_reg = QEIC_CIPYCC,
+-              },
+-      [41] = {
+-              .mask = 0x00400000,
+-              .mask_reg = QEIC_CIMR,
+-              .pri_code = 1,
+-              .pri_reg = QEIC_CIPYCC,
+-              },
+-      [42] = {
+-              .mask = 0x00200000,
+-              .mask_reg = QEIC_CIMR,
+-              .pri_code = 2,
+-              .pri_reg = QEIC_CIPYCC,
+-              },
+-      [43] = {
+-              .mask = 0x00100000,
+-              .mask_reg = QEIC_CIMR,
+-              .pri_code = 3,
+-              .pri_reg = QEIC_CIPYCC,
+-              },
+-};
+-
+-static inline u32 qe_ic_read(volatile __be32  __iomem * base, unsigned int reg)
+-{
+-      return in_be32(base + (reg >> 2));
+-}
+-
+-static inline void qe_ic_write(volatile __be32  __iomem * base, unsigned int reg,
+-                             u32 value)
+-{
+-      out_be32(base + (reg >> 2), value);
+-}
+-
+-static inline struct qe_ic *qe_ic_from_irq(unsigned int virq)
+-{
+-      return irq_get_chip_data(virq);
+-}
+-
+-static inline struct qe_ic *qe_ic_from_irq_data(struct irq_data *d)
+-{
+-      return irq_data_get_irq_chip_data(d);
+-}
+-
+-static void qe_ic_unmask_irq(struct irq_data *d)
+-{
+-      struct qe_ic *qe_ic = qe_ic_from_irq_data(d);
+-      unsigned int src = irqd_to_hwirq(d);
+-      unsigned long flags;
+-      u32 temp;
+-
+-      raw_spin_lock_irqsave(&qe_ic_lock, flags);
+-
+-      temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
+-      qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
+-                  temp | qe_ic_info[src].mask);
+-
+-      raw_spin_unlock_irqrestore(&qe_ic_lock, flags);
+-}
+-
+-static void qe_ic_mask_irq(struct irq_data *d)
+-{
+-      struct qe_ic *qe_ic = qe_ic_from_irq_data(d);
+-      unsigned int src = irqd_to_hwirq(d);
+-      unsigned long flags;
+-      u32 temp;
+-
+-      raw_spin_lock_irqsave(&qe_ic_lock, flags);
+-
+-      temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
+-      qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
+-                  temp & ~qe_ic_info[src].mask);
+-
+-      /* Flush the above write before enabling interrupts; otherwise,
+-       * spurious interrupts will sometimes happen.  To be 100% sure
+-       * that the write has reached the device before interrupts are
+-       * enabled, the mask register would have to be read back; however,
+-       * this is not required for correctness, only to avoid wasting
+-       * time on a large number of spurious interrupts.  In testing,
+-       * a sync reduced the observed spurious interrupts to zero.
+-       */
+-      mb();
+-
+-      raw_spin_unlock_irqrestore(&qe_ic_lock, flags);
+-}
+-
+-static struct irq_chip qe_ic_irq_chip = {
+-      .name = "QEIC",
+-      .irq_unmask = qe_ic_unmask_irq,
+-      .irq_mask = qe_ic_mask_irq,
+-      .irq_mask_ack = qe_ic_mask_irq,
+-};
+-
+-static int qe_ic_host_match(struct irq_domain *h, struct device_node *node,
+-                          enum irq_domain_bus_token bus_token)
+-{
+-      /* Exact match, unless qe_ic node is NULL */
+-      struct device_node *of_node = irq_domain_get_of_node(h);
+-      return of_node == NULL || of_node == node;
+-}
+-
+-static int qe_ic_host_map(struct irq_domain *h, unsigned int virq,
+-                        irq_hw_number_t hw)
+-{
+-      struct qe_ic *qe_ic = h->host_data;
+-      struct irq_chip *chip;
+-
+-      if (hw >= ARRAY_SIZE(qe_ic_info)) {
+-              pr_err("%s: Invalid hw irq number for QEIC\n", __func__);
+-              return -EINVAL;
+-      }
+-
+-      if (qe_ic_info[hw].mask == 0) {
+-              printk(KERN_ERR "Can't map reserved IRQ\n");
+-              return -EINVAL;
+-      }
+-      /* Default chip */
+-      chip = &qe_ic->hc_irq;
+-
+-      irq_set_chip_data(virq, qe_ic);
+-      irq_set_status_flags(virq, IRQ_LEVEL);
+-
+-      irq_set_chip_and_handler(virq, chip, handle_level_irq);
+-
+-      return 0;
+-}
+-
+-static const struct irq_domain_ops qe_ic_host_ops = {
+-      .match = qe_ic_host_match,
+-      .map = qe_ic_host_map,
+-      .xlate = irq_domain_xlate_onetwocell,
+-};
+-
+-/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
+-unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic)
+-{
+-      int irq;
+-
+-      BUG_ON(qe_ic == NULL);
+-
+-      /* get the interrupt source vector. */
+-      irq = qe_ic_read(qe_ic->regs, QEIC_CIVEC) >> 26;
+-
+-      if (irq == 0)
+-              return NO_IRQ;
+-
+-      return irq_linear_revmap(qe_ic->irqhost, irq);
+-}
+-
+-/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
+-unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic)
+-{
+-      int irq;
+-
+-      BUG_ON(qe_ic == NULL);
+-
+-      /* get the interrupt source vector. */
+-      irq = qe_ic_read(qe_ic->regs, QEIC_CHIVEC) >> 26;
+-
+-      if (irq == 0)
+-              return NO_IRQ;
+-
+-      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))
+-{
+-      struct qe_ic *qe_ic;
+-      struct resource res;
+-      u32 temp = 0, ret, high_active = 0;
+-
+-      ret = of_address_to_resource(node, 0, &res);
+-      if (ret)
+-              return;
+-
+-      qe_ic = kzalloc(sizeof(*qe_ic), GFP_KERNEL);
+-      if (qe_ic == NULL)
+-              return;
+-
+-      qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS,
+-                                             &qe_ic_host_ops, qe_ic);
+-      if (qe_ic->irqhost == NULL) {
+-              kfree(qe_ic);
+-              return;
+-      }
+-
+-      qe_ic->regs = ioremap(res.start, resource_size(&res));
+-
+-      qe_ic->hc_irq = qe_ic_irq_chip;
+-
+-      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) {
+-              printk(KERN_ERR "Failed to map QE_IC low IRQ\n");
+-              kfree(qe_ic);
+-              return;
+-      }
+-
+-      /* default priority scheme is grouped. If spread mode is    */
+-      /* required, configure cicr accordingly.                    */
+-      if (flags & QE_IC_SPREADMODE_GRP_W)
+-              temp |= CICR_GWCC;
+-      if (flags & QE_IC_SPREADMODE_GRP_X)
+-              temp |= CICR_GXCC;
+-      if (flags & QE_IC_SPREADMODE_GRP_Y)
+-              temp |= CICR_GYCC;
+-      if (flags & QE_IC_SPREADMODE_GRP_Z)
+-              temp |= CICR_GZCC;
+-      if (flags & QE_IC_SPREADMODE_GRP_RISCA)
+-              temp |= CICR_GRTA;
+-      if (flags & QE_IC_SPREADMODE_GRP_RISCB)
+-              temp |= CICR_GRTB;
+-
+-      /* choose destination signal for highest priority interrupt */
+-      if (flags & QE_IC_HIGH_SIGNAL) {
+-              temp |= (SIGNAL_HIGH << CICR_HPIT_SHIFT);
+-              high_active = 1;
+-      }
+-
+-      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);
+-
+-      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);
+-      }
+-}
+-
+-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);
+-      u32 temp = 0;
+-
+-      temp = qe_ic_read(qe_ic->regs, QEIC_CICR);
+-
+-      temp &= ~CICR_HP_MASK;
+-      temp |= src << CICR_HP_SHIFT;
+-
+-      temp &= ~CICR_HPIT_MASK;
+-      temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << CICR_HPIT_SHIFT;
+-
+-      qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
+-}
+-
+-/* Set Priority level within its group, from 1 to 8 */
+-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);
+-      u32 temp;
+-
+-      if (priority > 8 || priority == 0)
+-              return -EINVAL;
+-      if (WARN_ONCE(src >= ARRAY_SIZE(qe_ic_info),
+-                    "%s: Invalid hw irq number for QEIC\n", __func__))
+-              return -EINVAL;
+-      if (qe_ic_info[src].pri_reg == 0)
+-              return -EINVAL;
+-
+-      temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].pri_reg);
+-
+-      if (priority < 4) {
+-              temp &= ~(0x7 << (32 - priority * 3));
+-              temp |= qe_ic_info[src].pri_code << (32 - priority * 3);
+-      } else {
+-              temp &= ~(0x7 << (24 - priority * 3));
+-              temp |= qe_ic_info[src].pri_code << (24 - priority * 3);
+-      }
+-
+-      qe_ic_write(qe_ic->regs, qe_ic_info[src].pri_reg, temp);
+-
+-      return 0;
+-}
+-
+-/* Set a QE priority to use high irq, only priority 1~2 can use high irq */
+-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);
+-      u32 temp, control_reg = QEIC_CICNR, shift = 0;
+-
+-      if (priority > 2 || priority == 0)
+-              return -EINVAL;
+-      if (WARN_ONCE(src >= ARRAY_SIZE(qe_ic_info),
+-                    "%s: Invalid hw irq number for QEIC\n", __func__))
+-              return -EINVAL;
+-
+-      switch (qe_ic_info[src].pri_reg) {
+-      case QEIC_CIPZCC:
+-              shift = CICNR_ZCC1T_SHIFT;
+-              break;
+-      case QEIC_CIPWCC:
+-              shift = CICNR_WCC1T_SHIFT;
+-              break;
+-      case QEIC_CIPYCC:
+-              shift = CICNR_YCC1T_SHIFT;
+-              break;
+-      case QEIC_CIPXCC:
+-              shift = CICNR_XCC1T_SHIFT;
+-              break;
+-      case QEIC_CIPRTA:
+-              shift = CRICR_RTA1T_SHIFT;
+-              control_reg = QEIC_CRICR;
+-              break;
+-      case QEIC_CIPRTB:
+-              shift = CRICR_RTB1T_SHIFT;
+-              control_reg = QEIC_CRICR;
+-              break;
+-      default:
+-              return -EINVAL;
+-      }
+-
+-      shift += (2 - priority) * 2;
+-      temp = qe_ic_read(qe_ic->regs, control_reg);
+-      temp &= ~(SIGNAL_MASK << shift);
+-      temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << shift;
+-      qe_ic_write(qe_ic->regs, control_reg, temp);
+-
+-      return 0;
+-}
+-
+-static struct bus_type qe_ic_subsys = {
+-      .name = "qe_ic",
+-      .dev_name = "qe_ic",
+-};
+-
+-static struct device device_qe_ic = {
+-      .id = 0,
+-      .bus = &qe_ic_subsys,
+-};
+-
+-static int __init init_qe_ic_sysfs(void)
+-{
+-      int rc;
+-
+-      printk(KERN_DEBUG "Registering qe_ic with sysfs...\n");
+-
+-      rc = subsys_system_register(&qe_ic_subsys, NULL);
+-      if (rc) {
+-              printk(KERN_ERR "Failed registering qe_ic sys class\n");
+-              return -ENODEV;
+-      }
+-      rc = device_register(&device_qe_ic);
+-      if (rc) {
+-              printk(KERN_ERR "Failed registering qe_ic sys device\n");
+-              return -ENODEV;
+-      }
+-      return 0;
+-}
+-
+-subsys_initcall(init_qe_ic_sysfs);
+--- a/drivers/soc/fsl/qe/qe_ic.h
++++ /dev/null
+@@ -1,99 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0-or-later */
+-/*
+- * drivers/soc/fsl/qe/qe_ic.h
+- *
+- * QUICC ENGINE Interrupt Controller Header
+- *
+- * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
+- *
+- * Author: Li Yang <leoli@freescale.com>
+- * Based on code from Shlomi Gridish <gridish@freescale.com>
+- */
+-#ifndef _POWERPC_SYSDEV_QE_IC_H
+-#define _POWERPC_SYSDEV_QE_IC_H
+-
+-#include <soc/fsl/qe/qe_ic.h>
+-
+-#define NR_QE_IC_INTS         64
+-
+-/* QE IC registers offset */
+-#define QEIC_CICR             0x00
+-#define QEIC_CIVEC            0x04
+-#define QEIC_CRIPNR           0x08
+-#define QEIC_CIPNR            0x0c
+-#define QEIC_CIPXCC           0x10
+-#define QEIC_CIPYCC           0x14
+-#define QEIC_CIPWCC           0x18
+-#define QEIC_CIPZCC           0x1c
+-#define QEIC_CIMR             0x20
+-#define QEIC_CRIMR            0x24
+-#define QEIC_CICNR            0x28
+-#define QEIC_CIPRTA           0x30
+-#define QEIC_CIPRTB           0x34
+-#define QEIC_CRICR            0x3c
+-#define QEIC_CHIVEC           0x60
+-
+-/* 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             0x00040000
+-#define CICR_GXCC             0x00020000
+-#define CICR_GYCC             0x00010000
+-#define CICR_GZCC             0x00080000
+-#define CICR_GRTA             0x00200000
+-#define CICR_GRTB             0x00400000
+-#define CICR_HPIT_SHIFT               8
+-#define CICR_HPIT_MASK                0x00000300
+-#define CICR_HP_SHIFT         24
+-#define CICR_HP_MASK          0x3f000000
+-
+-/* 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_MASK           3
+-#define SIGNAL_HIGH           2
+-#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 {
+-      u32     mask;     /* location of this source at the QIMR register. */
+-      u32     mask_reg; /* Mask register offset */
+-      u8      pri_code; /* for grouped interrupts sources - the interrupt
+-                           code as appears at the group priority register */
+-      u32     pri_reg;  /* Group priority register offset */
+-};
+-
+-#endif /* _POWERPC_SYSDEV_QE_IC_H */