Skip to content

Commit 2b0d7ab

Browse files
author
Marc Zyngier
committed
Merge branch irq/renesas-irqc into irq/irqchip-next
* irq/renesas-irqc: : . : New Renesas RZ/G2L IRQC driver from Lad Prabhakar, equipped with : its companion GPIO driver. : . dt-bindings: interrupt-controller: renesas,rzg2l-irqc: Document RZ/V2L SoC gpio: thunderx: Don't directly include asm-generic/msi.h pinctrl: renesas: pinctrl-rzg2l: Add IRQ domain to handle GPIO interrupt dt-bindings: pinctrl: renesas,rzg2l-pinctrl: Document the properties to handle GPIO IRQ gpio: gpiolib: Allow free() callback to be overridden irqchip: Add RZ/G2L IA55 Interrupt Controller driver dt-bindings: interrupt-controller: Add Renesas RZ/G2L Interrupt Controller gpio: Remove dynamic allocation from populate_parent_alloc_arg() Signed-off-by: Marc Zyngier <maz@kernel.org>
2 parents d4a930a + 8cfc90e commit 2b0d7ab

File tree

14 files changed

+863
-106
lines changed

14 files changed

+863
-106
lines changed
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+
%YAML 1.2
3+
---
4+
$id: http://devicetree.org/schemas/interrupt-controller/renesas,rzg2l-irqc.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: Renesas RZ/G2L (and alike SoC's) Interrupt Controller (IA55)
8+
9+
maintainers:
10+
- Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
11+
- Geert Uytterhoeven <geert+renesas@glider.be>
12+
13+
description: |
14+
IA55 performs various interrupt controls including synchronization for the external
15+
interrupts of NMI, IRQ, and GPIOINT and the interrupts of the built-in peripheral
16+
interrupts output by each IP. And it notifies the interrupt to the GIC
17+
- IRQ sense select for 8 external interrupts, mapped to 8 GIC SPI interrupts
18+
- GPIO pins used as external interrupt input pins, mapped to 32 GIC SPI interrupts
19+
- NMI edge select (NMI is not treated as NMI exception and supports fall edge and
20+
stand-up edge detection interrupts)
21+
22+
allOf:
23+
- $ref: /schemas/interrupt-controller.yaml#
24+
25+
properties:
26+
compatible:
27+
items:
28+
- enum:
29+
- renesas,r9a07g044-irqc # RZ/G2{L,LC}
30+
- renesas,r9a07g054-irqc # RZ/V2L
31+
- const: renesas,rzg2l-irqc
32+
33+
'#interrupt-cells':
34+
description: The first cell should contain external interrupt number (IRQ0-7) and the
35+
second cell is used to specify the flag.
36+
const: 2
37+
38+
'#address-cells':
39+
const: 0
40+
41+
interrupt-controller: true
42+
43+
reg:
44+
maxItems: 1
45+
46+
interrupts:
47+
maxItems: 41
48+
49+
clocks:
50+
maxItems: 2
51+
52+
clock-names:
53+
items:
54+
- const: clk
55+
- const: pclk
56+
57+
power-domains:
58+
maxItems: 1
59+
60+
resets:
61+
maxItems: 1
62+
63+
required:
64+
- compatible
65+
- '#interrupt-cells'
66+
- '#address-cells'
67+
- interrupt-controller
68+
- reg
69+
- interrupts
70+
- clocks
71+
- clock-names
72+
- power-domains
73+
- resets
74+
75+
unevaluatedProperties: false
76+
77+
examples:
78+
- |
79+
#include <dt-bindings/interrupt-controller/arm-gic.h>
80+
#include <dt-bindings/clock/r9a07g044-cpg.h>
81+
82+
irqc: interrupt-controller@110a0000 {
83+
compatible = "renesas,r9a07g044-irqc", "renesas,rzg2l-irqc";
84+
reg = <0x110a0000 0x10000>;
85+
#interrupt-cells = <2>;
86+
#address-cells = <0>;
87+
interrupt-controller;
88+
interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
89+
<GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
90+
<GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
91+
<GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
92+
<GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
93+
<GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
94+
<GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
95+
<GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
96+
<GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
97+
<GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>,
98+
<GIC_SPI 445 IRQ_TYPE_LEVEL_HIGH>,
99+
<GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>,
100+
<GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH>,
101+
<GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>,
102+
<GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>,
103+
<GIC_SPI 450 IRQ_TYPE_LEVEL_HIGH>,
104+
<GIC_SPI 451 IRQ_TYPE_LEVEL_HIGH>,
105+
<GIC_SPI 452 IRQ_TYPE_LEVEL_HIGH>,
106+
<GIC_SPI 453 IRQ_TYPE_LEVEL_HIGH>,
107+
<GIC_SPI 454 IRQ_TYPE_LEVEL_HIGH>,
108+
<GIC_SPI 455 IRQ_TYPE_LEVEL_HIGH>,
109+
<GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>,
110+
<GIC_SPI 457 IRQ_TYPE_LEVEL_HIGH>,
111+
<GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>,
112+
<GIC_SPI 459 IRQ_TYPE_LEVEL_HIGH>,
113+
<GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH>,
114+
<GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH>,
115+
<GIC_SPI 462 IRQ_TYPE_LEVEL_HIGH>,
116+
<GIC_SPI 463 IRQ_TYPE_LEVEL_HIGH>,
117+
<GIC_SPI 464 IRQ_TYPE_LEVEL_HIGH>,
118+
<GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>,
119+
<GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>,
120+
<GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>,
121+
<GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>,
122+
<GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>,
123+
<GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH>,
124+
<GIC_SPI 471 IRQ_TYPE_LEVEL_HIGH>,
125+
<GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>,
126+
<GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>,
127+
<GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>,
128+
<GIC_SPI 475 IRQ_TYPE_LEVEL_HIGH>;
129+
clocks = <&cpg CPG_MOD R9A07G044_IA55_CLK>,
130+
<&cpg CPG_MOD R9A07G044_IA55_PCLK>;
131+
clock-names = "clk", "pclk";
132+
power-domains = <&cpg>;
133+
resets = <&cpg R9A07G044_IA55_RESETN>;
134+
};

Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@ properties:
4747
gpio-ranges:
4848
maxItems: 1
4949

50+
interrupt-controller: true
51+
52+
'#interrupt-cells':
53+
const: 2
54+
description:
55+
The first cell contains the global GPIO port index, constructed using the
56+
RZG2L_GPIO() helper macro in <dt-bindings/pinctrl/rzg2l-pinctrl.h> and the
57+
second cell is used to specify the flag.
58+
E.g. "interrupts = <RZG2L_GPIO(43, 0) IRQ_TYPE_EDGE_FALLING>;" if P43_0 is
59+
being used as an interrupt.
60+
5061
clocks:
5162
maxItems: 1
5263

@@ -110,6 +121,8 @@ required:
110121
- gpio-controller
111122
- '#gpio-cells'
112123
- gpio-ranges
124+
- interrupt-controller
125+
- '#interrupt-cells'
113126
- clocks
114127
- power-domains
115128
- resets
@@ -126,6 +139,8 @@ examples:
126139
gpio-controller;
127140
#gpio-cells = <2>;
128141
gpio-ranges = <&pinctrl 0 0 392>;
142+
interrupt-controller;
143+
#interrupt-cells = <2>;
129144
clocks = <&cpg CPG_MOD R9A07G044_GPIO_HCLK>;
130145
resets = <&cpg R9A07G044_GPIO_RSTN>,
131146
<&cpg R9A07G044_GPIO_PORT_RESETN>,

drivers/gpio/gpio-msc313.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -550,23 +550,20 @@ static struct irq_chip msc313_gpio_irqchip = {
550550
* so we need to provide the fwspec. Essentially gpiochip_populate_parent_fwspec_twocell
551551
* that puts GIC_SPI into the first cell.
552552
*/
553-
static void *msc313_gpio_populate_parent_fwspec(struct gpio_chip *gc,
554-
unsigned int parent_hwirq,
555-
unsigned int parent_type)
553+
static int msc313_gpio_populate_parent_fwspec(struct gpio_chip *gc,
554+
union gpio_irq_fwspec *gfwspec,
555+
unsigned int parent_hwirq,
556+
unsigned int parent_type)
556557
{
557-
struct irq_fwspec *fwspec;
558-
559-
fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL);
560-
if (!fwspec)
561-
return NULL;
558+
struct irq_fwspec *fwspec = &gfwspec->fwspec;
562559

563560
fwspec->fwnode = gc->irq.parent_domain->fwnode;
564561
fwspec->param_count = 3;
565562
fwspec->param[0] = GIC_SPI;
566563
fwspec->param[1] = parent_hwirq;
567564
fwspec->param[2] = parent_type;
568565

569-
return fwspec;
566+
return 0;
570567
}
571568

572569
static int msc313e_gpio_child_to_parent_hwirq(struct gpio_chip *chip,

drivers/gpio/gpio-tegra.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -443,23 +443,20 @@ static int tegra_gpio_child_to_parent_hwirq(struct gpio_chip *chip,
443443
return 0;
444444
}
445445

446-
static void *tegra_gpio_populate_parent_fwspec(struct gpio_chip *chip,
447-
unsigned int parent_hwirq,
448-
unsigned int parent_type)
446+
static int tegra_gpio_populate_parent_fwspec(struct gpio_chip *chip,
447+
union gpio_irq_fwspec *gfwspec,
448+
unsigned int parent_hwirq,
449+
unsigned int parent_type)
449450
{
450-
struct irq_fwspec *fwspec;
451-
452-
fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL);
453-
if (!fwspec)
454-
return NULL;
451+
struct irq_fwspec *fwspec = &gfwspec->fwspec;
455452

456453
fwspec->fwnode = chip->irq.parent_domain->fwnode;
457454
fwspec->param_count = 3;
458455
fwspec->param[0] = 0;
459456
fwspec->param[1] = parent_hwirq;
460457
fwspec->param[2] = parent_type;
461458

462-
return fwspec;
459+
return 0;
463460
}
464461

465462
#ifdef CONFIG_PM_SLEEP

drivers/gpio/gpio-tegra186.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -621,24 +621,21 @@ static int tegra186_gpio_irq_domain_translate(struct irq_domain *domain,
621621
return 0;
622622
}
623623

624-
static void *tegra186_gpio_populate_parent_fwspec(struct gpio_chip *chip,
625-
unsigned int parent_hwirq,
626-
unsigned int parent_type)
624+
static int tegra186_gpio_populate_parent_fwspec(struct gpio_chip *chip,
625+
union gpio_irq_fwspec *gfwspec,
626+
unsigned int parent_hwirq,
627+
unsigned int parent_type)
627628
{
628629
struct tegra_gpio *gpio = gpiochip_get_data(chip);
629-
struct irq_fwspec *fwspec;
630-
631-
fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL);
632-
if (!fwspec)
633-
return NULL;
630+
struct irq_fwspec *fwspec = &gfwspec->fwspec;
634631

635632
fwspec->fwnode = chip->irq.parent_domain->fwnode;
636633
fwspec->param_count = 3;
637634
fwspec->param[0] = gpio->soc->instance;
638635
fwspec->param[1] = parent_hwirq;
639636
fwspec->param[2] = parent_type;
640637

641-
return fwspec;
638+
return 0;
642639
}
643640

644641
static int tegra186_gpio_child_to_parent_hwirq(struct gpio_chip *chip,

drivers/gpio/gpio-thunderx.c

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
#include <linux/module.h>
1616
#include <linux/pci.h>
1717
#include <linux/spinlock.h>
18-
#include <asm-generic/msi.h>
19-
2018

2119
#define GPIO_RX_DAT 0x0
2220
#define GPIO_TX_SET 0x8
@@ -408,18 +406,15 @@ static int thunderx_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
408406
return 0;
409407
}
410408

411-
static void *thunderx_gpio_populate_parent_alloc_info(struct gpio_chip *chip,
412-
unsigned int parent_hwirq,
413-
unsigned int parent_type)
409+
static int thunderx_gpio_populate_parent_alloc_info(struct gpio_chip *chip,
410+
union gpio_irq_fwspec *gfwspec,
411+
unsigned int parent_hwirq,
412+
unsigned int parent_type)
414413
{
415-
msi_alloc_info_t *info;
416-
417-
info = kmalloc(sizeof(*info), GFP_KERNEL);
418-
if (!info)
419-
return NULL;
414+
msi_alloc_info_t *info = &gfwspec->msiinfo;
420415

421416
info->hwirq = parent_hwirq;
422-
return info;
417+
return 0;
423418
}
424419

425420
static int thunderx_gpio_probe(struct pci_dev *pdev,

drivers/gpio/gpio-visconti.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -103,23 +103,20 @@ static int visconti_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
103103
return -EINVAL;
104104
}
105105

106-
static void *visconti_gpio_populate_parent_fwspec(struct gpio_chip *chip,
107-
unsigned int parent_hwirq,
108-
unsigned int parent_type)
106+
static int visconti_gpio_populate_parent_fwspec(struct gpio_chip *chip,
107+
union gpio_irq_fwspec *gfwspec,
108+
unsigned int parent_hwirq,
109+
unsigned int parent_type)
109110
{
110-
struct irq_fwspec *fwspec;
111-
112-
fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL);
113-
if (!fwspec)
114-
return NULL;
111+
struct irq_fwspec *fwspec = &gfwspec->fwspec;
115112

116113
fwspec->fwnode = chip->irq.parent_domain->fwnode;
117114
fwspec->param_count = 3;
118115
fwspec->param[0] = 0;
119116
fwspec->param[1] = parent_hwirq;
120117
fwspec->param[2] = parent_type;
121118

122-
return fwspec;
119+
return 0;
123120
}
124121

125122
static int visconti_gpio_probe(struct platform_device *pdev)

0 commit comments

Comments
 (0)