All of lore.kernel.org
 help / color / mirror / Atom feed
* [Patch v3 00/11] microblaze/MIPS: xilfpga: intc and peripheral
@ 2016-08-31 16:35 ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

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 and then cleans it up a bit.
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-rc4

Regards,
ZubairLK

V2 -> V3
Cleanup the interrupt controller driver a bit based on feedback
Rebase to v4.8-rc4

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 (11):
  microblaze: irqchip: Move intc driver to irqchip
  irqchip: axi-intc: Clean up irqdomain argument and read/write
  irqchip: axi-intc: 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                | 241 ++++++++++++++++++++++++++
 drivers/net/ethernet/xilinx/Kconfig           |   4 +-
 drivers/net/ethernet/xilinx/xilinx_emaclite.c |   6 +-
 12 files changed, 356 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] 41+ messages in thread

* [Patch v3 00/11] microblaze/MIPS: xilfpga: intc and peripheral
@ 2016-08-31 16:35 ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

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 and then cleans it up a bit.
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-rc4

Regards,
ZubairLK

V2 -> V3
Cleanup the interrupt controller driver a bit based on feedback
Rebase to v4.8-rc4

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 (11):
  microblaze: irqchip: Move intc driver to irqchip
  irqchip: axi-intc: Clean up irqdomain argument and read/write
  irqchip: axi-intc: 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                | 241 ++++++++++++++++++++++++++
 drivers/net/ethernet/xilinx/Kconfig           |   4 +-
 drivers/net/ethernet/xilinx/xilinx_emaclite.c |   6 +-
 12 files changed, 356 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] 41+ messages in thread

* [Patch v3 01/11] microblaze: irqchip: Move intc driver to irqchip
@ 2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

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>

---
V2 -> V3
No change here. Cleanup patches follow after this patch.
Its debatable to cleanup before/after move. Decided to place cleanup
after move to put history in new place.

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] 41+ messages in thread

* [Patch v3 01/11] microblaze: irqchip: Move intc driver to irqchip
@ 2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

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>

---
V2 -> V3
No change here. Cleanup patches follow after this patch.
Its debatable to cleanup before/after move. Decided to place cleanup
after move to put history in new place.

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] 41+ messages in thread

* [Patch v3 02/11] irqchip: axi-intc: Clean up irqdomain argument and read/write
@ 2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

The drivers read/write function handling is a bit quirky.
And the irqmask is passed directly to the handler.

Add a new irqchip struct to pass to the handler and
cleanup read/write handling.

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

---
V2 -> V3
New patch. Cleans up driver structure
---
 drivers/irqchip/irq-axi-intc.c | 85 +++++++++++++++++++++++++++---------------
 1 file changed, 54 insertions(+), 31 deletions(-)

diff --git a/drivers/irqchip/irq-axi-intc.c b/drivers/irqchip/irq-axi-intc.c
index 90bec7d..cb69241 100644
--- a/drivers/irqchip/irq-axi-intc.c
+++ b/drivers/irqchip/irq-axi-intc.c
@@ -16,8 +16,6 @@
 #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 */
@@ -31,8 +29,16 @@ static void __iomem *intc_baseaddr;
 #define MER_ME (1<<0)
 #define MER_HIE (1<<1)
 
-static unsigned int (*read_fn)(void __iomem *);
-static void (*write_fn)(u32, void __iomem *);
+struct xintc_irq_chip {
+	void __iomem *base;
+	struct	irq_domain *domain;
+	struct	irq_chip chip;
+	u32	intr_mask;
+	unsigned int (*read)(void __iomem *iomem);
+	void (*write)(u32 data, void __iomem *iomem);
+};
+
+static struct xintc_irq_chip *xintc_irqc;
 
 static void intc_write32(u32 val, void __iomem *addr)
 {
@@ -54,6 +60,18 @@ static unsigned int intc_read32_be(void __iomem *addr)
 	return ioread32be(addr);
 }
 
+static inline unsigned int xintc_read(struct xintc_irq_chip *xintc_irqc,
+					     int reg)
+{
+	return xintc_irqc->read(xintc_irqc->base + reg);
+}
+
+static inline void xintc_write(struct xintc_irq_chip *xintc_irqc,
+				     int reg, u32 data)
+{
+	xintc_irqc->write(data, xintc_irqc->base + reg);
+}
+
 static void intc_enable_or_unmask(struct irq_data *d)
 {
 	unsigned long mask = 1 << d->hwirq;
@@ -65,21 +83,21 @@ static void intc_enable_or_unmask(struct irq_data *d)
 	 * acks the irq before calling the interrupt handler
 	 */
 	if (irqd_is_level_type(d))
-		write_fn(mask, intc_baseaddr + IAR);
+		xintc_write(xintc_irqc, IAR, mask);
 
-	write_fn(mask, intc_baseaddr + SIE);
+	xintc_write(xintc_irqc, SIE, mask);
 }
 
 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);
+	xintc_write(xintc_irqc, CIE, 1 << d->hwirq);
 }
 
 static void intc_ack(struct irq_data *d)
 {
 	pr_debug("ack: %ld\n", d->hwirq);
-	write_fn(1 << d->hwirq, intc_baseaddr + IAR);
+	xintc_write(xintc_irqc, IAR, 1 << d->hwirq);
 }
 
 static void intc_mask_ack(struct irq_data *d)
@@ -87,8 +105,8 @@ 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);
+	xintc_write(xintc_irqc, CIE, mask);
+	xintc_write(xintc_irqc, IAR, mask);
 }
 
 static struct irq_chip intc_dev = {
@@ -105,7 +123,7 @@ unsigned int get_irq(void)
 {
 	unsigned int hwirq, irq = -1;
 
-	hwirq = read_fn(intc_baseaddr + IVR);
+	hwirq = xintc_read(xintc_irqc, IVR);
 	if (hwirq != -1U)
 		irq = irq_find_mapping(root_domain, hwirq);
 
@@ -116,7 +134,8 @@ unsigned int get_irq(void)
 
 static int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
 {
-	u32 intr_mask = (u32)d->host_data;
+	struct xintc_irq_chip *irqc = d->host_data;
+	u32 intr_mask = irqc->intr_mask;
 
 	if (intr_mask & (1 << hw)) {
 		irq_set_chip_and_handler_name(irq, &intc_dev,
@@ -138,11 +157,18 @@ static const struct irq_domain_ops xintc_irq_domain_ops = {
 static int __init xilinx_intc_of_init(struct device_node *intc,
 					     struct device_node *parent)
 {
-	u32 nr_irq, intr_mask;
+	u32 nr_irq;
 	int ret;
+	struct xintc_irq_chip *irqc;
+
+	irqc = kzalloc(sizeof(*irqc), GFP_KERNEL);
+	if (!irqc)
+		return -ENOMEM;
+
+	xintc_irqc = irqc;
 
-	intc_baseaddr = of_iomap(intc, 0);
-	BUG_ON(!intc_baseaddr);
+	irqc->base = of_iomap(intc, 0);
+	BUG_ON(!irqc->base);
 
 	ret = of_property_read_u32(intc, "xlnx,num-intr-inputs", &nr_irq);
 	if (ret < 0) {
@@ -150,43 +176,40 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
 		return ret;
 	}
 
-	ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &intr_mask);
+	ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &irqc->intr_mask);
 	if (ret < 0) {
 		pr_err("%s: unable to read xlnx,kind-of-intr\n", __func__);
 		return ret;
 	}
 
-	if (intr_mask >> nr_irq)
+	if (irqc->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);
+		intc->full_name, nr_irq, irqc->intr_mask);
 
-	write_fn = intc_write32;
-	read_fn = intc_read32;
+	irqc->read = intc_read32;
+	irqc->write = intc_write32;
 
 	/*
 	 * Disable all external interrupts until they are
 	 * explicity requested.
 	 */
-	write_fn(0, intc_baseaddr + IER);
+	xintc_write(irqc, IER, 0);
 
 	/* Acknowledge any pending interrupts just in case. */
-	write_fn(0xffffffff, intc_baseaddr + IAR);
+	xintc_write(irqc, IAR, 0xffffffff);
 
 	/* 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);
+	xintc_write(irqc, MER, MER_HIE | MER_ME);
+	if (!(xintc_read(irqc, MER) & (MER_HIE | MER_ME))) {
+		irqc->read = intc_read32_be;
+		irqc->write = intc_write32_be;
+		xintc_write(irqc, MER, MER_HIE | MER_ME);
 	}
 
-	/* 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);
+					    irqc);
 
 	irq_set_default_host(root_domain);
 
-- 
1.9.1

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

* [Patch v3 02/11] irqchip: axi-intc: Clean up irqdomain argument and read/write
@ 2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

The drivers read/write function handling is a bit quirky.
And the irqmask is passed directly to the handler.

Add a new irqchip struct to pass to the handler and
cleanup read/write handling.

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

---
V2 -> V3
New patch. Cleans up driver structure
---
 drivers/irqchip/irq-axi-intc.c | 85 +++++++++++++++++++++++++++---------------
 1 file changed, 54 insertions(+), 31 deletions(-)

diff --git a/drivers/irqchip/irq-axi-intc.c b/drivers/irqchip/irq-axi-intc.c
index 90bec7d..cb69241 100644
--- a/drivers/irqchip/irq-axi-intc.c
+++ b/drivers/irqchip/irq-axi-intc.c
@@ -16,8 +16,6 @@
 #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 */
@@ -31,8 +29,16 @@ static void __iomem *intc_baseaddr;
 #define MER_ME (1<<0)
 #define MER_HIE (1<<1)
 
-static unsigned int (*read_fn)(void __iomem *);
-static void (*write_fn)(u32, void __iomem *);
+struct xintc_irq_chip {
+	void __iomem *base;
+	struct	irq_domain *domain;
+	struct	irq_chip chip;
+	u32	intr_mask;
+	unsigned int (*read)(void __iomem *iomem);
+	void (*write)(u32 data, void __iomem *iomem);
+};
+
+static struct xintc_irq_chip *xintc_irqc;
 
 static void intc_write32(u32 val, void __iomem *addr)
 {
@@ -54,6 +60,18 @@ static unsigned int intc_read32_be(void __iomem *addr)
 	return ioread32be(addr);
 }
 
+static inline unsigned int xintc_read(struct xintc_irq_chip *xintc_irqc,
+					     int reg)
+{
+	return xintc_irqc->read(xintc_irqc->base + reg);
+}
+
+static inline void xintc_write(struct xintc_irq_chip *xintc_irqc,
+				     int reg, u32 data)
+{
+	xintc_irqc->write(data, xintc_irqc->base + reg);
+}
+
 static void intc_enable_or_unmask(struct irq_data *d)
 {
 	unsigned long mask = 1 << d->hwirq;
@@ -65,21 +83,21 @@ static void intc_enable_or_unmask(struct irq_data *d)
 	 * acks the irq before calling the interrupt handler
 	 */
 	if (irqd_is_level_type(d))
-		write_fn(mask, intc_baseaddr + IAR);
+		xintc_write(xintc_irqc, IAR, mask);
 
-	write_fn(mask, intc_baseaddr + SIE);
+	xintc_write(xintc_irqc, SIE, mask);
 }
 
 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);
+	xintc_write(xintc_irqc, CIE, 1 << d->hwirq);
 }
 
 static void intc_ack(struct irq_data *d)
 {
 	pr_debug("ack: %ld\n", d->hwirq);
-	write_fn(1 << d->hwirq, intc_baseaddr + IAR);
+	xintc_write(xintc_irqc, IAR, 1 << d->hwirq);
 }
 
 static void intc_mask_ack(struct irq_data *d)
@@ -87,8 +105,8 @@ 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);
+	xintc_write(xintc_irqc, CIE, mask);
+	xintc_write(xintc_irqc, IAR, mask);
 }
 
 static struct irq_chip intc_dev = {
@@ -105,7 +123,7 @@ unsigned int get_irq(void)
 {
 	unsigned int hwirq, irq = -1;
 
-	hwirq = read_fn(intc_baseaddr + IVR);
+	hwirq = xintc_read(xintc_irqc, IVR);
 	if (hwirq != -1U)
 		irq = irq_find_mapping(root_domain, hwirq);
 
@@ -116,7 +134,8 @@ unsigned int get_irq(void)
 
 static int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
 {
-	u32 intr_mask = (u32)d->host_data;
+	struct xintc_irq_chip *irqc = d->host_data;
+	u32 intr_mask = irqc->intr_mask;
 
 	if (intr_mask & (1 << hw)) {
 		irq_set_chip_and_handler_name(irq, &intc_dev,
@@ -138,11 +157,18 @@ static const struct irq_domain_ops xintc_irq_domain_ops = {
 static int __init xilinx_intc_of_init(struct device_node *intc,
 					     struct device_node *parent)
 {
-	u32 nr_irq, intr_mask;
+	u32 nr_irq;
 	int ret;
+	struct xintc_irq_chip *irqc;
+
+	irqc = kzalloc(sizeof(*irqc), GFP_KERNEL);
+	if (!irqc)
+		return -ENOMEM;
+
+	xintc_irqc = irqc;
 
-	intc_baseaddr = of_iomap(intc, 0);
-	BUG_ON(!intc_baseaddr);
+	irqc->base = of_iomap(intc, 0);
+	BUG_ON(!irqc->base);
 
 	ret = of_property_read_u32(intc, "xlnx,num-intr-inputs", &nr_irq);
 	if (ret < 0) {
@@ -150,43 +176,40 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
 		return ret;
 	}
 
-	ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &intr_mask);
+	ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &irqc->intr_mask);
 	if (ret < 0) {
 		pr_err("%s: unable to read xlnx,kind-of-intr\n", __func__);
 		return ret;
 	}
 
-	if (intr_mask >> nr_irq)
+	if (irqc->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);
+		intc->full_name, nr_irq, irqc->intr_mask);
 
-	write_fn = intc_write32;
-	read_fn = intc_read32;
+	irqc->read = intc_read32;
+	irqc->write = intc_write32;
 
 	/*
 	 * Disable all external interrupts until they are
 	 * explicity requested.
 	 */
-	write_fn(0, intc_baseaddr + IER);
+	xintc_write(irqc, IER, 0);
 
 	/* Acknowledge any pending interrupts just in case. */
-	write_fn(0xffffffff, intc_baseaddr + IAR);
+	xintc_write(irqc, IAR, 0xffffffff);
 
 	/* 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);
+	xintc_write(irqc, MER, MER_HIE | MER_ME);
+	if (!(xintc_read(irqc, MER) & (MER_HIE | MER_ME))) {
+		irqc->read = intc_read32_be;
+		irqc->write = intc_write32_be;
+		xintc_write(irqc, MER, MER_HIE | MER_ME);
 	}
 
-	/* 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);
+					    irqc);
 
 	irq_set_default_host(root_domain);
 
-- 
1.9.1

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

* [Patch v3 03/11] irqchip: axi-intc: Add support for parent intc
@ 2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

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>

---
V2 -> V3
Reused existing parent node instead of finding again.
Cleanup up handler based on review

V1 -> V2

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

diff --git a/drivers/irqchip/irq-axi-intc.c b/drivers/irqchip/irq-axi-intc.c
index cb69241..30bb084 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>
 
 /* No one else should require these constants, so define them locally here. */
 #define ISR 0x00			/* Interrupt Status Register */
@@ -154,11 +155,23 @@ 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;
+
+	do {
+		pending = get_irq();
+		if (pending == -1U)
+			break;
+		generic_handle_irq(pending);
+	} while (true);
+}
+
 static int __init xilinx_intc_of_init(struct device_node *intc,
 					     struct device_node *parent)
 {
 	u32 nr_irq;
-	int ret;
+	int ret, irq;
 	struct xintc_irq_chip *irqc;
 
 	irqc = kzalloc(sizeof(*irqc), GFP_KERNEL);
@@ -211,6 +224,15 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
 	root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
 					    irqc);
 
+	if (parent) {
+		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] 41+ messages in thread

* [Patch v3 03/11] irqchip: axi-intc: Add support for parent intc
@ 2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

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>

---
V2 -> V3
Reused existing parent node instead of finding again.
Cleanup up handler based on review

V1 -> V2

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

diff --git a/drivers/irqchip/irq-axi-intc.c b/drivers/irqchip/irq-axi-intc.c
index cb69241..30bb084 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>
 
 /* No one else should require these constants, so define them locally here. */
 #define ISR 0x00			/* Interrupt Status Register */
@@ -154,11 +155,23 @@ 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;
+
+	do {
+		pending = get_irq();
+		if (pending == -1U)
+			break;
+		generic_handle_irq(pending);
+	} while (true);
+}
+
 static int __init xilinx_intc_of_init(struct device_node *intc,
 					     struct device_node *parent)
 {
 	u32 nr_irq;
-	int ret;
+	int ret, irq;
 	struct xintc_irq_chip *irqc;
 
 	irqc = kzalloc(sizeof(*irqc), GFP_KERNEL);
@@ -211,6 +224,15 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
 	root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
 					    irqc);
 
+	if (parent) {
+		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] 41+ messages in thread

* [Patch v3 04/11] MIPS: xilfpga: Use irqchip_init instead of the legacy way
@ 2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

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>
---
V2 -> V3
No change

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] 41+ messages in thread

* [Patch v3 04/11] MIPS: xilfpga: Use irqchip_init instead of the legacy way
@ 2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

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>
---
V2 -> V3
No change

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] 41+ messages in thread

* [Patch v3 05/11] MIPS: xilfpga: Use Xilinx AXI Interrupt Controller
@ 2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

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>

---
V2 -> V3
No change

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] 41+ messages in thread

* [Patch v3 05/11] MIPS: xilfpga: Use Xilinx AXI Interrupt Controller
@ 2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

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>

---
V2 -> V3
No change

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] 41+ messages in thread

* [Patch v3 06/11] MIPS: xilfpga: Update DT node and specify uart irq
@ 2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

Update the DT node with the UART irq

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

---
V2 -> V3
No change

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] 41+ messages in thread

* [Patch v3 06/11] MIPS: xilfpga: Update DT node and specify uart irq
@ 2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

Update the DT node with the UART irq

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

---
V2 -> V3
No change

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] 41+ messages in thread

* [Patch v3 07/11] MIPS: Xilfpga: Add DT node for AXI I2C
@ 2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

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>

---
V2 -> V3
No change

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] 41+ messages in thread

* [Patch v3 07/11] MIPS: Xilfpga: Add DT node for AXI I2C
@ 2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

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>

---
V2 -> V3
No change

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] 41+ messages in thread

* [Patch v3 08/11] net: ethernet: xilinx: Generate random mac if none found
@ 2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

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>

---
V2 -> V3
No change

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] 41+ messages in thread

* [Patch v3 08/11] net: ethernet: xilinx: Generate random mac if none found
@ 2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

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>

---
V2 -> V3
No change

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] 41+ messages in thread

* [Patch v3 09/11] net: ethernet: xilinx: Enable emaclite for MIPS
@ 2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

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

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

---
V2 -> V3
No change

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] 41+ messages in thread

* [Patch v3 09/11] net: ethernet: xilinx: Enable emaclite for MIPS
@ 2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

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

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

---
V2 -> V3
No change

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] 41+ messages in thread

* [Patch v3 10/11] MIPS: xilfpga: Add DT node for AXI emaclite
@ 2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

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>

---
V2 -> V3
No change

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] 41+ messages in thread

* [Patch v3 10/11] MIPS: xilfpga: Add DT node for AXI emaclite
@ 2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

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>

---
V2 -> V3
No change

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] 41+ messages in thread

* [Patch v3 11/11] MIPS: xilfpga: Update defconfig
@ 2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

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

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

---
V2 -> V3
No change

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] 41+ messages in thread

* [Patch v3 11/11] MIPS: xilfpga: Update defconfig
@ 2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-31 16:35 UTC (permalink / raw)
  To: monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, Zubair.Kakakhel, linux-kernel, linux-mips,
	michal.simek, netdev

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

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

---
V2 -> V3
No change

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] 41+ messages in thread

* Re: [Patch v3 02/11] irqchip: axi-intc: Clean up irqdomain argument and read/write
  2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  (?)
@ 2016-08-31 16:52   ` Marc Zyngier
  2016-09-01 10:41       ` Zubair Lutfullah Kakakhel
  -1 siblings, 1 reply; 41+ messages in thread
From: Marc Zyngier @ 2016-08-31 16:52 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel, monstr, ralf, tglx, jason
  Cc: soren.brinkmann, linux-kernel, linux-mips, michal.simek, netdev

On 31/08/16 17:35, Zubair Lutfullah Kakakhel wrote:
> The drivers read/write function handling is a bit quirky.
> And the irqmask is passed directly to the handler.
> 
> Add a new irqchip struct to pass to the handler and
> cleanup read/write handling.
> 
> Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
> 
> ---
> V2 -> V3
> New patch. Cleans up driver structure
> ---
>  drivers/irqchip/irq-axi-intc.c | 85 +++++++++++++++++++++++++++---------------
>  1 file changed, 54 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-axi-intc.c b/drivers/irqchip/irq-axi-intc.c
> index 90bec7d..cb69241 100644
> --- a/drivers/irqchip/irq-axi-intc.c
> +++ b/drivers/irqchip/irq-axi-intc.c
> @@ -16,8 +16,6 @@
>  #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 */
> @@ -31,8 +29,16 @@ static void __iomem *intc_baseaddr;
>  #define MER_ME (1<<0)
>  #define MER_HIE (1<<1)
>  
> -static unsigned int (*read_fn)(void __iomem *);
> -static void (*write_fn)(u32, void __iomem *);
> +struct xintc_irq_chip {
> +	void __iomem *base;
> +	struct	irq_domain *domain;
> +	struct	irq_chip chip;
> +	u32	intr_mask;
> +	unsigned int (*read)(void __iomem *iomem);
> +	void (*write)(u32 data, void __iomem *iomem);
> +};
> +
> +static struct xintc_irq_chip *xintc_irqc;
>  
>  static void intc_write32(u32 val, void __iomem *addr)
>  {
> @@ -54,6 +60,18 @@ static unsigned int intc_read32_be(void __iomem *addr)
>  	return ioread32be(addr);
>  }
>  
> +static inline unsigned int xintc_read(struct xintc_irq_chip *xintc_irqc,
> +					     int reg)
> +{
> +	return xintc_irqc->read(xintc_irqc->base + reg);
> +}
> +
> +static inline void xintc_write(struct xintc_irq_chip *xintc_irqc,
> +				     int reg, u32 data)
> +{
> +	xintc_irqc->write(data, xintc_irqc->base + reg);
> +}
> +
>  static void intc_enable_or_unmask(struct irq_data *d)
>  {
>  	unsigned long mask = 1 << d->hwirq;
> @@ -65,21 +83,21 @@ static void intc_enable_or_unmask(struct irq_data *d)
>  	 * acks the irq before calling the interrupt handler
>  	 */
>  	if (irqd_is_level_type(d))
> -		write_fn(mask, intc_baseaddr + IAR);
> +		xintc_write(xintc_irqc, IAR, mask);
>  
> -	write_fn(mask, intc_baseaddr + SIE);
> +	xintc_write(xintc_irqc, SIE, mask);
>  }
>  
>  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);
> +	xintc_write(xintc_irqc, CIE, 1 << d->hwirq);
>  }
>  
>  static void intc_ack(struct irq_data *d)
>  {
>  	pr_debug("ack: %ld\n", d->hwirq);
> -	write_fn(1 << d->hwirq, intc_baseaddr + IAR);
> +	xintc_write(xintc_irqc, IAR, 1 << d->hwirq);
>  }
>  
>  static void intc_mask_ack(struct irq_data *d)
> @@ -87,8 +105,8 @@ 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);
> +	xintc_write(xintc_irqc, CIE, mask);
> +	xintc_write(xintc_irqc, IAR, mask);
>  }
>  
>  static struct irq_chip intc_dev = {
> @@ -105,7 +123,7 @@ unsigned int get_irq(void)
>  {
>  	unsigned int hwirq, irq = -1;
>  
> -	hwirq = read_fn(intc_baseaddr + IVR);
> +	hwirq = xintc_read(xintc_irqc, IVR);
>  	if (hwirq != -1U)
>  		irq = irq_find_mapping(root_domain, hwirq);
>  
> @@ -116,7 +134,8 @@ unsigned int get_irq(void)
>  
>  static int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
>  {
> -	u32 intr_mask = (u32)d->host_data;
> +	struct xintc_irq_chip *irqc = d->host_data;
> +	u32 intr_mask = irqc->intr_mask;
>  
>  	if (intr_mask & (1 << hw)) {
>  		irq_set_chip_and_handler_name(irq, &intc_dev,
> @@ -138,11 +157,18 @@ static const struct irq_domain_ops xintc_irq_domain_ops = {
>  static int __init xilinx_intc_of_init(struct device_node *intc,
>  					     struct device_node *parent)
>  {
> -	u32 nr_irq, intr_mask;
> +	u32 nr_irq;
>  	int ret;
> +	struct xintc_irq_chip *irqc;
> +
> +	irqc = kzalloc(sizeof(*irqc), GFP_KERNEL);

Now that you dynamically allocate things, how are you handling failures?

> +	if (!irqc)
> +		return -ENOMEM;
> +
> +	xintc_irqc = irqc;
>  
> -	intc_baseaddr = of_iomap(intc, 0);
> -	BUG_ON(!intc_baseaddr);
> +	irqc->base = of_iomap(intc, 0);
> +	BUG_ON(!irqc->base);
>  
>  	ret = of_property_read_u32(intc, "xlnx,num-intr-inputs", &nr_irq);
>  	if (ret < 0) {
> @@ -150,43 +176,40 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
>  		return ret;

All the return paths should now take care of releasing the allocated
resources.

>  	}
>  
> -	ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &intr_mask);
> +	ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &irqc->intr_mask);
>  	if (ret < 0) {
>  		pr_err("%s: unable to read xlnx,kind-of-intr\n", __func__);
>  		return ret;
>  	}
>  
> -	if (intr_mask >> nr_irq)
> +	if (irqc->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);
> +		intc->full_name, nr_irq, irqc->intr_mask);
>  
> -	write_fn = intc_write32;
> -	read_fn = intc_read32;
> +	irqc->read = intc_read32;
> +	irqc->write = intc_write32;
>  
>  	/*
>  	 * Disable all external interrupts until they are
>  	 * explicity requested.
>  	 */
> -	write_fn(0, intc_baseaddr + IER);
> +	xintc_write(irqc, IER, 0);
>  
>  	/* Acknowledge any pending interrupts just in case. */
> -	write_fn(0xffffffff, intc_baseaddr + IAR);
> +	xintc_write(irqc, IAR, 0xffffffff);
>  
>  	/* 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);
> +	xintc_write(irqc, MER, MER_HIE | MER_ME);
> +	if (!(xintc_read(irqc, MER) & (MER_HIE | MER_ME))) {
> +		irqc->read = intc_read32_be;
> +		irqc->write = intc_write32_be;
> +		xintc_write(irqc, MER, MER_HIE | MER_ME);
>  	}
>  
> -	/* 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);
> +					    irqc);
>  
>  	irq_set_default_host(root_domain);
>  
> 

You haven't addressed the comment on get_irq() which could be static (at
least from solely looking at this file).

Thanks,

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

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

* Re: [Patch v3 03/11] irqchip: axi-intc: Add support for parent intc
  2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  (?)
@ 2016-08-31 16:57   ` Marc Zyngier
  2016-09-01 11:01       ` Zubair Lutfullah Kakakhel
  -1 siblings, 1 reply; 41+ messages in thread
From: Marc Zyngier @ 2016-08-31 16:57 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel, monstr, ralf, tglx, jason
  Cc: soren.brinkmann, linux-kernel, linux-mips, michal.simek, netdev

On 31/08/16 17:35, Zubair Lutfullah Kakakhel 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>
> 
> ---
> V2 -> V3
> Reused existing parent node instead of finding again.
> Cleanup up handler based on review
> 
> V1 -> V2
> 
> No change
> ---
>  drivers/irqchip/irq-axi-intc.c | 24 +++++++++++++++++++++++-
>  1 file changed, 23 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/irqchip/irq-axi-intc.c b/drivers/irqchip/irq-axi-intc.c
> index cb69241..30bb084 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>
>  
>  /* No one else should require these constants, so define them locally here. */
>  #define ISR 0x00			/* Interrupt Status Register */
> @@ -154,11 +155,23 @@ 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;
> +
> +	do {
> +		pending = get_irq();
> +		if (pending == -1U)
> +			break;
> +		generic_handle_irq(pending);
> +	} while (true);
> +}
> +
>  static int __init xilinx_intc_of_init(struct device_node *intc,
>  					     struct device_node *parent)
>  {
>  	u32 nr_irq;
> -	int ret;
> +	int ret, irq;
>  	struct xintc_irq_chip *irqc;
>  
>  	irqc = kzalloc(sizeof(*irqc), GFP_KERNEL);
> @@ -211,6 +224,15 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
>  	root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
>  					    irqc);
>  
> +	if (parent) {
> +		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;
> 

This doesn't seem right. You've now overridden the xintc_irqc pointer,
so I don't know how you can still process interrupts once you've
discovered a secondary interrupt controller. You've also allocated a
second root_domain, changed the default domain to point to the secondary
controller...

Have you tested this code? Or am I missing something obvious?

Thanks,

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

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

* Re: [Patch v3 02/11] irqchip: axi-intc: Clean up irqdomain argument and read/write
@ 2016-09-01 10:41       ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-09-01 10:41 UTC (permalink / raw)
  To: Marc Zyngier, monstr, ralf, tglx, jason
  Cc: soren.brinkmann, linux-kernel, linux-mips, michal.simek, netdev

Hi,

Thank you for the reviews.

Some comments below

On 08/31/2016 05:52 PM, Marc Zyngier wrote:
> On 31/08/16 17:35, Zubair Lutfullah Kakakhel wrote:
>> The drivers read/write function handling is a bit quirky.
>> And the irqmask is passed directly to the handler.
>>
>> Add a new irqchip struct to pass to the handler and
>> cleanup read/write handling.
>>
>> Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
>>
>> ---
>> V2 -> V3
>> New patch. Cleans up driver structure
>> ---
...
>>  static int __init xilinx_intc_of_init(struct device_node *intc,
>>  					     struct device_node *parent)
>>  {
>> -	u32 nr_irq, intr_mask;
>> +	u32 nr_irq;
>>  	int ret;
>> +	struct xintc_irq_chip *irqc;
>> +
>> +	irqc = kzalloc(sizeof(*irqc), GFP_KERNEL);
>
> Now that you dynamically allocate things, how are you handling failures?
>
>> +	if (!irqc)
>> +		return -ENOMEM;
>> +
>> +	xintc_irqc = irqc;
>>
>> -	intc_baseaddr = of_iomap(intc, 0);
>> -	BUG_ON(!intc_baseaddr);
>> +	irqc->base = of_iomap(intc, 0);
>> +	BUG_ON(!irqc->base);
>>
>>  	ret = of_property_read_u32(intc, "xlnx,num-intr-inputs", &nr_irq);
>>  	if (ret < 0) {
>> @@ -150,43 +176,40 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
>>  		return ret;
>
> All the return paths should now take care of releasing the allocated
> resources.
>

Thanks for pointing it out. I'll fix it in the next series.

>>  	}
>>
>> -	ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &intr_mask);
>> +	ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &irqc->intr_mask);
>>  	if (ret < 0) {
>>  		pr_err("%s: unable to read xlnx,kind-of-intr\n", __func__);
>>  		return ret;
>>  	}
>>
>> -	if (intr_mask >> nr_irq)
>> +	if (irqc->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);
>> +		intc->full_name, nr_irq, irqc->intr_mask);
>>
>> -	write_fn = intc_write32;
>> -	read_fn = intc_read32;
>> +	irqc->read = intc_read32;
>> +	irqc->write = intc_write32;
>>
>>  	/*
>>  	 * Disable all external interrupts until they are
>>  	 * explicity requested.
>>  	 */
>> -	write_fn(0, intc_baseaddr + IER);
>> +	xintc_write(irqc, IER, 0);
>>
>>  	/* Acknowledge any pending interrupts just in case. */
>> -	write_fn(0xffffffff, intc_baseaddr + IAR);
>> +	xintc_write(irqc, IAR, 0xffffffff);
>>
>>  	/* 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);
>> +	xintc_write(irqc, MER, MER_HIE | MER_ME);
>> +	if (!(xintc_read(irqc, MER) & (MER_HIE | MER_ME))) {
>> +		irqc->read = intc_read32_be;
>> +		irqc->write = intc_write32_be;
>> +		xintc_write(irqc, MER, MER_HIE | MER_ME);
>>  	}
>>
>> -	/* 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);
>> +					    irqc);
>>
>>  	irq_set_default_host(root_domain);
>>
>>
>
> You haven't addressed the comment on get_irq() which could be static (at
> least from solely looking at this file).

Apologies. In a rush to get a series out before heading home, it slipped my mind.
It is needed as it is used in arch/microblaze/kernel/irq.c

But I'll add a patch to rename it correctly. get_irq is far too generic outside arch code.

Thanks,
ZubairLK

>
> Thanks,
>
> 	M.
>

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

* Re: [Patch v3 02/11] irqchip: axi-intc: Clean up irqdomain argument and read/write
@ 2016-09-01 10:41       ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-09-01 10:41 UTC (permalink / raw)
  To: Marc Zyngier, monstr, ralf, tglx, jason
  Cc: soren.brinkmann, linux-kernel, linux-mips, michal.simek, netdev

Hi,

Thank you for the reviews.

Some comments below

On 08/31/2016 05:52 PM, Marc Zyngier wrote:
> On 31/08/16 17:35, Zubair Lutfullah Kakakhel wrote:
>> The drivers read/write function handling is a bit quirky.
>> And the irqmask is passed directly to the handler.
>>
>> Add a new irqchip struct to pass to the handler and
>> cleanup read/write handling.
>>
>> Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
>>
>> ---
>> V2 -> V3
>> New patch. Cleans up driver structure
>> ---
...
>>  static int __init xilinx_intc_of_init(struct device_node *intc,
>>  					     struct device_node *parent)
>>  {
>> -	u32 nr_irq, intr_mask;
>> +	u32 nr_irq;
>>  	int ret;
>> +	struct xintc_irq_chip *irqc;
>> +
>> +	irqc = kzalloc(sizeof(*irqc), GFP_KERNEL);
>
> Now that you dynamically allocate things, how are you handling failures?
>
>> +	if (!irqc)
>> +		return -ENOMEM;
>> +
>> +	xintc_irqc = irqc;
>>
>> -	intc_baseaddr = of_iomap(intc, 0);
>> -	BUG_ON(!intc_baseaddr);
>> +	irqc->base = of_iomap(intc, 0);
>> +	BUG_ON(!irqc->base);
>>
>>  	ret = of_property_read_u32(intc, "xlnx,num-intr-inputs", &nr_irq);
>>  	if (ret < 0) {
>> @@ -150,43 +176,40 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
>>  		return ret;
>
> All the return paths should now take care of releasing the allocated
> resources.
>

Thanks for pointing it out. I'll fix it in the next series.

>>  	}
>>
>> -	ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &intr_mask);
>> +	ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &irqc->intr_mask);
>>  	if (ret < 0) {
>>  		pr_err("%s: unable to read xlnx,kind-of-intr\n", __func__);
>>  		return ret;
>>  	}
>>
>> -	if (intr_mask >> nr_irq)
>> +	if (irqc->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);
>> +		intc->full_name, nr_irq, irqc->intr_mask);
>>
>> -	write_fn = intc_write32;
>> -	read_fn = intc_read32;
>> +	irqc->read = intc_read32;
>> +	irqc->write = intc_write32;
>>
>>  	/*
>>  	 * Disable all external interrupts until they are
>>  	 * explicity requested.
>>  	 */
>> -	write_fn(0, intc_baseaddr + IER);
>> +	xintc_write(irqc, IER, 0);
>>
>>  	/* Acknowledge any pending interrupts just in case. */
>> -	write_fn(0xffffffff, intc_baseaddr + IAR);
>> +	xintc_write(irqc, IAR, 0xffffffff);
>>
>>  	/* 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);
>> +	xintc_write(irqc, MER, MER_HIE | MER_ME);
>> +	if (!(xintc_read(irqc, MER) & (MER_HIE | MER_ME))) {
>> +		irqc->read = intc_read32_be;
>> +		irqc->write = intc_write32_be;
>> +		xintc_write(irqc, MER, MER_HIE | MER_ME);
>>  	}
>>
>> -	/* 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);
>> +					    irqc);
>>
>>  	irq_set_default_host(root_domain);
>>
>>
>
> You haven't addressed the comment on get_irq() which could be static (at
> least from solely looking at this file).

Apologies. In a rush to get a series out before heading home, it slipped my mind.
It is needed as it is used in arch/microblaze/kernel/irq.c

But I'll add a patch to rename it correctly. get_irq is far too generic outside arch code.

Thanks,
ZubairLK

>
> Thanks,
>
> 	M.
>

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

* Re: [Patch v3 08/11] net: ethernet: xilinx: Generate random mac if none found
  2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  (?)
@ 2016-09-01 10:52   ` Sergei Shtylyov
  2016-09-01 15:30       ` Zubair Lutfullah Kakakhel
  -1 siblings, 1 reply; 41+ messages in thread
From: Sergei Shtylyov @ 2016-09-01 10:52 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel, monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, linux-kernel, linux-mips, michal.simek, netdev

Hello.

On 8/31/2016 7:35 PM, Zubair Lutfullah Kakakhel wrote:

> 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>
[...]

> 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);
> +	}

    All branches of the *if* statement should have {} if at least one has 
them, see Documentation/CodingStyle, chaoter 3.

[...]

MBR, Sergei

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

* Re: [Patch v3 09/11] net: ethernet: xilinx: Enable emaclite for MIPS
  2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  (?)
@ 2016-09-01 10:54   ` Sergei Shtylyov
  -1 siblings, 0 replies; 41+ messages in thread
From: Sergei Shtylyov @ 2016-09-01 10:54 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel, monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, linux-kernel, linux-mips, michal.simek, netdev

On 8/31/2016 7:35 PM, Zubair Lutfullah Kakakhel wrote:

> The MIPS based xilfpga platform uses this driver.
> Enable it for MIPS
>
> Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>

[...]

> 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)

    Parens not needed here, you could remove them while at it.

[...]

MBR, Sergei

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

* Re: [Patch v3 07/11] MIPS: Xilfpga: Add DT node for AXI I2C
  2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
  (?)
@ 2016-09-01 10:57   ` Lars-Peter Clausen
  2016-09-01 15:22       ` Zubair Lutfullah Kakakhel
  -1 siblings, 1 reply; 41+ messages in thread
From: Lars-Peter Clausen @ 2016-09-01 10:57 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel, monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, linux-kernel, linux-mips, michal.simek, netdev

On 08/31/2016 06:35 PM, Zubair Lutfullah Kakakhel wrote:
[..]
> +	    ad7420@4B {
> +		compatible = "adt7420";

"adi,adt7420"

> +		reg = <0x4B>;
> +	    };
> +	} ;
>  };

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

* Re: [Patch v3 03/11] irqchip: axi-intc: Add support for parent intc
@ 2016-09-01 11:01       ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-09-01 11:01 UTC (permalink / raw)
  To: Marc Zyngier, monstr, ralf, tglx, jason
  Cc: soren.brinkmann, linux-kernel, linux-mips, michal.simek, netdev

Hi,

Thanks for the review
Comments inline.

On 08/31/2016 05:57 PM, Marc Zyngier wrote:
> On 31/08/16 17:35, Zubair Lutfullah Kakakhel 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>
>>
>> ---
>> V2 -> V3
>> Reused existing parent node instead of finding again.
>> Cleanup up handler based on review
>>
>> V1 -> V2
>>
>> No change
>> ---
>>  drivers/irqchip/irq-axi-intc.c | 24 +++++++++++++++++++++++-
>>  1 file changed, 23 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/irqchip/irq-axi-intc.c b/drivers/irqchip/irq-axi-intc.c
>> index cb69241..30bb084 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>
>>
>>  /* No one else should require these constants, so define them locally here. */
>>  #define ISR 0x00			/* Interrupt Status Register */
>> @@ -154,11 +155,23 @@ 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;
>> +
>> +	do {
>> +		pending = get_irq();
>> +		if (pending == -1U)
>> +			break;
>> +		generic_handle_irq(pending);
>> +	} while (true);
>> +}
>> +
>>  static int __init xilinx_intc_of_init(struct device_node *intc,
>>  					     struct device_node *parent)
>>  {
>>  	u32 nr_irq;
>> -	int ret;
>> +	int ret, irq;
>>  	struct xintc_irq_chip *irqc;
>>
>>  	irqc = kzalloc(sizeof(*irqc), GFP_KERNEL);
>> @@ -211,6 +224,15 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
>>  	root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
>>  					    irqc);
>>
>> +	if (parent) {
>> +		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;
>>
>
> This doesn't seem right. You've now overridden the xintc_irqc pointer,
> so I don't know how you can still process interrupts once you've
> discovered a secondary interrupt controller. You've also allocated a
> second root_domain, changed the default domain to point to the secondary
> controller...
>
> Have you tested this code? Or am I missing something obvious?

Yes it works. I'll try to explain the platform setup a bit.
Perhaps that will make it clear about what I'm trying to do.

UART IRQ -> AXI INTC -> MIPS internal INTC -> CPU

MIPS Internal Interrupt controller in drivers/irqchip/irq-mips-cpu.c
uses irq_domain_add_legacy while AXI Intc uses irq_domain_add_linear

My aim was to set up a chained irq handler with least disturbance.

Hence the above code.

Your concerns are valid. The code is working because read/writes rely
on the static xintc_irqc in the file.
And the second root domain is also not breaking the platform because
the irq-mips-cpu.c uses irq_domain_add_legacy and doesn't use
irq_set_default_host.

# cat /proc/interrupts
            CPU0
   7:      43493      MIPS   7  timer
   8:         83  Xilinx INTC   1-level     eth0
   9:        417  Xilinx INTC   0-level     serial
  10:         15  Xilinx INTC   4-level     10a00000.i2c
ERR:          0
#

Given the above concerns. How about doing things this way?

	if (parent) {
		irq = irq_of_parse_and_map(intc, 0);
		if (irq)
			irq_set_chained_handler_and_data(irq,
							 xil_intc_irq_handler,
							 irqc);

	} else
		irq_set_default_host(root_domain);

default host is only set if no parent exists.
And the irqc pointer is passed as the data.

Thanks
ZubairLK

>
> Thanks,
>
> 	M.
>

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

* Re: [Patch v3 03/11] irqchip: axi-intc: Add support for parent intc
@ 2016-09-01 11:01       ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-09-01 11:01 UTC (permalink / raw)
  To: Marc Zyngier, monstr, ralf, tglx, jason
  Cc: soren.brinkmann, linux-kernel, linux-mips, michal.simek, netdev

Hi,

Thanks for the review
Comments inline.

On 08/31/2016 05:57 PM, Marc Zyngier wrote:
> On 31/08/16 17:35, Zubair Lutfullah Kakakhel 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>
>>
>> ---
>> V2 -> V3
>> Reused existing parent node instead of finding again.
>> Cleanup up handler based on review
>>
>> V1 -> V2
>>
>> No change
>> ---
>>  drivers/irqchip/irq-axi-intc.c | 24 +++++++++++++++++++++++-
>>  1 file changed, 23 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/irqchip/irq-axi-intc.c b/drivers/irqchip/irq-axi-intc.c
>> index cb69241..30bb084 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>
>>
>>  /* No one else should require these constants, so define them locally here. */
>>  #define ISR 0x00			/* Interrupt Status Register */
>> @@ -154,11 +155,23 @@ 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;
>> +
>> +	do {
>> +		pending = get_irq();
>> +		if (pending == -1U)
>> +			break;
>> +		generic_handle_irq(pending);
>> +	} while (true);
>> +}
>> +
>>  static int __init xilinx_intc_of_init(struct device_node *intc,
>>  					     struct device_node *parent)
>>  {
>>  	u32 nr_irq;
>> -	int ret;
>> +	int ret, irq;
>>  	struct xintc_irq_chip *irqc;
>>
>>  	irqc = kzalloc(sizeof(*irqc), GFP_KERNEL);
>> @@ -211,6 +224,15 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
>>  	root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
>>  					    irqc);
>>
>> +	if (parent) {
>> +		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;
>>
>
> This doesn't seem right. You've now overridden the xintc_irqc pointer,
> so I don't know how you can still process interrupts once you've
> discovered a secondary interrupt controller. You've also allocated a
> second root_domain, changed the default domain to point to the secondary
> controller...
>
> Have you tested this code? Or am I missing something obvious?

Yes it works. I'll try to explain the platform setup a bit.
Perhaps that will make it clear about what I'm trying to do.

UART IRQ -> AXI INTC -> MIPS internal INTC -> CPU

MIPS Internal Interrupt controller in drivers/irqchip/irq-mips-cpu.c
uses irq_domain_add_legacy while AXI Intc uses irq_domain_add_linear

My aim was to set up a chained irq handler with least disturbance.

Hence the above code.

Your concerns are valid. The code is working because read/writes rely
on the static xintc_irqc in the file.
And the second root domain is also not breaking the platform because
the irq-mips-cpu.c uses irq_domain_add_legacy and doesn't use
irq_set_default_host.

# cat /proc/interrupts
            CPU0
   7:      43493      MIPS   7  timer
   8:         83  Xilinx INTC   1-level     eth0
   9:        417  Xilinx INTC   0-level     serial
  10:         15  Xilinx INTC   4-level     10a00000.i2c
ERR:          0
#

Given the above concerns. How about doing things this way?

	if (parent) {
		irq = irq_of_parse_and_map(intc, 0);
		if (irq)
			irq_set_chained_handler_and_data(irq,
							 xil_intc_irq_handler,
							 irqc);

	} else
		irq_set_default_host(root_domain);

default host is only set if no parent exists.
And the irqc pointer is passed as the data.

Thanks
ZubairLK

>
> Thanks,
>
> 	M.
>

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

* Re: [Patch v3 03/11] irqchip: axi-intc: Add support for parent intc
  2016-09-01 11:01       ` Zubair Lutfullah Kakakhel
  (?)
@ 2016-09-01 12:14       ` Marc Zyngier
  2016-09-01 13:52           ` Zubair Lutfullah Kakakhel
  -1 siblings, 1 reply; 41+ messages in thread
From: Marc Zyngier @ 2016-09-01 12:14 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel, monstr, ralf, tglx, jason
  Cc: soren.brinkmann, linux-kernel, linux-mips, michal.simek, netdev

On 01/09/16 12:01, Zubair Lutfullah Kakakhel wrote:
> Hi,
> 
> Thanks for the review
> Comments inline.
> 
> On 08/31/2016 05:57 PM, Marc Zyngier wrote:
>> On 31/08/16 17:35, Zubair Lutfullah Kakakhel 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>
>>>
>>> ---
>>> V2 -> V3
>>> Reused existing parent node instead of finding again.
>>> Cleanup up handler based on review
>>>
>>> V1 -> V2
>>>
>>> No change
>>> ---
>>>  drivers/irqchip/irq-axi-intc.c | 24 +++++++++++++++++++++++-
>>>  1 file changed, 23 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/irqchip/irq-axi-intc.c b/drivers/irqchip/irq-axi-intc.c
>>> index cb69241..30bb084 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>
>>>
>>>  /* No one else should require these constants, so define them locally here. */
>>>  #define ISR 0x00			/* Interrupt Status Register */
>>> @@ -154,11 +155,23 @@ 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;
>>> +
>>> +	do {
>>> +		pending = get_irq();
>>> +		if (pending == -1U)
>>> +			break;
>>> +		generic_handle_irq(pending);
>>> +	} while (true);
>>> +}
>>> +
>>>  static int __init xilinx_intc_of_init(struct device_node *intc,
>>>  					     struct device_node *parent)
>>>  {
>>>  	u32 nr_irq;
>>> -	int ret;
>>> +	int ret, irq;
>>>  	struct xintc_irq_chip *irqc;
>>>
>>>  	irqc = kzalloc(sizeof(*irqc), GFP_KERNEL);
>>> @@ -211,6 +224,15 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
>>>  	root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
>>>  					    irqc);
>>>
>>> +	if (parent) {
>>> +		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;
>>>
>>
>> This doesn't seem right. You've now overridden the xintc_irqc pointer,
>> so I don't know how you can still process interrupts once you've
>> discovered a secondary interrupt controller. You've also allocated a
>> second root_domain, changed the default domain to point to the secondary
>> controller...
>>
>> Have you tested this code? Or am I missing something obvious?
> 
> Yes it works. I'll try to explain the platform setup a bit.
> Perhaps that will make it clear about what I'm trying to do.
> 
> UART IRQ -> AXI INTC -> MIPS internal INTC -> CPU
> 
> MIPS Internal Interrupt controller in drivers/irqchip/irq-mips-cpu.c
> uses irq_domain_add_legacy while AXI Intc uses irq_domain_add_linear
> 
> My aim was to set up a chained irq handler with least disturbance.
> 
> Hence the above code.
> 
> Your concerns are valid. The code is working because read/writes rely
> on the static xintc_irqc in the file.
> And the second root domain is also not breaking the platform because
> the irq-mips-cpu.c uses irq_domain_add_legacy and doesn't use
> irq_set_default_host.
> 
> # cat /proc/interrupts
>             CPU0
>    7:      43493      MIPS   7  timer
>    8:         83  Xilinx INTC   1-level     eth0
>    9:        417  Xilinx INTC   0-level     serial
>   10:         15  Xilinx INTC   4-level     10a00000.i2c
> ERR:          0
> #
> 
> Given the above concerns. How about doing things this way?
> 
> 	if (parent) {
> 		irq = irq_of_parse_and_map(intc, 0);
> 		if (irq)
> 			irq_set_chained_handler_and_data(irq,
> 							 xil_intc_irq_handler,
> 							 irqc);
> 
> 	} else
> 		irq_set_default_host(root_domain);
> 
> default host is only set if no parent exists.
> And the irqc pointer is passed as the data.

But that still doesn't address the case I had in mind, which is when you
have *two* AXI-intc, one cascaded into the other. Is that something that
could be built? You should at least make sure that there is a big fat
warning if you don't want to support that case, because that will be
hell to debug.

Thanks,

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

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

* Re: [Patch v3 03/11] irqchip: axi-intc: Add support for parent intc
@ 2016-09-01 13:52           ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-09-01 13:52 UTC (permalink / raw)
  To: Marc Zyngier, monstr, ralf, tglx, jason
  Cc: soren.brinkmann, linux-kernel, linux-mips, michal.simek, netdev

Hi,

On 09/01/2016 01:14 PM, Marc Zyngier wrote:
> On 01/09/16 12:01, Zubair Lutfullah Kakakhel wrote:
>> Hi,
>>
>> Thanks for the review
>> Comments inline.
>>
>> On 08/31/2016 05:57 PM, Marc Zyngier wrote:
>>> On 31/08/16 17:35, Zubair Lutfullah Kakakhel 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>
>>>>
>>>> ---
>>>> V2 -> V3
>>>> Reused existing parent node instead of finding again.
>>>> Cleanup up handler based on review
>>>>
>>>> V1 -> V2
>>>>
>>>> No change
>>>> ---
>>>>  drivers/irqchip/irq-axi-intc.c | 24 +++++++++++++++++++++++-
>>>>  1 file changed, 23 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/irqchip/irq-axi-intc.c b/drivers/irqchip/irq-axi-intc.c
>>>> index cb69241..30bb084 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>
>>>>
>>>>  /* No one else should require these constants, so define them locally here. */
>>>>  #define ISR 0x00			/* Interrupt Status Register */
>>>> @@ -154,11 +155,23 @@ 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;
>>>> +
>>>> +	do {
>>>> +		pending = get_irq();
>>>> +		if (pending == -1U)
>>>> +			break;
>>>> +		generic_handle_irq(pending);
>>>> +	} while (true);
>>>> +}
>>>> +
>>>>  static int __init xilinx_intc_of_init(struct device_node *intc,
>>>>  					     struct device_node *parent)
>>>>  {
>>>>  	u32 nr_irq;
>>>> -	int ret;
>>>> +	int ret, irq;
>>>>  	struct xintc_irq_chip *irqc;
>>>>
>>>>  	irqc = kzalloc(sizeof(*irqc), GFP_KERNEL);
>>>> @@ -211,6 +224,15 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
>>>>  	root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
>>>>  					    irqc);
>>>>
>>>> +	if (parent) {
>>>> +		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;
>>>>
>>>
>>> This doesn't seem right. You've now overridden the xintc_irqc pointer,
>>> so I don't know how you can still process interrupts once you've
>>> discovered a secondary interrupt controller. You've also allocated a
>>> second root_domain, changed the default domain to point to the secondary
>>> controller...
>>>
>>> Have you tested this code? Or am I missing something obvious?
>>
>> Yes it works. I'll try to explain the platform setup a bit.
>> Perhaps that will make it clear about what I'm trying to do.
>>
>> UART IRQ -> AXI INTC -> MIPS internal INTC -> CPU
>>
>> MIPS Internal Interrupt controller in drivers/irqchip/irq-mips-cpu.c
>> uses irq_domain_add_legacy while AXI Intc uses irq_domain_add_linear
>>
>> My aim was to set up a chained irq handler with least disturbance.
>>
>> Hence the above code.
>>
>> Your concerns are valid. The code is working because read/writes rely
>> on the static xintc_irqc in the file.
>> And the second root domain is also not breaking the platform because
>> the irq-mips-cpu.c uses irq_domain_add_legacy and doesn't use
>> irq_set_default_host.
>>
>> # cat /proc/interrupts
>>             CPU0
>>    7:      43493      MIPS   7  timer
>>    8:         83  Xilinx INTC   1-level     eth0
>>    9:        417  Xilinx INTC   0-level     serial
>>   10:         15  Xilinx INTC   4-level     10a00000.i2c
>> ERR:          0
>> #
>>
>> Given the above concerns. How about doing things this way?
>>
>> 	if (parent) {
>> 		irq = irq_of_parse_and_map(intc, 0);
>> 		if (irq)
>> 			irq_set_chained_handler_and_data(irq,
>> 							 xil_intc_irq_handler,
>> 							 irqc);
>>
>> 	} else
>> 		irq_set_default_host(root_domain);
>>
>> default host is only set if no parent exists.
>> And the irqc pointer is passed as the data.
>
> But that still doesn't address the case I had in mind, which is when you
> have *two* AXI-intc, one cascaded into the other. Is that something that
> could be built? You should at least make sure that there is a big fat
> warning if you don't want to support that case, because that will be
> hell to debug.

Oo. I didn't think of that one. tbh, I'm not sure if that is currently supported
because this driver came out of arch/microblaze. And it didn't have any code that
looked supportive of chained interrupt handling.

'Technically', it should be possible to synthesize two daisy chained axi interrupt
controllers on an FPGA. But I don't see it being supported before.

A warning would be nice. Any suggestions on the most suitable way?

Thanks,
ZubairLK

>
> Thanks,
>
> 	M.
>

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

* Re: [Patch v3 03/11] irqchip: axi-intc: Add support for parent intc
@ 2016-09-01 13:52           ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-09-01 13:52 UTC (permalink / raw)
  To: Marc Zyngier, monstr, ralf, tglx, jason
  Cc: soren.brinkmann, linux-kernel, linux-mips, michal.simek, netdev

Hi,

On 09/01/2016 01:14 PM, Marc Zyngier wrote:
> On 01/09/16 12:01, Zubair Lutfullah Kakakhel wrote:
>> Hi,
>>
>> Thanks for the review
>> Comments inline.
>>
>> On 08/31/2016 05:57 PM, Marc Zyngier wrote:
>>> On 31/08/16 17:35, Zubair Lutfullah Kakakhel 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>
>>>>
>>>> ---
>>>> V2 -> V3
>>>> Reused existing parent node instead of finding again.
>>>> Cleanup up handler based on review
>>>>
>>>> V1 -> V2
>>>>
>>>> No change
>>>> ---
>>>>  drivers/irqchip/irq-axi-intc.c | 24 +++++++++++++++++++++++-
>>>>  1 file changed, 23 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/irqchip/irq-axi-intc.c b/drivers/irqchip/irq-axi-intc.c
>>>> index cb69241..30bb084 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>
>>>>
>>>>  /* No one else should require these constants, so define them locally here. */
>>>>  #define ISR 0x00			/* Interrupt Status Register */
>>>> @@ -154,11 +155,23 @@ 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;
>>>> +
>>>> +	do {
>>>> +		pending = get_irq();
>>>> +		if (pending == -1U)
>>>> +			break;
>>>> +		generic_handle_irq(pending);
>>>> +	} while (true);
>>>> +}
>>>> +
>>>>  static int __init xilinx_intc_of_init(struct device_node *intc,
>>>>  					     struct device_node *parent)
>>>>  {
>>>>  	u32 nr_irq;
>>>> -	int ret;
>>>> +	int ret, irq;
>>>>  	struct xintc_irq_chip *irqc;
>>>>
>>>>  	irqc = kzalloc(sizeof(*irqc), GFP_KERNEL);
>>>> @@ -211,6 +224,15 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
>>>>  	root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
>>>>  					    irqc);
>>>>
>>>> +	if (parent) {
>>>> +		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;
>>>>
>>>
>>> This doesn't seem right. You've now overridden the xintc_irqc pointer,
>>> so I don't know how you can still process interrupts once you've
>>> discovered a secondary interrupt controller. You've also allocated a
>>> second root_domain, changed the default domain to point to the secondary
>>> controller...
>>>
>>> Have you tested this code? Or am I missing something obvious?
>>
>> Yes it works. I'll try to explain the platform setup a bit.
>> Perhaps that will make it clear about what I'm trying to do.
>>
>> UART IRQ -> AXI INTC -> MIPS internal INTC -> CPU
>>
>> MIPS Internal Interrupt controller in drivers/irqchip/irq-mips-cpu.c
>> uses irq_domain_add_legacy while AXI Intc uses irq_domain_add_linear
>>
>> My aim was to set up a chained irq handler with least disturbance.
>>
>> Hence the above code.
>>
>> Your concerns are valid. The code is working because read/writes rely
>> on the static xintc_irqc in the file.
>> And the second root domain is also not breaking the platform because
>> the irq-mips-cpu.c uses irq_domain_add_legacy and doesn't use
>> irq_set_default_host.
>>
>> # cat /proc/interrupts
>>             CPU0
>>    7:      43493      MIPS   7  timer
>>    8:         83  Xilinx INTC   1-level     eth0
>>    9:        417  Xilinx INTC   0-level     serial
>>   10:         15  Xilinx INTC   4-level     10a00000.i2c
>> ERR:          0
>> #
>>
>> Given the above concerns. How about doing things this way?
>>
>> 	if (parent) {
>> 		irq = irq_of_parse_and_map(intc, 0);
>> 		if (irq)
>> 			irq_set_chained_handler_and_data(irq,
>> 							 xil_intc_irq_handler,
>> 							 irqc);
>>
>> 	} else
>> 		irq_set_default_host(root_domain);
>>
>> default host is only set if no parent exists.
>> And the irqc pointer is passed as the data.
>
> But that still doesn't address the case I had in mind, which is when you
> have *two* AXI-intc, one cascaded into the other. Is that something that
> could be built? You should at least make sure that there is a big fat
> warning if you don't want to support that case, because that will be
> hell to debug.

Oo. I didn't think of that one. tbh, I'm not sure if that is currently supported
because this driver came out of arch/microblaze. And it didn't have any code that
looked supportive of chained interrupt handling.

'Technically', it should be possible to synthesize two daisy chained axi interrupt
controllers on an FPGA. But I don't see it being supported before.

A warning would be nice. Any suggestions on the most suitable way?

Thanks,
ZubairLK

>
> Thanks,
>
> 	M.
>

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

* Re: [Patch v3 03/11] irqchip: axi-intc: Add support for parent intc
  2016-09-01 13:52           ` Zubair Lutfullah Kakakhel
  (?)
@ 2016-09-01 14:48           ` Marc Zyngier
  -1 siblings, 0 replies; 41+ messages in thread
From: Marc Zyngier @ 2016-09-01 14:48 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel, monstr, ralf, tglx, jason
  Cc: soren.brinkmann, linux-kernel, linux-mips, michal.simek, netdev

On 01/09/16 14:52, Zubair Lutfullah Kakakhel wrote:
> Hi,

[...]

>> But that still doesn't address the case I had in mind, which is when you
>> have *two* AXI-intc, one cascaded into the other. Is that something that
>> could be built? You should at least make sure that there is a big fat
>> warning if you don't want to support that case, because that will be
>> hell to debug.
> 
> Oo. I didn't think of that one. tbh, I'm not sure if that is currently supported
> because this driver came out of arch/microblaze. And it didn't have any code that
> looked supportive of chained interrupt handling.
> 
> 'Technically', it should be possible to synthesize two daisy chained axi interrupt
> controllers on an FPGA. But I don't see it being supported before.
> 
> A warning would be nice. Any suggestions on the most suitable way?

Check if you've already allocated a xintc_irqc. If so, abort the probing
early...

Thanks,

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

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

* Re: [Patch v3 07/11] MIPS: Xilfpga: Add DT node for AXI I2C
@ 2016-09-01 15:22       ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-09-01 15:22 UTC (permalink / raw)
  To: Lars-Peter Clausen, monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, linux-kernel, linux-mips, michal.simek, netdev



On 09/01/2016 11:57 AM, Lars-Peter Clausen wrote:
> On 08/31/2016 06:35 PM, Zubair Lutfullah Kakakhel wrote:
> [..]
>> +	    ad7420@4B {
>> +		compatible = "adt7420";
>
> "adi,adt7420"

danke schoen

:)
ZubairLK

>
>> +		reg = <0x4B>;
>> +	    };
>> +	} ;
>>  };

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

* Re: [Patch v3 07/11] MIPS: Xilfpga: Add DT node for AXI I2C
@ 2016-09-01 15:22       ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-09-01 15:22 UTC (permalink / raw)
  To: Lars-Peter Clausen, monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, linux-kernel, linux-mips, michal.simek, netdev



On 09/01/2016 11:57 AM, Lars-Peter Clausen wrote:
> On 08/31/2016 06:35 PM, Zubair Lutfullah Kakakhel wrote:
> [..]
>> +	    ad7420@4B {
>> +		compatible = "adt7420";
>
> "adi,adt7420"

danke schoen

:)
ZubairLK

>
>> +		reg = <0x4B>;
>> +	    };
>> +	} ;
>>  };

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

* Re: [Patch v3 08/11] net: ethernet: xilinx: Generate random mac if none found
@ 2016-09-01 15:30       ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-09-01 15:30 UTC (permalink / raw)
  To: Sergei Shtylyov, monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, linux-kernel, linux-mips, michal.simek, netdev



On 09/01/2016 11:52 AM, Sergei Shtylyov wrote:
> Hello.
>
> On 8/31/2016 7:35 PM, Zubair Lutfullah Kakakhel wrote:
>
>> 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>
> [...]
>
>> 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);
>> +    }
>
>    All branches of the *if* statement should have {} if at least one has them, see Documentation/CodingStyle, chaoter 3.

Спасибо

ZubairLK

>
> [...]
>
> MBR, Sergei
>

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

* Re: [Patch v3 08/11] net: ethernet: xilinx: Generate random mac if none found
@ 2016-09-01 15:30       ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 41+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-09-01 15:30 UTC (permalink / raw)
  To: Sergei Shtylyov, monstr, ralf, tglx, jason, marc.zyngier
  Cc: soren.brinkmann, linux-kernel, linux-mips, michal.simek, netdev



On 09/01/2016 11:52 AM, Sergei Shtylyov wrote:
> Hello.
>
> On 8/31/2016 7:35 PM, Zubair Lutfullah Kakakhel wrote:
>
>> 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>
> [...]
>
>> 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);
>> +    }
>
>    All branches of the *if* statement should have {} if at least one has them, see Documentation/CodingStyle, chaoter 3.

Спасибо

ZubairLK

>
> [...]
>
> MBR, Sergei
>

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

end of thread, other threads:[~2016-09-01 15:30 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-31 16:35 [Patch v3 00/11] microblaze/MIPS: xilfpga: intc and peripheral Zubair Lutfullah Kakakhel
2016-08-31 16:35 ` Zubair Lutfullah Kakakhel
2016-08-31 16:35 ` [Patch v3 01/11] microblaze: irqchip: Move intc driver to irqchip Zubair Lutfullah Kakakhel
2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
2016-08-31 16:35 ` [Patch v3 02/11] irqchip: axi-intc: Clean up irqdomain argument and read/write Zubair Lutfullah Kakakhel
2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
2016-08-31 16:52   ` Marc Zyngier
2016-09-01 10:41     ` Zubair Lutfullah Kakakhel
2016-09-01 10:41       ` Zubair Lutfullah Kakakhel
2016-08-31 16:35 ` [Patch v3 03/11] irqchip: axi-intc: Add support for parent intc Zubair Lutfullah Kakakhel
2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
2016-08-31 16:57   ` Marc Zyngier
2016-09-01 11:01     ` Zubair Lutfullah Kakakhel
2016-09-01 11:01       ` Zubair Lutfullah Kakakhel
2016-09-01 12:14       ` Marc Zyngier
2016-09-01 13:52         ` Zubair Lutfullah Kakakhel
2016-09-01 13:52           ` Zubair Lutfullah Kakakhel
2016-09-01 14:48           ` Marc Zyngier
2016-08-31 16:35 ` [Patch v3 04/11] MIPS: xilfpga: Use irqchip_init instead of the legacy way Zubair Lutfullah Kakakhel
2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
2016-08-31 16:35 ` [Patch v3 05/11] MIPS: xilfpga: Use Xilinx AXI Interrupt Controller Zubair Lutfullah Kakakhel
2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
2016-08-31 16:35 ` [Patch v3 06/11] MIPS: xilfpga: Update DT node and specify uart irq Zubair Lutfullah Kakakhel
2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
2016-08-31 16:35 ` [Patch v3 07/11] MIPS: Xilfpga: Add DT node for AXI I2C Zubair Lutfullah Kakakhel
2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
2016-09-01 10:57   ` Lars-Peter Clausen
2016-09-01 15:22     ` Zubair Lutfullah Kakakhel
2016-09-01 15:22       ` Zubair Lutfullah Kakakhel
2016-08-31 16:35 ` [Patch v3 08/11] net: ethernet: xilinx: Generate random mac if none found Zubair Lutfullah Kakakhel
2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
2016-09-01 10:52   ` Sergei Shtylyov
2016-09-01 15:30     ` Zubair Lutfullah Kakakhel
2016-09-01 15:30       ` Zubair Lutfullah Kakakhel
2016-08-31 16:35 ` [Patch v3 09/11] net: ethernet: xilinx: Enable emaclite for MIPS Zubair Lutfullah Kakakhel
2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
2016-09-01 10:54   ` Sergei Shtylyov
2016-08-31 16:35 ` [Patch v3 10/11] MIPS: xilfpga: Add DT node for AXI emaclite Zubair Lutfullah Kakakhel
2016-08-31 16:35   ` Zubair Lutfullah Kakakhel
2016-08-31 16:35 ` [Patch v3 11/11] MIPS: xilfpga: Update defconfig Zubair Lutfullah Kakakhel
2016-08-31 16:35   ` 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.