All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2 00/10] microblaze/MIPS: xilfpga: intc and peripheral
@ 2016-08-18 13:43 ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

Hi,

The MIPS based Xilfpga platform uses the axi interrupt controller
daisy chained to the MIPS microAptiv cpu interrupt controller.
This patch series moves the axi interrupt controller driver out
of arch/microblaze to drivers/irqchip. This makes it usable by
MIPS. The rest of the series basically enables drivers and adds dt
nodes.

Would make sense for this to go via the MIPS tree.
Hence, ACKs from microblaze. irqchip and net welcome.

Compile tested on microblaze-el only!
Based on v4.8-rc2

Regards,
ZubairLK

V1 -> V2
Resubmitting without truncating the diff output for file moves
Removed accidental local mac address entry
Individual logs have more detail

Zubair Lutfullah Kakakhel (10):
  microblaze: irqchip: Move intc driver to irqchip
  irqchip: xilinx: Add support for parent intc
  MIPS: xilfpga: Use irqchip_init instead of the legacy way
  MIPS: xilfpga: Use Xilinx AXI Interrupt Controller
  MIPS: xilfpga: Update DT node and specify uart irq
  MIPS: Xilfpga: Add DT node for AXI I2C
  net: ethernet: xilinx: Generate random mac if none found
  net: ethernet: xilinx: Enable emaclite for MIPS
  MIPS: xilfpga: Add DT node for AXI emaclite
  MIPS: xilfpga: Update defconfig

 arch/microblaze/Kconfig                       |   1 +
 arch/microblaze/kernel/Makefile               |   2 +-
 arch/microblaze/kernel/intc.c                 | 196 -----------------------
 arch/mips/Kconfig                             |   1 +
 arch/mips/boot/dts/xilfpga/nexys4ddr.dts      |  63 ++++++++
 arch/mips/configs/xilfpga_defconfig           |  37 ++++-
 arch/mips/xilfpga/intc.c                      |   7 +-
 drivers/irqchip/Kconfig                       |   4 +
 drivers/irqchip/Makefile                      |   1 +
 drivers/irqchip/irq-axi-intc.c                | 222 ++++++++++++++++++++++++++
 drivers/net/ethernet/xilinx/Kconfig           |   4 +-
 drivers/net/ethernet/xilinx/xilinx_emaclite.c |   6 +-
 12 files changed, 337 insertions(+), 207 deletions(-)
 delete mode 100644 arch/microblaze/kernel/intc.c
 create mode 100644 drivers/irqchip/irq-axi-intc.c

-- 
1.9.1

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH V2 00/10] microblaze/MIPS: xilfpga: intc and peripheral
@ 2016-08-18 13:43 ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

Hi,

The MIPS based Xilfpga platform uses the axi interrupt controller
daisy chained to the MIPS microAptiv cpu interrupt controller.
This patch series moves the axi interrupt controller driver out
of arch/microblaze to drivers/irqchip. This makes it usable by
MIPS. The rest of the series basically enables drivers and adds dt
nodes.

Would make sense for this to go via the MIPS tree.
Hence, ACKs from microblaze. irqchip and net welcome.

Compile tested on microblaze-el only!
Based on v4.8-rc2

Regards,
ZubairLK

V1 -> V2
Resubmitting without truncating the diff output for file moves
Removed accidental local mac address entry
Individual logs have more detail

Zubair Lutfullah Kakakhel (10):
  microblaze: irqchip: Move intc driver to irqchip
  irqchip: xilinx: Add support for parent intc
  MIPS: xilfpga: Use irqchip_init instead of the legacy way
  MIPS: xilfpga: Use Xilinx AXI Interrupt Controller
  MIPS: xilfpga: Update DT node and specify uart irq
  MIPS: Xilfpga: Add DT node for AXI I2C
  net: ethernet: xilinx: Generate random mac if none found
  net: ethernet: xilinx: Enable emaclite for MIPS
  MIPS: xilfpga: Add DT node for AXI emaclite
  MIPS: xilfpga: Update defconfig

 arch/microblaze/Kconfig                       |   1 +
 arch/microblaze/kernel/Makefile               |   2 +-
 arch/microblaze/kernel/intc.c                 | 196 -----------------------
 arch/mips/Kconfig                             |   1 +
 arch/mips/boot/dts/xilfpga/nexys4ddr.dts      |  63 ++++++++
 arch/mips/configs/xilfpga_defconfig           |  37 ++++-
 arch/mips/xilfpga/intc.c                      |   7 +-
 drivers/irqchip/Kconfig                       |   4 +
 drivers/irqchip/Makefile                      |   1 +
 drivers/irqchip/irq-axi-intc.c                | 222 ++++++++++++++++++++++++++
 drivers/net/ethernet/xilinx/Kconfig           |   4 +-
 drivers/net/ethernet/xilinx/xilinx_emaclite.c |   6 +-
 12 files changed, 337 insertions(+), 207 deletions(-)
 delete mode 100644 arch/microblaze/kernel/intc.c
 create mode 100644 drivers/irqchip/irq-axi-intc.c

-- 
1.9.1

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH V2 01/10] microblaze: irqchip: Move intc driver to irqchip
@ 2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

The Xilinx AXI Interrupt Controller IP block is used by the MIPS
based xilfpga platform.

Move the interrupt controller code out of arch/microblaze so that
it can be used by everyone

Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>

---
V1 -> V2

Renamed irq-xilinx to irq-axi-intc
Renamed CONFIG_XILINX_INTC to CONFIG_XILINX_AXI_INTC
Patch is now without rename flag so as to facilitate review
---
 arch/microblaze/Kconfig         |   1 +
 arch/microblaze/kernel/Makefile |   2 +-
 arch/microblaze/kernel/intc.c   | 196 ----------------------------------------
 drivers/irqchip/Kconfig         |   4 +
 drivers/irqchip/Makefile        |   1 +
 drivers/irqchip/irq-axi-intc.c  | 196 ++++++++++++++++++++++++++++++++++++++++
 6 files changed, 203 insertions(+), 197 deletions(-)
 delete mode 100644 arch/microblaze/kernel/intc.c
 create mode 100644 drivers/irqchip/irq-axi-intc.c

diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index 86f6572..a9ddcaa 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -27,6 +27,7 @@ config MICROBLAZE
 	select HAVE_MEMBLOCK_NODE_MAP
 	select HAVE_OPROFILE
 	select IRQ_DOMAIN
+	select XILINX_AXI_INTC
 	select MODULES_USE_ELF_RELA
 	select OF
 	select OF_EARLY_FLATTREE
diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile
index f08baca..e098381 100644
--- a/arch/microblaze/kernel/Makefile
+++ b/arch/microblaze/kernel/Makefile
@@ -15,7 +15,7 @@ endif
 extra-y := head.o vmlinux.lds
 
 obj-y += dma.o exceptions.o \
-	hw_exception_handler.o intc.o irq.o \
+	hw_exception_handler.o irq.o \
 	platform.o process.o prom.o ptrace.o \
 	reset.o setup.o signal.o sys_microblaze.o timer.o traps.o unwind.o
 
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c
deleted file mode 100644
index 90bec7d..0000000
--- a/arch/microblaze/kernel/intc.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2007-2013 Michal Simek <monstr@monstr.eu>
- * Copyright (C) 2012-2013 Xilinx, Inc.
- * Copyright (C) 2007-2009 PetaLogix
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#include <linux/irqdomain.h>
-#include <linux/irq.h>
-#include <linux/irqchip.h>
-#include <linux/of_address.h>
-#include <linux/io.h>
-#include <linux/bug.h>
-
-static void __iomem *intc_baseaddr;
-
-/* No one else should require these constants, so define them locally here. */
-#define ISR 0x00			/* Interrupt Status Register */
-#define IPR 0x04			/* Interrupt Pending Register */
-#define IER 0x08			/* Interrupt Enable Register */
-#define IAR 0x0c			/* Interrupt Acknowledge Register */
-#define SIE 0x10			/* Set Interrupt Enable bits */
-#define CIE 0x14			/* Clear Interrupt Enable bits */
-#define IVR 0x18			/* Interrupt Vector Register */
-#define MER 0x1c			/* Master Enable Register */
-
-#define MER_ME (1<<0)
-#define MER_HIE (1<<1)
-
-static unsigned int (*read_fn)(void __iomem *);
-static void (*write_fn)(u32, void __iomem *);
-
-static void intc_write32(u32 val, void __iomem *addr)
-{
-	iowrite32(val, addr);
-}
-
-static unsigned int intc_read32(void __iomem *addr)
-{
-	return ioread32(addr);
-}
-
-static void intc_write32_be(u32 val, void __iomem *addr)
-{
-	iowrite32be(val, addr);
-}
-
-static unsigned int intc_read32_be(void __iomem *addr)
-{
-	return ioread32be(addr);
-}
-
-static void intc_enable_or_unmask(struct irq_data *d)
-{
-	unsigned long mask = 1 << d->hwirq;
-
-	pr_debug("enable_or_unmask: %ld\n", d->hwirq);
-
-	/* ack level irqs because they can't be acked during
-	 * ack function since the handle_level_irq function
-	 * acks the irq before calling the interrupt handler
-	 */
-	if (irqd_is_level_type(d))
-		write_fn(mask, intc_baseaddr + IAR);
-
-	write_fn(mask, intc_baseaddr + SIE);
-}
-
-static void intc_disable_or_mask(struct irq_data *d)
-{
-	pr_debug("disable: %ld\n", d->hwirq);
-	write_fn(1 << d->hwirq, intc_baseaddr + CIE);
-}
-
-static void intc_ack(struct irq_data *d)
-{
-	pr_debug("ack: %ld\n", d->hwirq);
-	write_fn(1 << d->hwirq, intc_baseaddr + IAR);
-}
-
-static void intc_mask_ack(struct irq_data *d)
-{
-	unsigned long mask = 1 << d->hwirq;
-
-	pr_debug("disable_and_ack: %ld\n", d->hwirq);
-	write_fn(mask, intc_baseaddr + CIE);
-	write_fn(mask, intc_baseaddr + IAR);
-}
-
-static struct irq_chip intc_dev = {
-	.name = "Xilinx INTC",
-	.irq_unmask = intc_enable_or_unmask,
-	.irq_mask = intc_disable_or_mask,
-	.irq_ack = intc_ack,
-	.irq_mask_ack = intc_mask_ack,
-};
-
-static struct irq_domain *root_domain;
-
-unsigned int get_irq(void)
-{
-	unsigned int hwirq, irq = -1;
-
-	hwirq = read_fn(intc_baseaddr + IVR);
-	if (hwirq != -1U)
-		irq = irq_find_mapping(root_domain, hwirq);
-
-	pr_debug("get_irq: hwirq=%d, irq=%d\n", hwirq, irq);
-
-	return irq;
-}
-
-static int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
-{
-	u32 intr_mask = (u32)d->host_data;
-
-	if (intr_mask & (1 << hw)) {
-		irq_set_chip_and_handler_name(irq, &intc_dev,
-						handle_edge_irq, "edge");
-		irq_clear_status_flags(irq, IRQ_LEVEL);
-	} else {
-		irq_set_chip_and_handler_name(irq, &intc_dev,
-						handle_level_irq, "level");
-		irq_set_status_flags(irq, IRQ_LEVEL);
-	}
-	return 0;
-}
-
-static const struct irq_domain_ops xintc_irq_domain_ops = {
-	.xlate = irq_domain_xlate_onetwocell,
-	.map = xintc_map,
-};
-
-static int __init xilinx_intc_of_init(struct device_node *intc,
-					     struct device_node *parent)
-{
-	u32 nr_irq, intr_mask;
-	int ret;
-
-	intc_baseaddr = of_iomap(intc, 0);
-	BUG_ON(!intc_baseaddr);
-
-	ret = of_property_read_u32(intc, "xlnx,num-intr-inputs", &nr_irq);
-	if (ret < 0) {
-		pr_err("%s: unable to read xlnx,num-intr-inputs\n", __func__);
-		return ret;
-	}
-
-	ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &intr_mask);
-	if (ret < 0) {
-		pr_err("%s: unable to read xlnx,kind-of-intr\n", __func__);
-		return ret;
-	}
-
-	if (intr_mask >> nr_irq)
-		pr_warn("%s: mismatch in kind-of-intr param\n", __func__);
-
-	pr_info("%s: num_irq=%d, edge=0x%x\n",
-		intc->full_name, nr_irq, intr_mask);
-
-	write_fn = intc_write32;
-	read_fn = intc_read32;
-
-	/*
-	 * Disable all external interrupts until they are
-	 * explicity requested.
-	 */
-	write_fn(0, intc_baseaddr + IER);
-
-	/* Acknowledge any pending interrupts just in case. */
-	write_fn(0xffffffff, intc_baseaddr + IAR);
-
-	/* Turn on the Master Enable. */
-	write_fn(MER_HIE | MER_ME, intc_baseaddr + MER);
-	if (!(read_fn(intc_baseaddr + MER) & (MER_HIE | MER_ME))) {
-		write_fn = intc_write32_be;
-		read_fn = intc_read32_be;
-		write_fn(MER_HIE | MER_ME, intc_baseaddr + MER);
-	}
-
-	/* Yeah, okay, casting the intr_mask to a void* is butt-ugly, but I'm
-	 * lazy and Michal can clean it up to something nicer when he tests
-	 * and commits this patch.  ~~gcl */
-	root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
-							(void *)intr_mask);
-
-	irq_set_default_host(root_domain);
-
-	return 0;
-}
-
-IRQCHIP_DECLARE(xilinx_intc, "xlnx,xps-intc-1.00.a", xilinx_intc_of_init);
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 7f87289..4429888 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -203,6 +203,10 @@ config XTENSA_MX
 	bool
 	select IRQ_DOMAIN
 
+config XILINX_AXI_INTC
+	bool
+	select IRQ_DOMAIN
+
 config IRQ_CROSSBAR
 	bool
 	help
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 4c203b6..bf21f55 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_TB10X_IRQC)		+= irq-tb10x.o
 obj-$(CONFIG_TS4800_IRQ)		+= irq-ts4800.o
 obj-$(CONFIG_XTENSA)			+= irq-xtensa-pic.o
 obj-$(CONFIG_XTENSA_MX)			+= irq-xtensa-mx.o
+obj-$(CONFIG_XILINX_AXI_INTC)		+= irq-axi-intc.o
 obj-$(CONFIG_IRQ_CROSSBAR)		+= irq-crossbar.o
 obj-$(CONFIG_SOC_VF610)			+= irq-vf610-mscm-ir.o
 obj-$(CONFIG_BCM6345_L1_IRQ)		+= irq-bcm6345-l1.o
diff --git a/drivers/irqchip/irq-axi-intc.c b/drivers/irqchip/irq-axi-intc.c
new file mode 100644
index 0000000..90bec7d
--- /dev/null
+++ b/drivers/irqchip/irq-axi-intc.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2007-2013 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2012-2013 Xilinx, Inc.
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/irqdomain.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include <linux/bug.h>
+
+static void __iomem *intc_baseaddr;
+
+/* No one else should require these constants, so define them locally here. */
+#define ISR 0x00			/* Interrupt Status Register */
+#define IPR 0x04			/* Interrupt Pending Register */
+#define IER 0x08			/* Interrupt Enable Register */
+#define IAR 0x0c			/* Interrupt Acknowledge Register */
+#define SIE 0x10			/* Set Interrupt Enable bits */
+#define CIE 0x14			/* Clear Interrupt Enable bits */
+#define IVR 0x18			/* Interrupt Vector Register */
+#define MER 0x1c			/* Master Enable Register */
+
+#define MER_ME (1<<0)
+#define MER_HIE (1<<1)
+
+static unsigned int (*read_fn)(void __iomem *);
+static void (*write_fn)(u32, void __iomem *);
+
+static void intc_write32(u32 val, void __iomem *addr)
+{
+	iowrite32(val, addr);
+}
+
+static unsigned int intc_read32(void __iomem *addr)
+{
+	return ioread32(addr);
+}
+
+static void intc_write32_be(u32 val, void __iomem *addr)
+{
+	iowrite32be(val, addr);
+}
+
+static unsigned int intc_read32_be(void __iomem *addr)
+{
+	return ioread32be(addr);
+}
+
+static void intc_enable_or_unmask(struct irq_data *d)
+{
+	unsigned long mask = 1 << d->hwirq;
+
+	pr_debug("enable_or_unmask: %ld\n", d->hwirq);
+
+	/* ack level irqs because they can't be acked during
+	 * ack function since the handle_level_irq function
+	 * acks the irq before calling the interrupt handler
+	 */
+	if (irqd_is_level_type(d))
+		write_fn(mask, intc_baseaddr + IAR);
+
+	write_fn(mask, intc_baseaddr + SIE);
+}
+
+static void intc_disable_or_mask(struct irq_data *d)
+{
+	pr_debug("disable: %ld\n", d->hwirq);
+	write_fn(1 << d->hwirq, intc_baseaddr + CIE);
+}
+
+static void intc_ack(struct irq_data *d)
+{
+	pr_debug("ack: %ld\n", d->hwirq);
+	write_fn(1 << d->hwirq, intc_baseaddr + IAR);
+}
+
+static void intc_mask_ack(struct irq_data *d)
+{
+	unsigned long mask = 1 << d->hwirq;
+
+	pr_debug("disable_and_ack: %ld\n", d->hwirq);
+	write_fn(mask, intc_baseaddr + CIE);
+	write_fn(mask, intc_baseaddr + IAR);
+}
+
+static struct irq_chip intc_dev = {
+	.name = "Xilinx INTC",
+	.irq_unmask = intc_enable_or_unmask,
+	.irq_mask = intc_disable_or_mask,
+	.irq_ack = intc_ack,
+	.irq_mask_ack = intc_mask_ack,
+};
+
+static struct irq_domain *root_domain;
+
+unsigned int get_irq(void)
+{
+	unsigned int hwirq, irq = -1;
+
+	hwirq = read_fn(intc_baseaddr + IVR);
+	if (hwirq != -1U)
+		irq = irq_find_mapping(root_domain, hwirq);
+
+	pr_debug("get_irq: hwirq=%d, irq=%d\n", hwirq, irq);
+
+	return irq;
+}
+
+static int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
+{
+	u32 intr_mask = (u32)d->host_data;
+
+	if (intr_mask & (1 << hw)) {
+		irq_set_chip_and_handler_name(irq, &intc_dev,
+						handle_edge_irq, "edge");
+		irq_clear_status_flags(irq, IRQ_LEVEL);
+	} else {
+		irq_set_chip_and_handler_name(irq, &intc_dev,
+						handle_level_irq, "level");
+		irq_set_status_flags(irq, IRQ_LEVEL);
+	}
+	return 0;
+}
+
+static const struct irq_domain_ops xintc_irq_domain_ops = {
+	.xlate = irq_domain_xlate_onetwocell,
+	.map = xintc_map,
+};
+
+static int __init xilinx_intc_of_init(struct device_node *intc,
+					     struct device_node *parent)
+{
+	u32 nr_irq, intr_mask;
+	int ret;
+
+	intc_baseaddr = of_iomap(intc, 0);
+	BUG_ON(!intc_baseaddr);
+
+	ret = of_property_read_u32(intc, "xlnx,num-intr-inputs", &nr_irq);
+	if (ret < 0) {
+		pr_err("%s: unable to read xlnx,num-intr-inputs\n", __func__);
+		return ret;
+	}
+
+	ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &intr_mask);
+	if (ret < 0) {
+		pr_err("%s: unable to read xlnx,kind-of-intr\n", __func__);
+		return ret;
+	}
+
+	if (intr_mask >> nr_irq)
+		pr_warn("%s: mismatch in kind-of-intr param\n", __func__);
+
+	pr_info("%s: num_irq=%d, edge=0x%x\n",
+		intc->full_name, nr_irq, intr_mask);
+
+	write_fn = intc_write32;
+	read_fn = intc_read32;
+
+	/*
+	 * Disable all external interrupts until they are
+	 * explicity requested.
+	 */
+	write_fn(0, intc_baseaddr + IER);
+
+	/* Acknowledge any pending interrupts just in case. */
+	write_fn(0xffffffff, intc_baseaddr + IAR);
+
+	/* Turn on the Master Enable. */
+	write_fn(MER_HIE | MER_ME, intc_baseaddr + MER);
+	if (!(read_fn(intc_baseaddr + MER) & (MER_HIE | MER_ME))) {
+		write_fn = intc_write32_be;
+		read_fn = intc_read32_be;
+		write_fn(MER_HIE | MER_ME, intc_baseaddr + MER);
+	}
+
+	/* Yeah, okay, casting the intr_mask to a void* is butt-ugly, but I'm
+	 * lazy and Michal can clean it up to something nicer when he tests
+	 * and commits this patch.  ~~gcl */
+	root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
+							(void *)intr_mask);
+
+	irq_set_default_host(root_domain);
+
+	return 0;
+}
+
+IRQCHIP_DECLARE(xilinx_intc, "xlnx,xps-intc-1.00.a", xilinx_intc_of_init);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 01/10] microblaze: irqchip: Move intc driver to irqchip
@ 2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

The Xilinx AXI Interrupt Controller IP block is used by the MIPS
based xilfpga platform.

Move the interrupt controller code out of arch/microblaze so that
it can be used by everyone

Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>

---
V1 -> V2

Renamed irq-xilinx to irq-axi-intc
Renamed CONFIG_XILINX_INTC to CONFIG_XILINX_AXI_INTC
Patch is now without rename flag so as to facilitate review
---
 arch/microblaze/Kconfig         |   1 +
 arch/microblaze/kernel/Makefile |   2 +-
 arch/microblaze/kernel/intc.c   | 196 ----------------------------------------
 drivers/irqchip/Kconfig         |   4 +
 drivers/irqchip/Makefile        |   1 +
 drivers/irqchip/irq-axi-intc.c  | 196 ++++++++++++++++++++++++++++++++++++++++
 6 files changed, 203 insertions(+), 197 deletions(-)
 delete mode 100644 arch/microblaze/kernel/intc.c
 create mode 100644 drivers/irqchip/irq-axi-intc.c

diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index 86f6572..a9ddcaa 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -27,6 +27,7 @@ config MICROBLAZE
 	select HAVE_MEMBLOCK_NODE_MAP
 	select HAVE_OPROFILE
 	select IRQ_DOMAIN
+	select XILINX_AXI_INTC
 	select MODULES_USE_ELF_RELA
 	select OF
 	select OF_EARLY_FLATTREE
diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile
index f08baca..e098381 100644
--- a/arch/microblaze/kernel/Makefile
+++ b/arch/microblaze/kernel/Makefile
@@ -15,7 +15,7 @@ endif
 extra-y := head.o vmlinux.lds
 
 obj-y += dma.o exceptions.o \
-	hw_exception_handler.o intc.o irq.o \
+	hw_exception_handler.o irq.o \
 	platform.o process.o prom.o ptrace.o \
 	reset.o setup.o signal.o sys_microblaze.o timer.o traps.o unwind.o
 
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c
deleted file mode 100644
index 90bec7d..0000000
--- a/arch/microblaze/kernel/intc.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2007-2013 Michal Simek <monstr@monstr.eu>
- * Copyright (C) 2012-2013 Xilinx, Inc.
- * Copyright (C) 2007-2009 PetaLogix
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#include <linux/irqdomain.h>
-#include <linux/irq.h>
-#include <linux/irqchip.h>
-#include <linux/of_address.h>
-#include <linux/io.h>
-#include <linux/bug.h>
-
-static void __iomem *intc_baseaddr;
-
-/* No one else should require these constants, so define them locally here. */
-#define ISR 0x00			/* Interrupt Status Register */
-#define IPR 0x04			/* Interrupt Pending Register */
-#define IER 0x08			/* Interrupt Enable Register */
-#define IAR 0x0c			/* Interrupt Acknowledge Register */
-#define SIE 0x10			/* Set Interrupt Enable bits */
-#define CIE 0x14			/* Clear Interrupt Enable bits */
-#define IVR 0x18			/* Interrupt Vector Register */
-#define MER 0x1c			/* Master Enable Register */
-
-#define MER_ME (1<<0)
-#define MER_HIE (1<<1)
-
-static unsigned int (*read_fn)(void __iomem *);
-static void (*write_fn)(u32, void __iomem *);
-
-static void intc_write32(u32 val, void __iomem *addr)
-{
-	iowrite32(val, addr);
-}
-
-static unsigned int intc_read32(void __iomem *addr)
-{
-	return ioread32(addr);
-}
-
-static void intc_write32_be(u32 val, void __iomem *addr)
-{
-	iowrite32be(val, addr);
-}
-
-static unsigned int intc_read32_be(void __iomem *addr)
-{
-	return ioread32be(addr);
-}
-
-static void intc_enable_or_unmask(struct irq_data *d)
-{
-	unsigned long mask = 1 << d->hwirq;
-
-	pr_debug("enable_or_unmask: %ld\n", d->hwirq);
-
-	/* ack level irqs because they can't be acked during
-	 * ack function since the handle_level_irq function
-	 * acks the irq before calling the interrupt handler
-	 */
-	if (irqd_is_level_type(d))
-		write_fn(mask, intc_baseaddr + IAR);
-
-	write_fn(mask, intc_baseaddr + SIE);
-}
-
-static void intc_disable_or_mask(struct irq_data *d)
-{
-	pr_debug("disable: %ld\n", d->hwirq);
-	write_fn(1 << d->hwirq, intc_baseaddr + CIE);
-}
-
-static void intc_ack(struct irq_data *d)
-{
-	pr_debug("ack: %ld\n", d->hwirq);
-	write_fn(1 << d->hwirq, intc_baseaddr + IAR);
-}
-
-static void intc_mask_ack(struct irq_data *d)
-{
-	unsigned long mask = 1 << d->hwirq;
-
-	pr_debug("disable_and_ack: %ld\n", d->hwirq);
-	write_fn(mask, intc_baseaddr + CIE);
-	write_fn(mask, intc_baseaddr + IAR);
-}
-
-static struct irq_chip intc_dev = {
-	.name = "Xilinx INTC",
-	.irq_unmask = intc_enable_or_unmask,
-	.irq_mask = intc_disable_or_mask,
-	.irq_ack = intc_ack,
-	.irq_mask_ack = intc_mask_ack,
-};
-
-static struct irq_domain *root_domain;
-
-unsigned int get_irq(void)
-{
-	unsigned int hwirq, irq = -1;
-
-	hwirq = read_fn(intc_baseaddr + IVR);
-	if (hwirq != -1U)
-		irq = irq_find_mapping(root_domain, hwirq);
-
-	pr_debug("get_irq: hwirq=%d, irq=%d\n", hwirq, irq);
-
-	return irq;
-}
-
-static int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
-{
-	u32 intr_mask = (u32)d->host_data;
-
-	if (intr_mask & (1 << hw)) {
-		irq_set_chip_and_handler_name(irq, &intc_dev,
-						handle_edge_irq, "edge");
-		irq_clear_status_flags(irq, IRQ_LEVEL);
-	} else {
-		irq_set_chip_and_handler_name(irq, &intc_dev,
-						handle_level_irq, "level");
-		irq_set_status_flags(irq, IRQ_LEVEL);
-	}
-	return 0;
-}
-
-static const struct irq_domain_ops xintc_irq_domain_ops = {
-	.xlate = irq_domain_xlate_onetwocell,
-	.map = xintc_map,
-};
-
-static int __init xilinx_intc_of_init(struct device_node *intc,
-					     struct device_node *parent)
-{
-	u32 nr_irq, intr_mask;
-	int ret;
-
-	intc_baseaddr = of_iomap(intc, 0);
-	BUG_ON(!intc_baseaddr);
-
-	ret = of_property_read_u32(intc, "xlnx,num-intr-inputs", &nr_irq);
-	if (ret < 0) {
-		pr_err("%s: unable to read xlnx,num-intr-inputs\n", __func__);
-		return ret;
-	}
-
-	ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &intr_mask);
-	if (ret < 0) {
-		pr_err("%s: unable to read xlnx,kind-of-intr\n", __func__);
-		return ret;
-	}
-
-	if (intr_mask >> nr_irq)
-		pr_warn("%s: mismatch in kind-of-intr param\n", __func__);
-
-	pr_info("%s: num_irq=%d, edge=0x%x\n",
-		intc->full_name, nr_irq, intr_mask);
-
-	write_fn = intc_write32;
-	read_fn = intc_read32;
-
-	/*
-	 * Disable all external interrupts until they are
-	 * explicity requested.
-	 */
-	write_fn(0, intc_baseaddr + IER);
-
-	/* Acknowledge any pending interrupts just in case. */
-	write_fn(0xffffffff, intc_baseaddr + IAR);
-
-	/* Turn on the Master Enable. */
-	write_fn(MER_HIE | MER_ME, intc_baseaddr + MER);
-	if (!(read_fn(intc_baseaddr + MER) & (MER_HIE | MER_ME))) {
-		write_fn = intc_write32_be;
-		read_fn = intc_read32_be;
-		write_fn(MER_HIE | MER_ME, intc_baseaddr + MER);
-	}
-
-	/* Yeah, okay, casting the intr_mask to a void* is butt-ugly, but I'm
-	 * lazy and Michal can clean it up to something nicer when he tests
-	 * and commits this patch.  ~~gcl */
-	root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
-							(void *)intr_mask);
-
-	irq_set_default_host(root_domain);
-
-	return 0;
-}
-
-IRQCHIP_DECLARE(xilinx_intc, "xlnx,xps-intc-1.00.a", xilinx_intc_of_init);
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 7f87289..4429888 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -203,6 +203,10 @@ config XTENSA_MX
 	bool
 	select IRQ_DOMAIN
 
+config XILINX_AXI_INTC
+	bool
+	select IRQ_DOMAIN
+
 config IRQ_CROSSBAR
 	bool
 	help
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 4c203b6..bf21f55 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_TB10X_IRQC)		+= irq-tb10x.o
 obj-$(CONFIG_TS4800_IRQ)		+= irq-ts4800.o
 obj-$(CONFIG_XTENSA)			+= irq-xtensa-pic.o
 obj-$(CONFIG_XTENSA_MX)			+= irq-xtensa-mx.o
+obj-$(CONFIG_XILINX_AXI_INTC)		+= irq-axi-intc.o
 obj-$(CONFIG_IRQ_CROSSBAR)		+= irq-crossbar.o
 obj-$(CONFIG_SOC_VF610)			+= irq-vf610-mscm-ir.o
 obj-$(CONFIG_BCM6345_L1_IRQ)		+= irq-bcm6345-l1.o
diff --git a/drivers/irqchip/irq-axi-intc.c b/drivers/irqchip/irq-axi-intc.c
new file mode 100644
index 0000000..90bec7d
--- /dev/null
+++ b/drivers/irqchip/irq-axi-intc.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2007-2013 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2012-2013 Xilinx, Inc.
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/irqdomain.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include <linux/bug.h>
+
+static void __iomem *intc_baseaddr;
+
+/* No one else should require these constants, so define them locally here. */
+#define ISR 0x00			/* Interrupt Status Register */
+#define IPR 0x04			/* Interrupt Pending Register */
+#define IER 0x08			/* Interrupt Enable Register */
+#define IAR 0x0c			/* Interrupt Acknowledge Register */
+#define SIE 0x10			/* Set Interrupt Enable bits */
+#define CIE 0x14			/* Clear Interrupt Enable bits */
+#define IVR 0x18			/* Interrupt Vector Register */
+#define MER 0x1c			/* Master Enable Register */
+
+#define MER_ME (1<<0)
+#define MER_HIE (1<<1)
+
+static unsigned int (*read_fn)(void __iomem *);
+static void (*write_fn)(u32, void __iomem *);
+
+static void intc_write32(u32 val, void __iomem *addr)
+{
+	iowrite32(val, addr);
+}
+
+static unsigned int intc_read32(void __iomem *addr)
+{
+	return ioread32(addr);
+}
+
+static void intc_write32_be(u32 val, void __iomem *addr)
+{
+	iowrite32be(val, addr);
+}
+
+static unsigned int intc_read32_be(void __iomem *addr)
+{
+	return ioread32be(addr);
+}
+
+static void intc_enable_or_unmask(struct irq_data *d)
+{
+	unsigned long mask = 1 << d->hwirq;
+
+	pr_debug("enable_or_unmask: %ld\n", d->hwirq);
+
+	/* ack level irqs because they can't be acked during
+	 * ack function since the handle_level_irq function
+	 * acks the irq before calling the interrupt handler
+	 */
+	if (irqd_is_level_type(d))
+		write_fn(mask, intc_baseaddr + IAR);
+
+	write_fn(mask, intc_baseaddr + SIE);
+}
+
+static void intc_disable_or_mask(struct irq_data *d)
+{
+	pr_debug("disable: %ld\n", d->hwirq);
+	write_fn(1 << d->hwirq, intc_baseaddr + CIE);
+}
+
+static void intc_ack(struct irq_data *d)
+{
+	pr_debug("ack: %ld\n", d->hwirq);
+	write_fn(1 << d->hwirq, intc_baseaddr + IAR);
+}
+
+static void intc_mask_ack(struct irq_data *d)
+{
+	unsigned long mask = 1 << d->hwirq;
+
+	pr_debug("disable_and_ack: %ld\n", d->hwirq);
+	write_fn(mask, intc_baseaddr + CIE);
+	write_fn(mask, intc_baseaddr + IAR);
+}
+
+static struct irq_chip intc_dev = {
+	.name = "Xilinx INTC",
+	.irq_unmask = intc_enable_or_unmask,
+	.irq_mask = intc_disable_or_mask,
+	.irq_ack = intc_ack,
+	.irq_mask_ack = intc_mask_ack,
+};
+
+static struct irq_domain *root_domain;
+
+unsigned int get_irq(void)
+{
+	unsigned int hwirq, irq = -1;
+
+	hwirq = read_fn(intc_baseaddr + IVR);
+	if (hwirq != -1U)
+		irq = irq_find_mapping(root_domain, hwirq);
+
+	pr_debug("get_irq: hwirq=%d, irq=%d\n", hwirq, irq);
+
+	return irq;
+}
+
+static int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
+{
+	u32 intr_mask = (u32)d->host_data;
+
+	if (intr_mask & (1 << hw)) {
+		irq_set_chip_and_handler_name(irq, &intc_dev,
+						handle_edge_irq, "edge");
+		irq_clear_status_flags(irq, IRQ_LEVEL);
+	} else {
+		irq_set_chip_and_handler_name(irq, &intc_dev,
+						handle_level_irq, "level");
+		irq_set_status_flags(irq, IRQ_LEVEL);
+	}
+	return 0;
+}
+
+static const struct irq_domain_ops xintc_irq_domain_ops = {
+	.xlate = irq_domain_xlate_onetwocell,
+	.map = xintc_map,
+};
+
+static int __init xilinx_intc_of_init(struct device_node *intc,
+					     struct device_node *parent)
+{
+	u32 nr_irq, intr_mask;
+	int ret;
+
+	intc_baseaddr = of_iomap(intc, 0);
+	BUG_ON(!intc_baseaddr);
+
+	ret = of_property_read_u32(intc, "xlnx,num-intr-inputs", &nr_irq);
+	if (ret < 0) {
+		pr_err("%s: unable to read xlnx,num-intr-inputs\n", __func__);
+		return ret;
+	}
+
+	ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &intr_mask);
+	if (ret < 0) {
+		pr_err("%s: unable to read xlnx,kind-of-intr\n", __func__);
+		return ret;
+	}
+
+	if (intr_mask >> nr_irq)
+		pr_warn("%s: mismatch in kind-of-intr param\n", __func__);
+
+	pr_info("%s: num_irq=%d, edge=0x%x\n",
+		intc->full_name, nr_irq, intr_mask);
+
+	write_fn = intc_write32;
+	read_fn = intc_read32;
+
+	/*
+	 * Disable all external interrupts until they are
+	 * explicity requested.
+	 */
+	write_fn(0, intc_baseaddr + IER);
+
+	/* Acknowledge any pending interrupts just in case. */
+	write_fn(0xffffffff, intc_baseaddr + IAR);
+
+	/* Turn on the Master Enable. */
+	write_fn(MER_HIE | MER_ME, intc_baseaddr + MER);
+	if (!(read_fn(intc_baseaddr + MER) & (MER_HIE | MER_ME))) {
+		write_fn = intc_write32_be;
+		read_fn = intc_read32_be;
+		write_fn(MER_HIE | MER_ME, intc_baseaddr + MER);
+	}
+
+	/* Yeah, okay, casting the intr_mask to a void* is butt-ugly, but I'm
+	 * lazy and Michal can clean it up to something nicer when he tests
+	 * and commits this patch.  ~~gcl */
+	root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
+							(void *)intr_mask);
+
+	irq_set_default_host(root_domain);
+
+	return 0;
+}
+
+IRQCHIP_DECLARE(xilinx_intc, "xlnx,xps-intc-1.00.a", xilinx_intc_of_init);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 02/10] irqchip: xilinx: Add support for parent intc
@ 2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

The MIPS based xilfpga platform has the following IRQ structure

Peripherals --> xilinx_intcontroller -> mips_cpu_int controller

Add support for the driver to chain the irq handler

Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>

---
V1 -> V2

No change
---
 drivers/irqchip/irq-axi-intc.c | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-axi-intc.c b/drivers/irqchip/irq-axi-intc.c
index 90bec7d..a0be6fa 100644
--- a/drivers/irqchip/irq-axi-intc.c
+++ b/drivers/irqchip/irq-axi-intc.c
@@ -15,6 +15,7 @@
 #include <linux/of_address.h>
 #include <linux/io.h>
 #include <linux/bug.h>
+#include <linux/of_irq.h>
 
 static void __iomem *intc_baseaddr;
 
@@ -135,11 +136,26 @@ static const struct irq_domain_ops xintc_irq_domain_ops = {
 	.map = xintc_map,
 };
 
+static void xil_intc_irq_handler(struct irq_desc *desc)
+{
+	u32 pending = get_irq();
+
+	if (pending != -1U) {
+		while (true) {
+			pending = get_irq();
+			generic_handle_irq(pending);
+			if (pending == -1U)
+				break;
+		}
+	}
+}
+
 static int __init xilinx_intc_of_init(struct device_node *intc,
 					     struct device_node *parent)
 {
 	u32 nr_irq, intr_mask;
-	int ret;
+	int ret, irq;
+	struct device_node *parent_node;
 
 	intc_baseaddr = of_iomap(intc, 0);
 	BUG_ON(!intc_baseaddr);
@@ -188,6 +204,16 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
 	root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
 							(void *)intr_mask);
 
+	parent_node = of_irq_find_parent(intc);
+	if (parent_node) {
+		irq = irq_of_parse_and_map(intc, 0);
+		if (irq)
+			irq_set_chained_handler_and_data(irq,
+							 xil_intc_irq_handler,
+							 root_domain);
+
+	}
+
 	irq_set_default_host(root_domain);
 
 	return 0;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 02/10] irqchip: xilinx: Add support for parent intc
@ 2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

The MIPS based xilfpga platform has the following IRQ structure

Peripherals --> xilinx_intcontroller -> mips_cpu_int controller

Add support for the driver to chain the irq handler

Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>

---
V1 -> V2

No change
---
 drivers/irqchip/irq-axi-intc.c | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-axi-intc.c b/drivers/irqchip/irq-axi-intc.c
index 90bec7d..a0be6fa 100644
--- a/drivers/irqchip/irq-axi-intc.c
+++ b/drivers/irqchip/irq-axi-intc.c
@@ -15,6 +15,7 @@
 #include <linux/of_address.h>
 #include <linux/io.h>
 #include <linux/bug.h>
+#include <linux/of_irq.h>
 
 static void __iomem *intc_baseaddr;
 
@@ -135,11 +136,26 @@ static const struct irq_domain_ops xintc_irq_domain_ops = {
 	.map = xintc_map,
 };
 
+static void xil_intc_irq_handler(struct irq_desc *desc)
+{
+	u32 pending = get_irq();
+
+	if (pending != -1U) {
+		while (true) {
+			pending = get_irq();
+			generic_handle_irq(pending);
+			if (pending == -1U)
+				break;
+		}
+	}
+}
+
 static int __init xilinx_intc_of_init(struct device_node *intc,
 					     struct device_node *parent)
 {
 	u32 nr_irq, intr_mask;
-	int ret;
+	int ret, irq;
+	struct device_node *parent_node;
 
 	intc_baseaddr = of_iomap(intc, 0);
 	BUG_ON(!intc_baseaddr);
@@ -188,6 +204,16 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
 	root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
 							(void *)intr_mask);
 
+	parent_node = of_irq_find_parent(intc);
+	if (parent_node) {
+		irq = irq_of_parse_and_map(intc, 0);
+		if (irq)
+			irq_set_chained_handler_and_data(irq,
+							 xil_intc_irq_handler,
+							 root_domain);
+
+	}
+
 	irq_set_default_host(root_domain);
 
 	return 0;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 03/10] MIPS: xilfpga: Use irqchip_init instead of the legacy way
@ 2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

This prepares the code use the Xilinx AXI Interrupt Controller
driver now available in drivers/irqchip/irq-xilinx.c

Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
---
V1 -> V2
No change
---
 arch/mips/xilfpga/intc.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/arch/mips/xilfpga/intc.c b/arch/mips/xilfpga/intc.c
index c4d1a71..a127cca 100644
--- a/arch/mips/xilfpga/intc.c
+++ b/arch/mips/xilfpga/intc.c
@@ -11,15 +11,12 @@
 
 #include <linux/of.h>
 #include <linux/of_irq.h>
+#include <linux/irqchip.h>
 
 #include <asm/irq_cpu.h>
 
-static struct of_device_id of_irq_ids[] __initdata = {
-	{ .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_irq_of_init },
-	{},
-};
 
 void __init arch_init_irq(void)
 {
-	of_irq_init(of_irq_ids);
+	irqchip_init();
 }
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 03/10] MIPS: xilfpga: Use irqchip_init instead of the legacy way
@ 2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

This prepares the code use the Xilinx AXI Interrupt Controller
driver now available in drivers/irqchip/irq-xilinx.c

Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
---
V1 -> V2
No change
---
 arch/mips/xilfpga/intc.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/arch/mips/xilfpga/intc.c b/arch/mips/xilfpga/intc.c
index c4d1a71..a127cca 100644
--- a/arch/mips/xilfpga/intc.c
+++ b/arch/mips/xilfpga/intc.c
@@ -11,15 +11,12 @@
 
 #include <linux/of.h>
 #include <linux/of_irq.h>
+#include <linux/irqchip.h>
 
 #include <asm/irq_cpu.h>
 
-static struct of_device_id of_irq_ids[] __initdata = {
-	{ .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_irq_of_init },
-	{},
-};
 
 void __init arch_init_irq(void)
 {
-	of_irq_init(of_irq_ids);
+	irqchip_init();
 }
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 04/10] MIPS: xilfpga: Use Xilinx AXI Interrupt Controller
@ 2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

IRQs from peripherals such as i2c/uart/ethernet come via
the AXI Interrupt controller.

Select it in Kconfig for xilfpga and add the DT node

Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>

---
V1 -> V2
Renamed select XILINX_INTC to select XILINX_AXI_INTC
---
 arch/mips/Kconfig                        |  1 +
 arch/mips/boot/dts/xilfpga/nexys4ddr.dts | 12 ++++++++++++
 2 files changed, 13 insertions(+)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 2638856..e8a7786 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -426,6 +426,7 @@ config MACH_XILFPGA
 	select SYS_SUPPORTS_ZBOOT_UART16550
 	select USE_OF
 	select USE_GENERIC_EARLY_PRINTK_8250
+	select XILINX_AXI_INTC
 	help
 	  This enables support for the IMG University Program MIPSfpga platform.
 
diff --git a/arch/mips/boot/dts/xilfpga/nexys4ddr.dts b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
index 48d2112..8db660b 100644
--- a/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
+++ b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
@@ -17,6 +17,18 @@
 		compatible = "mti,cpu-interrupt-controller";
 	};
 
+	axi_intc: interrupt-controller@10200000 {
+		#interrupt-cells = <1>;
+		compatible = "xlnx,xps-intc-1.00.a";
+		interrupt-controller;
+		reg = <0x10200000 0x10000>;
+		xlnx,kind-of-intr = <0x0>;
+		xlnx,num-intr-inputs = <0x6>;
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <6>;
+	};
+
 	axi_gpio: gpio@10600000 {
 		#gpio-cells = <1>;
 		compatible = "xlnx,xps-gpio-1.00.a";
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 04/10] MIPS: xilfpga: Use Xilinx AXI Interrupt Controller
@ 2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

IRQs from peripherals such as i2c/uart/ethernet come via
the AXI Interrupt controller.

Select it in Kconfig for xilfpga and add the DT node

Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>

---
V1 -> V2
Renamed select XILINX_INTC to select XILINX_AXI_INTC
---
 arch/mips/Kconfig                        |  1 +
 arch/mips/boot/dts/xilfpga/nexys4ddr.dts | 12 ++++++++++++
 2 files changed, 13 insertions(+)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 2638856..e8a7786 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -426,6 +426,7 @@ config MACH_XILFPGA
 	select SYS_SUPPORTS_ZBOOT_UART16550
 	select USE_OF
 	select USE_GENERIC_EARLY_PRINTK_8250
+	select XILINX_AXI_INTC
 	help
 	  This enables support for the IMG University Program MIPSfpga platform.
 
diff --git a/arch/mips/boot/dts/xilfpga/nexys4ddr.dts b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
index 48d2112..8db660b 100644
--- a/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
+++ b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
@@ -17,6 +17,18 @@
 		compatible = "mti,cpu-interrupt-controller";
 	};
 
+	axi_intc: interrupt-controller@10200000 {
+		#interrupt-cells = <1>;
+		compatible = "xlnx,xps-intc-1.00.a";
+		interrupt-controller;
+		reg = <0x10200000 0x10000>;
+		xlnx,kind-of-intr = <0x0>;
+		xlnx,num-intr-inputs = <0x6>;
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <6>;
+	};
+
 	axi_gpio: gpio@10600000 {
 		#gpio-cells = <1>;
 		compatible = "xlnx,xps-gpio-1.00.a";
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 05/10] MIPS: xilfpga: Update DT node and specify uart irq
@ 2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

Update the DT node with the UART irq

Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>

---
V1 -> V2

No change
---
 arch/mips/boot/dts/xilfpga/nexys4ddr.dts | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/mips/boot/dts/xilfpga/nexys4ddr.dts b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
index 8db660b..d285c8d 100644
--- a/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
+++ b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
@@ -50,6 +50,9 @@
 		reg-offset = <0x1000>;
 
 		clocks	= <&ext>;
+
+		interrupt-parent = <&axi_intc>;
+		interrupts = <0>;
 	};
 };
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 05/10] MIPS: xilfpga: Update DT node and specify uart irq
@ 2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

Update the DT node with the UART irq

Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>

---
V1 -> V2

No change
---
 arch/mips/boot/dts/xilfpga/nexys4ddr.dts | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/mips/boot/dts/xilfpga/nexys4ddr.dts b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
index 8db660b..d285c8d 100644
--- a/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
+++ b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
@@ -50,6 +50,9 @@
 		reg-offset = <0x1000>;
 
 		clocks	= <&ext>;
+
+		interrupt-parent = <&axi_intc>;
+		interrupts = <0>;
 	};
 };
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 06/10] MIPS: Xilfpga: Add DT node for AXI I2C
@ 2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

The xilfpga platform has an AXI I2C Bus master with a temperature
sensor connected to it.

Add the device tree node to use them.

Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>

---
V1 -> V2

No change
---
 arch/mips/boot/dts/xilfpga/nexys4ddr.dts | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/mips/boot/dts/xilfpga/nexys4ddr.dts b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
index d285c8d..3658e21 100644
--- a/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
+++ b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
@@ -54,6 +54,28 @@
 		interrupt-parent = <&axi_intc>;
 		interrupts = <0>;
 	};
+
+	axi_i2c: i2c@10A00000 {
+	    compatible = "xlnx,xps-iic-2.00.a";
+	    interrupt-parent = <&axi_intc>;
+	    interrupts = <4>;
+	    reg = < 0x10A00000 0x10000 >;
+	    clocks = <&ext>;
+	    xlnx,clk-freq = <0x5f5e100>;
+	    xlnx,family = "Artix7";
+	    xlnx,gpo-width = <0x1>;
+	    xlnx,iic-freq = <0x186a0>;
+	    xlnx,scl-inertial-delay = <0x0>;
+	    xlnx,sda-inertial-delay = <0x0>;
+	    xlnx,ten-bit-adr = <0x0>;
+	    #address-cells = <1>;
+	    #size-cells = <0>;
+
+	    ad7420@4B {
+		compatible = "adt7420";
+		reg = <0x4B>;
+	    };
+	} ;
 };
 
 &ext {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 06/10] MIPS: Xilfpga: Add DT node for AXI I2C
@ 2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

The xilfpga platform has an AXI I2C Bus master with a temperature
sensor connected to it.

Add the device tree node to use them.

Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>

---
V1 -> V2

No change
---
 arch/mips/boot/dts/xilfpga/nexys4ddr.dts | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/mips/boot/dts/xilfpga/nexys4ddr.dts b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
index d285c8d..3658e21 100644
--- a/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
+++ b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
@@ -54,6 +54,28 @@
 		interrupt-parent = <&axi_intc>;
 		interrupts = <0>;
 	};
+
+	axi_i2c: i2c@10A00000 {
+	    compatible = "xlnx,xps-iic-2.00.a";
+	    interrupt-parent = <&axi_intc>;
+	    interrupts = <4>;
+	    reg = < 0x10A00000 0x10000 >;
+	    clocks = <&ext>;
+	    xlnx,clk-freq = <0x5f5e100>;
+	    xlnx,family = "Artix7";
+	    xlnx,gpo-width = <0x1>;
+	    xlnx,iic-freq = <0x186a0>;
+	    xlnx,scl-inertial-delay = <0x0>;
+	    xlnx,sda-inertial-delay = <0x0>;
+	    xlnx,ten-bit-adr = <0x0>;
+	    #address-cells = <1>;
+	    #size-cells = <0>;
+
+	    ad7420@4B {
+		compatible = "adt7420";
+		reg = <0x4B>;
+	    };
+	} ;
 };
 
 &ext {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 07/10] net: ethernet: xilinx: Generate random mac if none found
@ 2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

At the moment, if the emaclite device doesn't find a mac address
from any source, it simply uses 0x0 with a warning printed.

Instead of using a 0x0 mac address, use a randomly generated one.

Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>

---
V1 -> V2
New patch
---
 drivers/net/ethernet/xilinx/xilinx_emaclite.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
index 3cee84a..22e5a5a 100644
--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
@@ -1134,8 +1134,10 @@ static int xemaclite_of_probe(struct platform_device *ofdev)
 	if (mac_address)
 		/* Set the MAC address. */
 		memcpy(ndev->dev_addr, mac_address, ETH_ALEN);
-	else
-		dev_warn(dev, "No MAC address found\n");
+	else {
+		dev_warn(dev, "No MAC address found. Generating Random one\n");
+		eth_hw_addr_random(ndev);
+	}
 
 	/* Clear the Tx CSR's in case this is a restart */
 	__raw_writel(0, lp->base_addr + XEL_TSR_OFFSET);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 07/10] net: ethernet: xilinx: Generate random mac if none found
@ 2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

At the moment, if the emaclite device doesn't find a mac address
from any source, it simply uses 0x0 with a warning printed.

Instead of using a 0x0 mac address, use a randomly generated one.

Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>

---
V1 -> V2
New patch
---
 drivers/net/ethernet/xilinx/xilinx_emaclite.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
index 3cee84a..22e5a5a 100644
--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
@@ -1134,8 +1134,10 @@ static int xemaclite_of_probe(struct platform_device *ofdev)
 	if (mac_address)
 		/* Set the MAC address. */
 		memcpy(ndev->dev_addr, mac_address, ETH_ALEN);
-	else
-		dev_warn(dev, "No MAC address found\n");
+	else {
+		dev_warn(dev, "No MAC address found. Generating Random one\n");
+		eth_hw_addr_random(ndev);
+	}
 
 	/* Clear the Tx CSR's in case this is a restart */
 	__raw_writel(0, lp->base_addr + XEL_TSR_OFFSET);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 08/10] net: ethernet: xilinx: Enable emaclite for MIPS
@ 2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

The MIPS based xilfpga platform uses this driver.
Enable it for MIPS

Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>

---
V1 -> V2

No change
---
 drivers/net/ethernet/xilinx/Kconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/Kconfig b/drivers/net/ethernet/xilinx/Kconfig
index 4f5c024..ae5c404 100644
--- a/drivers/net/ethernet/xilinx/Kconfig
+++ b/drivers/net/ethernet/xilinx/Kconfig
@@ -5,7 +5,7 @@
 config NET_VENDOR_XILINX
 	bool "Xilinx devices"
 	default y
-	depends on PPC || PPC32 || MICROBLAZE || ARCH_ZYNQ
+	depends on PPC || PPC32 || MICROBLAZE || ARCH_ZYNQ || MIPS
 	---help---
 	  If you have a network (Ethernet) card belonging to this class, say Y.
 
@@ -18,7 +18,7 @@ if NET_VENDOR_XILINX
 
 config XILINX_EMACLITE
 	tristate "Xilinx 10/100 Ethernet Lite support"
-	depends on (PPC32 || MICROBLAZE || ARCH_ZYNQ)
+	depends on (PPC32 || MICROBLAZE || ARCH_ZYNQ || MIPS)
 	select PHYLIB
 	---help---
 	  This driver supports the 10/100 Ethernet Lite from Xilinx.
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 08/10] net: ethernet: xilinx: Enable emaclite for MIPS
@ 2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

The MIPS based xilfpga platform uses this driver.
Enable it for MIPS

Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>

---
V1 -> V2

No change
---
 drivers/net/ethernet/xilinx/Kconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/Kconfig b/drivers/net/ethernet/xilinx/Kconfig
index 4f5c024..ae5c404 100644
--- a/drivers/net/ethernet/xilinx/Kconfig
+++ b/drivers/net/ethernet/xilinx/Kconfig
@@ -5,7 +5,7 @@
 config NET_VENDOR_XILINX
 	bool "Xilinx devices"
 	default y
-	depends on PPC || PPC32 || MICROBLAZE || ARCH_ZYNQ
+	depends on PPC || PPC32 || MICROBLAZE || ARCH_ZYNQ || MIPS
 	---help---
 	  If you have a network (Ethernet) card belonging to this class, say Y.
 
@@ -18,7 +18,7 @@ if NET_VENDOR_XILINX
 
 config XILINX_EMACLITE
 	tristate "Xilinx 10/100 Ethernet Lite support"
-	depends on (PPC32 || MICROBLAZE || ARCH_ZYNQ)
+	depends on (PPC32 || MICROBLAZE || ARCH_ZYNQ || MIPS)
 	select PHYLIB
 	---help---
 	  This driver supports the 10/100 Ethernet Lite from Xilinx.
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 09/10] MIPS: xilfpga: Add DT node for AXI emaclite
@ 2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

The xilfpga platform has a Xilinx AXI emaclite block.

Add the DT node to use it.

Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>

---
V1 -> V2

Removed accidental local-mac-address entry
---
 arch/mips/boot/dts/xilfpga/nexys4ddr.dts | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/mips/boot/dts/xilfpga/nexys4ddr.dts b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
index 3658e21..1f25d0a 100644
--- a/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
+++ b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
@@ -42,6 +42,32 @@
 		xlnx,tri-default = <0xffffffff>;
 	} ;
 
+	axi_ethernetlite: ethernet@10e00000 {
+		compatible = "xlnx,xps-ethernetlite-3.00.a";
+		device_type = "network";
+		interrupt-parent = <&axi_intc>;
+		interrupts = <1>;
+		phy-handle = <&phy0>;
+		reg = <0x10e00000 0x10000>;
+		xlnx,duplex = <0x1>;
+		xlnx,include-global-buffers = <0x1>;
+		xlnx,include-internal-loopback = <0x0>;
+		xlnx,include-mdio = <0x1>;
+		xlnx,instance = "axi_ethernetlite_inst";
+		xlnx,rx-ping-pong = <0x1>;
+		xlnx,s-axi-id-width = <0x1>;
+		xlnx,tx-ping-pong = <0x1>;
+		xlnx,use-internal = <0x0>;
+		mdio {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			phy0: phy@1 {
+				device_type = "ethernet-phy";
+				reg = <1>;
+			};
+		};
+	};
+
 	axi_uart16550: serial@10400000 {
 		compatible = "ns16550a";
 		reg = <0x10400000 0x10000>;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 09/10] MIPS: xilfpga: Add DT node for AXI emaclite
@ 2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

The xilfpga platform has a Xilinx AXI emaclite block.

Add the DT node to use it.

Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>

---
V1 -> V2

Removed accidental local-mac-address entry
---
 arch/mips/boot/dts/xilfpga/nexys4ddr.dts | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/mips/boot/dts/xilfpga/nexys4ddr.dts b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
index 3658e21..1f25d0a 100644
--- a/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
+++ b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
@@ -42,6 +42,32 @@
 		xlnx,tri-default = <0xffffffff>;
 	} ;
 
+	axi_ethernetlite: ethernet@10e00000 {
+		compatible = "xlnx,xps-ethernetlite-3.00.a";
+		device_type = "network";
+		interrupt-parent = <&axi_intc>;
+		interrupts = <1>;
+		phy-handle = <&phy0>;
+		reg = <0x10e00000 0x10000>;
+		xlnx,duplex = <0x1>;
+		xlnx,include-global-buffers = <0x1>;
+		xlnx,include-internal-loopback = <0x0>;
+		xlnx,include-mdio = <0x1>;
+		xlnx,instance = "axi_ethernetlite_inst";
+		xlnx,rx-ping-pong = <0x1>;
+		xlnx,s-axi-id-width = <0x1>;
+		xlnx,tx-ping-pong = <0x1>;
+		xlnx,use-internal = <0x0>;
+		mdio {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			phy0: phy@1 {
+				device_type = "ethernet-phy";
+				reg = <1>;
+			};
+		};
+	};
+
 	axi_uart16550: serial@10400000 {
 		compatible = "ns16550a";
 		reg = <0x10400000 0x10000>;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 10/10] MIPS: xilfpga: Update defconfig
@ 2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

Update defconfig to enable emaclite, i2c, temp sensor found on the
xilfpga platform

Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>

---
V1 -> V2
No change
---
 arch/mips/configs/xilfpga_defconfig | 37 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/arch/mips/configs/xilfpga_defconfig b/arch/mips/configs/xilfpga_defconfig
index ed1dce3..829c637 100644
--- a/arch/mips/configs/xilfpga_defconfig
+++ b/arch/mips/configs/xilfpga_defconfig
@@ -7,6 +7,12 @@ CONFIG_EMBEDDED=y
 CONFIG_SLAB=y
 # CONFIG_BLOCK is not set
 # CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
@@ -14,6 +20,30 @@ CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
 # CONFIG_ALLOW_DEV_COREDUMP is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_CORE is not set
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_EZCHIP is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_RENESAS is not set
+# CONFIG_NET_VENDOR_ROCKER is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SYNOPSYS is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_XILINX_EMACLITE=y
+CONFIG_SMSC_PHY=y
+# CONFIG_WLAN is not set
 # CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
@@ -25,13 +55,18 @@ CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_XILINX=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_XILINX=y
-# CONFIG_HWMON is not set
+CONFIG_SENSORS_ADT7410=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MIPS_PLATFORM_DEVICES is not set
 # CONFIG_IOMMU_SUPPORT is not set
 # CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
 # CONFIG_MISC_FILESYSTEMS is not set
 CONFIG_PANIC_ON_OOPS=y
 # CONFIG_SCHED_DEBUG is not set
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH V2 10/10] MIPS: xilfpga: Update defconfig
@ 2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

Update defconfig to enable emaclite, i2c, temp sensor found on the
xilfpga platform

Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>

---
V1 -> V2
No change
---
 arch/mips/configs/xilfpga_defconfig | 37 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/arch/mips/configs/xilfpga_defconfig b/arch/mips/configs/xilfpga_defconfig
index ed1dce3..829c637 100644
--- a/arch/mips/configs/xilfpga_defconfig
+++ b/arch/mips/configs/xilfpga_defconfig
@@ -7,6 +7,12 @@ CONFIG_EMBEDDED=y
 CONFIG_SLAB=y
 # CONFIG_BLOCK is not set
 # CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
@@ -14,6 +20,30 @@ CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
 # CONFIG_ALLOW_DEV_COREDUMP is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_CORE is not set
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_EZCHIP is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_RENESAS is not set
+# CONFIG_NET_VENDOR_ROCKER is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SYNOPSYS is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_XILINX_EMACLITE=y
+CONFIG_SMSC_PHY=y
+# CONFIG_WLAN is not set
 # CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
@@ -25,13 +55,18 @@ CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_XILINX=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_XILINX=y
-# CONFIG_HWMON is not set
+CONFIG_SENSORS_ADT7410=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MIPS_PLATFORM_DEVICES is not set
 # CONFIG_IOMMU_SUPPORT is not set
 # CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
 # CONFIG_MISC_FILESYSTEMS is not set
 CONFIG_PANIC_ON_OOPS=y
 # CONFIG_SCHED_DEBUG is not set
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH V2 00/10] microblaze/MIPS: xilfpga: intc and peripheral
@ 2016-08-26 13:41   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-26 13:41 UTC (permalink / raw)
  To: monstr, ralf, tglx; +Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev

Hi,


On 08/18/2016 02:43 PM, Zubair Lutfullah Kakakhel wrote:
> Hi,
>
> The MIPS based Xilfpga platform uses the axi interrupt controller
> daisy chained to the MIPS microAptiv cpu interrupt controller.
> This patch series moves the axi interrupt controller driver out
> of arch/microblaze to drivers/irqchip. This makes it usable by
> MIPS. The rest of the series basically enables drivers and adds dt
> nodes.
>
> Would make sense for this to go via the MIPS tree.
> Hence, ACKs from microblaze. irqchip and net welcome.
>
> Compile tested on microblaze-el only!
> Based on v4.8-rc2

Ping. Would be nice to see this in for v4.9.

Thanks
ZubairLK

>
> Regards,
> ZubairLK
>
> V1 -> V2
> Resubmitting without truncating the diff output for file moves
> Removed accidental local mac address entry
> Individual logs have more detail
>
> Zubair Lutfullah Kakakhel (10):
>   microblaze: irqchip: Move intc driver to irqchip
>   irqchip: xilinx: Add support for parent intc
>   MIPS: xilfpga: Use irqchip_init instead of the legacy way
>   MIPS: xilfpga: Use Xilinx AXI Interrupt Controller
>   MIPS: xilfpga: Update DT node and specify uart irq
>   MIPS: Xilfpga: Add DT node for AXI I2C
>   net: ethernet: xilinx: Generate random mac if none found
>   net: ethernet: xilinx: Enable emaclite for MIPS
>   MIPS: xilfpga: Add DT node for AXI emaclite
>   MIPS: xilfpga: Update defconfig
>
>  arch/microblaze/Kconfig                       |   1 +
>  arch/microblaze/kernel/Makefile               |   2 +-
>  arch/microblaze/kernel/intc.c                 | 196 -----------------------
>  arch/mips/Kconfig                             |   1 +
>  arch/mips/boot/dts/xilfpga/nexys4ddr.dts      |  63 ++++++++
>  arch/mips/configs/xilfpga_defconfig           |  37 ++++-
>  arch/mips/xilfpga/intc.c                      |   7 +-
>  drivers/irqchip/Kconfig                       |   4 +
>  drivers/irqchip/Makefile                      |   1 +
>  drivers/irqchip/irq-axi-intc.c                | 222 ++++++++++++++++++++++++++
>  drivers/net/ethernet/xilinx/Kconfig           |   4 +-
>  drivers/net/ethernet/xilinx/xilinx_emaclite.c |   6 +-
>  12 files changed, 337 insertions(+), 207 deletions(-)
>  delete mode 100644 arch/microblaze/kernel/intc.c
>  create mode 100644 drivers/irqchip/irq-axi-intc.c
>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH V2 00/10] microblaze/MIPS: xilfpga: intc and peripheral
@ 2016-08-26 13:41   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 28+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-26 13:41 UTC (permalink / raw)
  To: monstr, ralf, tglx; +Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev

Hi,


On 08/18/2016 02:43 PM, Zubair Lutfullah Kakakhel wrote:
> Hi,
>
> The MIPS based Xilfpga platform uses the axi interrupt controller
> daisy chained to the MIPS microAptiv cpu interrupt controller.
> This patch series moves the axi interrupt controller driver out
> of arch/microblaze to drivers/irqchip. This makes it usable by
> MIPS. The rest of the series basically enables drivers and adds dt
> nodes.
>
> Would make sense for this to go via the MIPS tree.
> Hence, ACKs from microblaze. irqchip and net welcome.
>
> Compile tested on microblaze-el only!
> Based on v4.8-rc2

Ping. Would be nice to see this in for v4.9.

Thanks
ZubairLK

>
> Regards,
> ZubairLK
>
> V1 -> V2
> Resubmitting without truncating the diff output for file moves
> Removed accidental local mac address entry
> Individual logs have more detail
>
> Zubair Lutfullah Kakakhel (10):
>   microblaze: irqchip: Move intc driver to irqchip
>   irqchip: xilinx: Add support for parent intc
>   MIPS: xilfpga: Use irqchip_init instead of the legacy way
>   MIPS: xilfpga: Use Xilinx AXI Interrupt Controller
>   MIPS: xilfpga: Update DT node and specify uart irq
>   MIPS: Xilfpga: Add DT node for AXI I2C
>   net: ethernet: xilinx: Generate random mac if none found
>   net: ethernet: xilinx: Enable emaclite for MIPS
>   MIPS: xilfpga: Add DT node for AXI emaclite
>   MIPS: xilfpga: Update defconfig
>
>  arch/microblaze/Kconfig                       |   1 +
>  arch/microblaze/kernel/Makefile               |   2 +-
>  arch/microblaze/kernel/intc.c                 | 196 -----------------------
>  arch/mips/Kconfig                             |   1 +
>  arch/mips/boot/dts/xilfpga/nexys4ddr.dts      |  63 ++++++++
>  arch/mips/configs/xilfpga_defconfig           |  37 ++++-
>  arch/mips/xilfpga/intc.c                      |   7 +-
>  drivers/irqchip/Kconfig                       |   4 +
>  drivers/irqchip/Makefile                      |   1 +
>  drivers/irqchip/irq-axi-intc.c                | 222 ++++++++++++++++++++++++++
>  drivers/net/ethernet/xilinx/Kconfig           |   4 +-
>  drivers/net/ethernet/xilinx/xilinx_emaclite.c |   6 +-
>  12 files changed, 337 insertions(+), 207 deletions(-)
>  delete mode 100644 arch/microblaze/kernel/intc.c
>  create mode 100644 drivers/irqchip/irq-axi-intc.c
>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH V2 01/10] microblaze: irqchip: Move intc driver to irqchip
@ 2016-08-26 14:13     ` Marc Zyngier
  0 siblings, 0 replies; 28+ messages in thread
From: Marc Zyngier @ 2016-08-26 14:13 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel
  Cc: monstr, ralf, tglx, jason, linux-mips, linux-kernel, netdev

On Thu, 18 Aug 2016 14:43:15 +0100
Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com> wrote:

Hi Zubair,

Thanks for the heads up, comments below.

> The Xilinx AXI Interrupt Controller IP block is used by the MIPS
> based xilfpga platform.
> 
> Move the interrupt controller code out of arch/microblaze so that
> it can be used by everyone
> 
> Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
> 
> ---
> V1 -> V2
> 
> Renamed irq-xilinx to irq-axi-intc
> Renamed CONFIG_XILINX_INTC to CONFIG_XILINX_AXI_INTC
> Patch is now without rename flag so as to facilitate review
> ---
>  arch/microblaze/Kconfig         |   1 +
>  arch/microblaze/kernel/Makefile |   2 +-
>  arch/microblaze/kernel/intc.c   | 196 ----------------------------------------
>  drivers/irqchip/Kconfig         |   4 +
>  drivers/irqchip/Makefile        |   1 +
>  drivers/irqchip/irq-axi-intc.c  | 196 ++++++++++++++++++++++++++++++++++++++++
>  6 files changed, 203 insertions(+), 197 deletions(-)
>  delete mode 100644 arch/microblaze/kernel/intc.c
>  create mode 100644 drivers/irqchip/irq-axi-intc.c
> 

[...]

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index 7f87289..4429888 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -203,6 +203,10 @@ config XTENSA_MX
>  	bool
>  	select IRQ_DOMAIN
>  
> +config XILINX_AXI_INTC
> +	bool
> +	select IRQ_DOMAIN
> +
>  config IRQ_CROSSBAR
>  	bool
>  	help
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index 4c203b6..bf21f55 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -51,6 +51,7 @@ obj-$(CONFIG_TB10X_IRQC)		+= irq-tb10x.o
>  obj-$(CONFIG_TS4800_IRQ)		+= irq-ts4800.o
>  obj-$(CONFIG_XTENSA)			+= irq-xtensa-pic.o
>  obj-$(CONFIG_XTENSA_MX)			+= irq-xtensa-mx.o
> +obj-$(CONFIG_XILINX_AXI_INTC)		+= irq-axi-intc.o
>  obj-$(CONFIG_IRQ_CROSSBAR)		+= irq-crossbar.o
>  obj-$(CONFIG_SOC_VF610)			+= irq-vf610-mscm-ir.o
>  obj-$(CONFIG_BCM6345_L1_IRQ)		+= irq-bcm6345-l1.o
> diff --git a/drivers/irqchip/irq-axi-intc.c b/drivers/irqchip/irq-axi-intc.c
> new file mode 100644
> index 0000000..90bec7d
> --- /dev/null
> +++ b/drivers/irqchip/irq-axi-intc.c
> @@ -0,0 +1,196 @@
> +/*
> + * Copyright (C) 2007-2013 Michal Simek <monstr@monstr.eu>
> + * Copyright (C) 2012-2013 Xilinx, Inc.
> + * Copyright (C) 2007-2009 PetaLogix
> + * Copyright (C) 2006 Atmark Techno, Inc.
> + *
> + * This file is subject to the terms and conditions of the GNU General Public
> + * License. See the file "COPYING" in the main directory of this archive
> + * for more details.
> + */
> +
> +#include <linux/irqdomain.h>
> +#include <linux/irq.h>
> +#include <linux/irqchip.h>
> +#include <linux/of_address.h>
> +#include <linux/io.h>
> +#include <linux/bug.h>
> +
> +static void __iomem *intc_baseaddr;
> +
> +/* No one else should require these constants, so define them locally here. */
> +#define ISR 0x00			/* Interrupt Status Register */
> +#define IPR 0x04			/* Interrupt Pending Register */
> +#define IER 0x08			/* Interrupt Enable Register */
> +#define IAR 0x0c			/* Interrupt Acknowledge Register */
> +#define SIE 0x10			/* Set Interrupt Enable bits */
> +#define CIE 0x14			/* Clear Interrupt Enable bits */
> +#define IVR 0x18			/* Interrupt Vector Register */
> +#define MER 0x1c			/* Master Enable Register */
> +
> +#define MER_ME (1<<0)
> +#define MER_HIE (1<<1)
> +
> +static unsigned int (*read_fn)(void __iomem *);
> +static void (*write_fn)(u32, void __iomem *);
> +
> +static void intc_write32(u32 val, void __iomem *addr)
> +{
> +	iowrite32(val, addr);
> +}
> +
> +static unsigned int intc_read32(void __iomem *addr)
> +{
> +	return ioread32(addr);
> +}
> +
> +static void intc_write32_be(u32 val, void __iomem *addr)
> +{
> +	iowrite32be(val, addr);
> +}
> +
> +static unsigned int intc_read32_be(void __iomem *addr)
> +{
> +	return ioread32be(addr);
> +}
> +
> +static void intc_enable_or_unmask(struct irq_data *d)
> +{
> +	unsigned long mask = 1 << d->hwirq;
> +
> +	pr_debug("enable_or_unmask: %ld\n", d->hwirq);
> +
> +	/* ack level irqs because they can't be acked during
> +	 * ack function since the handle_level_irq function
> +	 * acks the irq before calling the interrupt handler
> +	 */
> +	if (irqd_is_level_type(d))
> +		write_fn(mask, intc_baseaddr + IAR);
> +
> +	write_fn(mask, intc_baseaddr + SIE);
> +}
> +
> +static void intc_disable_or_mask(struct irq_data *d)
> +{
> +	pr_debug("disable: %ld\n", d->hwirq);
> +	write_fn(1 << d->hwirq, intc_baseaddr + CIE);
> +}
> +
> +static void intc_ack(struct irq_data *d)
> +{
> +	pr_debug("ack: %ld\n", d->hwirq);
> +	write_fn(1 << d->hwirq, intc_baseaddr + IAR);
> +}
> +
> +static void intc_mask_ack(struct irq_data *d)
> +{
> +	unsigned long mask = 1 << d->hwirq;
> +
> +	pr_debug("disable_and_ack: %ld\n", d->hwirq);
> +	write_fn(mask, intc_baseaddr + CIE);
> +	write_fn(mask, intc_baseaddr + IAR);
> +}
> +
> +static struct irq_chip intc_dev = {
> +	.name = "Xilinx INTC",
> +	.irq_unmask = intc_enable_or_unmask,
> +	.irq_mask = intc_disable_or_mask,
> +	.irq_ack = intc_ack,
> +	.irq_mask_ack = intc_mask_ack,
> +};
> +
> +static struct irq_domain *root_domain;
> +
> +unsigned int get_irq(void)

Does this need to be global? It doesn't seem to be used in this patch...

> +{
> +	unsigned int hwirq, irq = -1;
> +
> +	hwirq = read_fn(intc_baseaddr + IVR);
> +	if (hwirq != -1U)
> +		irq = irq_find_mapping(root_domain, hwirq);
> +
> +	pr_debug("get_irq: hwirq=%d, irq=%d\n", hwirq, irq);
> +
> +	return irq;
> +}
> +
> +static int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
> +{
> +	u32 intr_mask = (u32)d->host_data;
> +
> +	if (intr_mask & (1 << hw)) {
> +		irq_set_chip_and_handler_name(irq, &intc_dev,
> +						handle_edge_irq, "edge");
> +		irq_clear_status_flags(irq, IRQ_LEVEL);
> +	} else {
> +		irq_set_chip_and_handler_name(irq, &intc_dev,
> +						handle_level_irq, "level");
> +		irq_set_status_flags(irq, IRQ_LEVEL);
> +	}
> +	return 0;
> +}
> +
> +static const struct irq_domain_ops xintc_irq_domain_ops = {
> +	.xlate = irq_domain_xlate_onetwocell,
> +	.map = xintc_map,
> +};
> +
> +static int __init xilinx_intc_of_init(struct device_node *intc,
> +					     struct device_node *parent)
> +{
> +	u32 nr_irq, intr_mask;
> +	int ret;
> +
> +	intc_baseaddr = of_iomap(intc, 0);
> +	BUG_ON(!intc_baseaddr);
> +
> +	ret = of_property_read_u32(intc, "xlnx,num-intr-inputs", &nr_irq);
> +	if (ret < 0) {
> +		pr_err("%s: unable to read xlnx,num-intr-inputs\n", __func__);
> +		return ret;
> +	}
> +
> +	ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &intr_mask);
> +	if (ret < 0) {
> +		pr_err("%s: unable to read xlnx,kind-of-intr\n", __func__);
> +		return ret;
> +	}
> +
> +	if (intr_mask >> nr_irq)
> +		pr_warn("%s: mismatch in kind-of-intr param\n", __func__);
> +
> +	pr_info("%s: num_irq=%d, edge=0x%x\n",
> +		intc->full_name, nr_irq, intr_mask);
> +
> +	write_fn = intc_write32;
> +	read_fn = intc_read32;
> +
> +	/*
> +	 * Disable all external interrupts until they are
> +	 * explicity requested.
> +	 */
> +	write_fn(0, intc_baseaddr + IER);
> +
> +	/* Acknowledge any pending interrupts just in case. */
> +	write_fn(0xffffffff, intc_baseaddr + IAR);
> +
> +	/* Turn on the Master Enable. */
> +	write_fn(MER_HIE | MER_ME, intc_baseaddr + MER);
> +	if (!(read_fn(intc_baseaddr + MER) & (MER_HIE | MER_ME))) {
> +		write_fn = intc_write32_be;
> +		read_fn = intc_read32_be;
> +		write_fn(MER_HIE | MER_ME, intc_baseaddr + MER);
> +	}
> +
> +	/* Yeah, okay, casting the intr_mask to a void* is butt-ugly, but I'm
> +	 * lazy and Michal can clean it up to something nicer when he tests
> +	 * and commits this patch.  ~~gcl */
> +	root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
> +							(void *)intr_mask);

Since you're now reworking this driver, how about addressing this
ugliness? You could store the intr_mask together with intc_baseaddr,
and the read/write functions in a global structure, and pass a
pointer to it? That would make the code a bit nicer...

> +
> +	irq_set_default_host(root_domain);
> +
> +	return 0;
> +}
> +
> +IRQCHIP_DECLARE(xilinx_intc, "xlnx,xps-intc-1.00.a", xilinx_intc_of_init);

Is "lnx,xps-intc-1.00.a" the only supported interrupt controller? Or is
there something slightly more generic than this one?

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH V2 01/10] microblaze: irqchip: Move intc driver to irqchip
@ 2016-08-26 14:13     ` Marc Zyngier
  0 siblings, 0 replies; 28+ messages in thread
From: Marc Zyngier @ 2016-08-26 14:13 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel
  Cc: monstr, ralf, tglx, jason, linux-mips, linux-kernel, netdev

On Thu, 18 Aug 2016 14:43:15 +0100
Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com> wrote:

Hi Zubair,

Thanks for the heads up, comments below.

> The Xilinx AXI Interrupt Controller IP block is used by the MIPS
> based xilfpga platform.
> 
> Move the interrupt controller code out of arch/microblaze so that
> it can be used by everyone
> 
> Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
> 
> ---
> V1 -> V2
> 
> Renamed irq-xilinx to irq-axi-intc
> Renamed CONFIG_XILINX_INTC to CONFIG_XILINX_AXI_INTC
> Patch is now without rename flag so as to facilitate review
> ---
>  arch/microblaze/Kconfig         |   1 +
>  arch/microblaze/kernel/Makefile |   2 +-
>  arch/microblaze/kernel/intc.c   | 196 ----------------------------------------
>  drivers/irqchip/Kconfig         |   4 +
>  drivers/irqchip/Makefile        |   1 +
>  drivers/irqchip/irq-axi-intc.c  | 196 ++++++++++++++++++++++++++++++++++++++++
>  6 files changed, 203 insertions(+), 197 deletions(-)
>  delete mode 100644 arch/microblaze/kernel/intc.c
>  create mode 100644 drivers/irqchip/irq-axi-intc.c
> 

[...]

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index 7f87289..4429888 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -203,6 +203,10 @@ config XTENSA_MX
>  	bool
>  	select IRQ_DOMAIN
>  
> +config XILINX_AXI_INTC
> +	bool
> +	select IRQ_DOMAIN
> +
>  config IRQ_CROSSBAR
>  	bool
>  	help
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index 4c203b6..bf21f55 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -51,6 +51,7 @@ obj-$(CONFIG_TB10X_IRQC)		+= irq-tb10x.o
>  obj-$(CONFIG_TS4800_IRQ)		+= irq-ts4800.o
>  obj-$(CONFIG_XTENSA)			+= irq-xtensa-pic.o
>  obj-$(CONFIG_XTENSA_MX)			+= irq-xtensa-mx.o
> +obj-$(CONFIG_XILINX_AXI_INTC)		+= irq-axi-intc.o
>  obj-$(CONFIG_IRQ_CROSSBAR)		+= irq-crossbar.o
>  obj-$(CONFIG_SOC_VF610)			+= irq-vf610-mscm-ir.o
>  obj-$(CONFIG_BCM6345_L1_IRQ)		+= irq-bcm6345-l1.o
> diff --git a/drivers/irqchip/irq-axi-intc.c b/drivers/irqchip/irq-axi-intc.c
> new file mode 100644
> index 0000000..90bec7d
> --- /dev/null
> +++ b/drivers/irqchip/irq-axi-intc.c
> @@ -0,0 +1,196 @@
> +/*
> + * Copyright (C) 2007-2013 Michal Simek <monstr@monstr.eu>
> + * Copyright (C) 2012-2013 Xilinx, Inc.
> + * Copyright (C) 2007-2009 PetaLogix
> + * Copyright (C) 2006 Atmark Techno, Inc.
> + *
> + * This file is subject to the terms and conditions of the GNU General Public
> + * License. See the file "COPYING" in the main directory of this archive
> + * for more details.
> + */
> +
> +#include <linux/irqdomain.h>
> +#include <linux/irq.h>
> +#include <linux/irqchip.h>
> +#include <linux/of_address.h>
> +#include <linux/io.h>
> +#include <linux/bug.h>
> +
> +static void __iomem *intc_baseaddr;
> +
> +/* No one else should require these constants, so define them locally here. */
> +#define ISR 0x00			/* Interrupt Status Register */
> +#define IPR 0x04			/* Interrupt Pending Register */
> +#define IER 0x08			/* Interrupt Enable Register */
> +#define IAR 0x0c			/* Interrupt Acknowledge Register */
> +#define SIE 0x10			/* Set Interrupt Enable bits */
> +#define CIE 0x14			/* Clear Interrupt Enable bits */
> +#define IVR 0x18			/* Interrupt Vector Register */
> +#define MER 0x1c			/* Master Enable Register */
> +
> +#define MER_ME (1<<0)
> +#define MER_HIE (1<<1)
> +
> +static unsigned int (*read_fn)(void __iomem *);
> +static void (*write_fn)(u32, void __iomem *);
> +
> +static void intc_write32(u32 val, void __iomem *addr)
> +{
> +	iowrite32(val, addr);
> +}
> +
> +static unsigned int intc_read32(void __iomem *addr)
> +{
> +	return ioread32(addr);
> +}
> +
> +static void intc_write32_be(u32 val, void __iomem *addr)
> +{
> +	iowrite32be(val, addr);
> +}
> +
> +static unsigned int intc_read32_be(void __iomem *addr)
> +{
> +	return ioread32be(addr);
> +}
> +
> +static void intc_enable_or_unmask(struct irq_data *d)
> +{
> +	unsigned long mask = 1 << d->hwirq;
> +
> +	pr_debug("enable_or_unmask: %ld\n", d->hwirq);
> +
> +	/* ack level irqs because they can't be acked during
> +	 * ack function since the handle_level_irq function
> +	 * acks the irq before calling the interrupt handler
> +	 */
> +	if (irqd_is_level_type(d))
> +		write_fn(mask, intc_baseaddr + IAR);
> +
> +	write_fn(mask, intc_baseaddr + SIE);
> +}
> +
> +static void intc_disable_or_mask(struct irq_data *d)
> +{
> +	pr_debug("disable: %ld\n", d->hwirq);
> +	write_fn(1 << d->hwirq, intc_baseaddr + CIE);
> +}
> +
> +static void intc_ack(struct irq_data *d)
> +{
> +	pr_debug("ack: %ld\n", d->hwirq);
> +	write_fn(1 << d->hwirq, intc_baseaddr + IAR);
> +}
> +
> +static void intc_mask_ack(struct irq_data *d)
> +{
> +	unsigned long mask = 1 << d->hwirq;
> +
> +	pr_debug("disable_and_ack: %ld\n", d->hwirq);
> +	write_fn(mask, intc_baseaddr + CIE);
> +	write_fn(mask, intc_baseaddr + IAR);
> +}
> +
> +static struct irq_chip intc_dev = {
> +	.name = "Xilinx INTC",
> +	.irq_unmask = intc_enable_or_unmask,
> +	.irq_mask = intc_disable_or_mask,
> +	.irq_ack = intc_ack,
> +	.irq_mask_ack = intc_mask_ack,
> +};
> +
> +static struct irq_domain *root_domain;
> +
> +unsigned int get_irq(void)

Does this need to be global? It doesn't seem to be used in this patch...

> +{
> +	unsigned int hwirq, irq = -1;
> +
> +	hwirq = read_fn(intc_baseaddr + IVR);
> +	if (hwirq != -1U)
> +		irq = irq_find_mapping(root_domain, hwirq);
> +
> +	pr_debug("get_irq: hwirq=%d, irq=%d\n", hwirq, irq);
> +
> +	return irq;
> +}
> +
> +static int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
> +{
> +	u32 intr_mask = (u32)d->host_data;
> +
> +	if (intr_mask & (1 << hw)) {
> +		irq_set_chip_and_handler_name(irq, &intc_dev,
> +						handle_edge_irq, "edge");
> +		irq_clear_status_flags(irq, IRQ_LEVEL);
> +	} else {
> +		irq_set_chip_and_handler_name(irq, &intc_dev,
> +						handle_level_irq, "level");
> +		irq_set_status_flags(irq, IRQ_LEVEL);
> +	}
> +	return 0;
> +}
> +
> +static const struct irq_domain_ops xintc_irq_domain_ops = {
> +	.xlate = irq_domain_xlate_onetwocell,
> +	.map = xintc_map,
> +};
> +
> +static int __init xilinx_intc_of_init(struct device_node *intc,
> +					     struct device_node *parent)
> +{
> +	u32 nr_irq, intr_mask;
> +	int ret;
> +
> +	intc_baseaddr = of_iomap(intc, 0);
> +	BUG_ON(!intc_baseaddr);
> +
> +	ret = of_property_read_u32(intc, "xlnx,num-intr-inputs", &nr_irq);
> +	if (ret < 0) {
> +		pr_err("%s: unable to read xlnx,num-intr-inputs\n", __func__);
> +		return ret;
> +	}
> +
> +	ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &intr_mask);
> +	if (ret < 0) {
> +		pr_err("%s: unable to read xlnx,kind-of-intr\n", __func__);
> +		return ret;
> +	}
> +
> +	if (intr_mask >> nr_irq)
> +		pr_warn("%s: mismatch in kind-of-intr param\n", __func__);
> +
> +	pr_info("%s: num_irq=%d, edge=0x%x\n",
> +		intc->full_name, nr_irq, intr_mask);
> +
> +	write_fn = intc_write32;
> +	read_fn = intc_read32;
> +
> +	/*
> +	 * Disable all external interrupts until they are
> +	 * explicity requested.
> +	 */
> +	write_fn(0, intc_baseaddr + IER);
> +
> +	/* Acknowledge any pending interrupts just in case. */
> +	write_fn(0xffffffff, intc_baseaddr + IAR);
> +
> +	/* Turn on the Master Enable. */
> +	write_fn(MER_HIE | MER_ME, intc_baseaddr + MER);
> +	if (!(read_fn(intc_baseaddr + MER) & (MER_HIE | MER_ME))) {
> +		write_fn = intc_write32_be;
> +		read_fn = intc_read32_be;
> +		write_fn(MER_HIE | MER_ME, intc_baseaddr + MER);
> +	}
> +
> +	/* Yeah, okay, casting the intr_mask to a void* is butt-ugly, but I'm
> +	 * lazy and Michal can clean it up to something nicer when he tests
> +	 * and commits this patch.  ~~gcl */
> +	root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
> +							(void *)intr_mask);

Since you're now reworking this driver, how about addressing this
ugliness? You could store the intr_mask together with intc_baseaddr,
and the read/write functions in a global structure, and pass a
pointer to it? That would make the code a bit nicer...

> +
> +	irq_set_default_host(root_domain);
> +
> +	return 0;
> +}
> +
> +IRQCHIP_DECLARE(xilinx_intc, "xlnx,xps-intc-1.00.a", xilinx_intc_of_init);

Is "lnx,xps-intc-1.00.a" the only supported interrupt controller? Or is
there something slightly more generic than this one?

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH V2 02/10] irqchip: xilinx: Add support for parent intc
@ 2016-08-26 14:23     ` Marc Zyngier
  0 siblings, 0 replies; 28+ messages in thread
From: Marc Zyngier @ 2016-08-26 14:23 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel
  Cc: monstr, ralf, tglx, jason, linux-mips, linux-kernel, netdev

On Thu, 18 Aug 2016 14:43:16 +0100
Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com> wrote:

> The MIPS based xilfpga platform has the following IRQ structure
> 
> Peripherals --> xilinx_intcontroller -> mips_cpu_int controller
> 
> Add support for the driver to chain the irq handler
> 
> Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
> 
> ---
> V1 -> V2
> 
> No change
> ---
>  drivers/irqchip/irq-axi-intc.c | 28 +++++++++++++++++++++++++++-
>  1 file changed, 27 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/irqchip/irq-axi-intc.c b/drivers/irqchip/irq-axi-intc.c
> index 90bec7d..a0be6fa 100644
> --- a/drivers/irqchip/irq-axi-intc.c
> +++ b/drivers/irqchip/irq-axi-intc.c
> @@ -15,6 +15,7 @@
>  #include <linux/of_address.h>
>  #include <linux/io.h>
>  #include <linux/bug.h>
> +#include <linux/of_irq.h>
>  
>  static void __iomem *intc_baseaddr;
>  
> @@ -135,11 +136,26 @@ static const struct irq_domain_ops xintc_irq_domain_ops = {
>  	.map = xintc_map,
>  };
>  
> +static void xil_intc_irq_handler(struct irq_desc *desc)
> +{
> +	u32 pending = get_irq();
> +
> +	if (pending != -1U) {
> +		while (true) {
> +			pending = get_irq();
> +			generic_handle_irq(pending);
> +			if (pending == -1U)

Erm... So even when pending is -1, you're calling generic_handle_irq?
This doesn't seem right.

You're also missing the chained_irq_enter/exit calls around this loop.

Overall, this should be rewritten in a less cumbersome way. Something
like:

	do {
		u32 pending;

		pending = get_irq();
		if (pending == ~0)
			break;
		generic_handle_irq(pending);
	} while (true);

> +				break;
> +		}
> +	}
> +}
> +
>  static int __init xilinx_intc_of_init(struct device_node *intc,
>  					     struct device_node *parent)
>  {
>  	u32 nr_irq, intr_mask;
> -	int ret;
> +	int ret, irq;
> +	struct device_node *parent_node;
>  
>  	intc_baseaddr = of_iomap(intc, 0);
>  	BUG_ON(!intc_baseaddr);
> @@ -188,6 +204,16 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
>  	root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
>  							(void *)intr_mask);
>  
> +	parent_node = of_irq_find_parent(intc);

You already have the parent node as an argument to the function. Why do
you need to do that again?

> +	if (parent_node) {
> +		irq = irq_of_parse_and_map(intc, 0);
> +		if (irq)
> +			irq_set_chained_handler_and_data(irq,
> +							 xil_intc_irq_handler,
> +							 root_domain);
> +
> +	}
> +
>  	irq_set_default_host(root_domain);
>  
>  	return 0;


Thanks,

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH V2 02/10] irqchip: xilinx: Add support for parent intc
@ 2016-08-26 14:23     ` Marc Zyngier
  0 siblings, 0 replies; 28+ messages in thread
From: Marc Zyngier @ 2016-08-26 14:23 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel
  Cc: monstr, ralf, tglx, jason, linux-mips, linux-kernel, netdev

On Thu, 18 Aug 2016 14:43:16 +0100
Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com> wrote:

> The MIPS based xilfpga platform has the following IRQ structure
> 
> Peripherals --> xilinx_intcontroller -> mips_cpu_int controller
> 
> Add support for the driver to chain the irq handler
> 
> Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
> 
> ---
> V1 -> V2
> 
> No change
> ---
>  drivers/irqchip/irq-axi-intc.c | 28 +++++++++++++++++++++++++++-
>  1 file changed, 27 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/irqchip/irq-axi-intc.c b/drivers/irqchip/irq-axi-intc.c
> index 90bec7d..a0be6fa 100644
> --- a/drivers/irqchip/irq-axi-intc.c
> +++ b/drivers/irqchip/irq-axi-intc.c
> @@ -15,6 +15,7 @@
>  #include <linux/of_address.h>
>  #include <linux/io.h>
>  #include <linux/bug.h>
> +#include <linux/of_irq.h>
>  
>  static void __iomem *intc_baseaddr;
>  
> @@ -135,11 +136,26 @@ static const struct irq_domain_ops xintc_irq_domain_ops = {
>  	.map = xintc_map,
>  };
>  
> +static void xil_intc_irq_handler(struct irq_desc *desc)
> +{
> +	u32 pending = get_irq();
> +
> +	if (pending != -1U) {
> +		while (true) {
> +			pending = get_irq();
> +			generic_handle_irq(pending);
> +			if (pending == -1U)

Erm... So even when pending is -1, you're calling generic_handle_irq?
This doesn't seem right.

You're also missing the chained_irq_enter/exit calls around this loop.

Overall, this should be rewritten in a less cumbersome way. Something
like:

	do {
		u32 pending;

		pending = get_irq();
		if (pending == ~0)
			break;
		generic_handle_irq(pending);
	} while (true);

> +				break;
> +		}
> +	}
> +}
> +
>  static int __init xilinx_intc_of_init(struct device_node *intc,
>  					     struct device_node *parent)
>  {
>  	u32 nr_irq, intr_mask;
> -	int ret;
> +	int ret, irq;
> +	struct device_node *parent_node;
>  
>  	intc_baseaddr = of_iomap(intc, 0);
>  	BUG_ON(!intc_baseaddr);
> @@ -188,6 +204,16 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
>  	root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
>  							(void *)intr_mask);
>  
> +	parent_node = of_irq_find_parent(intc);

You already have the parent node as an argument to the function. Why do
you need to do that again?

> +	if (parent_node) {
> +		irq = irq_of_parse_and_map(intc, 0);
> +		if (irq)
> +			irq_set_chained_handler_and_data(irq,
> +							 xil_intc_irq_handler,
> +							 root_domain);
> +
> +	}
> +
>  	irq_set_default_host(root_domain);
>  
>  	return 0;


Thanks,

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2016-08-26 14:23 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-18 13:43 [PATCH V2 00/10] microblaze/MIPS: xilfpga: intc and peripheral Zubair Lutfullah Kakakhel
2016-08-18 13:43 ` Zubair Lutfullah Kakakhel
2016-08-18 13:43 ` [PATCH V2 01/10] microblaze: irqchip: Move intc driver to irqchip Zubair Lutfullah Kakakhel
2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
2016-08-26 14:13   ` Marc Zyngier
2016-08-26 14:13     ` Marc Zyngier
2016-08-18 13:43 ` [PATCH V2 02/10] irqchip: xilinx: Add support for parent intc Zubair Lutfullah Kakakhel
2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
2016-08-26 14:23   ` Marc Zyngier
2016-08-26 14:23     ` Marc Zyngier
2016-08-18 13:43 ` [PATCH V2 03/10] MIPS: xilfpga: Use irqchip_init instead of the legacy way Zubair Lutfullah Kakakhel
2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
2016-08-18 13:43 ` [PATCH V2 04/10] MIPS: xilfpga: Use Xilinx AXI Interrupt Controller Zubair Lutfullah Kakakhel
2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
2016-08-18 13:43 ` [PATCH V2 05/10] MIPS: xilfpga: Update DT node and specify uart irq Zubair Lutfullah Kakakhel
2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
2016-08-18 13:43 ` [PATCH V2 06/10] MIPS: Xilfpga: Add DT node for AXI I2C Zubair Lutfullah Kakakhel
2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
2016-08-18 13:43 ` [PATCH V2 07/10] net: ethernet: xilinx: Generate random mac if none found Zubair Lutfullah Kakakhel
2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
2016-08-18 13:43 ` [PATCH V2 08/10] net: ethernet: xilinx: Enable emaclite for MIPS Zubair Lutfullah Kakakhel
2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
2016-08-18 13:43 ` [PATCH V2 09/10] MIPS: xilfpga: Add DT node for AXI emaclite Zubair Lutfullah Kakakhel
2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
2016-08-18 13:43 ` [PATCH V2 10/10] MIPS: xilfpga: Update defconfig Zubair Lutfullah Kakakhel
2016-08-18 13:43   ` Zubair Lutfullah Kakakhel
2016-08-26 13:41 ` [PATCH V2 00/10] microblaze/MIPS: xilfpga: intc and peripheral Zubair Lutfullah Kakakhel
2016-08-26 13:41   ` Zubair Lutfullah Kakakhel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.