linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V2 01/10] microblaze: irqchip: Move intc driver to irqchip
       [not found] <1471527804-26175-1-git-send-email-Zubair.Kakakhel@imgtec.com>
@ 2016-08-18 13:43 ` Zubair Lutfullah Kakakhel
  2016-08-26 14:13   ` Marc Zyngier
  2016-08-18 13:43 ` [PATCH V2 05/10] MIPS: xilfpga: Update DT node and specify uart irq Zubair Lutfullah Kakakhel
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 7+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

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

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

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

---
V1 -> V2

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

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

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

* [PATCH V2 05/10] MIPS: xilfpga: Update DT node and specify uart irq
       [not found] <1471527804-26175-1-git-send-email-Zubair.Kakakhel@imgtec.com>
  2016-08-18 13:43 ` [PATCH V2 01/10] microblaze: irqchip: Move intc driver to irqchip Zubair Lutfullah Kakakhel
@ 2016-08-18 13:43 ` Zubair Lutfullah Kakakhel
  2016-08-18 13:43 ` [PATCH V2 07/10] net: ethernet: xilinx: Generate random mac if none found Zubair Lutfullah Kakakhel
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

Update the DT node with the UART irq

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

---
V1 -> V2

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

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

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

* [PATCH V2 07/10] net: ethernet: xilinx: Generate random mac if none found
       [not found] <1471527804-26175-1-git-send-email-Zubair.Kakakhel@imgtec.com>
  2016-08-18 13:43 ` [PATCH V2 01/10] microblaze: irqchip: Move intc driver to irqchip Zubair Lutfullah Kakakhel
  2016-08-18 13:43 ` [PATCH V2 05/10] MIPS: xilfpga: Update DT node and specify uart irq Zubair Lutfullah Kakakhel
@ 2016-08-18 13:43 ` Zubair Lutfullah Kakakhel
  2016-08-18 13:43 ` [PATCH V2 10/10] MIPS: xilfpga: Update defconfig Zubair Lutfullah Kakakhel
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

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

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

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

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

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

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

* [PATCH V2 10/10] MIPS: xilfpga: Update defconfig
       [not found] <1471527804-26175-1-git-send-email-Zubair.Kakakhel@imgtec.com>
                   ` (2 preceding siblings ...)
  2016-08-18 13:43 ` [PATCH V2 07/10] net: ethernet: xilinx: Generate random mac if none found Zubair Lutfullah Kakakhel
@ 2016-08-18 13:43 ` Zubair Lutfullah Kakakhel
  2016-08-26 13:41 ` [PATCH V2 00/10] microblaze/MIPS: xilfpga: intc and peripheral Zubair Lutfullah Kakakhel
       [not found] ` <1471527804-26175-3-git-send-email-Zubair.Kakakhel@imgtec.com>
  5 siblings, 0 replies; 7+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-18 13:43 UTC (permalink / raw)
  To: monstr, ralf, tglx
  Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev, Zubair.Kakakhel

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

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

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

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

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

* Re: [PATCH V2 00/10] microblaze/MIPS: xilfpga: intc and peripheral
       [not found] <1471527804-26175-1-git-send-email-Zubair.Kakakhel@imgtec.com>
                   ` (3 preceding siblings ...)
  2016-08-18 13:43 ` [PATCH V2 10/10] MIPS: xilfpga: Update defconfig Zubair Lutfullah Kakakhel
@ 2016-08-26 13:41 ` Zubair Lutfullah Kakakhel
       [not found] ` <1471527804-26175-3-git-send-email-Zubair.Kakakhel@imgtec.com>
  5 siblings, 0 replies; 7+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2016-08-26 13:41 UTC (permalink / raw)
  To: monstr, ralf, tglx; +Cc: jason, marc.zyngier, linux-mips, linux-kernel, netdev

Hi,


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

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

Thanks
ZubairLK

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

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

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

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

Hi Zubair,

Thanks for the heads up, comments below.

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

[...]

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

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

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

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

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

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

Thanks,

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

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

* Re: [PATCH V2 02/10] irqchip: xilinx: Add support for parent intc
       [not found] ` <1471527804-26175-3-git-send-email-Zubair.Kakakhel@imgtec.com>
@ 2016-08-26 14:23   ` Marc Zyngier
  0 siblings, 0 replies; 7+ messages in thread
From: Marc Zyngier @ 2016-08-26 14:23 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel
  Cc: monstr, ralf, tglx, jason, linux-mips, linux-kernel, netdev

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

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

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

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

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

	do {
		u32 pending;

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

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

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

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


Thanks,

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

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

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

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1471527804-26175-1-git-send-email-Zubair.Kakakhel@imgtec.com>
2016-08-18 13:43 ` [PATCH V2 01/10] microblaze: irqchip: Move intc driver to irqchip Zubair Lutfullah Kakakhel
2016-08-26 14:13   ` Marc Zyngier
2016-08-18 13:43 ` [PATCH V2 05/10] MIPS: xilfpga: Update DT node and specify uart irq Zubair Lutfullah Kakakhel
2016-08-18 13:43 ` [PATCH V2 07/10] net: ethernet: xilinx: Generate random mac if none found Zubair Lutfullah Kakakhel
2016-08-18 13:43 ` [PATCH V2 10/10] MIPS: xilfpga: Update defconfig Zubair Lutfullah Kakakhel
2016-08-26 13:41 ` [PATCH V2 00/10] microblaze/MIPS: xilfpga: intc and peripheral Zubair Lutfullah Kakakhel
     [not found] ` <1471527804-26175-3-git-send-email-Zubair.Kakakhel@imgtec.com>
2016-08-26 14:23   ` [PATCH V2 02/10] irqchip: xilinx: Add support for parent intc Marc Zyngier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).