public inbox for devicetree@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v12 0/4] PolarFire SoC GPIO interrupt support
@ 2026-03-11 15:17 Conor Dooley
  2026-03-11 15:17 ` [PATCH v12 1/4] gpio: mpfs: Add " Conor Dooley
                   ` (3 more replies)
  0 siblings, 4 replies; 16+ messages in thread
From: Conor Dooley @ 2026-03-11 15:17 UTC (permalink / raw)
  To: linux-gpio
  Cc: conor, Conor Dooley, Thomas Gleixner, Herve Codina,
	Daire McNamara, Rob Herring, Krzysztof Kozlowski, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Linus Walleij,
	Bartosz Golaszewski, linux-riscv, devicetree, linux-kernel

From: Conor Dooley <conor.dooley@microchip.com>

In 2024 I sent a v7 of adding support for the GPIOs on PolarFire SoC,
which relied on an irqchip driver for a mux sitting between the GPIO
controllers and the main interrupt controller on the chip:
https://lore.kernel.org/all/20240723-flatworm-cornflake-8023212f6584@wendy/

Some feedback I got from Thomas there ended up being a complete black
hole for time spent, and I never managed to make the change he wanted,
as a house of cards collapsed whenever I tried it. I eventually
abandoned my attempt to upstream the GPIO driver with interrupt support
and cut it out of the driver to make progress. I've been carrying what
Thomas deemed incorrect downstream since.

Recently Hervé upstreamed a patchset for a Renesas chip that deals with
a mux sitting between a GPIO controller and the platform interrupt
controller by way of interrupt-map. I saw the opportunity to copy what
he did, so have gone from an irqchip driver that read the mux setting
that firmware had configured, to trivial driver that reads the mux
configuration from devicetree and sets the hardware up to match.

This gets rid entirely of the irqchip driver, so resolves Thomas'
complaint, but I don't love how the GPIO side of things turned out quite
as much. The hardware has 41 interrupts but 70 GPIO lines. 38 of these
are 1:1, direct connections to a dedicated line on the interrupt
controller and 3 are shared.
With the parent mux driver, the GPIO driver's interrupt handler was only
called either for specific direct interrupt or for only the subset that
are fed into the shared interrupt for that controller. Without the
parent irqchip from mux driver, and using interrupt-map, I lost the
ability to use mux driver to selectively call the handler, so now the
GPIO controller attempts to handle interrupts on all lines.
Probably this is ultimately not a big deal, it just feels bad to do.

The mux driver has moved from irqchip to soc, since that's where Hervé's
ended up.

I assume the merging strategy is going to be the kinda expected split
into three, and it's worth noting that this may lead to some issues with
the gpio interrupt support, depending on how the existing devicetrees
are written. Of course, it'll come good in linux-next and in Linus'
tree.

Cheers,
Conor.

v12:
- Implemented mux driver feedback from Hervé.
- Reworked the gpio interrupt stuff per Linus' feedback, so didn't pick
  up Hervés tag.
- Modified the binding description to cover the 6 always "direct mode"
  interrupts on gpio controller 1.

CC: Thomas Gleixner <tglx@linutronix.de>
CC: Herve Codina <herve.codina@bootlin.com>
CC: Conor Dooley <conor.dooley@microchip.com>
CC: Daire McNamara <daire.mcnamara@microchip.com>
CC: Rob Herring <robh@kernel.org>
CC: Krzysztof Kozlowski <krzk+dt@kernel.org>
CC: Paul Walmsley <pjw@kernel.org>
CC: Palmer Dabbelt <palmer@dabbelt.com>
CC: Albert Ou <aou@eecs.berkeley.edu>
CC: Alexandre Ghiti <alex@ghiti.fr>
CC: Linus Walleij <linusw@kernel.org>
CC: Bartosz Golaszewski <brgl@kernel.org>
CC: linux-riscv@lists.infradead.org
CC: devicetree@vger.kernel.org
CC: linux-kernel@vger.kernel.org
CC: linux-gpio@vger.kernel.org

Conor Dooley (4):
  gpio: mpfs: Add interrupt support
  dt-bindings: soc: microchip: document PolarFire SoC's gpio interrupt
    mux
  soc: microchip: add mpfs gpio interrupt mux driver
  riscv: dts: microchip: update mpfs gpio interrupts to better match the
    SoC

 .../soc/microchip/microchip,mpfs-irqmux.yaml  |  77 ++++++++
 .../microchip,mpfs-mss-top-sysreg.yaml        |   4 +
 MAINTAINERS                                   |   2 +-
 .../boot/dts/microchip/mpfs-beaglev-fire.dts  |  29 +++
 .../boot/dts/microchip/mpfs-disco-kit.dts     |  43 +++--
 .../dts/microchip/mpfs-icicle-kit-common.dtsi |  37 +++-
 .../boot/dts/microchip/mpfs-m100pfsevp.dts    |  41 ++--
 .../boot/dts/microchip/mpfs-polarberry.dts    |  29 +++
 .../riscv/boot/dts/microchip/mpfs-sev-kit.dts |  37 +++-
 .../riscv/boot/dts/microchip/mpfs-tysom-m.dts |  35 +++-
 arch/riscv/boot/dts/microchip/mpfs.dtsi       |  37 +++-
 drivers/gpio/Kconfig                          |   1 +
 drivers/gpio/gpio-mpfs.c                      | 122 +++++++++++-
 drivers/soc/microchip/Kconfig                 |  11 ++
 drivers/soc/microchip/Makefile                |   1 +
 drivers/soc/microchip/mpfs-irqmux.c           | 181 ++++++++++++++++++
 16 files changed, 632 insertions(+), 55 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.yaml
 create mode 100644 drivers/soc/microchip/mpfs-irqmux.c

-- 
2.51.0


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

* [PATCH v12 1/4] gpio: mpfs: Add interrupt support
  2026-03-11 15:17 [PATCH v12 0/4] PolarFire SoC GPIO interrupt support Conor Dooley
@ 2026-03-11 15:17 ` Conor Dooley
  2026-03-16  9:06   ` Bartosz Golaszewski
  2026-03-16  9:22   ` Linus Walleij
  2026-03-11 15:17 ` [PATCH v12 2/4] dt-bindings: soc: microchip: document PolarFire SoC's gpio interrupt mux Conor Dooley
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 16+ messages in thread
From: Conor Dooley @ 2026-03-11 15:17 UTC (permalink / raw)
  To: linux-gpio
  Cc: conor, Conor Dooley, Thomas Gleixner, Herve Codina,
	Daire McNamara, Rob Herring, Krzysztof Kozlowski, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Linus Walleij,
	Bartosz Golaszewski, linux-riscv, devicetree, linux-kernel

From: Conor Dooley <conor.dooley@microchip.com>

Add support for interrupts to the PolarFire SoC GPIO driver. Each GPIO
has an independent interrupt that is wired to an interrupt mux that sits
between the controllers and the PLIC. The SoC has more GPIO lines than
connections from the mux to the PLIC, so some GPIOs must share PLIC
interrupts. The configuration is not static and is set at runtime,
conventionally by the platform's firmware. CoreGPIO, the version
intended for use in the FPGA fabric has two interrupt output ports, one
is IO_NUM bits wide, as is used in the hardened cores, and the other is
a single bit with all lines ORed together.

Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
 drivers/gpio/Kconfig     |   1 +
 drivers/gpio/gpio-mpfs.c | 122 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 120 insertions(+), 3 deletions(-)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b45fb799e36c1..1d1239323f615 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -572,6 +572,7 @@ config GPIO_PL061
 config GPIO_POLARFIRE_SOC
 	bool "Microchip FPGA GPIO support"
 	select REGMAP_MMIO
+	select GPIOLIB_IRQCHIP
 	help
 	  Say yes here to support the GPIO controllers on Microchip FPGAs.
 
diff --git a/drivers/gpio/gpio-mpfs.c b/drivers/gpio/gpio-mpfs.c
index 9468795b96348..1a4cf213c723c 100644
--- a/drivers/gpio/gpio-mpfs.c
+++ b/drivers/gpio/gpio-mpfs.c
@@ -9,8 +9,9 @@
 #include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/gpio/driver.h>
-#include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/mod_devicetable.h>
+#include <linux/of_irq.h>
 #include <linux/platform_device.h>
 #include <linux/property.h>
 #include <linux/regmap.h>
@@ -18,7 +19,7 @@
 
 #define MPFS_GPIO_CTRL(i)		(0x4 * (i))
 #define MPFS_MAX_NUM_GPIO		32
-#define MPFS_GPIO_EN_INT		3
+#define MPFS_GPIO_EN_INT		BIT(3)
 #define MPFS_GPIO_EN_OUT_BUF		BIT(2)
 #define MPFS_GPIO_EN_IN			BIT(1)
 #define MPFS_GPIO_EN_OUT		BIT(0)
@@ -52,6 +53,7 @@ static const struct regmap_config mpfs_gpio_regmap_config = {
 	.reg_bits = 32,
 	.reg_stride = 4,
 	.val_bits = 32,
+	.use_raw_spinlock = true,
 };
 
 static int mpfs_gpio_direction_input(struct gpio_chip *gc, unsigned int gpio_index)
@@ -114,13 +116,98 @@ static int mpfs_gpio_set(struct gpio_chip *gc, unsigned int gpio_index, int valu
 	return ret;
 }
 
+static int mpfs_gpio_irq_set_type(struct irq_data *data, unsigned int type)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+	struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
+	int gpio_index = irqd_to_hwirq(data) % 32;
+	u32 interrupt_type;
+
+	switch (type) {
+	case IRQ_TYPE_EDGE_BOTH:
+		interrupt_type = MPFS_GPIO_TYPE_INT_EDGE_BOTH;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		interrupt_type = MPFS_GPIO_TYPE_INT_EDGE_NEG;
+		break;
+	case IRQ_TYPE_EDGE_RISING:
+		interrupt_type = MPFS_GPIO_TYPE_INT_EDGE_POS;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		interrupt_type = MPFS_GPIO_TYPE_INT_LEVEL_HIGH;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		interrupt_type = MPFS_GPIO_TYPE_INT_LEVEL_LOW;
+		break;
+	}
+
+	regmap_update_bits(mpfs_gpio->regs, MPFS_GPIO_CTRL(gpio_index),
+			   MPFS_GPIO_TYPE_INT_MASK, interrupt_type);
+
+	return 0;
+}
+
+static void mpfs_gpio_irq_unmask(struct irq_data *data)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+	struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
+	int gpio_index = irqd_to_hwirq(data) % 32;
+
+	gpiochip_enable_irq(gc, gpio_index);
+	mpfs_gpio_direction_input(gc, gpio_index);
+	regmap_update_bits(mpfs_gpio->regs, MPFS_GPIO_CTRL(gpio_index),
+			     MPFS_GPIO_EN_INT, MPFS_GPIO_EN_INT);
+}
+
+static void mpfs_gpio_irq_mask(struct irq_data *data)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+	struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
+	int gpio_index = irqd_to_hwirq(data) % 32;
+
+	regmap_update_bits(mpfs_gpio->regs, MPFS_GPIO_CTRL(gpio_index),
+			   MPFS_GPIO_EN_INT, 0);
+	gpiochip_disable_irq(gc, gpio_index);
+}
+
+static const struct irq_chip mpfs_gpio_irqchip = {
+	.name = "MPFS GPIO",
+	.irq_set_type = mpfs_gpio_irq_set_type,
+	.irq_mask = mpfs_gpio_irq_mask,
+	.irq_unmask = mpfs_gpio_irq_unmask,
+	.flags = IRQCHIP_IMMUTABLE | IRQCHIP_MASK_ON_SUSPEND,
+	GPIOCHIP_IRQ_RESOURCE_HELPERS,
+};
+
+static void mpfs_gpio_irq_handler(struct irq_desc *desc)
+{
+	struct irq_chip *irqchip = irq_desc_get_chip(desc);
+	struct mpfs_gpio_chip *mpfs_gpio = irq_desc_get_handler_data(desc);
+	unsigned long status;
+	u32 val;
+	int i;
+
+	chained_irq_enter(irqchip, desc);
+
+	regmap_read(mpfs_gpio->regs, MPFS_IRQ_REG, &val);
+	status = val;
+	for_each_set_bit(i, &status, MPFS_MAX_NUM_GPIO) {
+		regmap_write(mpfs_gpio->regs, MPFS_IRQ_REG, BIT(i));
+		generic_handle_domain_irq(mpfs_gpio->gc.irq.domain, i);
+	}
+
+	chained_irq_exit(irqchip, desc);
+}
+
 static int mpfs_gpio_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->of_node;
 	struct mpfs_gpio_chip *mpfs_gpio;
+	struct gpio_irq_chip *girq;
 	struct clk *clk;
 	void __iomem *base;
-	int ngpios;
+	int ngpios, nirqs, ret;
 
 	mpfs_gpio = devm_kzalloc(dev, sizeof(*mpfs_gpio), GFP_KERNEL);
 	if (!mpfs_gpio)
@@ -157,6 +244,35 @@ static int mpfs_gpio_probe(struct platform_device *pdev)
 	mpfs_gpio->gc.parent = dev;
 	mpfs_gpio->gc.owner = THIS_MODULE;
 
+	nirqs = of_irq_count(node);
+	if (nirqs > MPFS_MAX_NUM_GPIO)
+		return -ENXIO;
+
+	if (nirqs) {
+		girq = &mpfs_gpio->gc.irq;
+
+		gpio_irq_chip_set_chip(girq, &mpfs_gpio_irqchip);
+
+		girq->num_parents = nirqs;
+		girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents,
+					     sizeof(*girq->parents), GFP_KERNEL);
+		if (!girq->parents)
+			return -ENOMEM;
+
+		for (int i = 0; i < nirqs; i++) {
+			ret = platform_get_irq(pdev, i);
+			if (ret < 0)
+				return ret;
+
+			girq->parents[i] = ret;
+			girq->parent_handler_data = mpfs_gpio;
+			girq->parent_handler = mpfs_gpio_irq_handler;
+		}
+
+		girq->handler = handle_level_irq;
+		girq->default_type = IRQ_TYPE_NONE;
+	}
+
 	return devm_gpiochip_add_data(dev, &mpfs_gpio->gc, mpfs_gpio);
 }
 
-- 
2.51.0


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

* [PATCH v12 2/4] dt-bindings: soc: microchip: document PolarFire SoC's gpio interrupt mux
  2026-03-11 15:17 [PATCH v12 0/4] PolarFire SoC GPIO interrupt support Conor Dooley
  2026-03-11 15:17 ` [PATCH v12 1/4] gpio: mpfs: Add " Conor Dooley
@ 2026-03-11 15:17 ` Conor Dooley
  2026-03-11 16:41   ` Rob Herring (Arm)
  2026-03-11 15:17 ` [PATCH v12 3/4] soc: microchip: add mpfs gpio interrupt mux driver Conor Dooley
  2026-03-11 15:17 ` [PATCH v12 4/4] riscv: dts: microchip: update mpfs gpio interrupts to better match the SoC Conor Dooley
  3 siblings, 1 reply; 16+ messages in thread
From: Conor Dooley @ 2026-03-11 15:17 UTC (permalink / raw)
  To: linux-gpio
  Cc: conor, Conor Dooley, Thomas Gleixner, Herve Codina,
	Daire McNamara, Rob Herring, Krzysztof Kozlowski, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Linus Walleij,
	Bartosz Golaszewski, linux-riscv, devicetree, linux-kernel

From: Conor Dooley <conor.dooley@microchip.com>

On PolarFire SoC there are more GPIO interrupts than there are interrupt
lines available on the PLIC, and a runtime configurable mux is used to
decide which interrupts are assigned direct connections to the PLIC &
which are relegated to sharing a line.

Reviewed-by: Herve Codina <herve.codina@bootlin.com>
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
 .../soc/microchip/microchip,mpfs-irqmux.yaml  | 77 +++++++++++++++++++
 .../microchip,mpfs-mss-top-sysreg.yaml        |  4 +
 2 files changed, 81 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.yaml

diff --git a/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.yaml b/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.yaml
new file mode 100644
index 0000000000000..6a743b5067f75
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/microchip/microchip,mpfs-irqmux.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip Polarfire SoC GPIO Interrupt Mux
+
+maintainers:
+  - Conor Dooley <conor.dooley@microchip.com>
+
+description: |
+  There are 3 GPIO controllers on this SoC, of which:
+  - GPIO controller 0 has 14 GPIOs
+  - GPIO controller 1 has 24 GPIOs
+  - GPIO controller 2 has 32 GPIOs
+
+  All GPIOs are capable of generating interrupts, for a total of 70.
+  There are only 41 IRQs available however, so a configurable mux is used to
+  ensure all GPIOs can be used for interrupt generation.
+  38 of the 41 interrupts are in what the documentation calls "direct mode",
+  as they provide an exclusive connection from a GPIO to the PLIC.
+  Lines 18 to 23 on GPIO controller 1 are always in "direct mode".
+  The 3 remaining interrupts are used to mux the interrupts which do not have
+  a exclusive connection, one for each GPIO controller.
+
+properties:
+  compatible:
+    const: microchip,mpfs-irqmux
+
+  reg:
+    maxItems: 1
+
+  "#address-cells":
+    const: 0
+
+  "#interrupt-cells":
+    const: 1
+
+  interrupt-map-mask:
+    items:
+      - const: 0x7f
+
+  interrupt-map:
+    description: |
+      Specifies the mapping from GPIO interrupt lines to plic interrupts.
+
+      The child interrupt number set in arrays items is computed using the
+      following formula:
+          gpio_bank * 32 + gpio_number
+      with:
+        - gpio_bank: The GPIO bank number
+            - 0 for GPIO0,
+            - 1 for GPIO1,
+            - 2 for GPIO2
+        - gpio_number: Number of the gpio in the bank (0..31)
+    maxItems: 70
+
+required:
+  - compatible
+  - reg
+  - "#address-cells"
+  - "#interrupt-cells"
+  - interrupt-map-mask
+  - interrupt-map
+
+additionalProperties: false
+
+examples:
+  - |
+    interrupt-controller@54 {
+        compatible = "microchip,mpfs-irqmux";
+        reg = <0x54 0x4>;
+        #address-cells = <0>;
+        #interrupt-cells = <1>;
+        interrupt-map-mask = <0xff>;
+    };
diff --git a/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-mss-top-sysreg.yaml b/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-mss-top-sysreg.yaml
index 44e4a50c31554..276d48ba15f01 100644
--- a/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-mss-top-sysreg.yaml
+++ b/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-mss-top-sysreg.yaml
@@ -38,6 +38,10 @@ properties:
       of PolarFire clock/reset IDs.
     const: 1
 
+  interrupt-controller@54:
+    type: object
+    $ref: /schemas/soc/microchip/microchip,mpfs-irqmux.yaml
+
   pinctrl@200:
     type: object
     $ref: /schemas/pinctrl/microchip,mpfs-pinctrl-iomux0.yaml
-- 
2.51.0


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

* [PATCH v12 3/4] soc: microchip: add mpfs gpio interrupt mux driver
  2026-03-11 15:17 [PATCH v12 0/4] PolarFire SoC GPIO interrupt support Conor Dooley
  2026-03-11 15:17 ` [PATCH v12 1/4] gpio: mpfs: Add " Conor Dooley
  2026-03-11 15:17 ` [PATCH v12 2/4] dt-bindings: soc: microchip: document PolarFire SoC's gpio interrupt mux Conor Dooley
@ 2026-03-11 15:17 ` Conor Dooley
  2026-03-11 16:11   ` Herve Codina
                     ` (2 more replies)
  2026-03-11 15:17 ` [PATCH v12 4/4] riscv: dts: microchip: update mpfs gpio interrupts to better match the SoC Conor Dooley
  3 siblings, 3 replies; 16+ messages in thread
From: Conor Dooley @ 2026-03-11 15:17 UTC (permalink / raw)
  To: linux-gpio
  Cc: conor, Conor Dooley, Thomas Gleixner, Herve Codina,
	Daire McNamara, Rob Herring, Krzysztof Kozlowski, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Linus Walleij,
	Bartosz Golaszewski, linux-riscv, devicetree, linux-kernel

From: Conor Dooley <conor.dooley@microchip.com>

On PolarFire SoC there are more GPIO interrupts than there are interrupt
lines available on the PLIC, and a runtime configurable mux is used to
decide which interrupts are assigned direct connections to the PLIC &
which are relegated to sharing a line.

Add a driver so that Linux can set the mux based on the interrupt
mapping in the devicetree.

Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
 MAINTAINERS                         |   2 +-
 drivers/soc/microchip/Kconfig       |  11 ++
 drivers/soc/microchip/Makefile      |   1 +
 drivers/soc/microchip/mpfs-irqmux.c | 181 ++++++++++++++++++++++++++++
 4 files changed, 194 insertions(+), 1 deletion(-)
 create mode 100644 drivers/soc/microchip/mpfs-irqmux.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 55af015174a54..723c58756a5c1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22734,7 +22734,7 @@ F:	Documentation/devicetree/bindings/pinctrl/microchip,mpfs-pinctrl-mssio.yaml
 F:	Documentation/devicetree/bindings/pinctrl/microchip,pic64gx-pinctrl-gpio2.yaml
 F:	Documentation/devicetree/bindings/pwm/microchip,corepwm.yaml
 F:	Documentation/devicetree/bindings/riscv/microchip.yaml
-F:	Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-sys-controller.yaml
+F:	Documentation/devicetree/bindings/soc/microchip/microchip,mpfs*.yaml
 F:	Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml
 F:	Documentation/devicetree/bindings/usb/microchip,mpfs-musb.yaml
 F:	arch/riscv/boot/dts/microchip/
diff --git a/drivers/soc/microchip/Kconfig b/drivers/soc/microchip/Kconfig
index bcf5546025610..af7946741bce4 100644
--- a/drivers/soc/microchip/Kconfig
+++ b/drivers/soc/microchip/Kconfig
@@ -1,3 +1,14 @@
+config POLARFIRE_SOC_IRQ_MUX
+	bool "Microchip PolarFire SoC's GPIO IRQ Mux"
+	depends on ARCH_MICROCHIP
+	select REGMAP
+	select REGMAP_MMIO
+	default y
+	help
+	  Support for the interrupt mux on Polarfire SoC. It sits between
+	  the GPIO controllers and the PLIC, as only 41 interrupts are shared
+	  between 3 GPIO controllers with a total of 70 interrupts.
+
 config POLARFIRE_SOC_SYS_CTRL
 	tristate "Microchip PolarFire SoC (MPFS) system controller support"
 	depends on POLARFIRE_SOC_MAILBOX
diff --git a/drivers/soc/microchip/Makefile b/drivers/soc/microchip/Makefile
index 1a3a1594b089b..55775db45ee76 100644
--- a/drivers/soc/microchip/Makefile
+++ b/drivers/soc/microchip/Makefile
@@ -1,2 +1,3 @@
+obj-$(CONFIG_POLARFIRE_SOC_IRQ_MUX)	+= mpfs-irqmux.o
 obj-$(CONFIG_POLARFIRE_SOC_SYS_CTRL)	+= mpfs-sys-controller.o
 obj-$(CONFIG_POLARFIRE_SOC_SYSCONS)	+= mpfs-control-scb.o mpfs-mss-top-sysreg.o
diff --git a/drivers/soc/microchip/mpfs-irqmux.c b/drivers/soc/microchip/mpfs-irqmux.c
new file mode 100644
index 0000000000000..ae15e913e7802
--- /dev/null
+++ b/drivers/soc/microchip/mpfs-irqmux.c
@@ -0,0 +1,181 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Largely copied from rzn1_irqmux.c
+ */
+
+#include <linux/bitmap.h>
+#include <linux/bitops.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define MPFS_IRQMUX_CR			0x54
+#define MPFS_IRQMUX_NUM_CHILDREN	96
+#define MPFS_IRQMUX_NUM_DIRECT		38
+#define MPFS_IRQMUX_DIRECT_START	13
+#define MPFS_IRQMUX_DIRECT_END		50
+#define MPFS_IRQMUX_NONDIRECT_END	53
+
+static int mpfs_irqmux_is_direct_mode(struct device *dev,
+				      const struct of_phandle_args *parent_args)
+{
+	if (parent_args->args_count != 1) {
+		dev_err(dev, "Invalid interrupt-map item\n");
+		return -EINVAL;
+	}
+
+	if (parent_args->args[0] < MPFS_IRQMUX_DIRECT_START ||
+			parent_args->args[0] > MPFS_IRQMUX_NONDIRECT_END) {
+		dev_err(dev, "Invalid interrupt %u\n", parent_args->args[0]);
+		return -EINVAL;
+	}
+
+	if (parent_args->args[0] > MPFS_IRQMUX_DIRECT_END)
+		return 0;
+
+	return 1;
+}
+
+static int mpfs_irqmux_probe(struct platform_device *pdev)
+{
+	DECLARE_BITMAP(child_done, MPFS_IRQMUX_NUM_CHILDREN) = {};
+	DECLARE_BITMAP(parent_done, MPFS_IRQMUX_NUM_DIRECT) = {};
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct of_imap_parser imap_parser;
+	struct of_imap_item imap_item;
+	struct regmap *regmap;
+	int ret, direct_mode, line, controller, gpio, parent_line;
+	u32 tmp, val = 0, old;
+
+	regmap = device_node_to_regmap(pdev->dev.parent->of_node);
+	if (IS_ERR(regmap))
+		return dev_err_probe(dev, PTR_ERR(regmap), "Failed to find syscon regmap\n");
+
+	/* We support only #interrupt-cells = <1> and #address-cells = <0> */
+	ret = of_property_read_u32(np, "#interrupt-cells", &tmp);
+	if (ret)
+		return ret;
+	if (tmp != 1)
+		return -EINVAL;
+
+	ret = of_property_read_u32(np, "#address-cells", &tmp);
+	if (ret)
+		return ret;
+	if (tmp != 0)
+		return -EINVAL;
+
+	ret = of_imap_parser_init(&imap_parser, np, &imap_item);
+	if (ret)
+		return ret;
+
+	for_each_of_imap_item(&imap_parser, &imap_item) {
+
+		direct_mode = mpfs_irqmux_is_direct_mode(dev, &imap_item.parent_args);
+		if (direct_mode < 0) {
+			of_node_put(imap_item.parent_args.np);
+			return direct_mode;
+		}
+
+		line = imap_item.child_imap[0];
+		gpio = line % 32;
+		controller = line / 32;
+
+		if (controller > 2) {
+			of_node_put(imap_item.parent_args.np);
+			dev_err(dev, "child interrupt number too large: %d\n", line);
+			return -EINVAL;
+		}
+
+		if (test_and_set_bit(line, child_done)) {
+			of_node_put(imap_item.parent_args.np);
+			dev_err(dev, "mux child line %d already defined in interrupt-map\n",
+				line);
+			return -EINVAL;
+		}
+
+		parent_line = imap_item.parent_args.args[0] - MPFS_IRQMUX_DIRECT_START;
+		if (direct_mode && test_and_set_bit(parent_line, parent_done)) {
+			of_node_put(imap_item.parent_args.np);
+			dev_err(dev, "mux parent line %d already defined in interrupt-map\n",
+				line);
+			return -EINVAL;
+		}
+
+		/*
+		 * There are 41 interrupts assigned to GPIOs, of which 38 are "direct". Since the
+		 * mux has 32 bits only, 6 of these exclusive/"direct" interrupts remain. These
+		 * are used by GPIO controller 1's lines 18 to 23. Nothing needs to be done
+		 * for these interrupts.
+		 */
+		if (controller == 1 && gpio >= 18)
+			continue;
+
+		/*
+		 * The mux has a single register, where bits 0 to 13 mux between GPIO controller
+		 * 1's 14 GPIOs and GPIO controller 2's first 14 GPIOs. The remaining bits mux
+		 * between the first 18 GPIOs of controller 1 and the last 18 GPIOS of
+		 * controller 2. If a bit in the mux's control register is set, the
+		 * corresponding interrupt line for GPIO controller 0 or 1 will be put in
+		 * "non-direct" mode. If cleared, the "fabric" controller's will.
+		 *
+		 * Register layout:
+		 *    GPIO 1 interrupt line 17 | mux bit 31 | GPIO 2 interrupt line 31
+		 *    ...                      | ...        | ...
+		 *    ...                      | ...        | ...
+		 *    GPIO 1 interrupt line  0 | mux bit 14 | GPIO 2 interrupt line 14
+		 *    GPIO 0 interrupt line 13 | mux bit 13 | GPIO 2 interrupt line 13
+		 *    ...                      | ...        | ...
+		 *    ...                      | ...        | ...
+		 *    GPIO 0 interrupt line  0 | mux bit  0 | GPIO 2 interrupt line  0
+		 *
+		 * As the binding mandates 70 items, one for each GPIO line, there's no need to
+		 * handle anything for GPIO controller 2, since the bit will be set for the
+		 * corresponding line in GPIO controller 0 or 1.
+		 */
+		if (controller == 2)
+			continue;
+
+		/*
+		 * If in direct mode, the bit is cleared, nothing needs to be done as val is zero
+		 * initialised and that's the direct mode setting for GPIO controller 0 and 1.
+		 */
+		if (direct_mode)
+			continue;
+
+		if (controller == 0)
+			val |= 1U << gpio;
+		else
+			val |= 1U << (gpio + 14);
+	}
+
+	regmap_read(regmap, MPFS_IRQMUX_CR, &old);
+	regmap_write(regmap, MPFS_IRQMUX_CR, val);
+
+	if (val != old)
+		dev_info(dev, "firmware mux setting of 0x%x overwritten to 0x%x\n", old, val);
+
+	return 0;
+}
+
+static const struct of_device_id mpfs_irqmux_of_match[] = {
+	{ .compatible = "microchip,mpfs-irqmux", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, mpfs_irqmux_of_match);
+
+static struct platform_driver mpfs_irqmux_driver = {
+	.probe = mpfs_irqmux_probe,
+	.driver = {
+		.name = "mpfs_irqmux",
+		.of_match_table = mpfs_irqmux_of_match,
+	},
+};
+module_platform_driver(mpfs_irqmux_driver);
+
+MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>");
+MODULE_DESCRIPTION("Polarfire SoC interrupt mux driver");
+MODULE_LICENSE("GPL");
-- 
2.51.0


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

* [PATCH v12 4/4] riscv: dts: microchip: update mpfs gpio interrupts to better match the SoC
  2026-03-11 15:17 [PATCH v12 0/4] PolarFire SoC GPIO interrupt support Conor Dooley
                   ` (2 preceding siblings ...)
  2026-03-11 15:17 ` [PATCH v12 3/4] soc: microchip: add mpfs gpio interrupt mux driver Conor Dooley
@ 2026-03-11 15:17 ` Conor Dooley
  2026-03-16  9:27   ` Linus Walleij
  3 siblings, 1 reply; 16+ messages in thread
From: Conor Dooley @ 2026-03-11 15:17 UTC (permalink / raw)
  To: linux-gpio
  Cc: conor, Conor Dooley, Thomas Gleixner, Herve Codina,
	Daire McNamara, Rob Herring, Krzysztof Kozlowski, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Linus Walleij,
	Bartosz Golaszewski, linux-riscv, devicetree, linux-kernel

From: Conor Dooley <conor.dooley@microchip.com>

There are 3 GPIO controllers on this SoC, of which:
- GPIO controller 0 has 14 GPIOs
- GPIO controller 1 has 24 GPIOs
- GPIO controller 2 has 32 GPIOs

All GPIOs are capable of generating interrupts, for a total of 70.
There are only 41 IRQs available however, so a configurable mux is used
to ensure all GPIOs can be used for interrupt generation.
38 of the 41 interrupts are in what the documentation calls "direct
mode", as they provide an exclusive connection from a GPIO to the PLIC.
The 3 remaining interrupts are used to mux the interrupts which do not
have a exclusive connection, one for each GPIO controller.

The mux was overlooked when the bindings and driver were originally
written for the GPIO controllers on Polarfire SoC, and the interrupts
property in the GPIO nodes used to try and convey what the mapping was.
Instead, the mux should be a device in its own right, and the GPIO
controllers should be connected to it, rather than to the PLIC.
Now that a binding exists for that mux, fix the inaccurate description
of the interrupt controller hierarchy.

GPIO controllers 0 and 1 do not have all 32 possible GPIO lines, so
ngpios needs to be set to match the number of lines/interrupts.

The m100pfsevp has conflicting interrupt mappings for controllers 0 and
2, as they cannot both be using an interrupt in "direct mode" at the
same time, so the default replaces this impossible configuration.

Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
 .../boot/dts/microchip/mpfs-beaglev-fire.dts  | 29 +++++++++++++
 .../boot/dts/microchip/mpfs-disco-kit.dts     | 43 +++++++++++++------
 .../dts/microchip/mpfs-icicle-kit-common.dtsi | 37 ++++++++++++----
 .../boot/dts/microchip/mpfs-m100pfsevp.dts    | 41 ++++++++++++------
 .../boot/dts/microchip/mpfs-polarberry.dts    | 29 +++++++++++++
 .../riscv/boot/dts/microchip/mpfs-sev-kit.dts | 37 ++++++++++++----
 .../riscv/boot/dts/microchip/mpfs-tysom-m.dts | 35 ++++++++++++---
 arch/riscv/boot/dts/microchip/mpfs.dtsi       | 37 ++++++++++++++--
 8 files changed, 237 insertions(+), 51 deletions(-)

diff --git a/arch/riscv/boot/dts/microchip/mpfs-beaglev-fire.dts b/arch/riscv/boot/dts/microchip/mpfs-beaglev-fire.dts
index f44ad8e6f4e49..0e1b0b8d394b9 100644
--- a/arch/riscv/boot/dts/microchip/mpfs-beaglev-fire.dts
+++ b/arch/riscv/boot/dts/microchip/mpfs-beaglev-fire.dts
@@ -164,6 +164,35 @@ imx219_0: endpoint {
 	};
 };
 
+&irqmux {
+	interrupt-map = <0 &plic 13>, <1 &plic 14>, <2 &plic 15>,
+			<3 &plic 16>, <4 &plic 17>, <5 &plic 18>,
+			<6 &plic 19>, <7 &plic 20>, <8 &plic 21>,
+			<9 &plic 22>, <10 &plic 23>, <11 &plic 24>,
+			<12 &plic 25>, <13 &plic 26>,
+
+			<32 &plic 27>, <33 &plic 28>, <34 &plic 29>,
+			<35 &plic 30>, <36 &plic 31>, <37 &plic 32>,
+			<38 &plic 33>, <39 &plic 34>, <40 &plic 35>,
+			<41 &plic 36>, <42 &plic 37>, <43 &plic 38>,
+			<44 &plic 39>, <45 &plic 40>, <46 &plic 41>,
+			<47 &plic 42>, <48 &plic 43>, <49 &plic 44>,
+			<50 &plic 45>, <51 &plic 46>, <52 &plic 47>,
+			<53 &plic 48>, <54 &plic 49>, <55 &plic 50>,
+
+			<64 &plic 53>, <65 &plic 53>, <66 &plic 53>,
+			<67 &plic 53>, <68 &plic 53>, <69 &plic 53>,
+			<70 &plic 53>, <71 &plic 53>, <72 &plic 53>,
+			<73 &plic 53>, <74 &plic 53>, <75 &plic 53>,
+			<76 &plic 53>, <77 &plic 53>, <78 &plic 53>,
+			<79 &plic 53>, <80 &plic 53>, <81 &plic 53>,
+			<82 &plic 53>, <83 &plic 53>, <84 &plic 53>,
+			<85 &plic 53>, <86 &plic 53>, <87 &plic 53>,
+			<88 &plic 53>, <89 &plic 53>, <90 &plic 53>,
+			<91 &plic 53>, <92 &plic 53>, <93 &plic 53>,
+			<94 &plic 53>, <95 &plic 53>;
+};
+
 &mac0 {
 	status = "okay";
 	phy-mode = "sgmii";
diff --git a/arch/riscv/boot/dts/microchip/mpfs-disco-kit.dts b/arch/riscv/boot/dts/microchip/mpfs-disco-kit.dts
index c068b9bb5bfdf..f769c9d5d7b47 100644
--- a/arch/riscv/boot/dts/microchip/mpfs-disco-kit.dts
+++ b/arch/riscv/boot/dts/microchip/mpfs-disco-kit.dts
@@ -97,24 +97,10 @@ &core_pwm0 {
 };
 
 &gpio1 {
-	interrupts = <27>, <28>, <29>, <30>,
-		     <31>, <32>, <33>, <47>,
-		     <35>, <36>, <37>, <38>,
-		     <39>, <40>, <41>, <42>,
-		     <43>, <44>, <45>, <46>,
-		     <47>, <48>, <49>, <50>;
 	status = "okay";
 };
 
 &gpio2 {
-	interrupts = <53>, <53>, <53>, <53>,
-		     <53>, <53>, <53>, <53>,
-		     <53>, <53>, <53>, <53>,
-		     <53>, <53>, <53>, <53>,
-		     <53>, <53>, <53>, <53>,
-		     <53>, <53>, <53>, <53>,
-		     <53>, <53>, <53>, <53>,
-		     <53>, <53>, <53>, <53>;
 	status = "okay";
 };
 
@@ -130,6 +116,35 @@ &ihc {
 	status = "okay";
 };
 
+&irqmux {
+	interrupt-map = <0 &plic 13>, <1 &plic 14>, <2 &plic 15>,
+			<3 &plic 16>, <4 &plic 17>, <5 &plic 18>,
+			<6 &plic 19>, <7 &plic 20>, <8 &plic 21>,
+			<9 &plic 22>, <10 &plic 23>, <11 &plic 24>,
+			<12 &plic 25>, <13 &plic 26>,
+
+			<32 &plic 27>, <33 &plic 28>, <34 &plic 29>,
+			<35 &plic 30>, <36 &plic 31>, <37 &plic 32>,
+			<38 &plic 33>, <39 &plic 34>, <40 &plic 35>,
+			<41 &plic 36>, <42 &plic 37>, <43 &plic 38>,
+			<44 &plic 39>, <45 &plic 40>, <46 &plic 41>,
+			<47 &plic 42>, <48 &plic 43>, <49 &plic 44>,
+			<50 &plic 45>, <51 &plic 46>, <52 &plic 47>,
+			<53 &plic 48>, <54 &plic 49>, <55 &plic 50>,
+
+			<64 &plic 53>, <65 &plic 53>, <66 &plic 53>,
+			<67 &plic 53>, <68 &plic 53>, <69 &plic 53>,
+			<70 &plic 53>, <71 &plic 53>, <72 &plic 53>,
+			<73 &plic 53>, <74 &plic 53>, <75 &plic 53>,
+			<76 &plic 53>, <77 &plic 53>, <78 &plic 53>,
+			<79 &plic 53>, <80 &plic 53>, <81 &plic 53>,
+			<82 &plic 53>, <83 &plic 53>, <84 &plic 53>,
+			<85 &plic 53>, <86 &plic 53>, <87 &plic 53>,
+			<88 &plic 53>, <89 &plic 53>, <90 &plic 53>,
+			<91 &plic 53>, <92 &plic 53>, <93 &plic 53>,
+			<94 &plic 53>, <95 &plic 53>;
+};
+
 &mac0 {
 	phy-mode = "sgmii";
 	phy-handle = <&phy0>;
diff --git a/arch/riscv/boot/dts/microchip/mpfs-icicle-kit-common.dtsi b/arch/riscv/boot/dts/microchip/mpfs-icicle-kit-common.dtsi
index e01a216e6c3a8..e25edc5f3b451 100644
--- a/arch/riscv/boot/dts/microchip/mpfs-icicle-kit-common.dtsi
+++ b/arch/riscv/boot/dts/microchip/mpfs-icicle-kit-common.dtsi
@@ -77,14 +77,6 @@ &core_pwm0 {
 };
 
 &gpio2 {
-	interrupts = <53>, <53>, <53>, <53>,
-		     <53>, <53>, <53>, <53>,
-		     <53>, <53>, <53>, <53>,
-		     <53>, <53>, <53>, <53>,
-		     <53>, <53>, <53>, <53>,
-		     <53>, <53>, <53>, <53>,
-		     <53>, <53>, <53>, <53>,
-		     <53>, <53>, <53>, <53>;
 	status = "okay";
 };
 
@@ -136,6 +128,35 @@ &ihc {
 	status = "okay";
 };
 
+&irqmux {
+	interrupt-map = <0 &plic 13>, <1 &plic 14>, <2 &plic 15>,
+			<3 &plic 16>, <4 &plic 17>, <5 &plic 18>,
+			<6 &plic 19>, <7 &plic 20>, <8 &plic 21>,
+			<9 &plic 22>, <10 &plic 23>, <11 &plic 24>,
+			<12 &plic 25>, <13 &plic 26>,
+
+			<32 &plic 27>, <33 &plic 28>, <34 &plic 29>,
+			<35 &plic 30>, <36 &plic 31>, <37 &plic 32>,
+			<38 &plic 33>, <39 &plic 34>, <40 &plic 35>,
+			<41 &plic 36>, <42 &plic 37>, <43 &plic 38>,
+			<44 &plic 39>, <45 &plic 40>, <46 &plic 41>,
+			<47 &plic 42>, <48 &plic 43>, <49 &plic 44>,
+			<50 &plic 45>, <51 &plic 46>, <52 &plic 47>,
+			<53 &plic 48>, <54 &plic 49>, <55 &plic 50>,
+
+			<64 &plic 53>, <65 &plic 53>, <66 &plic 53>,
+			<67 &plic 53>, <68 &plic 53>, <69 &plic 53>,
+			<70 &plic 53>, <71 &plic 53>, <72 &plic 53>,
+			<73 &plic 53>, <74 &plic 53>, <75 &plic 53>,
+			<76 &plic 53>, <77 &plic 53>, <78 &plic 53>,
+			<79 &plic 53>, <80 &plic 53>, <81 &plic 53>,
+			<82 &plic 53>, <83 &plic 53>, <84 &plic 53>,
+			<85 &plic 53>, <86 &plic 53>, <87 &plic 53>,
+			<88 &plic 53>, <89 &plic 53>, <90 &plic 53>,
+			<91 &plic 53>, <92 &plic 53>, <93 &plic 53>,
+			<94 &plic 53>, <95 &plic 53>;
+};
+
 &mac0 {
 	phy-mode = "sgmii";
 	phy-handle = <&phy0>;
diff --git a/arch/riscv/boot/dts/microchip/mpfs-m100pfsevp.dts b/arch/riscv/boot/dts/microchip/mpfs-m100pfsevp.dts
index a8d623ee9fa4c..86234968df486 100644
--- a/arch/riscv/boot/dts/microchip/mpfs-m100pfsevp.dts
+++ b/arch/riscv/boot/dts/microchip/mpfs-m100pfsevp.dts
@@ -52,11 +52,36 @@ &i2c1 {
 	status = "okay";
 };
 
+&irqmux {
+	interrupt-map = <0 &plic 13>, <1 &plic 14>, <2 &plic 15>,
+			<3 &plic 16>, <4 &plic 17>, <5 &plic 18>,
+			<6 &plic 19>, <7 &plic 20>, <8 &plic 21>,
+			<9 &plic 22>, <10 &plic 23>, <11 &plic 24>,
+			<12 &plic 25>, <13 &plic 26>,
+
+			<32 &plic 27>, <33 &plic 28>, <34 &plic 29>,
+			<35 &plic 30>, <36 &plic 31>, <37 &plic 32>,
+			<38 &plic 33>, <39 &plic 34>, <40 &plic 35>,
+			<41 &plic 36>, <42 &plic 37>, <43 &plic 38>,
+			<44 &plic 39>, <45 &plic 40>, <46 &plic 41>,
+			<47 &plic 42>, <48 &plic 43>, <49 &plic 44>,
+			<50 &plic 45>, <51 &plic 46>, <52 &plic 47>,
+			<53 &plic 48>, <54 &plic 49>, <55 &plic 50>,
+
+			<64 &plic 53>, <65 &plic 53>, <66 &plic 53>,
+			<67 &plic 53>, <68 &plic 53>, <69 &plic 53>,
+			<70 &plic 53>, <71 &plic 53>, <72 &plic 53>,
+			<73 &plic 53>, <74 &plic 53>, <75 &plic 53>,
+			<76 &plic 53>, <77 &plic 53>, <78 &plic 53>,
+			<79 &plic 53>, <80 &plic 53>, <81 &plic 53>,
+			<82 &plic 53>, <83 &plic 53>, <84 &plic 53>,
+			<85 &plic 53>, <86 &plic 53>, <87 &plic 53>,
+			<88 &plic 53>, <89 &plic 53>, <90 &plic 53>,
+			<91 &plic 53>, <92 &plic 53>, <93 &plic 53>,
+			<94 &plic 53>, <95 &plic 53>;
+};
+
 &gpio0 {
-	interrupts = <13>, <14>, <15>, <16>,
-		     <17>, <18>, <19>, <20>,
-		     <21>, <22>, <23>, <24>,
-		     <25>, <26>;
 	ngpios = <14>;
 	status = "okay";
 
@@ -75,14 +100,6 @@ mmc-sel-hog {
 };
 
 &gpio2 {
-	interrupts = <13>, <14>, <15>, <16>,
-		     <17>, <18>, <19>, <20>,
-		     <21>, <22>, <23>, <24>,
-		     <25>, <26>, <27>, <28>,
-		     <29>, <30>, <31>, <32>,
-		     <33>, <34>, <35>, <36>,
-		     <37>, <38>, <39>, <40>,
-		     <41>, <42>, <43>, <44>;
 	status = "okay";
 };
 
diff --git a/arch/riscv/boot/dts/microchip/mpfs-polarberry.dts b/arch/riscv/boot/dts/microchip/mpfs-polarberry.dts
index ea0808ab10425..510d59153cd07 100644
--- a/arch/riscv/boot/dts/microchip/mpfs-polarberry.dts
+++ b/arch/riscv/boot/dts/microchip/mpfs-polarberry.dts
@@ -30,6 +30,35 @@ ddrc_cache_hi: memory@1000000000 {
 	};
 };
 
+&irqmux {
+	interrupt-map = <0 &plic 13>, <1 &plic 14>, <2 &plic 15>,
+			<3 &plic 16>, <4 &plic 17>, <5 &plic 18>,
+			<6 &plic 19>, <7 &plic 20>, <8 &plic 21>,
+			<9 &plic 22>, <10 &plic 23>, <11 &plic 24>,
+			<12 &plic 25>, <13 &plic 26>,
+
+			<32 &plic 27>, <33 &plic 28>, <34 &plic 29>,
+			<35 &plic 30>, <36 &plic 31>, <37 &plic 32>,
+			<38 &plic 33>, <39 &plic 34>, <40 &plic 35>,
+			<41 &plic 36>, <42 &plic 37>, <43 &plic 38>,
+			<44 &plic 39>, <45 &plic 40>, <46 &plic 41>,
+			<47 &plic 42>, <48 &plic 43>, <49 &plic 44>,
+			<50 &plic 45>, <51 &plic 46>, <52 &plic 47>,
+			<53 &plic 48>, <54 &plic 49>, <55 &plic 50>,
+
+			<64 &plic 53>, <65 &plic 53>, <66 &plic 53>,
+			<67 &plic 53>, <68 &plic 53>, <69 &plic 53>,
+			<70 &plic 53>, <71 &plic 53>, <72 &plic 53>,
+			<73 &plic 53>, <74 &plic 53>, <75 &plic 53>,
+			<76 &plic 53>, <77 &plic 53>, <78 &plic 53>,
+			<79 &plic 53>, <80 &plic 53>, <81 &plic 53>,
+			<82 &plic 53>, <83 &plic 53>, <84 &plic 53>,
+			<85 &plic 53>, <86 &plic 53>, <87 &plic 53>,
+			<88 &plic 53>, <89 &plic 53>, <90 &plic 53>,
+			<91 &plic 53>, <92 &plic 53>, <93 &plic 53>,
+			<94 &plic 53>, <95 &plic 53>;
+};
+
 /*
  * phy0 is connected to mac0, but the port itself is on the (optional) carrier
  * board.
diff --git a/arch/riscv/boot/dts/microchip/mpfs-sev-kit.dts b/arch/riscv/boot/dts/microchip/mpfs-sev-kit.dts
index f9a8905794383..8f1908a105671 100644
--- a/arch/riscv/boot/dts/microchip/mpfs-sev-kit.dts
+++ b/arch/riscv/boot/dts/microchip/mpfs-sev-kit.dts
@@ -56,15 +56,36 @@ &i2c0 {
 	status = "okay";
 };
 
+&irqmux {
+	interrupt-map = <0 &plic 13>, <1 &plic 14>, <2 &plic 15>,
+			<3 &plic 16>, <4 &plic 17>, <5 &plic 18>,
+			<6 &plic 19>, <7 &plic 20>, <8 &plic 21>,
+			<9 &plic 22>, <10 &plic 23>, <11 &plic 24>,
+			<12 &plic 25>, <13 &plic 26>,
+
+			<32 &plic 27>, <33 &plic 28>, <34 &plic 29>,
+			<35 &plic 30>, <36 &plic 31>, <37 &plic 32>,
+			<38 &plic 33>, <39 &plic 34>, <40 &plic 35>,
+			<41 &plic 36>, <42 &plic 37>, <43 &plic 38>,
+			<44 &plic 39>, <45 &plic 40>, <46 &plic 41>,
+			<47 &plic 42>, <48 &plic 43>, <49 &plic 44>,
+			<50 &plic 45>, <51 &plic 46>, <52 &plic 47>,
+			<53 &plic 48>, <54 &plic 49>, <55 &plic 50>,
+
+			<64 &plic 53>, <65 &plic 53>, <66 &plic 53>,
+			<67 &plic 53>, <68 &plic 53>, <69 &plic 53>,
+			<70 &plic 53>, <71 &plic 53>, <72 &plic 53>,
+			<73 &plic 53>, <74 &plic 53>, <75 &plic 53>,
+			<76 &plic 53>, <77 &plic 53>, <78 &plic 53>,
+			<79 &plic 53>, <80 &plic 53>, <81 &plic 53>,
+			<82 &plic 53>, <83 &plic 53>, <84 &plic 53>,
+			<85 &plic 53>, <86 &plic 53>, <87 &plic 53>,
+			<88 &plic 53>, <89 &plic 53>, <90 &plic 53>,
+			<91 &plic 53>, <92 &plic 53>, <93 &plic 53>,
+			<94 &plic 53>, <95 &plic 53>;
+};
+
 &gpio2 {
-	interrupts = <53>, <53>, <53>, <53>,
-		     <53>, <53>, <53>, <53>,
-		     <53>, <53>, <53>, <53>,
-		     <53>, <53>, <53>, <53>,
-		     <53>, <53>, <53>, <53>,
-		     <53>, <53>, <53>, <53>,
-		     <53>, <53>, <53>, <53>,
-		     <53>, <53>, <53>, <53>;
 	status = "okay";
 };
 
diff --git a/arch/riscv/boot/dts/microchip/mpfs-tysom-m.dts b/arch/riscv/boot/dts/microchip/mpfs-tysom-m.dts
index d1120f5f2c015..bc15530a2979b 100644
--- a/arch/riscv/boot/dts/microchip/mpfs-tysom-m.dts
+++ b/arch/riscv/boot/dts/microchip/mpfs-tysom-m.dts
@@ -69,13 +69,36 @@ hwmon: hwmon@45 {
 	};
 };
 
+&irqmux {
+	interrupt-map = <0 &plic 13>, <1 &plic 14>, <2 &plic 15>,
+			<3 &plic 16>, <4 &plic 17>, <5 &plic 18>,
+			<6 &plic 19>, <7 &plic 20>, <8 &plic 21>,
+			<9 &plic 22>, <10 &plic 23>, <11 &plic 24>,
+			<12 &plic 25>, <13 &plic 26>,
+
+			<32 &plic 27>, <33 &plic 28>, <34 &plic 29>,
+			<35 &plic 30>, <36 &plic 31>, <37 &plic 32>,
+			<38 &plic 33>, <39 &plic 34>, <40 &plic 35>,
+			<41 &plic 36>, <42 &plic 37>, <43 &plic 38>,
+			<44 &plic 39>, <45 &plic 40>, <46 &plic 41>,
+			<47 &plic 42>, <48 &plic 43>, <49 &plic 44>,
+			<50 &plic 45>, <51 &plic 46>, <52 &plic 47>,
+			<53 &plic 48>, <54 &plic 49>, <55 &plic 50>,
+
+			<64 &plic 53>, <65 &plic 53>, <66 &plic 53>,
+			<67 &plic 53>, <68 &plic 53>, <69 &plic 53>,
+			<70 &plic 53>, <71 &plic 53>, <72 &plic 53>,
+			<73 &plic 53>, <74 &plic 53>, <75 &plic 53>,
+			<76 &plic 53>, <77 &plic 53>, <78 &plic 53>,
+			<79 &plic 53>, <80 &plic 53>, <81 &plic 53>,
+			<82 &plic 53>, <83 &plic 53>, <84 &plic 53>,
+			<85 &plic 53>, <86 &plic 53>, <87 &plic 53>,
+			<88 &plic 53>, <89 &plic 53>, <90 &plic 53>,
+			<91 &plic 53>, <92 &plic 53>, <93 &plic 53>,
+			<94 &plic 53>, <95 &plic 53>;
+};
+
 &gpio1 {
-	interrupts = <27>, <28>, <29>, <30>,
-		     <31>, <32>, <33>, <47>,
-		     <35>, <36>, <37>, <38>,
-		     <39>, <40>, <41>, <42>,
-		     <43>, <44>, <45>, <46>,
-		     <47>, <48>, <49>, <50>;
 	status = "okay";
 };
 
diff --git a/arch/riscv/boot/dts/microchip/mpfs.dtsi b/arch/riscv/boot/dts/microchip/mpfs.dtsi
index 5c2963e269b83..4f0d5bdee3da6 100644
--- a/arch/riscv/boot/dts/microchip/mpfs.dtsi
+++ b/arch/riscv/boot/dts/microchip/mpfs.dtsi
@@ -254,7 +254,17 @@ pdma: dma-controller@3000000 {
 		mss_top_sysreg: syscon@20002000 {
 			compatible = "microchip,mpfs-mss-top-sysreg", "syscon", "simple-mfd";
 			reg = <0x0 0x20002000 0x0 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
 			#reset-cells = <1>;
+
+			irqmux: interrupt-controller@54 {
+				compatible = "microchip,mpfs-irqmux";
+				reg = <0x54 0x4>;
+				#address-cells = <0>;
+				#interrupt-cells = <1>;
+				interrupt-map-mask = <0x7f>;
+			};
 		};
 
 		sysreg_scb: syscon@20003000 {
@@ -471,36 +481,57 @@ mac1: ethernet@20112000 {
 		gpio0: gpio@20120000 {
 			compatible = "microchip,mpfs-gpio";
 			reg = <0x0 0x20120000 0x0 0x1000>;
-			interrupt-parent = <&plic>;
+			interrupt-parent = <&irqmux>;
 			interrupt-controller;
 			#interrupt-cells = <1>;
+			interrupts = <0>, <1>, <2>, <3>,
+				     <4>, <5>, <6>, <7>,
+				     <8>, <9>, <10>, <11>,
+				     <12>, <13>;
 			clocks = <&clkcfg CLK_GPIO0>;
 			gpio-controller;
 			#gpio-cells = <2>;
+			ngpios = <14>;
 			status = "disabled";
 		};
 
 		gpio1: gpio@20121000 {
 			compatible = "microchip,mpfs-gpio";
 			reg = <0x0 0x20121000 0x0 0x1000>;
-			interrupt-parent = <&plic>;
+			interrupt-parent = <&irqmux>;
 			interrupt-controller;
 			#interrupt-cells = <1>;
+			interrupts = <32>, <33>, <34>, <35>,
+				     <36>, <37>, <38>, <39>,
+				     <40>, <41>, <42>, <43>,
+				     <44>, <45>, <46>, <47>,
+				     <48>, <49>, <50>, <51>,
+				     <52>, <53>, <54>, <55>;
 			clocks = <&clkcfg CLK_GPIO1>;
 			gpio-controller;
 			#gpio-cells = <2>;
+			ngpios = <24>;
 			status = "disabled";
 		};
 
 		gpio2: gpio@20122000 {
 			compatible = "microchip,mpfs-gpio";
 			reg = <0x0 0x20122000 0x0 0x1000>;
-			interrupt-parent = <&plic>;
+			interrupt-parent = <&irqmux>;
 			interrupt-controller;
 			#interrupt-cells = <1>;
+			interrupts = <64>, <65>, <66>, <67>,
+				     <68>, <69>, <70>, <71>,
+				     <72>, <73>, <74>, <75>,
+				     <76>, <77>, <78>, <79>,
+				     <80>, <81>, <82>, <83>,
+				     <84>, <85>, <86>, <87>,
+				     <88>, <89>, <90>, <91>,
+				     <92>, <93>, <94>, <95>;
 			clocks = <&clkcfg CLK_GPIO2>;
 			gpio-controller;
 			#gpio-cells = <2>;
+			ngpios = <32>;
 			status = "disabled";
 		};
 
-- 
2.51.0


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

* Re: [PATCH v12 3/4] soc: microchip: add mpfs gpio interrupt mux driver
  2026-03-11 15:17 ` [PATCH v12 3/4] soc: microchip: add mpfs gpio interrupt mux driver Conor Dooley
@ 2026-03-11 16:11   ` Herve Codina
  2026-03-16  9:27   ` Linus Walleij
  2026-03-16  9:47   ` Bartosz Golaszewski
  2 siblings, 0 replies; 16+ messages in thread
From: Herve Codina @ 2026-03-11 16:11 UTC (permalink / raw)
  To: Conor Dooley
  Cc: linux-gpio, Conor Dooley, Thomas Gleixner, Daire McNamara,
	Rob Herring, Krzysztof Kozlowski, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Alexandre Ghiti, Linus Walleij, Bartosz Golaszewski,
	linux-riscv, devicetree, linux-kernel

Hi Conor,

On Wed, 11 Mar 2026 15:17:40 +0000
Conor Dooley <conor@kernel.org> wrote:

> From: Conor Dooley <conor.dooley@microchip.com>
> 
> On PolarFire SoC there are more GPIO interrupts than there are interrupt
> lines available on the PLIC, and a runtime configurable mux is used to
> decide which interrupts are assigned direct connections to the PLIC &
> which are relegated to sharing a line.
> 
> Add a driver so that Linux can set the mux based on the interrupt
> mapping in the devicetree.
> 
> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
> ---
>  MAINTAINERS                         |   2 +-
>  drivers/soc/microchip/Kconfig       |  11 ++
>  drivers/soc/microchip/Makefile      |   1 +
>  drivers/soc/microchip/mpfs-irqmux.c | 181 ++++++++++++++++++++++++++++
>  4 files changed, 194 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/soc/microchip/mpfs-irqmux.c
> 

Looks good.

Reviewed-by: Herve Codina <herve.codina@bootlin.com>

Best regards,
Hervé


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

* Re: [PATCH v12 2/4] dt-bindings: soc: microchip: document PolarFire SoC's gpio interrupt mux
  2026-03-11 15:17 ` [PATCH v12 2/4] dt-bindings: soc: microchip: document PolarFire SoC's gpio interrupt mux Conor Dooley
@ 2026-03-11 16:41   ` Rob Herring (Arm)
  2026-03-11 17:58     ` Conor Dooley
  0 siblings, 1 reply; 16+ messages in thread
From: Rob Herring (Arm) @ 2026-03-11 16:41 UTC (permalink / raw)
  To: Conor Dooley
  Cc: Albert Ou, Daire McNamara, devicetree, Krzysztof Kozlowski,
	Palmer Dabbelt, linux-riscv, Alexandre Ghiti, Linus Walleij,
	Bartosz Golaszewski, Paul Walmsley, Herve Codina, linux-gpio,
	Conor Dooley, Thomas Gleixner, linux-kernel


On Wed, 11 Mar 2026 15:17:39 +0000, Conor Dooley wrote:
> From: Conor Dooley <conor.dooley@microchip.com>
> 
> On PolarFire SoC there are more GPIO interrupts than there are interrupt
> lines available on the PLIC, and a runtime configurable mux is used to
> decide which interrupts are assigned direct connections to the PLIC &
> which are relegated to sharing a line.
> 
> Reviewed-by: Herve Codina <herve.codina@bootlin.com>
> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
> ---
>  .../soc/microchip/microchip,mpfs-irqmux.yaml  | 77 +++++++++++++++++++
>  .../microchip,mpfs-mss-top-sysreg.yaml        |  4 +
>  2 files changed, 81 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.yaml
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.example.dts:18.33-24.11: Warning (interrupt_provider): /example-0/interrupt-controller@54: '#interrupt-cells' found, but node is not an interrupt provider
Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.example.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.example.dtb: interrupt-controller@54 (microchip,mpfs-irqmux): interrupt-map-mask:0: 127 was expected
	from schema $id: http://devicetree.org/schemas/soc/microchip/microchip,mpfs-irqmux.yaml
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.example.dtb: interrupt-controller@54 (microchip,mpfs-irqmux): 'interrupt-map' is a required property
	from schema $id: http://devicetree.org/schemas/soc/microchip/microchip,mpfs-irqmux.yaml
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.example.dtb: interrupt-controller@54 (microchip,mpfs-irqmux): 'interrupt-map' is a dependency of 'interrupt-map-mask'
	from schema $id: http://devicetree.org/schemas/interrupt-controller.yaml
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.example.dtb: interrupt-controller@54 (microchip,mpfs-irqmux): 'anyOf' conditional failed, one must be fixed:
	'interrupt-controller' is a required property
	'interrupt-map' is a required property
	from schema $id: http://devicetree.org/schemas/interrupt-controller.yaml

doc reference errors (make refcheckdocs):

See https://patchwork.kernel.org/project/devicetree/patch/20260311-collar-smokiness-5313aa648a6f@spud

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.


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

* Re: [PATCH v12 2/4] dt-bindings: soc: microchip: document PolarFire SoC's gpio interrupt mux
  2026-03-11 16:41   ` Rob Herring (Arm)
@ 2026-03-11 17:58     ` Conor Dooley
  2026-03-11 19:44       ` Rob Herring
  0 siblings, 1 reply; 16+ messages in thread
From: Conor Dooley @ 2026-03-11 17:58 UTC (permalink / raw)
  To: Rob Herring (Arm)
  Cc: Albert Ou, Daire McNamara, devicetree, Krzysztof Kozlowski,
	Palmer Dabbelt, linux-riscv, Alexandre Ghiti, Linus Walleij,
	Bartosz Golaszewski, Paul Walmsley, Herve Codina, linux-gpio,
	Conor Dooley, Thomas Gleixner, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 3563 bytes --]

Rob,

On Wed, Mar 11, 2026 at 11:41:17AM -0500, Rob Herring (Arm) wrote:
> 
> On Wed, 11 Mar 2026 15:17:39 +0000, Conor Dooley wrote:
> > From: Conor Dooley <conor.dooley@microchip.com>
> > 
> > On PolarFire SoC there are more GPIO interrupts than there are interrupt
> > lines available on the PLIC, and a runtime configurable mux is used to
> > decide which interrupts are assigned direct connections to the PLIC &
> > which are relegated to sharing a line.
> > 
> > Reviewed-by: Herve Codina <herve.codina@bootlin.com>
> > Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
> > ---
> >  .../soc/microchip/microchip,mpfs-irqmux.yaml  | 77 +++++++++++++++++++
> >  .../microchip,mpfs-mss-top-sysreg.yaml        |  4 +
> >  2 files changed, 81 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.yaml
> > 
> 
> My bot found errors running 'make dt_binding_check' on your patch:

AAAAAAAAA, goddammit. I forgot there was a reason why I had not just
sent off the new version of the series.

> yamllint warnings/errors:
> 
> dtschema/dtc warnings/errors:
> Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.example.dts:18.33-24.11: Warning (interrupt_provider): /example-0/interrupt-controller@54: '#interrupt-cells' found, but node is not an interrupt provider
> Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.example.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'

I wanted to ask about this Rob, I wasn't sure I fully understood it.
I figured it was because...


> /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.example.dtb: interrupt-controller@54 (microchip,mpfs-irqmux): 'interrupt-map' is a required property
> 	from schema $id: http://devicetree.org/schemas/soc/microchip/microchip,mpfs-irqmux.yaml

...I had not added the interrupt-map yet...

> /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.example.dtb: interrupt-controller@54 (microchip,mpfs-irqmux): 'interrupt-map' is a dependency of 'interrupt-map-mask'
> 	from schema $id: http://devicetree.org/schemas/interrupt-controller.yaml
> /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.example.dtb: interrupt-controller@54 (microchip,mpfs-irqmux): 'anyOf' conditional failed, one must be fixed:
> 	'interrupt-controller' is a required property
> 	'interrupt-map' is a required property
> 	from schema $id: http://devicetree.org/schemas/interrupt-controller.yaml

...so this schema complained. But why is there a custom warning about
"node is not an interrupt provider", when the conditional schema
produces a warning of its own?

> doc reference errors (make refcheckdocs):
> 
> See https://patchwork.kernel.org/project/devicetree/patch/20260311-collar-smokiness-5313aa648a6f@spud
> 
> The base for the series is generally the latest rc1. A different dependency
> should be noted in *this* patch.
> 
> If you already ran 'make dt_binding_check' and didn't see the above
> error(s), then make sure 'yamllint' is installed and dt-schema is up to
> date:
> 
> pip3 install dtschema --upgrade
> 
> Please check and re-submit after running the above command yourself. Note
> that DT_SCHEMA_FILES can be set to your schema file to speed up checking
> your schema. However, it must be unset to test all examples with your schema.
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH v12 2/4] dt-bindings: soc: microchip: document PolarFire SoC's gpio interrupt mux
  2026-03-11 17:58     ` Conor Dooley
@ 2026-03-11 19:44       ` Rob Herring
  0 siblings, 0 replies; 16+ messages in thread
From: Rob Herring @ 2026-03-11 19:44 UTC (permalink / raw)
  To: Conor Dooley
  Cc: Albert Ou, Daire McNamara, devicetree, Krzysztof Kozlowski,
	Palmer Dabbelt, linux-riscv, Alexandre Ghiti, Linus Walleij,
	Bartosz Golaszewski, Paul Walmsley, Herve Codina, linux-gpio,
	Conor Dooley, Thomas Gleixner, linux-kernel

On Wed, Mar 11, 2026 at 12:58 PM Conor Dooley <conor@kernel.org> wrote:
>
> Rob,
>
> On Wed, Mar 11, 2026 at 11:41:17AM -0500, Rob Herring (Arm) wrote:
> >
> > On Wed, 11 Mar 2026 15:17:39 +0000, Conor Dooley wrote:
> > > From: Conor Dooley <conor.dooley@microchip.com>
> > >
> > > On PolarFire SoC there are more GPIO interrupts than there are interrupt
> > > lines available on the PLIC, and a runtime configurable mux is used to
> > > decide which interrupts are assigned direct connections to the PLIC &
> > > which are relegated to sharing a line.
> > >
> > > Reviewed-by: Herve Codina <herve.codina@bootlin.com>
> > > Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
> > > ---
> > >  .../soc/microchip/microchip,mpfs-irqmux.yaml  | 77 +++++++++++++++++++
> > >  .../microchip,mpfs-mss-top-sysreg.yaml        |  4 +
> > >  2 files changed, 81 insertions(+)
> > >  create mode 100644 Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.yaml
> > >
> >
> > My bot found errors running 'make dt_binding_check' on your patch:
>
> AAAAAAAAA, goddammit. I forgot there was a reason why I had not just
> sent off the new version of the series.

Providing reviews of bindings entitles you to free testing of your patches. :)

> > yamllint warnings/errors:
> >
> > dtschema/dtc warnings/errors:
> > Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.example.dts:18.33-24.11: Warning (interrupt_provider): /example-0/interrupt-controller@54: '#interrupt-cells' found, but node is not an interrupt provider
> > Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.example.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
>
> I wanted to ask about this Rob, I wasn't sure I fully understood it.
> I figured it was because...
>
>
> > /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.example.dtb: interrupt-controller@54 (microchip,mpfs-irqmux): 'interrupt-map' is a required property
> >       from schema $id: http://devicetree.org/schemas/soc/microchip/microchip,mpfs-irqmux.yaml
>
> ...I had not added the interrupt-map yet...

Yes.

> > /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.example.dtb: interrupt-controller@54 (microchip,mpfs-irqmux): 'interrupt-map' is a dependency of 'interrupt-map-mask'
> >       from schema $id: http://devicetree.org/schemas/interrupt-controller.yaml
> > /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.example.dtb: interrupt-controller@54 (microchip,mpfs-irqmux): 'anyOf' conditional failed, one must be fixed:
> >       'interrupt-controller' is a required property
> >       'interrupt-map' is a required property
> >       from schema $id: http://devicetree.org/schemas/interrupt-controller.yaml
>
> ...so this schema complained. But why is there a custom warning about
> "node is not an interrupt provider", when the conditional schema
> produces a warning of its own?

The first warning is from dtc. There is some overlap with schema checks.

Rob

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

* Re: [PATCH v12 1/4] gpio: mpfs: Add interrupt support
  2026-03-11 15:17 ` [PATCH v12 1/4] gpio: mpfs: Add " Conor Dooley
@ 2026-03-16  9:06   ` Bartosz Golaszewski
  2026-03-16  9:22   ` Linus Walleij
  1 sibling, 0 replies; 16+ messages in thread
From: Bartosz Golaszewski @ 2026-03-16  9:06 UTC (permalink / raw)
  To: Conor Dooley
  Cc: Conor Dooley, Thomas Gleixner, Herve Codina, Daire McNamara,
	Rob Herring, Krzysztof Kozlowski, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Alexandre Ghiti, Linus Walleij, Bartosz Golaszewski,
	linux-riscv, devicetree, linux-kernel, linux-gpio

On Wed, 11 Mar 2026 16:17:38 +0100, Conor Dooley <conor@kernel.org> said:
> From: Conor Dooley <conor.dooley@microchip.com>
>
> Add support for interrupts to the PolarFire SoC GPIO driver. Each GPIO
> has an independent interrupt that is wired to an interrupt mux that sits
> between the controllers and the PLIC. The SoC has more GPIO lines than
> connections from the mux to the PLIC, so some GPIOs must share PLIC
> interrupts. The configuration is not static and is set at runtime,
> conventionally by the platform's firmware. CoreGPIO, the version
> intended for use in the FPGA fabric has two interrupt output ports, one
> is IO_NUM bits wide, as is used in the hardened cores, and the other is
> a single bit with all lines ORed together.
>
> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
> ---

Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>

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

* Re: [PATCH v12 1/4] gpio: mpfs: Add interrupt support
  2026-03-11 15:17 ` [PATCH v12 1/4] gpio: mpfs: Add " Conor Dooley
  2026-03-16  9:06   ` Bartosz Golaszewski
@ 2026-03-16  9:22   ` Linus Walleij
  1 sibling, 0 replies; 16+ messages in thread
From: Linus Walleij @ 2026-03-16  9:22 UTC (permalink / raw)
  To: Conor Dooley
  Cc: linux-gpio, Conor Dooley, Thomas Gleixner, Herve Codina,
	Daire McNamara, Rob Herring, Krzysztof Kozlowski, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Bartosz Golaszewski,
	linux-riscv, devicetree, linux-kernel

On Wed, Mar 11, 2026 at 4:17 PM Conor Dooley <conor@kernel.org> wrote:

> From: Conor Dooley <conor.dooley@microchip.com>
>
> Add support for interrupts to the PolarFire SoC GPIO driver. Each GPIO
> has an independent interrupt that is wired to an interrupt mux that sits
> between the controllers and the PLIC. The SoC has more GPIO lines than
> connections from the mux to the PLIC, so some GPIOs must share PLIC
> interrupts. The configuration is not static and is set at runtime,
> conventionally by the platform's firmware. CoreGPIO, the version
> intended for use in the FPGA fabric has two interrupt output ports, one
> is IO_NUM bits wide, as is used in the hardened cores, and the other is
> a single bit with all lines ORed together.
>
> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>

It's a beauty.
Reviewed-by: Linus Walleij <linusw@kernel.org>

Yours,
Linus Walleij

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

* Re: [PATCH v12 3/4] soc: microchip: add mpfs gpio interrupt mux driver
  2026-03-11 15:17 ` [PATCH v12 3/4] soc: microchip: add mpfs gpio interrupt mux driver Conor Dooley
  2026-03-11 16:11   ` Herve Codina
@ 2026-03-16  9:27   ` Linus Walleij
  2026-03-16 10:59     ` Conor Dooley
  2026-03-16  9:47   ` Bartosz Golaszewski
  2 siblings, 1 reply; 16+ messages in thread
From: Linus Walleij @ 2026-03-16  9:27 UTC (permalink / raw)
  To: Conor Dooley
  Cc: linux-gpio, Conor Dooley, Thomas Gleixner, Herve Codina,
	Daire McNamara, Rob Herring, Krzysztof Kozlowski, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Bartosz Golaszewski,
	linux-riscv, devicetree, linux-kernel

On Wed, Mar 11, 2026 at 4:18 PM Conor Dooley <conor@kernel.org> wrote:

> From: Conor Dooley <conor.dooley@microchip.com>
>
> On PolarFire SoC there are more GPIO interrupts than there are interrupt
> lines available on the PLIC, and a runtime configurable mux is used to
> decide which interrupts are assigned direct connections to the PLIC &
> which are relegated to sharing a line.
>
> Add a driver so that Linux can set the mux based on the interrupt
> mapping in the devicetree.
>
> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>

Reviewed-by: Linus Walleij <linusw@kernel.org>

We need a piece of accessible documentation that clearly defines
the difference between an IRQ mux and a hierarchical IRQ chip.
If only a post on people.kernel.org, just something to help people
to know when to use which approach.

Yours,
Linus Walleij

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

* Re: [PATCH v12 4/4] riscv: dts: microchip: update mpfs gpio interrupts to better match the SoC
  2026-03-11 15:17 ` [PATCH v12 4/4] riscv: dts: microchip: update mpfs gpio interrupts to better match the SoC Conor Dooley
@ 2026-03-16  9:27   ` Linus Walleij
  0 siblings, 0 replies; 16+ messages in thread
From: Linus Walleij @ 2026-03-16  9:27 UTC (permalink / raw)
  To: Conor Dooley
  Cc: linux-gpio, Conor Dooley, Thomas Gleixner, Herve Codina,
	Daire McNamara, Rob Herring, Krzysztof Kozlowski, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Bartosz Golaszewski,
	linux-riscv, devicetree, linux-kernel

On Wed, Mar 11, 2026 at 4:18 PM Conor Dooley <conor@kernel.org> wrote:

> From: Conor Dooley <conor.dooley@microchip.com>
>
> There are 3 GPIO controllers on this SoC, of which:
> - GPIO controller 0 has 14 GPIOs
> - GPIO controller 1 has 24 GPIOs
> - GPIO controller 2 has 32 GPIOs
>
> All GPIOs are capable of generating interrupts, for a total of 70.
> There are only 41 IRQs available however, so a configurable mux is used
> to ensure all GPIOs can be used for interrupt generation.
> 38 of the 41 interrupts are in what the documentation calls "direct
> mode", as they provide an exclusive connection from a GPIO to the PLIC.
> The 3 remaining interrupts are used to mux the interrupts which do not
> have a exclusive connection, one for each GPIO controller.
>
> The mux was overlooked when the bindings and driver were originally
> written for the GPIO controllers on Polarfire SoC, and the interrupts
> property in the GPIO nodes used to try and convey what the mapping was.
> Instead, the mux should be a device in its own right, and the GPIO
> controllers should be connected to it, rather than to the PLIC.
> Now that a binding exists for that mux, fix the inaccurate description
> of the interrupt controller hierarchy.
>
> GPIO controllers 0 and 1 do not have all 32 possible GPIO lines, so
> ngpios needs to be set to match the number of lines/interrupts.
>
> The m100pfsevp has conflicting interrupt mappings for controllers 0 and
> 2, as they cannot both be using an interrupt in "direct mode" at the
> same time, so the default replaces this impossible configuration.
>
> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>

Reviewed-by: Linus Walleij <linusw@kernel.org>

Yours,
Linus Walleij

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

* Re: [PATCH v12 3/4] soc: microchip: add mpfs gpio interrupt mux driver
  2026-03-11 15:17 ` [PATCH v12 3/4] soc: microchip: add mpfs gpio interrupt mux driver Conor Dooley
  2026-03-11 16:11   ` Herve Codina
  2026-03-16  9:27   ` Linus Walleij
@ 2026-03-16  9:47   ` Bartosz Golaszewski
  2 siblings, 0 replies; 16+ messages in thread
From: Bartosz Golaszewski @ 2026-03-16  9:47 UTC (permalink / raw)
  To: Conor Dooley
  Cc: linux-gpio, Conor Dooley, Thomas Gleixner, Herve Codina,
	Daire McNamara, Rob Herring, Krzysztof Kozlowski, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Linus Walleij,
	linux-riscv, devicetree, linux-kernel

On Wed, Mar 11, 2026 at 4:18 PM Conor Dooley <conor@kernel.org> wrote:
>
> From: Conor Dooley <conor.dooley@microchip.com>
>
> On PolarFire SoC there are more GPIO interrupts than there are interrupt
> lines available on the PLIC, and a runtime configurable mux is used to
> decide which interrupts are assigned direct connections to the PLIC &
> which are relegated to sharing a line.
>
> Add a driver so that Linux can set the mux based on the interrupt
> mapping in the devicetree.
>
> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
> ---

Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>

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

* Re: [PATCH v12 3/4] soc: microchip: add mpfs gpio interrupt mux driver
  2026-03-16  9:27   ` Linus Walleij
@ 2026-03-16 10:59     ` Conor Dooley
  2026-03-19 13:37       ` Linus Walleij
  0 siblings, 1 reply; 16+ messages in thread
From: Conor Dooley @ 2026-03-16 10:59 UTC (permalink / raw)
  To: Linus Walleij
  Cc: linux-gpio, Conor Dooley, Thomas Gleixner, Herve Codina,
	Daire McNamara, Rob Herring, Krzysztof Kozlowski, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Bartosz Golaszewski,
	linux-riscv, devicetree, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1438 bytes --]

On Mon, Mar 16, 2026 at 10:27:15AM +0100, Linus Walleij wrote:
> On Wed, Mar 11, 2026 at 4:18 PM Conor Dooley <conor@kernel.org> wrote:
> 
> > From: Conor Dooley <conor.dooley@microchip.com>
> >
> > On PolarFire SoC there are more GPIO interrupts than there are interrupt
> > lines available on the PLIC, and a runtime configurable mux is used to
> > decide which interrupts are assigned direct connections to the PLIC &
> > which are relegated to sharing a line.
> >
> > Add a driver so that Linux can set the mux based on the interrupt
> > mapping in the devicetree.
> >
> > Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
> 
> Reviewed-by: Linus Walleij <linusw@kernel.org>
> 
> We need a piece of accessible documentation that clearly defines
> the difference between an IRQ mux and a hierarchical IRQ chip.
> If only a post on people.kernel.org, just something to help people
> to know when to use which approach.

I'm guessing you're not looking for looking for me to be the arbiter,
but I'd say that the muxing aspect is pretty important!
On a serious note though, the lack of anything in the hardware to do
masking etc is key, it'd have to be nothing more than a register that
determines routing.
That said, even the simplest mux should be an irqchip if reconfiguration
after probe is to be supported.
That'd make the delimiter "a simple mux that you set at probe and never
touch again"?

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH v12 3/4] soc: microchip: add mpfs gpio interrupt mux driver
  2026-03-16 10:59     ` Conor Dooley
@ 2026-03-19 13:37       ` Linus Walleij
  0 siblings, 0 replies; 16+ messages in thread
From: Linus Walleij @ 2026-03-19 13:37 UTC (permalink / raw)
  To: Conor Dooley
  Cc: linux-gpio, Conor Dooley, Thomas Gleixner, Herve Codina,
	Daire McNamara, Rob Herring, Krzysztof Kozlowski, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Bartosz Golaszewski,
	linux-riscv, devicetree, linux-kernel

On Mon, Mar 16, 2026 at 11:59 AM Conor Dooley <conor@kernel.org> wrote:

> I'm guessing you're not looking for looking for me to be the arbiter,
> but I'd say that the muxing aspect is pretty important!
> On a serious note though, the lack of anything in the hardware to do
> masking etc is key, it'd have to be nothing more than a register that
> determines routing.
> That said, even the simplest mux should be an irqchip if reconfiguration
> after probe is to be supported.
> That'd make the delimiter "a simple mux that you set at probe and never
> touch again"?

This definition works for me, as maintainer I really want to be
able to determine how a contribution should look for each case.

Yours,
Linus Walleij

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

end of thread, other threads:[~2026-03-19 13:38 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-11 15:17 [PATCH v12 0/4] PolarFire SoC GPIO interrupt support Conor Dooley
2026-03-11 15:17 ` [PATCH v12 1/4] gpio: mpfs: Add " Conor Dooley
2026-03-16  9:06   ` Bartosz Golaszewski
2026-03-16  9:22   ` Linus Walleij
2026-03-11 15:17 ` [PATCH v12 2/4] dt-bindings: soc: microchip: document PolarFire SoC's gpio interrupt mux Conor Dooley
2026-03-11 16:41   ` Rob Herring (Arm)
2026-03-11 17:58     ` Conor Dooley
2026-03-11 19:44       ` Rob Herring
2026-03-11 15:17 ` [PATCH v12 3/4] soc: microchip: add mpfs gpio interrupt mux driver Conor Dooley
2026-03-11 16:11   ` Herve Codina
2026-03-16  9:27   ` Linus Walleij
2026-03-16 10:59     ` Conor Dooley
2026-03-19 13:37       ` Linus Walleij
2026-03-16  9:47   ` Bartosz Golaszewski
2026-03-11 15:17 ` [PATCH v12 4/4] riscv: dts: microchip: update mpfs gpio interrupts to better match the SoC Conor Dooley
2026-03-16  9:27   ` Linus Walleij

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox