Skip to content

Commit ecaf3a9

Browse files
committed
Merge tag 'riscv-soc-drivers-for-v7.1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/conor/linux into soc/drivers
RISC-V soc drivers for v7.1 Microchip: Add coverage for the pic64gx in the system controller and syscons. Add a interrupt mux driver (akin to the one that Renesas recently added) that fixes a problem where the platform never properly modelled gpio interrupts. There's a gpio driver change here that Bartosz has acked that adds the interrupt support to the GPIO driver itself. Signed-off-by: Conor Dooley <conor.dooley@microchip.com> * tag 'riscv-soc-drivers-for-v7.1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/conor/linux: soc: microchip: add mpfs gpio interrupt mux driver dt-bindings: soc: microchip: document PolarFire SoC's gpio interrupt mux gpio: mpfs: Add interrupt support soc: microchip: mpfs-sys-controller: add support for pic64gx dt-bindings: soc: microchip: mpfs-sys-controller: Add pic64gx compatibility dt-bindings: soc: microchip: add compatible for the mss-top-sysreg on pic64gx Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
2 parents 98bc768 + bd34cdd commit ecaf3a9

10 files changed

Lines changed: 488 additions & 29 deletions

File tree

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+
%YAML 1.2
3+
---
4+
$id: http://devicetree.org/schemas/soc/microchip/microchip,mpfs-irqmux.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: Microchip Polarfire SoC GPIO Interrupt Mux
8+
9+
maintainers:
10+
- Conor Dooley <conor.dooley@microchip.com>
11+
12+
description: |
13+
There are 3 GPIO controllers on this SoC, of which:
14+
- GPIO controller 0 has 14 GPIOs
15+
- GPIO controller 1 has 24 GPIOs
16+
- GPIO controller 2 has 32 GPIOs
17+
18+
All GPIOs are capable of generating interrupts, for a total of 70.
19+
There are only 41 IRQs available however, so a configurable mux is used to
20+
ensure all GPIOs can be used for interrupt generation.
21+
38 of the 41 interrupts are in what the documentation calls "direct mode",
22+
as they provide an exclusive connection from a GPIO to the PLIC.
23+
Lines 18 to 23 on GPIO controller 1 are always in "direct mode".
24+
The 3 remaining interrupts are used to mux the interrupts which do not have
25+
a exclusive connection, one for each GPIO controller.
26+
27+
properties:
28+
compatible:
29+
const: microchip,mpfs-irqmux
30+
31+
reg:
32+
maxItems: 1
33+
34+
"#address-cells":
35+
const: 0
36+
37+
"#interrupt-cells":
38+
const: 1
39+
40+
interrupt-map-mask:
41+
items:
42+
- const: 0x7f
43+
44+
interrupt-map:
45+
description: |
46+
Specifies the mapping from GPIO interrupt lines to plic interrupts.
47+
48+
The child interrupt number set in arrays items is computed using the
49+
following formula:
50+
gpio_bank * 32 + gpio_number
51+
with:
52+
- gpio_bank: The GPIO bank number
53+
- 0 for GPIO0,
54+
- 1 for GPIO1,
55+
- 2 for GPIO2
56+
- gpio_number: Number of the gpio in the bank (0..31)
57+
maxItems: 70
58+
59+
required:
60+
- compatible
61+
- reg
62+
- "#address-cells"
63+
- "#interrupt-cells"
64+
- interrupt-map-mask
65+
- interrupt-map
66+
67+
additionalProperties: false
68+
69+
examples:
70+
- |
71+
interrupt-controller@54 {
72+
compatible = "microchip,mpfs-irqmux";
73+
reg = <0x54 0x4>;
74+
#address-cells = <0>;
75+
#interrupt-cells = <1>;
76+
interrupt-map-mask = <0x7f>;
77+
interrupt-map = <0 &plic 13>, <1 &plic 14>, <2 &plic 15>,
78+
<3 &plic 16>, <4 &plic 17>, <5 &plic 18>,
79+
<6 &plic 19>, <7 &plic 20>, <8 &plic 21>,
80+
<9 &plic 22>, <10 &plic 23>, <11 &plic 24>,
81+
<12 &plic 25>, <13 &plic 26>,
82+
83+
<32 &plic 27>, <33 &plic 28>, <34 &plic 29>,
84+
<35 &plic 30>, <36 &plic 31>, <37 &plic 32>,
85+
<38 &plic 33>, <39 &plic 34>, <40 &plic 35>,
86+
<41 &plic 36>, <42 &plic 37>, <43 &plic 38>,
87+
<44 &plic 39>, <45 &plic 40>, <46 &plic 41>,
88+
<47 &plic 42>, <48 &plic 43>, <49 &plic 44>,
89+
<50 &plic 45>, <51 &plic 46>, <52 &plic 47>,
90+
<53 &plic 48>, <54 &plic 49>, <55 &plic 50>,
91+
92+
<64 &plic 53>, <65 &plic 53>, <66 &plic 53>,
93+
<67 &plic 53>, <68 &plic 53>, <69 &plic 53>,
94+
<70 &plic 53>, <71 &plic 53>, <72 &plic 53>,
95+
<73 &plic 53>, <74 &plic 53>, <75 &plic 53>,
96+
<76 &plic 53>, <77 &plic 53>, <78 &plic 53>,
97+
<79 &plic 53>, <80 &plic 53>, <81 &plic 53>,
98+
<82 &plic 53>, <83 &plic 53>, <84 &plic 53>,
99+
<85 &plic 53>, <86 &plic 53>, <87 &plic 53>,
100+
<88 &plic 53>, <89 &plic 53>, <90 &plic 53>,
101+
<91 &plic 53>, <92 &plic 53>, <93 &plic 53>,
102+
<94 &plic 53>, <95 &plic 53>;
103+
};

Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-mss-top-sysreg.yaml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,16 @@ description:
1515

1616
properties:
1717
compatible:
18-
items:
19-
- const: microchip,mpfs-mss-top-sysreg
20-
- const: syscon
21-
- const: simple-mfd
18+
oneOf:
19+
- items:
20+
- const: microchip,mpfs-mss-top-sysreg
21+
- const: syscon
22+
- const: simple-mfd
23+
- items:
24+
- const: microchip,pic64gx-mss-top-sysreg
25+
- const: microchip,mpfs-mss-top-sysreg
26+
- const: syscon
27+
- const: simple-mfd
2228

2329
reg:
2430
maxItems: 1
@@ -38,6 +44,10 @@ properties:
3844
of PolarFire clock/reset IDs.
3945
const: 1
4046

47+
interrupt-controller@54:
48+
type: object
49+
$ref: /schemas/soc/microchip/microchip,mpfs-irqmux.yaml
50+
4151
pinctrl@200:
4252
type: object
4353
$ref: /schemas/pinctrl/microchip,mpfs-pinctrl-iomux0.yaml

Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-sys-controller.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ properties:
2424
maxItems: 1
2525

2626
compatible:
27-
const: microchip,mpfs-sys-controller
27+
enum:
28+
- microchip,mpfs-sys-controller
29+
- microchip,pic64gx-sys-controller
2830

2931
microchip,bitstream-flash:
3032
$ref: /schemas/types.yaml#/definitions/phandle

MAINTAINERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22733,7 +22733,7 @@ F: Documentation/devicetree/bindings/pinctrl/microchip,mpfs-pinctrl-mssio.yaml
2273322733
F: Documentation/devicetree/bindings/pinctrl/microchip,pic64gx-pinctrl-gpio2.yaml
2273422734
F: Documentation/devicetree/bindings/pwm/microchip,corepwm.yaml
2273522735
F: Documentation/devicetree/bindings/riscv/microchip.yaml
22736-
F: Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-sys-controller.yaml
22736+
F: Documentation/devicetree/bindings/soc/microchip/microchip,mpfs*.yaml
2273722737
F: Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml
2273822738
F: Documentation/devicetree/bindings/usb/microchip,mpfs-musb.yaml
2273922739
F: arch/riscv/boot/dts/microchip/

drivers/gpio/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,7 @@ config GPIO_PL061
572572
config GPIO_POLARFIRE_SOC
573573
bool "Microchip FPGA GPIO support"
574574
select REGMAP_MMIO
575+
select GPIOLIB_IRQCHIP
575576
help
576577
Say yes here to support the GPIO controllers on Microchip FPGAs.
577578

drivers/gpio/gpio-mpfs.c

Lines changed: 119 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,17 @@
99
#include <linux/device.h>
1010
#include <linux/errno.h>
1111
#include <linux/gpio/driver.h>
12-
#include <linux/init.h>
12+
#include <linux/interrupt.h>
1313
#include <linux/mod_devicetable.h>
14+
#include <linux/of_irq.h>
1415
#include <linux/platform_device.h>
1516
#include <linux/property.h>
1617
#include <linux/regmap.h>
1718
#include <linux/spinlock.h>
1819

1920
#define MPFS_GPIO_CTRL(i) (0x4 * (i))
2021
#define MPFS_MAX_NUM_GPIO 32
21-
#define MPFS_GPIO_EN_INT 3
22+
#define MPFS_GPIO_EN_INT BIT(3)
2223
#define MPFS_GPIO_EN_OUT_BUF BIT(2)
2324
#define MPFS_GPIO_EN_IN BIT(1)
2425
#define MPFS_GPIO_EN_OUT BIT(0)
@@ -52,6 +53,7 @@ static const struct regmap_config mpfs_gpio_regmap_config = {
5253
.reg_bits = 32,
5354
.reg_stride = 4,
5455
.val_bits = 32,
56+
.use_raw_spinlock = true,
5557
};
5658

5759
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
114116
return ret;
115117
}
116118

119+
static int mpfs_gpio_irq_set_type(struct irq_data *data, unsigned int type)
120+
{
121+
struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
122+
struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
123+
int gpio_index = irqd_to_hwirq(data) % 32;
124+
u32 interrupt_type;
125+
126+
switch (type) {
127+
case IRQ_TYPE_EDGE_BOTH:
128+
interrupt_type = MPFS_GPIO_TYPE_INT_EDGE_BOTH;
129+
break;
130+
case IRQ_TYPE_EDGE_FALLING:
131+
interrupt_type = MPFS_GPIO_TYPE_INT_EDGE_NEG;
132+
break;
133+
case IRQ_TYPE_EDGE_RISING:
134+
interrupt_type = MPFS_GPIO_TYPE_INT_EDGE_POS;
135+
break;
136+
case IRQ_TYPE_LEVEL_HIGH:
137+
interrupt_type = MPFS_GPIO_TYPE_INT_LEVEL_HIGH;
138+
break;
139+
case IRQ_TYPE_LEVEL_LOW:
140+
interrupt_type = MPFS_GPIO_TYPE_INT_LEVEL_LOW;
141+
break;
142+
}
143+
144+
regmap_update_bits(mpfs_gpio->regs, MPFS_GPIO_CTRL(gpio_index),
145+
MPFS_GPIO_TYPE_INT_MASK, interrupt_type);
146+
147+
return 0;
148+
}
149+
150+
static void mpfs_gpio_irq_unmask(struct irq_data *data)
151+
{
152+
struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
153+
struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
154+
int gpio_index = irqd_to_hwirq(data) % 32;
155+
156+
gpiochip_enable_irq(gc, gpio_index);
157+
mpfs_gpio_direction_input(gc, gpio_index);
158+
regmap_update_bits(mpfs_gpio->regs, MPFS_GPIO_CTRL(gpio_index),
159+
MPFS_GPIO_EN_INT, MPFS_GPIO_EN_INT);
160+
}
161+
162+
static void mpfs_gpio_irq_mask(struct irq_data *data)
163+
{
164+
struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
165+
struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
166+
int gpio_index = irqd_to_hwirq(data) % 32;
167+
168+
regmap_update_bits(mpfs_gpio->regs, MPFS_GPIO_CTRL(gpio_index),
169+
MPFS_GPIO_EN_INT, 0);
170+
gpiochip_disable_irq(gc, gpio_index);
171+
}
172+
173+
static const struct irq_chip mpfs_gpio_irqchip = {
174+
.name = "MPFS GPIO",
175+
.irq_set_type = mpfs_gpio_irq_set_type,
176+
.irq_mask = mpfs_gpio_irq_mask,
177+
.irq_unmask = mpfs_gpio_irq_unmask,
178+
.flags = IRQCHIP_IMMUTABLE | IRQCHIP_MASK_ON_SUSPEND,
179+
GPIOCHIP_IRQ_RESOURCE_HELPERS,
180+
};
181+
182+
static void mpfs_gpio_irq_handler(struct irq_desc *desc)
183+
{
184+
struct irq_chip *irqchip = irq_desc_get_chip(desc);
185+
struct mpfs_gpio_chip *mpfs_gpio = irq_desc_get_handler_data(desc);
186+
unsigned long status;
187+
u32 val;
188+
int i;
189+
190+
chained_irq_enter(irqchip, desc);
191+
192+
regmap_read(mpfs_gpio->regs, MPFS_IRQ_REG, &val);
193+
status = val;
194+
for_each_set_bit(i, &status, MPFS_MAX_NUM_GPIO) {
195+
regmap_write(mpfs_gpio->regs, MPFS_IRQ_REG, BIT(i));
196+
generic_handle_domain_irq(mpfs_gpio->gc.irq.domain, i);
197+
}
198+
199+
chained_irq_exit(irqchip, desc);
200+
}
201+
117202
static int mpfs_gpio_probe(struct platform_device *pdev)
118203
{
119204
struct device *dev = &pdev->dev;
205+
struct device_node *node = dev->of_node;
120206
struct mpfs_gpio_chip *mpfs_gpio;
207+
struct gpio_irq_chip *girq;
121208
struct clk *clk;
122209
void __iomem *base;
123-
int ngpios;
210+
int ngpios, nirqs, ret;
124211

125212
mpfs_gpio = devm_kzalloc(dev, sizeof(*mpfs_gpio), GFP_KERNEL);
126213
if (!mpfs_gpio)
@@ -157,6 +244,35 @@ static int mpfs_gpio_probe(struct platform_device *pdev)
157244
mpfs_gpio->gc.parent = dev;
158245
mpfs_gpio->gc.owner = THIS_MODULE;
159246

247+
nirqs = of_irq_count(node);
248+
if (nirqs > MPFS_MAX_NUM_GPIO)
249+
return -ENXIO;
250+
251+
if (nirqs) {
252+
girq = &mpfs_gpio->gc.irq;
253+
254+
gpio_irq_chip_set_chip(girq, &mpfs_gpio_irqchip);
255+
256+
girq->num_parents = nirqs;
257+
girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents,
258+
sizeof(*girq->parents), GFP_KERNEL);
259+
if (!girq->parents)
260+
return -ENOMEM;
261+
262+
for (int i = 0; i < nirqs; i++) {
263+
ret = platform_get_irq(pdev, i);
264+
if (ret < 0)
265+
return ret;
266+
267+
girq->parents[i] = ret;
268+
girq->parent_handler_data = mpfs_gpio;
269+
girq->parent_handler = mpfs_gpio_irq_handler;
270+
}
271+
272+
girq->handler = handle_level_irq;
273+
girq->default_type = IRQ_TYPE_NONE;
274+
}
275+
160276
return devm_gpiochip_add_data(dev, &mpfs_gpio->gc, mpfs_gpio);
161277
}
162278

drivers/soc/microchip/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
config POLARFIRE_SOC_IRQ_MUX
2+
bool "Microchip PolarFire SoC's GPIO IRQ Mux"
3+
depends on ARCH_MICROCHIP
4+
select REGMAP
5+
select REGMAP_MMIO
6+
default y
7+
help
8+
Support for the interrupt mux on Polarfire SoC. It sits between
9+
the GPIO controllers and the PLIC, as only 41 interrupts are shared
10+
between 3 GPIO controllers with a total of 70 interrupts.
11+
112
config POLARFIRE_SOC_SYS_CTRL
213
tristate "Microchip PolarFire SoC (MPFS) system controller support"
314
depends on POLARFIRE_SOC_MAILBOX

drivers/soc/microchip/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
obj-$(CONFIG_POLARFIRE_SOC_IRQ_MUX) += mpfs-irqmux.o
12
obj-$(CONFIG_POLARFIRE_SOC_SYS_CTRL) += mpfs-sys-controller.o
23
obj-$(CONFIG_POLARFIRE_SOC_SYSCONS) += mpfs-control-scb.o mpfs-mss-top-sysreg.o

0 commit comments

Comments
 (0)