linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v7 00/12] Modernize Loongson64 Machine v6
       [not found] <20190827085302.5197-1-jiaxun.yang@flygoat.com>
@ 2020-03-25  2:28 ` Jiaxun Yang
  2020-03-25  2:28   ` [PATCH v7 01/12] irqchip: Add driver for Loongson I/O Local Interrupt Controller Jiaxun Yang
                     ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Jiaxun Yang @ 2020-03-25  2:28 UTC (permalink / raw)
  To: linux-mips
  Cc: Jiaxun Yang, Thomas Gleixner, Jason Cooper, Marc Zyngier,
	Rob Herring, Mark Rutland, Thomas Bogendoerfer, Jonathan Corbet,
	Paul Cercueil, Huacai Chen, John Crispin, Matthias Brugger,
	Jean Delvare, David S. Miller, Mauro Carvalho Chehab,
	Jonathan Cameron, Greg Kroah-Hartman, Andy Shevchenko,
	Paul Burton, Geert Uytterhoeven, Eric W. Biederman, Andi Kleen,
	H. Nikolaus Schaller, Miquel Raynal, Krzysztof Kozlowski,
	Tiezhu Yang, Yinglu Yang, Allison Randal,
	Bartlomiej Zolnierkiewicz, Manuel Lauss, Serge Semin,
	Matt Redfearn, linux-kernel, devicetree, linux-doc,
	linux-arm-kernel, linux-mediatek, linux-ide

Loongson have a long history of contributing their code to mainline kernel.
However, it seems like recent years, they are focusing on maintain a kernel by themselves
rather than contribute there code to the community.

Kernel is progress rapidly too. Their code slept in mainline for a long peroid without proper
maintainance and became outdated.

This patchset brings modern DeviceTree and irqchip support to the Loongson64 machine, and leaves
Loongson 2e/f alone since they are too legacy to touch.

PCI and some legacy I/O device will be converted later, together with LS7A PCH support.

v1:
- dt-bindings fixup according to Rob's comments
- irqchip fixup according to Marc's comments
- ls3-iointc: Make Core&IP map per-IRQ
- Regenerate kconfigs
- Typo & style improvements

v2:
- dt-bindings: Fix IOINTC, collect Rob's review tag
- dtbs: Drop CPU Node, merge different ways according to Huacai and Paul's comments

v3:
- Split code have been merged
- Fix IOINTC binding to allow map any child IRQ to and parent
- Convert "HTINTC" into "HTPIC", which mixed HT vectors processing and i8259
- Naming style fix according to Huacai's suggestions

v4:
- More naming related fixes

v5:
- irqchip fixes thanks to maz (see per file changelog)
- Remove unnecessary details in dt-bindings
- Credit Huacai with Co-developed-by

v6:
- HTPIC minor fix
- device binding naming fix 

v7:
- Add Huacai's sign-off
- Fix all reasonable checkpatch warnings

Jiaxun Yang (12):
  irqchip: Add driver for Loongson I/O Local Interrupt Controller
  irqchip: loongson-liointc: Workaround LPC IRQ Errata
  dt-bindings: interrupt-controller: Add Loongson LIOINTC
  irqchip: Add driver for Loongson-3 HyperTransport PIC controller
  dt-bindings: interrupt-controller: Add Loongson-3 HTPIC
  irqchip: mips-cpu: Convert to simple domain
  MIPS: Loongson64: Drop legacy IRQ code
  dt-bindings: mips: Add loongson boards
  MIPS: Loongson64: Add generic dts
  MIPS: Loongson64: Load built-in dtbs
  MIPS: Loongson64: Move MIPS_CPU_IRQ_BASE
  MAINTAINERS: Update Loongson64 entry

 .../interrupt-controller/loongson,htpic.yaml  |  59 ++++
 .../loongson,liointc.yaml                     |  93 ++++++
 .../bindings/mips/loongson/devices.yaml       |  27 ++
 MAINTAINERS                                   |   1 +
 arch/mips/Kconfig                             |   6 +-
 arch/mips/boot/dts/Makefile                   |   1 +
 arch/mips/boot/dts/loongson/Makefile          |   4 +
 .../boot/dts/loongson/loongson3-package.dtsi  |  64 +++++
 .../dts/loongson/loongson3_4core_rs780e.dts   |  25 ++
 .../dts/loongson/loongson3_8core_rs780e.dts   |  25 ++
 arch/mips/boot/dts/loongson/rs780e-pch.dtsi   |  26 ++
 arch/mips/include/asm/i8259.h                 |   1 +
 .../include/asm/mach-loongson64/boot_param.h  |   2 +
 .../asm/mach-loongson64/builtin_dtbs.h        |  13 +
 arch/mips/include/asm/mach-loongson64/irq.h   |  32 +--
 .../include/asm/mach-loongson64/loongson.h    |   1 +
 arch/mips/loongson64/Makefile                 |   2 +-
 arch/mips/loongson64/env.c                    |  23 ++
 arch/mips/loongson64/init.c                   |   6 +
 arch/mips/loongson64/irq.c                    | 162 -----------
 arch/mips/loongson64/setup.c                  |  16 ++
 arch/mips/loongson64/smp.c                    |  28 +-
 drivers/irqchip/Kconfig                       |  19 ++
 drivers/irqchip/Makefile                      |   2 +
 drivers/irqchip/irq-loongson-htpic.c          | 149 ++++++++++
 drivers/irqchip/irq-loongson-liointc.c        | 270 ++++++++++++++++++
 drivers/irqchip/irq-mips-cpu.c                |   2 +-
 27 files changed, 846 insertions(+), 213 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/loongson,htpic.yaml
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/loongson,liointc.yaml
 create mode 100644 Documentation/devicetree/bindings/mips/loongson/devices.yaml
 create mode 100644 arch/mips/boot/dts/loongson/Makefile
 create mode 100644 arch/mips/boot/dts/loongson/loongson3-package.dtsi
 create mode 100644 arch/mips/boot/dts/loongson/loongson3_4core_rs780e.dts
 create mode 100644 arch/mips/boot/dts/loongson/loongson3_8core_rs780e.dts
 create mode 100644 arch/mips/boot/dts/loongson/rs780e-pch.dtsi
 create mode 100644 arch/mips/include/asm/mach-loongson64/builtin_dtbs.h
 delete mode 100644 arch/mips/loongson64/irq.c
 create mode 100644 drivers/irqchip/irq-loongson-htpic.c
 create mode 100644 drivers/irqchip/irq-loongson-liointc.c

-- 
2.26.0.rc2



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

* [PATCH v7 01/12] irqchip: Add driver for Loongson I/O Local Interrupt Controller
  2020-03-25  2:28 ` [PATCH v7 00/12] Modernize Loongson64 Machine v6 Jiaxun Yang
@ 2020-03-25  2:28   ` Jiaxun Yang
  2020-03-25 11:25     ` Paul Cercueil
  2020-03-25  2:28   ` [PATCH v7 01/12] MIPS: Loongson: Do not initialise statics to 0 Jiaxun Yang
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 8+ messages in thread
From: Jiaxun Yang @ 2020-03-25  2:28 UTC (permalink / raw)
  To: linux-mips
  Cc: Jiaxun Yang, Huacai Chen, Marc Zyngier, Thomas Gleixner,
	Jason Cooper, Rob Herring, Mark Rutland, Thomas Bogendoerfer,
	Jonathan Corbet, Paul Cercueil, John Crispin, Matthias Brugger,
	Jean Delvare, David S. Miller, Mauro Carvalho Chehab,
	Jonathan Cameron, Greg Kroah-Hartman, Andy Shevchenko,
	Geert Uytterhoeven, Krzysztof Kozlowski, Miquel Raynal,
	Andi Kleen, H. Nikolaus Schaller, Eric W. Biederman, Tiezhu Yang,
	Yinglu Yang, Allison Randal, Bartlomiej Zolnierkiewicz,
	Paul Burton, Manuel Lauss, Serge Semin, Matt Redfearn,
	linux-kernel, devicetree, linux-doc, linux-arm-kernel,
	linux-mediatek, linux-ide

This controller appeared on Loongson family of chips as the primary
package interrupt source.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Co-developed-by: Huacai Chen <chenhc@lemote.com>
Signed-off-by: Huacai Chen <chenhc@lemote.com>
Reviewed-by: Marc Zyngier <maz@kernel.org>
---
v4-v5:
	Resolve suggestions from maz:
		- Remove DT validation
		- Simplify unnucessary functions & variables
---
 drivers/irqchip/Kconfig                |   9 +
 drivers/irqchip/Makefile               |   1 +
 drivers/irqchip/irq-loongson-liointc.c | 261 +++++++++++++++++++++++++
 3 files changed, 271 insertions(+)
 create mode 100644 drivers/irqchip/irq-loongson-liointc.c

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 6d397732138d..c609eaa319d2 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -513,4 +513,13 @@ config EXYNOS_IRQ_COMBINER
 	  Say yes here to add support for the IRQ combiner devices embedded
 	  in Samsung Exynos chips.
 
+config LOONGSON_LIOINTC
+	bool "Loongson Local I/O Interrupt Controller"
+	depends on MACH_LOONGSON64
+	default y
+	select IRQ_DOMAIN
+	select GENERIC_IRQ_CHIP
+	help
+	  Support for the Loongson Local I/O Interrupt Controller.
+
 endmenu
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index eae0d78cbf22..5e7678efdfe6 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -105,3 +105,4 @@ obj-$(CONFIG_MADERA_IRQ)		+= irq-madera.o
 obj-$(CONFIG_LS1X_IRQ)			+= irq-ls1x.o
 obj-$(CONFIG_TI_SCI_INTR_IRQCHIP)	+= irq-ti-sci-intr.o
 obj-$(CONFIG_TI_SCI_INTA_IRQCHIP)	+= irq-ti-sci-inta.o
+obj-$(CONFIG_LOONGSON_LIOINTC)		+= irq-loongson-liointc.o
diff --git a/drivers/irqchip/irq-loongson-liointc.c b/drivers/irqchip/irq-loongson-liointc.c
new file mode 100644
index 000000000000..18de2c09ece4
--- /dev/null
+++ b/drivers/irqchip/irq-loongson-liointc.c
@@ -0,0 +1,261 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *  Copyright (C) 2020, Jiaxun Yang <jiaxun.yang@flygoat.com>
+ *  Loongson Local IO Interrupt Controller support
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/irqchip.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/io.h>
+#include <linux/smp.h>
+#include <linux/irqchip/chained_irq.h>
+
+#include <boot_param.h>
+
+#define LIOINTC_CHIP_IRQ	32
+#define LIOINTC_NUM_PARENT 4
+
+#define LIOINTC_INTC_CHIP_START	0x20
+
+#define LIOINTC_REG_INTC_STATUS	(LIOINTC_INTC_CHIP_START + 0x20)
+#define LIOINTC_REG_INTC_EN_STATUS	(LIOINTC_INTC_CHIP_START + 0x04)
+#define LIOINTC_REG_INTC_ENABLE	(LIOINTC_INTC_CHIP_START + 0x08)
+#define LIOINTC_REG_INTC_DISABLE	(LIOINTC_INTC_CHIP_START + 0x0c)
+#define LIOINTC_REG_INTC_POL	(LIOINTC_INTC_CHIP_START + 0x10)
+#define LIOINTC_REG_INTC_EDGE	(LIOINTC_INTC_CHIP_START + 0x14)
+
+#define LIOINTC_SHIFT_INTx	4
+
+struct liointc_handler_data {
+	struct liointc_priv	*priv;
+	u32			parent_int_map;
+};
+
+struct liointc_priv {
+	struct irq_chip_generic		*gc;
+	struct liointc_handler_data	handler[LIOINTC_NUM_PARENT];
+	u8				map_cache[LIOINTC_CHIP_IRQ];
+};
+
+static void liointc_chained_handle_irq(struct irq_desc *desc)
+{
+	struct liointc_handler_data *handler = irq_desc_get_handler_data(desc);
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	struct irq_chip_generic *gc = handler->priv->gc;
+	u32 pending;
+
+	chained_irq_enter(chip, desc);
+
+	pending = readl(gc->reg_base + LIOINTC_REG_INTC_STATUS);
+
+	if (!pending)
+		spurious_interrupt();
+
+	while (pending) {
+		int bit = __ffs(pending);
+
+		generic_handle_irq(irq_find_mapping(gc->domain, bit));
+		pending &= ~BIT(bit);
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
+static void liointc_set_bit(struct irq_chip_generic *gc,
+				unsigned int offset,
+				u32 mask, bool set)
+{
+	if (set)
+		writel(readl(gc->reg_base + offset) | mask,
+				gc->reg_base + offset);
+	else
+		writel(readl(gc->reg_base + offset) & ~mask,
+				gc->reg_base + offset);
+}
+
+static int liointc_set_type(struct irq_data *data, unsigned int type)
+{
+	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
+	u32 mask = data->mask;
+	unsigned long flags;
+
+	irq_gc_lock_irqsave(gc, flags);
+	switch (type) {
+	case IRQ_TYPE_LEVEL_HIGH:
+		liointc_set_bit(gc, LIOINTC_REG_INTC_EDGE, mask, false);
+		liointc_set_bit(gc, LIOINTC_REG_INTC_POL, mask, true);
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		liointc_set_bit(gc, LIOINTC_REG_INTC_EDGE, mask, false);
+		liointc_set_bit(gc, LIOINTC_REG_INTC_POL, mask, false);
+		break;
+	case IRQ_TYPE_EDGE_RISING:
+		liointc_set_bit(gc, LIOINTC_REG_INTC_EDGE, mask, true);
+		liointc_set_bit(gc, LIOINTC_REG_INTC_POL, mask, true);
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		liointc_set_bit(gc, LIOINTC_REG_INTC_EDGE, mask, true);
+		liointc_set_bit(gc, LIOINTC_REG_INTC_POL, mask, false);
+		break;
+	default:
+		return -EINVAL;
+	}
+	irq_gc_unlock_irqrestore(gc, flags);
+
+	irqd_set_trigger_type(data, type);
+	return 0;
+}
+
+static void liointc_resume(struct irq_chip_generic *gc)
+{
+	struct liointc_priv *priv = gc->private;
+	unsigned long flags;
+	int i;
+
+	irq_gc_lock_irqsave(gc, flags);
+	/* Disable all at first */
+	writel(0xffffffff, gc->reg_base + LIOINTC_REG_INTC_DISABLE);
+	/* Revert map cache */
+	for (i = 0; i < LIOINTC_CHIP_IRQ; i++)
+		writeb(priv->map_cache[i], gc->reg_base + i);
+	/* Revert mask cache */
+	writel(~gc->mask_cache, gc->reg_base + LIOINTC_REG_INTC_ENABLE);
+	irq_gc_unlock_irqrestore(gc, flags);
+}
+
+static const char * const parent_names[] = {"int0", "int1", "int2", "int3"};
+
+int __init liointc_of_init(struct device_node *node,
+				struct device_node *parent)
+{
+	struct irq_chip_generic *gc;
+	struct irq_domain *domain;
+	struct irq_chip_type *ct;
+	struct liointc_priv *priv;
+	void __iomem *base;
+	u32 of_parent_int_map[LIOINTC_NUM_PARENT];
+	int parent_irq[LIOINTC_NUM_PARENT];
+	bool have_parent = FALSE;
+	int sz, i, err = 0;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	base = of_iomap(node, 0);
+	if (!base) {
+		err = -ENODEV;
+		goto out_free_priv;
+	}
+
+	for (i = 0; i < LIOINTC_NUM_PARENT; i++) {
+		parent_irq[i] = of_irq_get_byname(node, parent_names[i]);
+		if (parent_irq[i] > 0)
+			have_parent = TRUE;
+	}
+	if (!have_parent) {
+		err = -ENODEV;
+		goto out_iounmap;
+	}
+
+	sz = of_property_read_variable_u32_array(node,
+						"loongson,parent_int_map",
+						&of_parent_int_map[0],
+						LIOINTC_NUM_PARENT,
+						LIOINTC_NUM_PARENT);
+	if (sz < 4) {
+		pr_err("loongson-liointc: No parent_int_map\n");
+		err = -ENODEV;
+		goto out_iounmap;
+	}
+
+	for (i = 0; i < LIOINTC_NUM_PARENT; i++)
+		priv->handler[i].parent_int_map = of_parent_int_map[i];
+
+	/* Setup IRQ domain */
+	domain = irq_domain_add_linear(node, 32,
+					&irq_generic_chip_ops, priv);
+	if (!domain) {
+		pr_err("loongson-liointc: cannot add IRQ domain\n");
+		err = -EINVAL;
+		goto out_iounmap;
+	}
+
+	err = irq_alloc_domain_generic_chips(domain, 32, 1,
+					node->full_name, handle_level_irq,
+					IRQ_NOPROBE, 0, 0);
+	if (err) {
+		pr_err("loongson-liointc: unable to register IRQ domain\n");
+		goto out_free_domain;
+	}
+
+
+	/* Disable all IRQs */
+	writel(0xffffffff, base + LIOINTC_REG_INTC_DISABLE);
+	/* Set to level triggered */
+	writel(0x0, base + LIOINTC_REG_INTC_EDGE);
+
+	/* Generate parent INT part of map cache */
+	for (i = 0; i < LIOINTC_NUM_PARENT; i++) {
+		u32 pending = priv->handler[i].parent_int_map;
+
+		while (pending) {
+			int bit = __ffs(pending);
+
+			priv->map_cache[bit] = BIT(i) << LIOINTC_SHIFT_INTx;
+			pending &= ~BIT(bit);
+		}
+	}
+
+	for (i = 0; i < LIOINTC_CHIP_IRQ; i++) {
+		/* Generate core part of map cache */
+		priv->map_cache[i] |= BIT(loongson_sysconf.boot_cpu_id);
+		writeb(priv->map_cache[i], base + i);
+	}
+
+	gc = irq_get_domain_generic_chip(domain, 0);
+	gc->private = priv;
+	gc->reg_base = base;
+	gc->domain = domain;
+	gc->resume = liointc_resume;
+
+	ct = gc->chip_types;
+	ct->regs.enable = LIOINTC_REG_INTC_ENABLE;
+	ct->regs.disable = LIOINTC_REG_INTC_DISABLE;
+	ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
+	ct->chip.irq_mask = irq_gc_mask_disable_reg;
+	ct->chip.irq_mask_ack = irq_gc_mask_disable_reg;
+	ct->chip.irq_set_type = liointc_set_type;
+
+	gc->mask_cache = 0xffffffff;
+	priv->gc = gc;
+
+	for (i = 0; i < LIOINTC_NUM_PARENT; i++) {
+		if (parent_irq[i] <= 0)
+			continue;
+
+		priv->handler[i].priv = priv;
+		irq_set_chained_handler_and_data(parent_irq[i],
+				liointc_chained_handle_irq, &priv->handler[i]);
+	}
+
+	return 0;
+
+out_free_domain:
+	irq_domain_remove(domain);
+out_iounmap:
+	iounmap(base);
+out_free_priv:
+	kfree(priv);
+
+	return err;
+}
+
+IRQCHIP_DECLARE(loongson_liointc_1_0, "loongson,liointc-1.0", liointc_of_init);
+IRQCHIP_DECLARE(loongson_liointc_1_0a, "loongson,liointc-1.0a", liointc_of_init);
-- 
2.26.0.rc2



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

* [PATCH v7 01/12] MIPS: Loongson: Do not initialise statics to 0
  2020-03-25  2:28 ` [PATCH v7 00/12] Modernize Loongson64 Machine v6 Jiaxun Yang
  2020-03-25  2:28   ` [PATCH v7 01/12] irqchip: Add driver for Loongson I/O Local Interrupt Controller Jiaxun Yang
@ 2020-03-25  2:28   ` Jiaxun Yang
  2020-03-25  2:28   ` [PATCH v7 02/12] irqchip: loongson-liointc: Workaround LPC IRQ Errata Jiaxun Yang
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Jiaxun Yang @ 2020-03-25  2:28 UTC (permalink / raw)
  To: linux-mips
  Cc: Tiezhu Yang, Thomas Bogendoerfer, Thomas Gleixner, Jason Cooper,
	Marc Zyngier, Rob Herring, Mark Rutland, Jonathan Corbet,
	Paul Cercueil, Huacai Chen, Jiaxun Yang, John Crispin,
	Matthias Brugger, Jean Delvare, David S. Miller,
	Mauro Carvalho Chehab, Jonathan Cameron, Greg Kroah-Hartman,
	Andy Shevchenko, H. Nikolaus Schaller, Andi Kleen,
	Eric W. Biederman, Miquel Raynal, Krzysztof Kozlowski,
	Yinglu Yang, Allison Randal, Manuel Lauss,
	Bartlomiej Zolnierkiewicz, Paul Burton, Serge Semin,
	Matt Redfearn, linux-kernel, devicetree, linux-doc,
	linux-arm-kernel, linux-mediatek, linux-ide

From: Tiezhu Yang <yangtiezhu@loongson.cn>

Fix the following checkpatch error:

ERROR: do not initialise statics to 0
#125: FILE: loongson64/numa.c:125:
+	static unsigned long num_physpages = 0;

Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
 arch/mips/loongson64/numa.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/loongson64/numa.c b/arch/mips/loongson64/numa.c
index e5b40c5e3296..1ae072df4831 100644
--- a/arch/mips/loongson64/numa.c
+++ b/arch/mips/loongson64/numa.c
@@ -122,7 +122,7 @@ static unsigned long nid_to_addroffset(unsigned int nid)
 static void __init szmem(unsigned int node)
 {
 	u32 i, mem_type;
-	static unsigned long num_physpages = 0;
+	static unsigned long num_physpages;
 	u64 node_id, node_psize, start_pfn, end_pfn, mem_start, mem_size;
 
 	/* Parse memory information and activate */
-- 
2.26.0.rc2



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

* [PATCH v7 02/12] irqchip: loongson-liointc: Workaround LPC IRQ Errata
  2020-03-25  2:28 ` [PATCH v7 00/12] Modernize Loongson64 Machine v6 Jiaxun Yang
  2020-03-25  2:28   ` [PATCH v7 01/12] irqchip: Add driver for Loongson I/O Local Interrupt Controller Jiaxun Yang
  2020-03-25  2:28   ` [PATCH v7 01/12] MIPS: Loongson: Do not initialise statics to 0 Jiaxun Yang
@ 2020-03-25  2:28   ` Jiaxun Yang
  2020-03-25  2:28   ` [PATCH v7 02/12] MIPS: DTS: CI20: add DT node for IR sensor Jiaxun Yang
  2020-03-25  2:28   ` [PATCH v7 03/12] dt-bindings: interrupt-controller: Add Loongson LIOINTC Jiaxun Yang
  4 siblings, 0 replies; 8+ messages in thread
From: Jiaxun Yang @ 2020-03-25  2:28 UTC (permalink / raw)
  To: linux-mips
  Cc: Jiaxun Yang, Huacai Chen, Marc Zyngier, Thomas Gleixner,
	Jason Cooper, Rob Herring, Mark Rutland, Thomas Bogendoerfer,
	Jonathan Corbet, Paul Cercueil, John Crispin, Matthias Brugger,
	Jean Delvare, David S. Miller, Mauro Carvalho Chehab,
	Jonathan Cameron, Greg Kroah-Hartman, Andy Shevchenko,
	Krzysztof Kozlowski, Andi Kleen, Geert Uytterhoeven, Kees Cook,
	Miquel Raynal, H. Nikolaus Schaller, Eric W. Biederman,
	Yinglu Yang, Tiezhu Yang, Allison Randal, Paul Burton,
	Manuel Lauss, Bartlomiej Zolnierkiewicz, Serge Semin,
	Matt Redfearn, linux-kernel, devicetree, linux-doc,
	linux-arm-kernel, linux-mediatek, linux-ide

The 1.0 version of that controller has a bug that status bit
of LPC IRQ sometimes doesn't get set correctly.

So we can always blame LPC IRQ when spurious interrupt happens
at the parent interrupt line which LPC IRQ supposed to route
to.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Co-developed-by: Huacai Chen <chenhc@lemote.com>
Signed-off-by: Huacai Chen <chenhc@lemote.com>
Reviewed-by: Marc Zyngier <maz@kernel.org>
---
 drivers/irqchip/irq-loongson-liointc.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-loongson-liointc.c b/drivers/irqchip/irq-loongson-liointc.c
index 18de2c09ece4..7d2339e638db 100644
--- a/drivers/irqchip/irq-loongson-liointc.c
+++ b/drivers/irqchip/irq-loongson-liointc.c
@@ -32,6 +32,8 @@
 
 #define LIOINTC_SHIFT_INTx	4
 
+#define LIOINTC_ERRATA_IRQ	10
+
 struct liointc_handler_data {
 	struct liointc_priv	*priv;
 	u32			parent_int_map;
@@ -41,6 +43,7 @@ struct liointc_priv {
 	struct irq_chip_generic		*gc;
 	struct liointc_handler_data	handler[LIOINTC_NUM_PARENT];
 	u8				map_cache[LIOINTC_CHIP_IRQ];
+	bool				have_lpc_irq_errata;
 };
 
 static void liointc_chained_handle_irq(struct irq_desc *desc)
@@ -54,8 +57,15 @@ static void liointc_chained_handle_irq(struct irq_desc *desc)
 
 	pending = readl(gc->reg_base + LIOINTC_REG_INTC_STATUS);
 
-	if (!pending)
-		spurious_interrupt();
+	if (!pending) {
+		/* Always blame LPC IRQ if we have that bug */
+		if (handler->priv->have_lpc_irq_errata &&
+			(handler->parent_int_map & ~gc->mask_cache &
+			BIT(LIOINTC_ERRATA_IRQ)))
+			pending = BIT(LIOINTC_ERRATA_IRQ);
+		else
+			spurious_interrupt();
+	}
 
 	while (pending) {
 		int bit = __ffs(pending);
-- 
2.26.0.rc2



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

* [PATCH v7 02/12] MIPS: DTS: CI20: add DT node for IR sensor
  2020-03-25  2:28 ` [PATCH v7 00/12] Modernize Loongson64 Machine v6 Jiaxun Yang
                     ` (2 preceding siblings ...)
  2020-03-25  2:28   ` [PATCH v7 02/12] irqchip: loongson-liointc: Workaround LPC IRQ Errata Jiaxun Yang
@ 2020-03-25  2:28   ` Jiaxun Yang
  2020-03-25  2:28   ` [PATCH v7 03/12] dt-bindings: interrupt-controller: Add Loongson LIOINTC Jiaxun Yang
  4 siblings, 0 replies; 8+ messages in thread
From: Jiaxun Yang @ 2020-03-25  2:28 UTC (permalink / raw)
  To: linux-mips
  Cc: Alex Smith, H . Nikolaus Schaller, Paul Cercueil,
	Thomas Bogendoerfer, Thomas Gleixner, Jason Cooper, Marc Zyngier,
	Rob Herring, Mark Rutland, Jonathan Corbet, Huacai Chen,
	Jiaxun Yang, John Crispin, Matthias Brugger, Jean Delvare,
	David S. Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Jonathan Cameron, Andy Shevchenko, Andi Kleen, Eric W. Biederman,
	Kees Cook, Paul Burton, Miquel Raynal, Krzysztof Kozlowski,
	Yinglu Yang, Tiezhu Yang, Allison Randal,
	Bartlomiej Zolnierkiewicz, Manuel Lauss, Serge Semin,
	Matt Redfearn, linux-kernel, devicetree, linux-doc,
	linux-arm-kernel, linux-mediatek, linux-ide

From: Alex Smith <alex.smith@imgtec.com>

The infrared sensor on the CI20 board is connected to a GPIO and can
be operated by using the gpio-ir-recv driver. Add a DT node for the
sensor to allow that driver to be used.

Signed-off-by: Alex Smith <alex.smith@imgtec.com>
Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
Reviewed-by: Paul Cercueil <paul@crapouillou.net>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
 arch/mips/boot/dts/ingenic/ci20.dts | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts
index c340f947baa0..fc4e64200c3d 100644
--- a/arch/mips/boot/dts/ingenic/ci20.dts
+++ b/arch/mips/boot/dts/ingenic/ci20.dts
@@ -62,6 +62,11 @@ eth0_power: fixedregulator@0 {
 		enable-active-high;
 	};
 
+	ir: ir {
+		compatible = "gpio-ir-receiver";
+		gpios = <&gpe 3 GPIO_ACTIVE_LOW>;
+	};
+
 	wlan0_power: fixedregulator@1 {
 		compatible = "regulator-fixed";
 		regulator-name = "wlan0_power";
-- 
2.26.0.rc2



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

* [PATCH v7 03/12] dt-bindings: interrupt-controller: Add Loongson LIOINTC
  2020-03-25  2:28 ` [PATCH v7 00/12] Modernize Loongson64 Machine v6 Jiaxun Yang
                     ` (3 preceding siblings ...)
  2020-03-25  2:28   ` [PATCH v7 02/12] MIPS: DTS: CI20: add DT node for IR sensor Jiaxun Yang
@ 2020-03-25  2:28   ` Jiaxun Yang
  4 siblings, 0 replies; 8+ messages in thread
From: Jiaxun Yang @ 2020-03-25  2:28 UTC (permalink / raw)
  To: linux-mips
  Cc: Jiaxun Yang, Rob Herring, Huacai Chen, Thomas Gleixner,
	Jason Cooper, Marc Zyngier, Rob Herring, Mark Rutland,
	Thomas Bogendoerfer, Jonathan Corbet, Paul Cercueil,
	John Crispin, Matthias Brugger, Jean Delvare, David S. Miller,
	Mauro Carvalho Chehab, Jonathan Cameron, Greg Kroah-Hartman,
	Andy Shevchenko, Krzysztof Kozlowski, H. Nikolaus Schaller,
	Miquel Raynal, Andi Kleen, Eric W. Biederman, Yinglu Yang,
	Tiezhu Yang, Allison Randal, Bartlomiej Zolnierkiewicz,
	Paul Burton, Manuel Lauss, Serge Semin, Matt Redfearn,
	linux-kernel, devicetree, linux-doc, linux-arm-kernel,
	linux-mediatek, linux-ide

Document Loongson I/O Interrupt controller.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Co-developed-by: Huacai Chen <chenhc@lemote.com>
Signed-off-by: Huacai Chen <chenhc@lemote.com>
---
 .../loongson,liointc.yaml                     | 93 +++++++++++++++++++
 1 file changed, 93 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/loongson,liointc.yaml

diff --git a/Documentation/devicetree/bindings/interrupt-controller/loongson,liointc.yaml b/Documentation/devicetree/bindings/interrupt-controller/loongson,liointc.yaml
new file mode 100644
index 000000000000..9c6b91fee477
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/loongson,liointc.yaml
@@ -0,0 +1,93 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/interrupt-controller/loongson,liointc.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Loongson Local I/O Interrupt Controller
+
+maintainers:
+  - Jiaxun Yang <jiaxun.yang@flygoat.com>
+
+description: |
+  This interrupt controller is found in the Loongson-3 family of chips as the primary
+  package interrupt controller which can route local I/O interrupt to interrupt lines
+  of cores.
+
+allOf:
+  - $ref: /schemas/interrupt-controller.yaml#
+
+properties:
+  compatible:
+    oneOf:
+      - const: loongson,liointc-1.0
+      - const: loongson,liointc-1.0a
+
+  reg:
+    maxItems: 1
+
+  interrupt-controller: true
+
+  interrupts:
+    description:
+      Interrupt source of the CPU interrupts.
+    minItems: 1
+    maxItems: 4
+
+  interrupt-names:
+    description: List of names for the parent interrupts.
+    items:
+      - const: int0
+      - const: int1
+      - const: int2
+      - const: int3
+    minItems: 1
+    maxItems: 4
+
+  '#interrupt-cells':
+    const: 2
+
+  'loongson,parent_int_map':
+    description: |
+      This property points how the children interrupts will be mapped into CPU
+      interrupt lines. Each cell refers to a parent interrupt line from 0 to 3
+      and each bit in the cell refers to a children interrupt fron 0 to 31.
+      If a CPU interrupt line didn't connected with liointc, then keep it's
+      cell with zero.
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32-array
+      - items:
+          minItems: 4
+          maxItems: 4
+
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-controller
+  - '#interrupt-cells'
+  - 'loongson,parent_int_map'
+
+
+examples:
+  - |
+    iointc: interrupt-controller@3ff01400 {
+      compatible = "loongson,liointc-1.0";
+      reg = <0x3ff01400 0x64>;
+
+      interrupt-controller;
+      #interrupt-cells = <2>;
+
+      interrupt-parent = <&cpuintc>;
+      interrupts = <2>, <3>;
+      interrupt-names = "int0", "int1";
+
+      loongson,parent_int_map = <0xf0ffffff>, /* int0 */
+                                <0x0f000000>, /* int1 */
+                                <0x00000000>, /* int2 */
+                                <0x00000000>; /* int3 */
+
+    };
+
+...
-- 
2.26.0.rc2



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

* Re: [PATCH v7 01/12] irqchip: Add driver for Loongson I/O Local Interrupt Controller
  2020-03-25  2:28   ` [PATCH v7 01/12] irqchip: Add driver for Loongson I/O Local Interrupt Controller Jiaxun Yang
@ 2020-03-25 11:25     ` Paul Cercueil
  2020-03-25 11:35       ` Marc Zyngier
  0 siblings, 1 reply; 8+ messages in thread
From: Paul Cercueil @ 2020-03-25 11:25 UTC (permalink / raw)
  To: Jiaxun Yang
  Cc: linux-mips, Huacai Chen, Marc Zyngier, Thomas Gleixner,
	Jason Cooper, Rob Herring, Mark Rutland, Thomas Bogendoerfer,
	Jonathan Corbet, John Crispin, Matthias Brugger, Jean Delvare,
	David S. Miller, Mauro Carvalho Chehab, Jonathan Cameron,
	Greg Kroah-Hartman, Andy Shevchenko, Geert Uytterhoeven,
	Krzysztof Kozlowski, Miquel Raynal, Andi Kleen,
	H. Nikolaus Schaller, Eric W. Biederman, Tiezhu Yang,
	Yinglu Yang, Allison Randal, Bartlomiej Zolnierkiewicz,
	Paul Burton, Manuel Lauss, Serge Semin, Matt Redfearn,
	linux-kernel, devicetree, linux-doc, linux-arm-kernel,
	linux-mediatek, linux-ide

Hi Jiaxun,


Le mer. 25 mars 2020 à 10:28, Jiaxun Yang <jiaxun.yang@flygoat.com> a 
écrit :
> This controller appeared on Loongson family of chips as the primary
> package interrupt source.
> 
> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> Co-developed-by: Huacai Chen <chenhc@lemote.com>
> Signed-off-by: Huacai Chen <chenhc@lemote.com>
> Reviewed-by: Marc Zyngier <maz@kernel.org>
> ---
> v4-v5:
> 	Resolve suggestions from maz:
> 		- Remove DT validation
> 		- Simplify unnucessary functions & variables
> ---
>  drivers/irqchip/Kconfig                |   9 +
>  drivers/irqchip/Makefile               |   1 +
>  drivers/irqchip/irq-loongson-liointc.c | 261 
> +++++++++++++++++++++++++
>  3 files changed, 271 insertions(+)
>  create mode 100644 drivers/irqchip/irq-loongson-liointc.c
> 
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index 6d397732138d..c609eaa319d2 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -513,4 +513,13 @@ config EXYNOS_IRQ_COMBINER
>  	  Say yes here to add support for the IRQ combiner devices embedded
>  	  in Samsung Exynos chips.
> 
> +config LOONGSON_LIOINTC
> +	bool "Loongson Local I/O Interrupt Controller"
> +	depends on MACH_LOONGSON64
> +	default y
> +	select IRQ_DOMAIN
> +	select GENERIC_IRQ_CHIP
> +	help
> +	  Support for the Loongson Local I/O Interrupt Controller.
> +
>  endmenu
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index eae0d78cbf22..5e7678efdfe6 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -105,3 +105,4 @@ obj-$(CONFIG_MADERA_IRQ)		+= irq-madera.o
>  obj-$(CONFIG_LS1X_IRQ)			+= irq-ls1x.o
>  obj-$(CONFIG_TI_SCI_INTR_IRQCHIP)	+= irq-ti-sci-intr.o
>  obj-$(CONFIG_TI_SCI_INTA_IRQCHIP)	+= irq-ti-sci-inta.o
> +obj-$(CONFIG_LOONGSON_LIOINTC)		+= irq-loongson-liointc.o
> diff --git a/drivers/irqchip/irq-loongson-liointc.c 
> b/drivers/irqchip/irq-loongson-liointc.c
> new file mode 100644
> index 000000000000..18de2c09ece4
> --- /dev/null
> +++ b/drivers/irqchip/irq-loongson-liointc.c
> @@ -0,0 +1,261 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + *  Copyright (C) 2020, Jiaxun Yang <jiaxun.yang@flygoat.com>
> + *  Loongson Local IO Interrupt Controller support
> + */
> +
> +#include <linux/errno.h>
> +#include <linux/init.h>
> +#include <linux/types.h>
> +#include <linux/interrupt.h>
> +#include <linux/ioport.h>
> +#include <linux/irqchip.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/io.h>
> +#include <linux/smp.h>
> +#include <linux/irqchip/chained_irq.h>
> +
> +#include <boot_param.h>
> +
> +#define LIOINTC_CHIP_IRQ	32
> +#define LIOINTC_NUM_PARENT 4
> +
> +#define LIOINTC_INTC_CHIP_START	0x20
> +
> +#define LIOINTC_REG_INTC_STATUS	(LIOINTC_INTC_CHIP_START + 0x20)
> +#define LIOINTC_REG_INTC_EN_STATUS	(LIOINTC_INTC_CHIP_START + 0x04)
> +#define LIOINTC_REG_INTC_ENABLE	(LIOINTC_INTC_CHIP_START + 0x08)
> +#define LIOINTC_REG_INTC_DISABLE	(LIOINTC_INTC_CHIP_START + 0x0c)
> +#define LIOINTC_REG_INTC_POL	(LIOINTC_INTC_CHIP_START + 0x10)
> +#define LIOINTC_REG_INTC_EDGE	(LIOINTC_INTC_CHIP_START + 0x14)
> +
> +#define LIOINTC_SHIFT_INTx	4
> +
> +struct liointc_handler_data {
> +	struct liointc_priv	*priv;
> +	u32			parent_int_map;
> +};
> +
> +struct liointc_priv {
> +	struct irq_chip_generic		*gc;
> +	struct liointc_handler_data	handler[LIOINTC_NUM_PARENT];
> +	u8				map_cache[LIOINTC_CHIP_IRQ];
> +};
> +
> +static void liointc_chained_handle_irq(struct irq_desc *desc)
> +{
> +	struct liointc_handler_data *handler = 
> irq_desc_get_handler_data(desc);
> +	struct irq_chip *chip = irq_desc_get_chip(desc);
> +	struct irq_chip_generic *gc = handler->priv->gc;
> +	u32 pending;
> +
> +	chained_irq_enter(chip, desc);
> +
> +	pending = readl(gc->reg_base + LIOINTC_REG_INTC_STATUS);
> +
> +	if (!pending)
> +		spurious_interrupt();
> +
> +	while (pending) {
> +		int bit = __ffs(pending);
> +
> +		generic_handle_irq(irq_find_mapping(gc->domain, bit));
> +		pending &= ~BIT(bit);
> +	}

Consider using the for_each_set_bit() macro from <linux/bitops.h>.
See drivers/irqchip/irq-ingenic-tcu.c for instance.

> +
> +	chained_irq_exit(chip, desc);
> +}
> +
> +static void liointc_set_bit(struct irq_chip_generic *gc,
> +				unsigned int offset,
> +				u32 mask, bool set)
> +{
> +	if (set)
> +		writel(readl(gc->reg_base + offset) | mask,
> +				gc->reg_base + offset);
> +	else
> +		writel(readl(gc->reg_base + offset) & ~mask,
> +				gc->reg_base + offset);
> +}
> +
> +static int liointc_set_type(struct irq_data *data, unsigned int type)
> +{
> +	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
> +	u32 mask = data->mask;
> +	unsigned long flags;
> +
> +	irq_gc_lock_irqsave(gc, flags);
> +	switch (type) {
> +	case IRQ_TYPE_LEVEL_HIGH:
> +		liointc_set_bit(gc, LIOINTC_REG_INTC_EDGE, mask, false);
> +		liointc_set_bit(gc, LIOINTC_REG_INTC_POL, mask, true);
> +		break;
> +	case IRQ_TYPE_LEVEL_LOW:
> +		liointc_set_bit(gc, LIOINTC_REG_INTC_EDGE, mask, false);
> +		liointc_set_bit(gc, LIOINTC_REG_INTC_POL, mask, false);
> +		break;
> +	case IRQ_TYPE_EDGE_RISING:
> +		liointc_set_bit(gc, LIOINTC_REG_INTC_EDGE, mask, true);
> +		liointc_set_bit(gc, LIOINTC_REG_INTC_POL, mask, true);
> +		break;
> +	case IRQ_TYPE_EDGE_FALLING:
> +		liointc_set_bit(gc, LIOINTC_REG_INTC_EDGE, mask, true);
> +		liointc_set_bit(gc, LIOINTC_REG_INTC_POL, mask, false);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +	irq_gc_unlock_irqrestore(gc, flags);
> +
> +	irqd_set_trigger_type(data, type);
> +	return 0;
> +}
> +
> +static void liointc_resume(struct irq_chip_generic *gc)
> +{
> +	struct liointc_priv *priv = gc->private;
> +	unsigned long flags;
> +	int i;
> +
> +	irq_gc_lock_irqsave(gc, flags);
> +	/* Disable all at first */
> +	writel(0xffffffff, gc->reg_base + LIOINTC_REG_INTC_DISABLE);
> +	/* Revert map cache */
> +	for (i = 0; i < LIOINTC_CHIP_IRQ; i++)
> +		writeb(priv->map_cache[i], gc->reg_base + i);
> +	/* Revert mask cache */
> +	writel(~gc->mask_cache, gc->reg_base + LIOINTC_REG_INTC_ENABLE);
> +	irq_gc_unlock_irqrestore(gc, flags);
> +}
> +
> +static const char * const parent_names[] = {"int0", "int1", "int2", 
> "int3"};
> +
> +int __init liointc_of_init(struct device_node *node,
> +				struct device_node *parent)
> +{
> +	struct irq_chip_generic *gc;
> +	struct irq_domain *domain;
> +	struct irq_chip_type *ct;
> +	struct liointc_priv *priv;
> +	void __iomem *base;
> +	u32 of_parent_int_map[LIOINTC_NUM_PARENT];
> +	int parent_irq[LIOINTC_NUM_PARENT];
> +	bool have_parent = FALSE;
> +	int sz, i, err = 0;
> +
> +	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	base = of_iomap(node, 0);
> +	if (!base) {
> +		err = -ENODEV;
> +		goto out_free_priv;
> +	}
> +
> +	for (i = 0; i < LIOINTC_NUM_PARENT; i++) {
> +		parent_irq[i] = of_irq_get_byname(node, parent_names[i]);
> +		if (parent_irq[i] > 0)
> +			have_parent = TRUE;
> +	}
> +	if (!have_parent) {
> +		err = -ENODEV;
> +		goto out_iounmap;
> +	}
> +
> +	sz = of_property_read_variable_u32_array(node,
> +						"loongson,parent_int_map",
> +						&of_parent_int_map[0],
> +						LIOINTC_NUM_PARENT,
> +						LIOINTC_NUM_PARENT);
> +	if (sz < 4) {
> +		pr_err("loongson-liointc: No parent_int_map\n");
> +		err = -ENODEV;
> +		goto out_iounmap;
> +	}
> +
> +	for (i = 0; i < LIOINTC_NUM_PARENT; i++)
> +		priv->handler[i].parent_int_map = of_parent_int_map[i];
> +
> +	/* Setup IRQ domain */
> +	domain = irq_domain_add_linear(node, 32,
> +					&irq_generic_chip_ops, priv);
> +	if (!domain) {
> +		pr_err("loongson-liointc: cannot add IRQ domain\n");
> +		err = -EINVAL;
> +		goto out_iounmap;
> +	}
> +
> +	err = irq_alloc_domain_generic_chips(domain, 32, 1,
> +					node->full_name, handle_level_irq,
> +					IRQ_NOPROBE, 0, 0);
> +	if (err) {
> +		pr_err("loongson-liointc: unable to register IRQ domain\n");
> +		goto out_free_domain;
> +	}
> +
> +
> +	/* Disable all IRQs */
> +	writel(0xffffffff, base + LIOINTC_REG_INTC_DISABLE);
> +	/* Set to level triggered */
> +	writel(0x0, base + LIOINTC_REG_INTC_EDGE);
> +
> +	/* Generate parent INT part of map cache */
> +	for (i = 0; i < LIOINTC_NUM_PARENT; i++) {
> +		u32 pending = priv->handler[i].parent_int_map;
> +
> +		while (pending) {
> +			int bit = __ffs(pending);
> +
> +			priv->map_cache[bit] = BIT(i) << LIOINTC_SHIFT_INTx;
> +			pending &= ~BIT(bit);
> +		}

Same here.

-Paul

> +	}
> +
> +	for (i = 0; i < LIOINTC_CHIP_IRQ; i++) {
> +		/* Generate core part of map cache */
> +		priv->map_cache[i] |= BIT(loongson_sysconf.boot_cpu_id);
> +		writeb(priv->map_cache[i], base + i);
> +	}
> +
> +	gc = irq_get_domain_generic_chip(domain, 0);
> +	gc->private = priv;
> +	gc->reg_base = base;
> +	gc->domain = domain;
> +	gc->resume = liointc_resume;
> +
> +	ct = gc->chip_types;
> +	ct->regs.enable = LIOINTC_REG_INTC_ENABLE;
> +	ct->regs.disable = LIOINTC_REG_INTC_DISABLE;
> +	ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
> +	ct->chip.irq_mask = irq_gc_mask_disable_reg;
> +	ct->chip.irq_mask_ack = irq_gc_mask_disable_reg;
> +	ct->chip.irq_set_type = liointc_set_type;
> +
> +	gc->mask_cache = 0xffffffff;
> +	priv->gc = gc;
> +
> +	for (i = 0; i < LIOINTC_NUM_PARENT; i++) {
> +		if (parent_irq[i] <= 0)
> +			continue;
> +
> +		priv->handler[i].priv = priv;
> +		irq_set_chained_handler_and_data(parent_irq[i],
> +				liointc_chained_handle_irq, &priv->handler[i]);
> +	}
> +
> +	return 0;
> +
> +out_free_domain:
> +	irq_domain_remove(domain);
> +out_iounmap:
> +	iounmap(base);
> +out_free_priv:
> +	kfree(priv);
> +
> +	return err;
> +}
> +
> +IRQCHIP_DECLARE(loongson_liointc_1_0, "loongson,liointc-1.0", 
> liointc_of_init);
> +IRQCHIP_DECLARE(loongson_liointc_1_0a, "loongson,liointc-1.0a", 
> liointc_of_init);
> --
> 2.26.0.rc2
> 
> 



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

* Re: [PATCH v7 01/12] irqchip: Add driver for Loongson I/O Local Interrupt Controller
  2020-03-25 11:25     ` Paul Cercueil
@ 2020-03-25 11:35       ` Marc Zyngier
  0 siblings, 0 replies; 8+ messages in thread
From: Marc Zyngier @ 2020-03-25 11:35 UTC (permalink / raw)
  To: Paul Cercueil
  Cc: Jiaxun Yang, linux-mips, Huacai Chen, Thomas Gleixner,
	Jason Cooper, Rob Herring, Mark Rutland, Thomas Bogendoerfer,
	Jonathan Corbet, John Crispin, Matthias Brugger, Jean Delvare,
	David S. Miller, Mauro Carvalho Chehab, Jonathan Cameron,
	Greg Kroah-Hartman, Andy Shevchenko, Geert Uytterhoeven,
	Krzysztof Kozlowski, Miquel Raynal, Andi Kleen,
	H. Nikolaus Schaller, Eric W. Biederman, Tiezhu Yang,
	Yinglu Yang, Allison Randal, Bartlomiej Zolnierkiewicz,
	Paul Burton, Manuel Lauss, Serge Semin, Matt Redfearn,
	linux-kernel, devicetree, linux-doc, linux-arm-kernel,
	linux-mediatek, linux-ide

On 2020-03-25 11:25, Paul Cercueil wrote:
> Hi Jiaxun,
> 
> 
> Le mer. 25 mars 2020 à 10:28, Jiaxun Yang <jiaxun.yang@flygoat.com> a 
> écrit :
>> This controller appeared on Loongson family of chips as the primary
>> package interrupt source.
>> 
>> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>> Co-developed-by: Huacai Chen <chenhc@lemote.com>
>> Signed-off-by: Huacai Chen <chenhc@lemote.com>
>> Reviewed-by: Marc Zyngier <maz@kernel.org>
>> ---
>> v4-v5:
>> 	Resolve suggestions from maz:
>> 		- Remove DT validation
>> 		- Simplify unnucessary functions & variables
>> ---
>>  drivers/irqchip/Kconfig                |   9 +
>>  drivers/irqchip/Makefile               |   1 +
>>  drivers/irqchip/irq-loongson-liointc.c | 261 
>> +++++++++++++++++++++++++
>>  3 files changed, 271 insertions(+)
>>  create mode 100644 drivers/irqchip/irq-loongson-liointc.c
>> 
>> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
>> index 6d397732138d..c609eaa319d2 100644
>> --- a/drivers/irqchip/Kconfig
>> +++ b/drivers/irqchip/Kconfig
>> @@ -513,4 +513,13 @@ config EXYNOS_IRQ_COMBINER
>>  	  Say yes here to add support for the IRQ combiner devices embedded
>>  	  in Samsung Exynos chips.
>> 
>> +config LOONGSON_LIOINTC
>> +	bool "Loongson Local I/O Interrupt Controller"
>> +	depends on MACH_LOONGSON64
>> +	default y
>> +	select IRQ_DOMAIN
>> +	select GENERIC_IRQ_CHIP
>> +	help
>> +	  Support for the Loongson Local I/O Interrupt Controller.
>> +
>>  endmenu
>> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
>> index eae0d78cbf22..5e7678efdfe6 100644
>> --- a/drivers/irqchip/Makefile
>> +++ b/drivers/irqchip/Makefile
>> @@ -105,3 +105,4 @@ obj-$(CONFIG_MADERA_IRQ)		+= irq-madera.o
>>  obj-$(CONFIG_LS1X_IRQ)			+= irq-ls1x.o
>>  obj-$(CONFIG_TI_SCI_INTR_IRQCHIP)	+= irq-ti-sci-intr.o
>>  obj-$(CONFIG_TI_SCI_INTA_IRQCHIP)	+= irq-ti-sci-inta.o
>> +obj-$(CONFIG_LOONGSON_LIOINTC)		+= irq-loongson-liointc.o
>> diff --git a/drivers/irqchip/irq-loongson-liointc.c 
>> b/drivers/irqchip/irq-loongson-liointc.c
>> new file mode 100644
>> index 000000000000..18de2c09ece4
>> --- /dev/null
>> +++ b/drivers/irqchip/irq-loongson-liointc.c
>> @@ -0,0 +1,261 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + *  Copyright (C) 2020, Jiaxun Yang <jiaxun.yang@flygoat.com>
>> + *  Loongson Local IO Interrupt Controller support
>> + */
>> +
>> +#include <linux/errno.h>
>> +#include <linux/init.h>
>> +#include <linux/types.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/ioport.h>
>> +#include <linux/irqchip.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_irq.h>
>> +#include <linux/io.h>
>> +#include <linux/smp.h>
>> +#include <linux/irqchip/chained_irq.h>
>> +
>> +#include <boot_param.h>
>> +
>> +#define LIOINTC_CHIP_IRQ	32
>> +#define LIOINTC_NUM_PARENT 4
>> +
>> +#define LIOINTC_INTC_CHIP_START	0x20
>> +
>> +#define LIOINTC_REG_INTC_STATUS	(LIOINTC_INTC_CHIP_START + 0x20)
>> +#define LIOINTC_REG_INTC_EN_STATUS	(LIOINTC_INTC_CHIP_START + 0x04)
>> +#define LIOINTC_REG_INTC_ENABLE	(LIOINTC_INTC_CHIP_START + 0x08)
>> +#define LIOINTC_REG_INTC_DISABLE	(LIOINTC_INTC_CHIP_START + 0x0c)
>> +#define LIOINTC_REG_INTC_POL	(LIOINTC_INTC_CHIP_START + 0x10)
>> +#define LIOINTC_REG_INTC_EDGE	(LIOINTC_INTC_CHIP_START + 0x14)
>> +
>> +#define LIOINTC_SHIFT_INTx	4
>> +
>> +struct liointc_handler_data {
>> +	struct liointc_priv	*priv;
>> +	u32			parent_int_map;
>> +};
>> +
>> +struct liointc_priv {
>> +	struct irq_chip_generic		*gc;
>> +	struct liointc_handler_data	handler[LIOINTC_NUM_PARENT];
>> +	u8				map_cache[LIOINTC_CHIP_IRQ];
>> +};
>> +
>> +static void liointc_chained_handle_irq(struct irq_desc *desc)
>> +{
>> +	struct liointc_handler_data *handler = 
>> irq_desc_get_handler_data(desc);
>> +	struct irq_chip *chip = irq_desc_get_chip(desc);
>> +	struct irq_chip_generic *gc = handler->priv->gc;
>> +	u32 pending;
>> +
>> +	chained_irq_enter(chip, desc);
>> +
>> +	pending = readl(gc->reg_base + LIOINTC_REG_INTC_STATUS);
>> +
>> +	if (!pending)
>> +		spurious_interrupt();
>> +
>> +	while (pending) {
>> +		int bit = __ffs(pending);
>> +
>> +		generic_handle_irq(irq_find_mapping(gc->domain, bit));
>> +		pending &= ~BIT(bit);
>> +	}
> 
> Consider using the for_each_set_bit() macro from <linux/bitops.h>.
> See drivers/irqchip/irq-ingenic-tcu.c for instance.

which would require changing the pending type to be unsigned long.
Open-coding these if fine if it helps keeping the type system 
consistent.

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

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

end of thread, other threads:[~2020-03-25 11:35 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20190827085302.5197-1-jiaxun.yang@flygoat.com>
2020-03-25  2:28 ` [PATCH v7 00/12] Modernize Loongson64 Machine v6 Jiaxun Yang
2020-03-25  2:28   ` [PATCH v7 01/12] irqchip: Add driver for Loongson I/O Local Interrupt Controller Jiaxun Yang
2020-03-25 11:25     ` Paul Cercueil
2020-03-25 11:35       ` Marc Zyngier
2020-03-25  2:28   ` [PATCH v7 01/12] MIPS: Loongson: Do not initialise statics to 0 Jiaxun Yang
2020-03-25  2:28   ` [PATCH v7 02/12] irqchip: loongson-liointc: Workaround LPC IRQ Errata Jiaxun Yang
2020-03-25  2:28   ` [PATCH v7 02/12] MIPS: DTS: CI20: add DT node for IR sensor Jiaxun Yang
2020-03-25  2:28   ` [PATCH v7 03/12] dt-bindings: interrupt-controller: Add Loongson LIOINTC Jiaxun Yang

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