* [PATCH 01/11] irqchip: stm32: Optimizes and cleans up stm32-exti irq_domain
2018-04-26 16:18 [PATCH 00/11] irqchip: stm32: add exti support for stm32mp157c Ludovic Barre
@ 2018-04-26 16:18 ` Ludovic Barre
2018-05-08 14:47 ` Marc Zyngier
2018-04-26 16:18 ` [PATCH 02/11] irqchip: stm32: checkpatch fix Ludovic Barre
` (9 subsequent siblings)
10 siblings, 1 reply; 20+ messages in thread
From: Ludovic Barre @ 2018-04-26 16:18 UTC (permalink / raw)
To: Thomas Gleixner, Jason Cooper, Marc Zyngier, Rob Herring
Cc: Maxime Coquelin, Alexandre Torgue, Gerald BAEZA, Loic PALLARDY,
linux-kernel, linux-arm-kernel, devicetree, radek, Ludovic Barre
From: radek <radoslaw.pietrzyk@gmail.com>
- In stm32_exti_alloc function, discards irq_domain_set_info
with handle_simple_irq. This overwrite the setting defined while init
of generic chips. Exti controller manages edge irq type.
- Removes acking in chained irq handler as this is done by
irq_chip itself inside handle_edge_irq
- removes unneeded irq_domain_ops.xlate callback
Signed-off-by: Radoslaw Pietrzyk <radoslaw.pietrzyk@gmail.com>
Acked-by: Ludovic Barre <ludovic.barre@st.com>
Tested-by: Ludovic Barre <ludovic.barre@st.com>
Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
---
drivers/irqchip/irq-stm32-exti.c | 13 -------------
1 file changed, 13 deletions(-)
diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
index 36f0fbe..8013a87 100644
--- a/drivers/irqchip/irq-stm32-exti.c
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -79,13 +79,6 @@ static unsigned long stm32_exti_pending(struct irq_chip_generic *gc)
return irq_reg_readl(gc, stm32_bank->pr_ofst);
}
-static void stm32_exti_irq_ack(struct irq_chip_generic *gc, u32 mask)
-{
- const struct stm32_exti_bank *stm32_bank = gc->private;
-
- irq_reg_writel(gc, mask, stm32_bank->pr_ofst);
-}
-
static void stm32_irq_handler(struct irq_desc *desc)
{
struct irq_domain *domain = irq_desc_get_handler_data(desc);
@@ -106,7 +99,6 @@ static void stm32_irq_handler(struct irq_desc *desc)
for_each_set_bit(n, &pending, IRQS_PER_BANK) {
virq = irq_find_mapping(domain, irq_base + n);
generic_handle_irq(virq);
- stm32_exti_irq_ack(gc, BIT(n));
}
}
}
@@ -176,16 +168,12 @@ static int stm32_irq_set_wake(struct irq_data *data, unsigned int on)
static int stm32_exti_alloc(struct irq_domain *d, unsigned int virq,
unsigned int nr_irqs, void *data)
{
- struct irq_chip_generic *gc;
struct irq_fwspec *fwspec = data;
irq_hw_number_t hwirq;
hwirq = fwspec->param[0];
- gc = irq_get_domain_generic_chip(d, hwirq);
irq_map_generic_chip(d, virq, hwirq);
- irq_domain_set_info(d, virq, hwirq, &gc->chip_types->chip, gc,
- handle_simple_irq, NULL, NULL);
return 0;
}
@@ -200,7 +188,6 @@ static void stm32_exti_free(struct irq_domain *d, unsigned int virq,
struct irq_domain_ops irq_exti_domain_ops = {
.map = irq_map_generic_chip,
- .xlate = irq_domain_xlate_onetwocell,
.alloc = stm32_exti_alloc,
.free = stm32_exti_free,
};
--
2.7.4
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 01/11] irqchip: stm32: Optimizes and cleans up stm32-exti irq_domain
2018-04-26 16:18 ` [PATCH 01/11] irqchip: stm32: Optimizes and cleans up stm32-exti irq_domain Ludovic Barre
@ 2018-05-08 14:47 ` Marc Zyngier
2018-05-11 7:47 ` Ludovic BARRE
0 siblings, 1 reply; 20+ messages in thread
From: Marc Zyngier @ 2018-05-08 14:47 UTC (permalink / raw)
To: Ludovic Barre, Thomas Gleixner, Jason Cooper, Rob Herring
Cc: Maxime Coquelin, Alexandre Torgue, Gerald BAEZA, Loic PALLARDY,
linux-kernel, linux-arm-kernel, devicetree, radek
On 26/04/18 17:18, Ludovic Barre wrote:
> From: radek <radoslaw.pietrzyk@gmail.com>
>
> - In stm32_exti_alloc function, discards irq_domain_set_info
> with handle_simple_irq. This overwrite the setting defined while init
> of generic chips. Exti controller manages edge irq type.
> - Removes acking in chained irq handler as this is done by
> irq_chip itself inside handle_edge_irq
> - removes unneeded irq_domain_ops.xlate callback
>
> Signed-off-by: Radoslaw Pietrzyk <radoslaw.pietrzyk@gmail.com>
> Acked-by: Ludovic Barre <ludovic.barre@st.com>
> Tested-by: Ludovic Barre <ludovic.barre@st.com>
> Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Nit: the "From:" should match the SoB line (the address does, but not
the name). I can fix that up when I apply the series.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 01/11] irqchip: stm32: Optimizes and cleans up stm32-exti irq_domain
2018-05-08 14:47 ` Marc Zyngier
@ 2018-05-11 7:47 ` Ludovic BARRE
0 siblings, 0 replies; 20+ messages in thread
From: Ludovic BARRE @ 2018-05-11 7:47 UTC (permalink / raw)
To: Marc Zyngier, Thomas Gleixner, Jason Cooper, Rob Herring
Cc: Maxime Coquelin, Alexandre Torgue, Gerald BAEZA, Loic PALLARDY,
linux-kernel, linux-arm-kernel, devicetree, radek
On 05/08/2018 04:47 PM, Marc Zyngier wrote:
> On 26/04/18 17:18, Ludovic Barre wrote:
>> From: radek <radoslaw.pietrzyk@gmail.com>
>>
>> - In stm32_exti_alloc function, discards irq_domain_set_info
>> with handle_simple_irq. This overwrite the setting defined while init
>> of generic chips. Exti controller manages edge irq type.
>> - Removes acking in chained irq handler as this is done by
>> irq_chip itself inside handle_edge_irq
>> - removes unneeded irq_domain_ops.xlate callback
>>
>> Signed-off-by: Radoslaw Pietrzyk <radoslaw.pietrzyk@gmail.com>
>> Acked-by: Ludovic Barre <ludovic.barre@st.com>
>> Tested-by: Ludovic Barre <ludovic.barre@st.com>
>> Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
>
> Nit: the "From:" should match the SoB line (the address does, but not
> the name). I can fix that up when I apply the series.
>
Thanks
> Thanks,
>
> M.
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 02/11] irqchip: stm32: checkpatch fix
2018-04-26 16:18 [PATCH 00/11] irqchip: stm32: add exti support for stm32mp157c Ludovic Barre
2018-04-26 16:18 ` [PATCH 01/11] irqchip: stm32: Optimizes and cleans up stm32-exti irq_domain Ludovic Barre
@ 2018-04-26 16:18 ` Ludovic Barre
2018-04-26 16:18 ` [PATCH 03/11] irqchip: stm32: add falling pending register support Ludovic Barre
` (8 subsequent siblings)
10 siblings, 0 replies; 20+ messages in thread
From: Ludovic Barre @ 2018-04-26 16:18 UTC (permalink / raw)
To: Thomas Gleixner, Jason Cooper, Marc Zyngier, Rob Herring
Cc: Maxime Coquelin, Alexandre Torgue, Gerald BAEZA, Loic PALLARDY,
linux-kernel, linux-arm-kernel, devicetree, Ludovic Barre
From: Ludovic Barre <ludovic.barre@st.com>
-WARNING: struct irq_domain_ops should normally be const
-CHECK: Alignment should match open parenthesis
Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
---
drivers/irqchip/irq-stm32-exti.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
index 8013a87..b91a8c2 100644
--- a/drivers/irqchip/irq-stm32-exti.c
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -186,7 +186,7 @@ static void stm32_exti_free(struct irq_domain *d, unsigned int virq,
irq_domain_reset_irq_data(data);
}
-struct irq_domain_ops irq_exti_domain_ops = {
+static const struct irq_domain_ops irq_exti_domain_ops = {
.map = irq_map_generic_chip,
.alloc = stm32_exti_alloc,
.free = stm32_exti_free,
@@ -221,7 +221,7 @@ __init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks,
handle_edge_irq, clr, 0, 0);
if (ret) {
pr_err("%pOF: Could not allocate generic interrupt chip.\n",
- node);
+ node);
goto out_free_domain;
}
--
2.7.4
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 03/11] irqchip: stm32: add falling pending register support
2018-04-26 16:18 [PATCH 00/11] irqchip: stm32: add exti support for stm32mp157c Ludovic Barre
2018-04-26 16:18 ` [PATCH 01/11] irqchip: stm32: Optimizes and cleans up stm32-exti irq_domain Ludovic Barre
2018-04-26 16:18 ` [PATCH 02/11] irqchip: stm32: checkpatch fix Ludovic Barre
@ 2018-04-26 16:18 ` Ludovic Barre
2018-04-26 16:18 ` [PATCH 04/11] irqchip: stm32: add suspend support Ludovic Barre
` (7 subsequent siblings)
10 siblings, 0 replies; 20+ messages in thread
From: Ludovic Barre @ 2018-04-26 16:18 UTC (permalink / raw)
To: Thomas Gleixner, Jason Cooper, Marc Zyngier, Rob Herring
Cc: Maxime Coquelin, Alexandre Torgue, Gerald BAEZA, Loic PALLARDY,
linux-kernel, linux-arm-kernel, devicetree, Ludovic Barre
From: Ludovic Barre <ludovic.barre@st.com>
This patch adds support of rising/falling pending registers.
Falling pending register (fpr) is needed for next revision.
Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
---
drivers/irqchip/irq-stm32-exti.c | 47 ++++++++++++++++++++++++++++++----------
1 file changed, 36 insertions(+), 11 deletions(-)
diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
index b91a8c2..69a4453 100644
--- a/drivers/irqchip/irq-stm32-exti.c
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -23,16 +23,20 @@ struct stm32_exti_bank {
u32 rtsr_ofst;
u32 ftsr_ofst;
u32 swier_ofst;
- u32 pr_ofst;
+ u32 rpr_ofst;
+ u32 fpr_ofst;
};
+#define UNDEF_REG ~0
+
static const struct stm32_exti_bank stm32f4xx_exti_b1 = {
.imr_ofst = 0x00,
.emr_ofst = 0x04,
.rtsr_ofst = 0x08,
.ftsr_ofst = 0x0C,
.swier_ofst = 0x10,
- .pr_ofst = 0x14,
+ .rpr_ofst = 0x14,
+ .fpr_ofst = UNDEF_REG,
};
static const struct stm32_exti_bank *stm32f4xx_exti_banks[] = {
@@ -45,7 +49,8 @@ static const struct stm32_exti_bank stm32h7xx_exti_b1 = {
.rtsr_ofst = 0x00,
.ftsr_ofst = 0x04,
.swier_ofst = 0x08,
- .pr_ofst = 0x88,
+ .rpr_ofst = 0x88,
+ .fpr_ofst = UNDEF_REG,
};
static const struct stm32_exti_bank stm32h7xx_exti_b2 = {
@@ -54,7 +59,8 @@ static const struct stm32_exti_bank stm32h7xx_exti_b2 = {
.rtsr_ofst = 0x20,
.ftsr_ofst = 0x24,
.swier_ofst = 0x28,
- .pr_ofst = 0x98,
+ .rpr_ofst = 0x98,
+ .fpr_ofst = UNDEF_REG,
};
static const struct stm32_exti_bank stm32h7xx_exti_b3 = {
@@ -63,7 +69,8 @@ static const struct stm32_exti_bank stm32h7xx_exti_b3 = {
.rtsr_ofst = 0x40,
.ftsr_ofst = 0x44,
.swier_ofst = 0x48,
- .pr_ofst = 0xA8,
+ .rpr_ofst = 0xA8,
+ .fpr_ofst = UNDEF_REG,
};
static const struct stm32_exti_bank *stm32h7xx_exti_banks[] = {
@@ -75,8 +82,13 @@ static const struct stm32_exti_bank *stm32h7xx_exti_banks[] = {
static unsigned long stm32_exti_pending(struct irq_chip_generic *gc)
{
const struct stm32_exti_bank *stm32_bank = gc->private;
+ unsigned long pending;
+
+ pending = irq_reg_readl(gc, stm32_bank->rpr_ofst);
+ if (stm32_bank->fpr_ofst != UNDEF_REG)
+ pending |= irq_reg_readl(gc, stm32_bank->fpr_ofst);
- return irq_reg_readl(gc, stm32_bank->pr_ofst);
+ return pending;
}
static void stm32_irq_handler(struct irq_desc *desc)
@@ -85,7 +97,6 @@ static void stm32_irq_handler(struct irq_desc *desc)
struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned int virq, nbanks = domain->gc->num_chips;
struct irq_chip_generic *gc;
- const struct stm32_exti_bank *stm32_bank;
unsigned long pending;
int n, i, irq_base = 0;
@@ -93,7 +104,6 @@ static void stm32_irq_handler(struct irq_desc *desc)
for (i = 0; i < nbanks; i++, irq_base += IRQS_PER_BANK) {
gc = irq_get_domain_generic_chip(domain, irq_base);
- stm32_bank = gc->private;
while ((pending = stm32_exti_pending(gc))) {
for_each_set_bit(n, &pending, IRQS_PER_BANK) {
@@ -192,6 +202,20 @@ static const struct irq_domain_ops irq_exti_domain_ops = {
.free = stm32_exti_free,
};
+static void stm32_irq_ack(struct irq_data *d)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ const struct stm32_exti_bank *stm32_bank = gc->private;
+
+ irq_gc_lock(gc);
+
+ irq_reg_writel(gc, d->mask, stm32_bank->rpr_ofst);
+ if (stm32_bank->fpr_ofst != UNDEF_REG)
+ irq_reg_writel(gc, d->mask, stm32_bank->fpr_ofst);
+
+ irq_gc_unlock(gc);
+}
+
static int
__init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks,
int bank_nr, struct device_node *node)
@@ -233,12 +257,11 @@ __init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks,
gc->reg_base = base;
gc->chip_types->type = IRQ_TYPE_EDGE_BOTH;
- gc->chip_types->chip.irq_ack = irq_gc_ack_set_bit;
+ gc->chip_types->chip.irq_ack = stm32_irq_ack;
gc->chip_types->chip.irq_mask = irq_gc_mask_clr_bit;
gc->chip_types->chip.irq_unmask = irq_gc_mask_set_bit;
gc->chip_types->chip.irq_set_type = stm32_irq_set_type;
gc->chip_types->chip.irq_set_wake = stm32_irq_set_wake;
- gc->chip_types->regs.ack = stm32_bank->pr_ofst;
gc->chip_types->regs.mask = stm32_bank->imr_ofst;
gc->private = (void *)stm32_bank;
@@ -255,7 +278,9 @@ __init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks,
writel_relaxed(0, base + stm32_bank->emr_ofst);
writel_relaxed(0, base + stm32_bank->rtsr_ofst);
writel_relaxed(0, base + stm32_bank->ftsr_ofst);
- writel_relaxed(~0UL, base + stm32_bank->pr_ofst);
+ writel_relaxed(~0UL, base + stm32_bank->rpr_ofst);
+ if (stm32_bank->fpr_ofst != UNDEF_REG)
+ writel_relaxed(~0UL, base + stm32_bank->fpr_ofst);
pr_info("%s: bank%d, External IRQs available:%#x\n",
node->full_name, i, irqs_mask);
--
2.7.4
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 04/11] irqchip: stm32: add suspend support
2018-04-26 16:18 [PATCH 00/11] irqchip: stm32: add exti support for stm32mp157c Ludovic Barre
` (2 preceding siblings ...)
2018-04-26 16:18 ` [PATCH 03/11] irqchip: stm32: add falling pending register support Ludovic Barre
@ 2018-04-26 16:18 ` Ludovic Barre
2018-04-26 16:18 ` [PATCH 05/11] irqchip: stm32: add host and driver data structures Ludovic Barre
` (6 subsequent siblings)
10 siblings, 0 replies; 20+ messages in thread
From: Ludovic Barre @ 2018-04-26 16:18 UTC (permalink / raw)
To: Thomas Gleixner, Jason Cooper, Marc Zyngier, Rob Herring
Cc: Maxime Coquelin, Alexandre Torgue, Gerald BAEZA, Loic PALLARDY,
linux-kernel, linux-arm-kernel, devicetree, Ludovic Barre
From: Ludovic Barre <ludovic.barre@st.com>
This patch adds suspend feature.
-Use default irq_set_wake function to store wakeup request.
-Suspend function set wake_active into imr of each bank
and save rising/falling trigger registers.
-Resume function restore the mask_cache interrupt into
imr of each bank and restore rising/falling trigger registers.
Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
---
drivers/irqchip/irq-stm32-exti.c | 69 ++++++++++++++++++++++++++++++----------
1 file changed, 52 insertions(+), 17 deletions(-)
diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
index 69a4453..1e09667 100644
--- a/drivers/irqchip/irq-stm32-exti.c
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -29,6 +29,14 @@ struct stm32_exti_bank {
#define UNDEF_REG ~0
+struct stm32_exti_chip_data {
+ const struct stm32_exti_bank *reg_bank;
+ u32 rtsr_cache;
+ u32 ftsr_cache;
+};
+
+static struct stm32_exti_chip_data *stm32_exti_data;
+
static const struct stm32_exti_bank stm32f4xx_exti_b1 = {
.imr_ofst = 0x00,
.emr_ofst = 0x04,
@@ -81,7 +89,8 @@ static const struct stm32_exti_bank *stm32h7xx_exti_banks[] = {
static unsigned long stm32_exti_pending(struct irq_chip_generic *gc)
{
- const struct stm32_exti_bank *stm32_bank = gc->private;
+ struct stm32_exti_chip_data *chip_data = gc->private;
+ const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
unsigned long pending;
pending = irq_reg_readl(gc, stm32_bank->rpr_ofst);
@@ -119,7 +128,8 @@ static void stm32_irq_handler(struct irq_desc *desc)
static int stm32_irq_set_type(struct irq_data *data, unsigned int type)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
- const struct stm32_exti_bank *stm32_bank = gc->private;
+ struct stm32_exti_chip_data *chip_data = gc->private;
+ const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
int pin = data->hwirq % IRQS_PER_BANK;
u32 rtsr, ftsr;
@@ -154,25 +164,36 @@ static int stm32_irq_set_type(struct irq_data *data, unsigned int type)
return 0;
}
-static int stm32_irq_set_wake(struct irq_data *data, unsigned int on)
+static void stm32_irq_suspend(struct irq_chip_generic *gc)
{
- struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
- const struct stm32_exti_bank *stm32_bank = gc->private;
- int pin = data->hwirq % IRQS_PER_BANK;
- u32 imr;
+ struct stm32_exti_chip_data *chip_data = gc->private;
+ const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
irq_gc_lock(gc);
- imr = irq_reg_readl(gc, stm32_bank->imr_ofst);
- if (on)
- imr |= BIT(pin);
- else
- imr &= ~BIT(pin);
- irq_reg_writel(gc, imr, stm32_bank->imr_ofst);
+ /* save rtsr, ftsr registers */
+ chip_data->rtsr_cache = irq_reg_readl(gc, stm32_bank->rtsr_ofst);
+ chip_data->ftsr_cache = irq_reg_readl(gc, stm32_bank->ftsr_ofst);
+
+ irq_reg_writel(gc, gc->wake_active, stm32_bank->imr_ofst);
irq_gc_unlock(gc);
+}
- return 0;
+static void stm32_irq_resume(struct irq_chip_generic *gc)
+{
+ struct stm32_exti_chip_data *chip_data = gc->private;
+ const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
+
+ irq_gc_lock(gc);
+
+ /* restore rtsr, ftsr registers */
+ irq_reg_writel(gc, chip_data->rtsr_cache, stm32_bank->rtsr_ofst);
+ irq_reg_writel(gc, chip_data->ftsr_cache, stm32_bank->ftsr_ofst);
+
+ irq_reg_writel(gc, gc->mask_cache, stm32_bank->imr_ofst);
+
+ irq_gc_unlock(gc);
}
static int stm32_exti_alloc(struct irq_domain *d, unsigned int virq,
@@ -205,7 +226,8 @@ static const struct irq_domain_ops irq_exti_domain_ops = {
static void stm32_irq_ack(struct irq_data *d)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
- const struct stm32_exti_bank *stm32_bank = gc->private;
+ struct stm32_exti_chip_data *chip_data = gc->private;
+ const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
irq_gc_lock(gc);
@@ -232,6 +254,11 @@ __init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks,
return -ENOMEM;
}
+ stm32_exti_data = kcalloc(bank_nr, sizeof(*stm32_exti_data),
+ GFP_KERNEL);
+ if (!stm32_exti_data)
+ return -ENOMEM;
+
domain = irq_domain_add_linear(node, bank_nr * IRQS_PER_BANK,
&irq_exti_domain_ops, NULL);
if (!domain) {
@@ -251,8 +278,11 @@ __init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks,
for (i = 0; i < bank_nr; i++) {
const struct stm32_exti_bank *stm32_bank = stm32_exti_banks[i];
+ struct stm32_exti_chip_data *chip_data = &stm32_exti_data[i];
u32 irqs_mask;
+ chip_data->reg_bank = stm32_bank;
+
gc = irq_get_domain_generic_chip(domain, i * IRQS_PER_BANK);
gc->reg_base = base;
@@ -261,9 +291,13 @@ __init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks,
gc->chip_types->chip.irq_mask = irq_gc_mask_clr_bit;
gc->chip_types->chip.irq_unmask = irq_gc_mask_set_bit;
gc->chip_types->chip.irq_set_type = stm32_irq_set_type;
- gc->chip_types->chip.irq_set_wake = stm32_irq_set_wake;
+ gc->chip_types->chip.irq_set_wake = irq_gc_set_wake;
+ gc->suspend = stm32_irq_suspend;
+ gc->resume = stm32_irq_resume;
+ gc->wake_enabled = IRQ_MSK(IRQS_PER_BANK);
+
gc->chip_types->regs.mask = stm32_bank->imr_ofst;
- gc->private = (void *)stm32_bank;
+ gc->private = (void *)chip_data;
/* Determine number of irqs supported */
writel_relaxed(~0UL, base + stm32_bank->rtsr_ofst);
@@ -300,6 +334,7 @@ __init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks,
irq_domain_remove(domain);
out_unmap:
iounmap(base);
+ kfree(stm32_exti_data);
return ret;
}
--
2.7.4
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 05/11] irqchip: stm32: add host and driver data structures
2018-04-26 16:18 [PATCH 00/11] irqchip: stm32: add exti support for stm32mp157c Ludovic Barre
` (3 preceding siblings ...)
2018-04-26 16:18 ` [PATCH 04/11] irqchip: stm32: add suspend support Ludovic Barre
@ 2018-04-26 16:18 ` Ludovic Barre
2018-04-26 16:18 ` [PATCH 06/11] irqchip: stm32: prepare common functions Ludovic Barre
` (5 subsequent siblings)
10 siblings, 0 replies; 20+ messages in thread
From: Ludovic Barre @ 2018-04-26 16:18 UTC (permalink / raw)
To: Thomas Gleixner, Jason Cooper, Marc Zyngier, Rob Herring
Cc: Maxime Coquelin, Alexandre Torgue, Gerald BAEZA, Loic PALLARDY,
linux-kernel, linux-arm-kernel, devicetree, Ludovic Barre
From: Ludovic Barre <ludovic.barre@st.com>
This patch adds host and driver data structures to support
different stm32 exti controllers with variants.
Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
---
drivers/irqchip/irq-stm32-exti.c | 152 ++++++++++++++++++++++++++-------------
1 file changed, 104 insertions(+), 48 deletions(-)
diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
index 1e09667..9655a57 100644
--- a/drivers/irqchip/irq-stm32-exti.c
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -29,13 +29,23 @@ struct stm32_exti_bank {
#define UNDEF_REG ~0
+struct stm32_exti_drv_data {
+ const struct stm32_exti_bank **exti_banks;
+ u32 bank_nr;
+};
+
struct stm32_exti_chip_data {
+ struct stm32_exti_host_data *host_data;
const struct stm32_exti_bank *reg_bank;
u32 rtsr_cache;
u32 ftsr_cache;
};
-static struct stm32_exti_chip_data *stm32_exti_data;
+struct stm32_exti_host_data {
+ void __iomem *base;
+ struct stm32_exti_chip_data *chips_data;
+ const struct stm32_exti_drv_data *drv_data;
+};
static const struct stm32_exti_bank stm32f4xx_exti_b1 = {
.imr_ofst = 0x00,
@@ -51,6 +61,11 @@ static const struct stm32_exti_bank *stm32f4xx_exti_banks[] = {
&stm32f4xx_exti_b1,
};
+static const struct stm32_exti_drv_data stm32f4xx_drv_data = {
+ .exti_banks = stm32f4xx_exti_banks,
+ .bank_nr = ARRAY_SIZE(stm32f4xx_exti_banks),
+};
+
static const struct stm32_exti_bank stm32h7xx_exti_b1 = {
.imr_ofst = 0x80,
.emr_ofst = 0x84,
@@ -87,6 +102,11 @@ static const struct stm32_exti_bank *stm32h7xx_exti_banks[] = {
&stm32h7xx_exti_b3,
};
+static const struct stm32_exti_drv_data stm32h7xx_drv_data = {
+ .exti_banks = stm32h7xx_exti_banks,
+ .bank_nr = ARRAY_SIZE(stm32h7xx_exti_banks),
+};
+
static unsigned long stm32_exti_pending(struct irq_chip_generic *gc)
{
struct stm32_exti_chip_data *chip_data = gc->private;
@@ -237,29 +257,85 @@ static void stm32_irq_ack(struct irq_data *d)
irq_gc_unlock(gc);
}
+static struct
+stm32_exti_host_data *stm32_exti_host_init(const struct stm32_exti_drv_data *dd,
+ struct device_node *node)
+{
+ struct stm32_exti_host_data *host_data;
+
+ host_data = kzalloc(sizeof(*host_data), GFP_KERNEL);
+ if (!host_data)
+ return NULL;
+
+ host_data->drv_data = dd;
+ host_data->chips_data = kcalloc(dd->bank_nr,
+ sizeof(struct stm32_exti_chip_data),
+ GFP_KERNEL);
+ if (!host_data->chips_data)
+ return NULL;
+
+ host_data->base = of_iomap(node, 0);
+ if (!host_data->base) {
+ pr_err("%pOF: Unable to map registers\n", node);
+ return NULL;
+ }
-static int
-__init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks,
- int bank_nr, struct device_node *node)
+ return host_data;
+}
+
+static struct
+stm32_exti_chip_data *stm32_exti_chip_init(struct stm32_exti_host_data *h_data,
+ u32 bank_idx,
+ struct device_node *node)
+{
+ const struct stm32_exti_bank *stm32_bank;
+ struct stm32_exti_chip_data *chip_data;
+ void __iomem *base = h_data->base;
+ u32 irqs_mask;
+
+ stm32_bank = h_data->drv_data->exti_banks[bank_idx];
+ chip_data = &h_data->chips_data[bank_idx];
+ chip_data->host_data = h_data;
+ chip_data->reg_bank = stm32_bank;
+
+ /* Determine number of irqs supported */
+ writel_relaxed(~0UL, base + stm32_bank->rtsr_ofst);
+ irqs_mask = readl_relaxed(base + stm32_bank->rtsr_ofst);
+
+ /*
+ * This IP has no reset, so after hot reboot we should
+ * clear registers to avoid residue
+ */
+ writel_relaxed(0, base + stm32_bank->imr_ofst);
+ writel_relaxed(0, base + stm32_bank->emr_ofst);
+ writel_relaxed(0, base + stm32_bank->rtsr_ofst);
+ writel_relaxed(0, base + stm32_bank->ftsr_ofst);
+ writel_relaxed(~0UL, base + stm32_bank->rpr_ofst);
+ if (stm32_bank->fpr_ofst != UNDEF_REG)
+ writel_relaxed(~0UL, base + stm32_bank->fpr_ofst);
+
+ pr_info("%s: bank%d, External IRQs available:%#x\n",
+ node->full_name, bank_idx, irqs_mask);
+
+ return chip_data;
+}
+
+static int __init stm32_exti_init(const struct stm32_exti_drv_data *drv_data,
+ struct device_node *node)
{
+ struct stm32_exti_host_data *host_data;
unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
- int nr_irqs, nr_exti, ret, i;
+ int nr_irqs, ret, i;
struct irq_chip_generic *gc;
struct irq_domain *domain;
- void *base;
- base = of_iomap(node, 0);
- if (!base) {
- pr_err("%pOF: Unable to map registers\n", node);
- return -ENOMEM;
+ host_data = stm32_exti_host_init(drv_data, node);
+ if (!host_data) {
+ ret = -ENOMEM;
+ goto out_free_mem;
}
- stm32_exti_data = kcalloc(bank_nr, sizeof(*stm32_exti_data),
- GFP_KERNEL);
- if (!stm32_exti_data)
- return -ENOMEM;
-
- domain = irq_domain_add_linear(node, bank_nr * IRQS_PER_BANK,
+ domain = irq_domain_add_linear(node, drv_data->bank_nr * IRQS_PER_BANK,
&irq_exti_domain_ops, NULL);
if (!domain) {
pr_err("%s: Could not register interrupt domain.\n",
@@ -276,16 +352,16 @@ __init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks,
goto out_free_domain;
}
- for (i = 0; i < bank_nr; i++) {
- const struct stm32_exti_bank *stm32_bank = stm32_exti_banks[i];
- struct stm32_exti_chip_data *chip_data = &stm32_exti_data[i];
- u32 irqs_mask;
+ for (i = 0; i < drv_data->bank_nr; i++) {
+ const struct stm32_exti_bank *stm32_bank;
+ struct stm32_exti_chip_data *chip_data;
- chip_data->reg_bank = stm32_bank;
+ stm32_bank = drv_data->exti_banks[i];
+ chip_data = stm32_exti_chip_init(host_data, i, node);
gc = irq_get_domain_generic_chip(domain, i * IRQS_PER_BANK);
- gc->reg_base = base;
+ gc->reg_base = host_data->base;
gc->chip_types->type = IRQ_TYPE_EDGE_BOTH;
gc->chip_types->chip.irq_ack = stm32_irq_ack;
gc->chip_types->chip.irq_mask = irq_gc_mask_clr_bit;
@@ -298,26 +374,6 @@ __init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks,
gc->chip_types->regs.mask = stm32_bank->imr_ofst;
gc->private = (void *)chip_data;
-
- /* Determine number of irqs supported */
- writel_relaxed(~0UL, base + stm32_bank->rtsr_ofst);
- irqs_mask = readl_relaxed(base + stm32_bank->rtsr_ofst);
- nr_exti = fls(readl_relaxed(base + stm32_bank->rtsr_ofst));
-
- /*
- * This IP has no reset, so after hot reboot we should
- * clear registers to avoid residue
- */
- writel_relaxed(0, base + stm32_bank->imr_ofst);
- writel_relaxed(0, base + stm32_bank->emr_ofst);
- writel_relaxed(0, base + stm32_bank->rtsr_ofst);
- writel_relaxed(0, base + stm32_bank->ftsr_ofst);
- writel_relaxed(~0UL, base + stm32_bank->rpr_ofst);
- if (stm32_bank->fpr_ofst != UNDEF_REG)
- writel_relaxed(~0UL, base + stm32_bank->fpr_ofst);
-
- pr_info("%s: bank%d, External IRQs available:%#x\n",
- node->full_name, i, irqs_mask);
}
nr_irqs = of_irq_count(node);
@@ -333,16 +389,17 @@ __init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks,
out_free_domain:
irq_domain_remove(domain);
out_unmap:
- iounmap(base);
- kfree(stm32_exti_data);
+ iounmap(host_data->base);
+out_free_mem:
+ kfree(host_data->chips_data);
+ kfree(host_data);
return ret;
}
static int __init stm32f4_exti_of_init(struct device_node *np,
struct device_node *parent)
{
- return stm32_exti_init(stm32f4xx_exti_banks,
- ARRAY_SIZE(stm32f4xx_exti_banks), np);
+ return stm32_exti_init(&stm32f4xx_drv_data, np);
}
IRQCHIP_DECLARE(stm32f4_exti, "st,stm32-exti", stm32f4_exti_of_init);
@@ -350,8 +407,7 @@ IRQCHIP_DECLARE(stm32f4_exti, "st,stm32-exti", stm32f4_exti_of_init);
static int __init stm32h7_exti_of_init(struct device_node *np,
struct device_node *parent)
{
- return stm32_exti_init(stm32h7xx_exti_banks,
- ARRAY_SIZE(stm32h7xx_exti_banks), np);
+ return stm32_exti_init(&stm32h7xx_drv_data, np);
}
IRQCHIP_DECLARE(stm32h7_exti, "st,stm32h7-exti", stm32h7_exti_of_init);
--
2.7.4
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 06/11] irqchip: stm32: prepare common functions
2018-04-26 16:18 [PATCH 00/11] irqchip: stm32: add exti support for stm32mp157c Ludovic Barre
` (4 preceding siblings ...)
2018-04-26 16:18 ` [PATCH 05/11] irqchip: stm32: add host and driver data structures Ludovic Barre
@ 2018-04-26 16:18 ` Ludovic Barre
2018-04-26 16:18 ` [PATCH 07/11] irqchip: stm32: add stm32mp1 support with hierarchy domain Ludovic Barre
` (4 subsequent siblings)
10 siblings, 0 replies; 20+ messages in thread
From: Ludovic Barre @ 2018-04-26 16:18 UTC (permalink / raw)
To: Thomas Gleixner, Jason Cooper, Marc Zyngier, Rob Herring
Cc: Maxime Coquelin, Alexandre Torgue, Gerald BAEZA, Loic PALLARDY,
linux-kernel, linux-arm-kernel, devicetree, Ludovic Barre
From: Ludovic Barre <ludovic.barre@st.com>
This patch prepares functions which could be reused by
next variant of stm32 exti controller.
Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
---
drivers/irqchip/irq-stm32-exti.c | 91 +++++++++++++++++++++++++---------------
1 file changed, 58 insertions(+), 33 deletions(-)
diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
index 9655a57..b38c655 100644
--- a/drivers/irqchip/irq-stm32-exti.c
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -145,37 +145,50 @@ static void stm32_irq_handler(struct irq_desc *desc)
chained_irq_exit(chip, desc);
}
-static int stm32_irq_set_type(struct irq_data *data, unsigned int type)
+static int stm32_exti_set_type(struct irq_data *d,
+ unsigned int type, u32 *rtsr, u32 *ftsr)
{
- struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
- struct stm32_exti_chip_data *chip_data = gc->private;
- const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
- int pin = data->hwirq % IRQS_PER_BANK;
- u32 rtsr, ftsr;
-
- irq_gc_lock(gc);
-
- rtsr = irq_reg_readl(gc, stm32_bank->rtsr_ofst);
- ftsr = irq_reg_readl(gc, stm32_bank->ftsr_ofst);
+ u32 mask = BIT(d->hwirq % IRQS_PER_BANK);
switch (type) {
case IRQ_TYPE_EDGE_RISING:
- rtsr |= BIT(pin);
- ftsr &= ~BIT(pin);
+ *rtsr |= mask;
+ *ftsr &= ~mask;
break;
case IRQ_TYPE_EDGE_FALLING:
- rtsr &= ~BIT(pin);
- ftsr |= BIT(pin);
+ *rtsr &= ~mask;
+ *ftsr |= mask;
break;
case IRQ_TYPE_EDGE_BOTH:
- rtsr |= BIT(pin);
- ftsr |= BIT(pin);
+ *rtsr |= mask;
+ *ftsr |= mask;
break;
default:
- irq_gc_unlock(gc);
return -EINVAL;
}
+ return 0;
+}
+
+static int stm32_irq_set_type(struct irq_data *d, unsigned int type)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct stm32_exti_chip_data *chip_data = gc->private;
+ const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
+ u32 rtsr, ftsr;
+ int err;
+
+ irq_gc_lock(gc);
+
+ rtsr = irq_reg_readl(gc, stm32_bank->rtsr_ofst);
+ ftsr = irq_reg_readl(gc, stm32_bank->ftsr_ofst);
+
+ err = stm32_exti_set_type(d, type, &rtsr, &ftsr);
+ if (err) {
+ irq_gc_unlock(gc);
+ return err;
+ }
+
irq_reg_writel(gc, rtsr, stm32_bank->rtsr_ofst);
irq_reg_writel(gc, ftsr, stm32_bank->ftsr_ofst);
@@ -184,35 +197,47 @@ static int stm32_irq_set_type(struct irq_data *data, unsigned int type)
return 0;
}
-static void stm32_irq_suspend(struct irq_chip_generic *gc)
+static void stm32_chip_suspend(struct stm32_exti_chip_data *chip_data,
+ u32 wake_active)
{
- struct stm32_exti_chip_data *chip_data = gc->private;
const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
-
- irq_gc_lock(gc);
+ void __iomem *base = chip_data->host_data->base;
/* save rtsr, ftsr registers */
- chip_data->rtsr_cache = irq_reg_readl(gc, stm32_bank->rtsr_ofst);
- chip_data->ftsr_cache = irq_reg_readl(gc, stm32_bank->ftsr_ofst);
+ chip_data->rtsr_cache = readl_relaxed(base + stm32_bank->rtsr_ofst);
+ chip_data->ftsr_cache = readl_relaxed(base + stm32_bank->ftsr_ofst);
- irq_reg_writel(gc, gc->wake_active, stm32_bank->imr_ofst);
+ writel_relaxed(wake_active, base + stm32_bank->imr_ofst);
+}
- irq_gc_unlock(gc);
+static void stm32_chip_resume(struct stm32_exti_chip_data *chip_data,
+ u32 mask_cache)
+{
+ const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
+ void __iomem *base = chip_data->host_data->base;
+
+ /* restore rtsr, ftsr, registers */
+ writel_relaxed(chip_data->rtsr_cache, base + stm32_bank->rtsr_ofst);
+ writel_relaxed(chip_data->ftsr_cache, base + stm32_bank->ftsr_ofst);
+
+ writel_relaxed(mask_cache, base + stm32_bank->imr_ofst);
}
-static void stm32_irq_resume(struct irq_chip_generic *gc)
+static void stm32_irq_suspend(struct irq_chip_generic *gc)
{
struct stm32_exti_chip_data *chip_data = gc->private;
- const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
irq_gc_lock(gc);
+ stm32_chip_suspend(chip_data, gc->wake_active);
+ irq_gc_unlock(gc);
+}
- /* restore rtsr, ftsr registers */
- irq_reg_writel(gc, chip_data->rtsr_cache, stm32_bank->rtsr_ofst);
- irq_reg_writel(gc, chip_data->ftsr_cache, stm32_bank->ftsr_ofst);
-
- irq_reg_writel(gc, gc->mask_cache, stm32_bank->imr_ofst);
+static void stm32_irq_resume(struct irq_chip_generic *gc)
+{
+ struct stm32_exti_chip_data *chip_data = gc->private;
+ irq_gc_lock(gc);
+ stm32_chip_resume(chip_data, gc->mask_cache);
irq_gc_unlock(gc);
}
--
2.7.4
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 07/11] irqchip: stm32: add stm32mp1 support with hierarchy domain
2018-04-26 16:18 [PATCH 00/11] irqchip: stm32: add exti support for stm32mp157c Ludovic Barre
` (5 preceding siblings ...)
2018-04-26 16:18 ` [PATCH 06/11] irqchip: stm32: prepare common functions Ludovic Barre
@ 2018-04-26 16:18 ` Ludovic Barre
2018-05-01 14:56 ` Rob Herring
2018-04-26 16:18 ` [PATCH 08/11] irqchip: stm32: add suspend/resume support for " Ludovic Barre
` (3 subsequent siblings)
10 siblings, 1 reply; 20+ messages in thread
From: Ludovic Barre @ 2018-04-26 16:18 UTC (permalink / raw)
To: Thomas Gleixner, Jason Cooper, Marc Zyngier, Rob Herring
Cc: Maxime Coquelin, Alexandre Torgue, Gerald BAEZA, Loic PALLARDY,
linux-kernel, linux-arm-kernel, devicetree, Ludovic Barre
From: Ludovic Barre <ludovic.barre@st.com>
Exti controller has been differently integrated on stm32mp1 SoC.
A parent irq has only one external interrupt. A hierachy domain could
be used. Handlers are call by parent, each parent interrupt could be
masked and unmasked according to the needs.
Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
---
.../interrupt-controller/st,stm32-exti.txt | 3 +
drivers/irqchip/irq-stm32-exti.c | 322 +++++++++++++++++++++
2 files changed, 325 insertions(+)
diff --git a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
index edf03f0..136bd61 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
@@ -5,11 +5,14 @@ Required properties:
- compatible: Should be:
"st,stm32-exti"
"st,stm32h7-exti"
+ "st,stm32mp1-exti"
- reg: Specifies base physical address and size of the registers
- interrupt-controller: Indentifies the node as an interrupt controller
- #interrupt-cells: Specifies the number of cells to encode an interrupt
specifier, shall be 2
- interrupts: interrupts references to primary interrupt controller
+ (only needed for exti controller with multiple exti under
+ same parent interrupt: st,stm32-exti and st,stm32h7-exti")
Example:
diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
index b38c655..ebf7146 100644
--- a/drivers/irqchip/irq-stm32-exti.c
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -15,6 +15,8 @@
#include <linux/of_address.h>
#include <linux/of_irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
#define IRQS_PER_BANK 32
struct stm32_exti_bank {
@@ -29,14 +31,24 @@ struct stm32_exti_bank {
#define UNDEF_REG ~0
+struct stm32_desc_irq {
+ u32 exti;
+ u32 irq_parent;
+};
+
struct stm32_exti_drv_data {
const struct stm32_exti_bank **exti_banks;
+ const struct stm32_desc_irq *desc_irqs;
u32 bank_nr;
+ u32 irq_nr;
};
struct stm32_exti_chip_data {
struct stm32_exti_host_data *host_data;
const struct stm32_exti_bank *reg_bank;
+ struct raw_spinlock rlock;
+ u32 wake_active;
+ u32 mask_cache;
u32 rtsr_cache;
u32 ftsr_cache;
};
@@ -107,6 +119,89 @@ static const struct stm32_exti_drv_data stm32h7xx_drv_data = {
.bank_nr = ARRAY_SIZE(stm32h7xx_exti_banks),
};
+static const struct stm32_exti_bank stm32mp1_exti_b1 = {
+ .imr_ofst = 0x80,
+ .emr_ofst = 0x84,
+ .rtsr_ofst = 0x00,
+ .ftsr_ofst = 0x04,
+ .swier_ofst = 0x08,
+ .rpr_ofst = 0x0C,
+ .fpr_ofst = 0x10,
+};
+
+static const struct stm32_exti_bank stm32mp1_exti_b2 = {
+ .imr_ofst = 0x90,
+ .emr_ofst = 0x94,
+ .rtsr_ofst = 0x20,
+ .ftsr_ofst = 0x24,
+ .swier_ofst = 0x28,
+ .rpr_ofst = 0x2C,
+ .fpr_ofst = 0x30,
+};
+
+static const struct stm32_exti_bank stm32mp1_exti_b3 = {
+ .imr_ofst = 0xA0,
+ .emr_ofst = 0xA4,
+ .rtsr_ofst = 0x40,
+ .ftsr_ofst = 0x44,
+ .swier_ofst = 0x48,
+ .rpr_ofst = 0x4C,
+ .fpr_ofst = 0x50,
+};
+
+static const struct stm32_exti_bank *stm32mp1_exti_banks[] = {
+ &stm32mp1_exti_b1,
+ &stm32mp1_exti_b2,
+ &stm32mp1_exti_b3,
+};
+
+static const struct stm32_desc_irq stm32mp1_desc_irq[] = {
+ { .exti = 1, .irq_parent = 7 },
+ { .exti = 2, .irq_parent = 8 },
+ { .exti = 3, .irq_parent = 9 },
+ { .exti = 4, .irq_parent = 10 },
+ { .exti = 5, .irq_parent = 23 },
+ { .exti = 6, .irq_parent = 64 },
+ { .exti = 7, .irq_parent = 65 },
+ { .exti = 8, .irq_parent = 66 },
+ { .exti = 9, .irq_parent = 67 },
+ { .exti = 10, .irq_parent = 40 },
+ { .exti = 11, .irq_parent = 42 },
+ { .exti = 12, .irq_parent = 76 },
+ { .exti = 13, .irq_parent = 77 },
+ { .exti = 14, .irq_parent = 121 },
+ { .exti = 15, .irq_parent = 127 },
+ { .exti = 16, .irq_parent = 1 },
+ { .exti = 65, .irq_parent = 144 },
+ { .exti = 68, .irq_parent = 143 },
+ { .exti = 73, .irq_parent = 129 },
+};
+
+static const struct stm32_exti_drv_data stm32mp1_drv_data = {
+ .exti_banks = stm32mp1_exti_banks,
+ .bank_nr = ARRAY_SIZE(stm32mp1_exti_banks),
+ .desc_irqs = stm32mp1_desc_irq,
+ .irq_nr = ARRAY_SIZE(stm32mp1_desc_irq),
+};
+
+static int stm32_exti_to_irq(const struct stm32_exti_drv_data *drv_data,
+ irq_hw_number_t hwirq)
+{
+ const struct stm32_desc_irq *desc_irq;
+ int i;
+
+ if (!drv_data->desc_irqs)
+ return -EINVAL;
+
+ for (i = 0; i < drv_data->irq_nr; i++) {
+ desc_irq = &drv_data->desc_irqs[i];
+ if (desc_irq->exti == hwirq)
+ return desc_irq->irq_parent;
+ }
+
+ return -EINVAL;
+}
+
static unsigned long stm32_exti_pending(struct irq_chip_generic *gc)
{
struct stm32_exti_chip_data *chip_data = gc->private;
@@ -282,6 +377,173 @@ static void stm32_irq_ack(struct irq_data *d)
irq_gc_unlock(gc);
}
+
+static inline u32 stm32_exti_set_bit(struct irq_data *d, u32 reg)
+{
+ struct stm32_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d);
+ void __iomem *base = chip_data->host_data->base;
+ u32 val;
+
+ val = readl_relaxed(base + reg);
+ val |= BIT(d->hwirq % IRQS_PER_BANK);
+ writel_relaxed(val, base + reg);
+
+ return val;
+}
+
+static inline u32 stm32_exti_clr_bit(struct irq_data *d, u32 reg)
+{
+ struct stm32_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d);
+ void __iomem *base = chip_data->host_data->base;
+ u32 val;
+
+ val = readl_relaxed(base + reg);
+ val &= ~BIT(d->hwirq % IRQS_PER_BANK);
+ writel_relaxed(val, base + reg);
+
+ return val;
+}
+
+static void stm32_exti_h_eoi(struct irq_data *d)
+{
+ struct stm32_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d);
+ const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
+
+ raw_spin_lock(&chip_data->rlock);
+
+ stm32_exti_set_bit(d, stm32_bank->rpr_ofst);
+ if (stm32_bank->fpr_ofst != UNDEF_REG)
+ stm32_exti_set_bit(d, stm32_bank->fpr_ofst);
+
+ raw_spin_unlock(&chip_data->rlock);
+
+ if (d->parent_data->chip)
+ irq_chip_eoi_parent(d);
+}
+
+static void stm32_exti_h_mask(struct irq_data *d)
+{
+ struct stm32_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d);
+ const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
+
+ raw_spin_lock(&chip_data->rlock);
+ chip_data->mask_cache = stm32_exti_clr_bit(d, stm32_bank->imr_ofst);
+ raw_spin_unlock(&chip_data->rlock);
+
+ if (d->parent_data->chip)
+ irq_chip_mask_parent(d);
+}
+
+static void stm32_exti_h_unmask(struct irq_data *d)
+{
+ struct stm32_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d);
+ const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
+
+ raw_spin_lock(&chip_data->rlock);
+ chip_data->mask_cache = stm32_exti_set_bit(d, stm32_bank->imr_ofst);
+ raw_spin_unlock(&chip_data->rlock);
+
+ if (d->parent_data->chip)
+ irq_chip_unmask_parent(d);
+}
+
+static int stm32_exti_h_set_type(struct irq_data *d, unsigned int type)
+{
+ struct stm32_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d);
+ const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
+ void __iomem *base = chip_data->host_data->base;
+ u32 rtsr, ftsr;
+ int err;
+
+ raw_spin_lock(&chip_data->rlock);
+ rtsr = readl_relaxed(base + stm32_bank->rtsr_ofst);
+ ftsr = readl_relaxed(base + stm32_bank->ftsr_ofst);
+
+ err = stm32_exti_set_type(d, type, &rtsr, &ftsr);
+ if (err) {
+ raw_spin_unlock(&chip_data->rlock);
+ return err;
+ }
+
+ writel_relaxed(rtsr, base + stm32_bank->rtsr_ofst);
+ writel_relaxed(ftsr, base + stm32_bank->ftsr_ofst);
+ raw_spin_unlock(&chip_data->rlock);
+
+ return 0;
+}
+
+static int stm32_exti_h_set_wake(struct irq_data *d, unsigned int on)
+{
+ struct stm32_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d);
+ u32 mask = BIT(d->hwirq % IRQS_PER_BANK);
+
+ raw_spin_lock(&chip_data->rlock);
+
+ if (on)
+ chip_data->wake_active |= mask;
+ else
+ chip_data->wake_active &= ~mask;
+
+ raw_spin_unlock(&chip_data->rlock);
+
+ return 0;
+}
+
+static int stm32_exti_h_set_affinity(struct irq_data *d,
+ const struct cpumask *dest, bool force)
+{
+ if (d->parent_data->chip)
+ return irq_chip_set_affinity_parent(d, dest, force);
+
+ return -EINVAL;
+}
+
+static struct irq_chip stm32_exti_h_chip = {
+ .name = "stm32-exti-h",
+ .irq_eoi = stm32_exti_h_eoi,
+ .irq_mask = stm32_exti_h_mask,
+ .irq_unmask = stm32_exti_h_unmask,
+ .irq_retrigger = irq_chip_retrigger_hierarchy,
+ .irq_set_type = stm32_exti_h_set_type,
+ .irq_set_wake = stm32_exti_h_set_wake,
+ .flags = IRQCHIP_MASK_ON_SUSPEND,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = stm32_exti_h_set_affinity,
+#endif
+};
+
+static int stm32_exti_h_domain_alloc(struct irq_domain *dm,
+ unsigned int virq,
+ unsigned int nr_irqs, void *data)
+{
+ struct stm32_exti_host_data *host_data = dm->host_data;
+ struct stm32_exti_chip_data *chip_data;
+ struct irq_fwspec *fwspec = data;
+ struct irq_fwspec p_fwspec;
+ irq_hw_number_t hwirq;
+ int p_irq, bank;
+
+ hwirq = fwspec->param[0];
+ bank = hwirq / IRQS_PER_BANK;
+ chip_data = &host_data->chips_data[bank];
+
+ irq_domain_set_hwirq_and_chip(dm, virq, hwirq,
+ &stm32_exti_h_chip, chip_data);
+
+ p_irq = stm32_exti_to_irq(host_data->drv_data, hwirq);
+ if (p_irq >= 0) {
+ p_fwspec.fwnode = dm->parent->fwnode;
+ p_fwspec.param_count = 3;
+ p_fwspec.param[0] = GIC_SPI;
+ p_fwspec.param[1] = p_irq;
+ p_fwspec.param[2] = IRQ_TYPE_LEVEL_HIGH;
+
+ return irq_domain_alloc_irqs_parent(dm, virq, 1, &p_fwspec);
+ }
+
+ return 0;
+}
+
static struct
stm32_exti_host_data *stm32_exti_host_init(const struct stm32_exti_drv_data *dd,
struct device_node *node)
@@ -323,6 +585,8 @@ stm32_exti_chip_data *stm32_exti_chip_init(struct stm32_exti_host_data *h_data,
chip_data->host_data = h_data;
chip_data->reg_bank = stm32_bank;
+ raw_spin_lock_init(&chip_data->rlock);
+
/* Determine number of irqs supported */
writel_relaxed(~0UL, base + stm32_bank->rtsr_ofst);
irqs_mask = readl_relaxed(base + stm32_bank->rtsr_ofst);
@@ -421,6 +685,56 @@ static int __init stm32_exti_init(const struct stm32_exti_drv_data *drv_data,
return ret;
}
+static const struct irq_domain_ops stm32_exti_h_domain_ops = {
+ .alloc = stm32_exti_h_domain_alloc,
+ .free = irq_domain_free_irqs_common,
+};
+
+static int
+__init stm32_exti_hierarchy_init(const struct stm32_exti_drv_data *drv_data,
+ struct device_node *node,
+ struct device_node *parent)
+{
+ struct irq_domain *parent_domain, *domain;
+ struct stm32_exti_host_data *host_data;
+ int ret, i;
+
+ parent_domain = irq_find_host(parent);
+ if (!parent_domain) {
+ pr_err("interrupt-parent not found\n");
+ return -EINVAL;
+ }
+
+ host_data = stm32_exti_host_init(drv_data, node);
+ if (!host_data) {
+ ret = -ENOMEM;
+ goto out_free_mem;
+ }
+
+ for (i = 0; i < drv_data->bank_nr; i++)
+ stm32_exti_chip_init(host_data, i, node);
+
+ domain = irq_domain_add_hierarchy(parent_domain, 0,
+ drv_data->bank_nr * IRQS_PER_BANK,
+ node, &stm32_exti_h_domain_ops,
+ host_data);
+
+ if (!domain) {
+ pr_err("%s: Could not register exti domain.\n", node->name);
+ ret = -ENOMEM;
+ goto out_unmap;
+ }
+
+ return 0;
+
+out_unmap:
+ iounmap(host_data->base);
+out_free_mem:
+ kfree(host_data->chips_data);
+ kfree(host_data);
+ return ret;
+}
+
static int __init stm32f4_exti_of_init(struct device_node *np,
struct device_node *parent)
{
@@ -436,3 +750,11 @@ static int __init stm32h7_exti_of_init(struct device_node *np,
}
IRQCHIP_DECLARE(stm32h7_exti, "st,stm32h7-exti", stm32h7_exti_of_init);
+
+static int __init stm32mp1_exti_of_init(struct device_node *np,
+ struct device_node *parent)
+{
+ return stm32_exti_hierarchy_init(&stm32mp1_drv_data, np, parent);
+}
+
+IRQCHIP_DECLARE(stm32mp1_exti, "st,stm32mp1-exti", stm32mp1_exti_of_init);
--
2.7.4
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 07/11] irqchip: stm32: add stm32mp1 support with hierarchy domain
2018-04-26 16:18 ` [PATCH 07/11] irqchip: stm32: add stm32mp1 support with hierarchy domain Ludovic Barre
@ 2018-05-01 14:56 ` Rob Herring
2018-05-02 16:03 ` Ludovic BARRE
0 siblings, 1 reply; 20+ messages in thread
From: Rob Herring @ 2018-05-01 14:56 UTC (permalink / raw)
To: Ludovic Barre
Cc: Thomas Gleixner, Jason Cooper, Marc Zyngier, Maxime Coquelin,
Alexandre Torgue, Gerald BAEZA, Loic PALLARDY, linux-kernel,
linux-arm-kernel, devicetree
On Thu, Apr 26, 2018 at 06:18:30PM +0200, Ludovic Barre wrote:
> From: Ludovic Barre <ludovic.barre@st.com>
>
> Exti controller has been differently integrated on stm32mp1 SoC.
> A parent irq has only one external interrupt. A hierachy domain could
> be used. Handlers are call by parent, each parent interrupt could be
> masked and unmasked according to the needs.
>
> Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
> ---
> .../interrupt-controller/st,stm32-exti.txt | 3 +
> drivers/irqchip/irq-stm32-exti.c | 322 +++++++++++++++++++++
> 2 files changed, 325 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
> index edf03f0..136bd61 100644
> --- a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
> +++ b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
> @@ -5,11 +5,14 @@ Required properties:
> - compatible: Should be:
> "st,stm32-exti"
> "st,stm32h7-exti"
> + "st,stm32mp1-exti"
> - reg: Specifies base physical address and size of the registers
> - interrupt-controller: Indentifies the node as an interrupt controller
> - #interrupt-cells: Specifies the number of cells to encode an interrupt
> specifier, shall be 2
> - interrupts: interrupts references to primary interrupt controller
> + (only needed for exti controller with multiple exti under
> + same parent interrupt: st,stm32-exti and st,stm32h7-exti")
>
> Example:
>
> diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
> index b38c655..ebf7146 100644
> --- a/drivers/irqchip/irq-stm32-exti.c
> +++ b/drivers/irqchip/irq-stm32-exti.c
[...]
> +static const struct stm32_desc_irq stm32mp1_desc_irq[] = {
> + { .exti = 1, .irq_parent = 7 },
> + { .exti = 2, .irq_parent = 8 },
> + { .exti = 3, .irq_parent = 9 },
> + { .exti = 4, .irq_parent = 10 },
> + { .exti = 5, .irq_parent = 23 },
> + { .exti = 6, .irq_parent = 64 },
> + { .exti = 7, .irq_parent = 65 },
> + { .exti = 8, .irq_parent = 66 },
> + { .exti = 9, .irq_parent = 67 },
> + { .exti = 10, .irq_parent = 40 },
> + { .exti = 11, .irq_parent = 42 },
> + { .exti = 12, .irq_parent = 76 },
> + { .exti = 13, .irq_parent = 77 },
> + { .exti = 14, .irq_parent = 121 },
> + { .exti = 15, .irq_parent = 127 },
> + { .exti = 16, .irq_parent = 1 },
> + { .exti = 65, .irq_parent = 144 },
> + { .exti = 68, .irq_parent = 143 },
> + { .exti = 73, .irq_parent = 129 },
> +};
You can use an interrupt-map property rather than put this into the
driver.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 07/11] irqchip: stm32: add stm32mp1 support with hierarchy domain
2018-05-01 14:56 ` Rob Herring
@ 2018-05-02 16:03 ` Ludovic BARRE
2018-05-02 17:45 ` Rob Herring
0 siblings, 1 reply; 20+ messages in thread
From: Ludovic BARRE @ 2018-05-02 16:03 UTC (permalink / raw)
To: Rob Herring
Cc: Thomas Gleixner, Jason Cooper, Marc Zyngier, Maxime Coquelin,
Alexandre Torgue, Gerald BAEZA, Loic PALLARDY, linux-kernel,
linux-arm-kernel, devicetree
Hi Rob
On 05/01/2018 04:56 PM, Rob Herring wrote:
> On Thu, Apr 26, 2018 at 06:18:30PM +0200, Ludovic Barre wrote:
>> From: Ludovic Barre <ludovic.barre@st.com>
>>
>> Exti controller has been differently integrated on stm32mp1 SoC.
>> A parent irq has only one external interrupt. A hierachy domain could
>> be used. Handlers are call by parent, each parent interrupt could be
>> masked and unmasked according to the needs.
>>
>> Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
>> ---
>> .../interrupt-controller/st,stm32-exti.txt | 3 +
>> drivers/irqchip/irq-stm32-exti.c | 322 +++++++++++++++++++++
>> 2 files changed, 325 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>> index edf03f0..136bd61 100644
>> --- a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>> +++ b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>> @@ -5,11 +5,14 @@ Required properties:
>> - compatible: Should be:
>> "st,stm32-exti"
>> "st,stm32h7-exti"
>> + "st,stm32mp1-exti"
>> - reg: Specifies base physical address and size of the registers
>> - interrupt-controller: Indentifies the node as an interrupt controller
>> - #interrupt-cells: Specifies the number of cells to encode an interrupt
>> specifier, shall be 2
>> - interrupts: interrupts references to primary interrupt controller
>> + (only needed for exti controller with multiple exti under
>> + same parent interrupt: st,stm32-exti and st,stm32h7-exti")
>>
>> Example:
>>
>> diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
>> index b38c655..ebf7146 100644
>> --- a/drivers/irqchip/irq-stm32-exti.c
>> +++ b/drivers/irqchip/irq-stm32-exti.c
>
> [...]
>
>> +static const struct stm32_desc_irq stm32mp1_desc_irq[] = {
>> + { .exti = 1, .irq_parent = 7 },
>> + { .exti = 2, .irq_parent = 8 },
>> + { .exti = 3, .irq_parent = 9 },
>> + { .exti = 4, .irq_parent = 10 },
>> + { .exti = 5, .irq_parent = 23 },
>> + { .exti = 6, .irq_parent = 64 },
>> + { .exti = 7, .irq_parent = 65 },
>> + { .exti = 8, .irq_parent = 66 },
>> + { .exti = 9, .irq_parent = 67 },
>> + { .exti = 10, .irq_parent = 40 },
>> + { .exti = 11, .irq_parent = 42 },
>> + { .exti = 12, .irq_parent = 76 },
>> + { .exti = 13, .irq_parent = 77 },
>> + { .exti = 14, .irq_parent = 121 },
>> + { .exti = 15, .irq_parent = 127 },
>> + { .exti = 16, .irq_parent = 1 },
>> + { .exti = 65, .irq_parent = 144 },
>> + { .exti = 68, .irq_parent = 143 },
>> + { .exti = 73, .irq_parent = 129 },
>> +};
>
> You can use an interrupt-map property rather than put this into the
> driver.
interrupt-map seemed interesting and promising like used in pci host.
At first sight this property can't be used into node with
"interrupt-controller" property (see in drivers/of/irq.c function:
of_irq_parse_raw) because "of_irq_parse_raw" checks if node got
it first, and after lookup the interrupt-map.
Rob, Thomas, Jason, Marc what do you prefers or the right ways...?
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 07/11] irqchip: stm32: add stm32mp1 support with hierarchy domain
2018-05-02 16:03 ` Ludovic BARRE
@ 2018-05-02 17:45 ` Rob Herring
2018-05-03 9:55 ` Ludovic BARRE
0 siblings, 1 reply; 20+ messages in thread
From: Rob Herring @ 2018-05-02 17:45 UTC (permalink / raw)
To: Ludovic BARRE
Cc: Thomas Gleixner, Jason Cooper, Marc Zyngier, Maxime Coquelin,
Alexandre Torgue, Gerald BAEZA, Loic PALLARDY, linux-kernel,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
devicetree
On Wed, May 2, 2018 at 11:03 AM, Ludovic BARRE <ludovic.barre@st.com> wrote:
> Hi Rob
>
>
>
> On 05/01/2018 04:56 PM, Rob Herring wrote:
>>
>> On Thu, Apr 26, 2018 at 06:18:30PM +0200, Ludovic Barre wrote:
>>>
>>> From: Ludovic Barre <ludovic.barre@st.com>
>>>
>>> Exti controller has been differently integrated on stm32mp1 SoC.
>>> A parent irq has only one external interrupt. A hierachy domain could
>>> be used. Handlers are call by parent, each parent interrupt could be
>>> masked and unmasked according to the needs.
>>>
>>> Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
>>> ---
>>> .../interrupt-controller/st,stm32-exti.txt | 3 +
>>> drivers/irqchip/irq-stm32-exti.c | 322
>>> +++++++++++++++++++++
>>> 2 files changed, 325 insertions(+)
>>>
>>> diff --git
>>> a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>>> b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>>> index edf03f0..136bd61 100644
>>> ---
>>> a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>>> +++
>>> b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>>> @@ -5,11 +5,14 @@ Required properties:
>>> - compatible: Should be:
>>> "st,stm32-exti"
>>> "st,stm32h7-exti"
>>> + "st,stm32mp1-exti"
>>> - reg: Specifies base physical address and size of the registers
>>> - interrupt-controller: Indentifies the node as an interrupt controller
>>> - #interrupt-cells: Specifies the number of cells to encode an
>>> interrupt
>>> specifier, shall be 2
>>> - interrupts: interrupts references to primary interrupt controller
>>> + (only needed for exti controller with multiple exti under
>>> + same parent interrupt: st,stm32-exti and st,stm32h7-exti")
>>> Example:
>>> diff --git a/drivers/irqchip/irq-stm32-exti.c
>>> b/drivers/irqchip/irq-stm32-exti.c
>>> index b38c655..ebf7146 100644
>>> --- a/drivers/irqchip/irq-stm32-exti.c
>>> +++ b/drivers/irqchip/irq-stm32-exti.c
>>
>>
>> [...]
>>
>>> +static const struct stm32_desc_irq stm32mp1_desc_irq[] = {
>>> + { .exti = 1, .irq_parent = 7 },
>>> + { .exti = 2, .irq_parent = 8 },
>>> + { .exti = 3, .irq_parent = 9 },
>>> + { .exti = 4, .irq_parent = 10 },
>>> + { .exti = 5, .irq_parent = 23 },
>>> + { .exti = 6, .irq_parent = 64 },
>>> + { .exti = 7, .irq_parent = 65 },
>>> + { .exti = 8, .irq_parent = 66 },
>>> + { .exti = 9, .irq_parent = 67 },
>>> + { .exti = 10, .irq_parent = 40 },
>>> + { .exti = 11, .irq_parent = 42 },
>>> + { .exti = 12, .irq_parent = 76 },
>>> + { .exti = 13, .irq_parent = 77 },
>>> + { .exti = 14, .irq_parent = 121 },
>>> + { .exti = 15, .irq_parent = 127 },
>>> + { .exti = 16, .irq_parent = 1 },
>>> + { .exti = 65, .irq_parent = 144 },
>>> + { .exti = 68, .irq_parent = 143 },
>>> + { .exti = 73, .irq_parent = 129 },
>>> +};
>>
>>
>> You can use an interrupt-map property rather than put this into the
>> driver.
>
>
> interrupt-map seemed interesting and promising like used in pci host.
> At first sight this property can't be used into node with
> "interrupt-controller" property (see in drivers/of/irq.c function:
> of_irq_parse_raw) because "of_irq_parse_raw" checks if node got
> it first, and after lookup the interrupt-map.
>
> Rob, Thomas, Jason, Marc what do you prefers or the right ways...?
I believe the correct thing to do is simply drop "interrupt-controller".
Rob
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 07/11] irqchip: stm32: add stm32mp1 support with hierarchy domain
2018-05-02 17:45 ` Rob Herring
@ 2018-05-03 9:55 ` Ludovic BARRE
2018-05-04 20:38 ` Rob Herring
0 siblings, 1 reply; 20+ messages in thread
From: Ludovic BARRE @ 2018-05-03 9:55 UTC (permalink / raw)
To: Rob Herring
Cc: Thomas Gleixner, Jason Cooper, Marc Zyngier, Maxime Coquelin,
Alexandre Torgue, Gerald BAEZA, Loic PALLARDY, linux-kernel,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
devicetree
On 05/02/2018 07:45 PM, Rob Herring wrote:
> On Wed, May 2, 2018 at 11:03 AM, Ludovic BARRE <ludovic.barre@st.com> wrote:
>> Hi Rob
>>
>>
>>
>> On 05/01/2018 04:56 PM, Rob Herring wrote:
>>>
>>> On Thu, Apr 26, 2018 at 06:18:30PM +0200, Ludovic Barre wrote:
>>>>
>>>> From: Ludovic Barre <ludovic.barre@st.com>
>>>>
>>>> Exti controller has been differently integrated on stm32mp1 SoC.
>>>> A parent irq has only one external interrupt. A hierachy domain could
>>>> be used. Handlers are call by parent, each parent interrupt could be
>>>> masked and unmasked according to the needs.
>>>>
>>>> Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
>>>> ---
>>>> .../interrupt-controller/st,stm32-exti.txt | 3 +
>>>> drivers/irqchip/irq-stm32-exti.c | 322
>>>> +++++++++++++++++++++
>>>> 2 files changed, 325 insertions(+)
>>>>
>>>> diff --git
>>>> a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>>>> b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>>>> index edf03f0..136bd61 100644
>>>> ---
>>>> a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>>>> +++
>>>> b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>>>> @@ -5,11 +5,14 @@ Required properties:
>>>> - compatible: Should be:
>>>> "st,stm32-exti"
>>>> "st,stm32h7-exti"
>>>> + "st,stm32mp1-exti"
>>>> - reg: Specifies base physical address and size of the registers
>>>> - interrupt-controller: Indentifies the node as an interrupt controller
>>>> - #interrupt-cells: Specifies the number of cells to encode an
>>>> interrupt
>>>> specifier, shall be 2
>>>> - interrupts: interrupts references to primary interrupt controller
>>>> + (only needed for exti controller with multiple exti under
>>>> + same parent interrupt: st,stm32-exti and st,stm32h7-exti")
>>>> Example:
>>>> diff --git a/drivers/irqchip/irq-stm32-exti.c
>>>> b/drivers/irqchip/irq-stm32-exti.c
>>>> index b38c655..ebf7146 100644
>>>> --- a/drivers/irqchip/irq-stm32-exti.c
>>>> +++ b/drivers/irqchip/irq-stm32-exti.c
>>>
>>>
>>> [...]
>>>
>>>> +static const struct stm32_desc_irq stm32mp1_desc_irq[] = {
>>>> + { .exti = 1, .irq_parent = 7 },
>>>> + { .exti = 2, .irq_parent = 8 },
>>>> + { .exti = 3, .irq_parent = 9 },
>>>> + { .exti = 4, .irq_parent = 10 },
>>>> + { .exti = 5, .irq_parent = 23 },
>>>> + { .exti = 6, .irq_parent = 64 },
>>>> + { .exti = 7, .irq_parent = 65 },
>>>> + { .exti = 8, .irq_parent = 66 },
>>>> + { .exti = 9, .irq_parent = 67 },
>>>> + { .exti = 10, .irq_parent = 40 },
>>>> + { .exti = 11, .irq_parent = 42 },
>>>> + { .exti = 12, .irq_parent = 76 },
>>>> + { .exti = 13, .irq_parent = 77 },
>>>> + { .exti = 14, .irq_parent = 121 },
>>>> + { .exti = 15, .irq_parent = 127 },
>>>> + { .exti = 16, .irq_parent = 1 },
>>>> + { .exti = 65, .irq_parent = 144 },
>>>> + { .exti = 68, .irq_parent = 143 },
>>>> + { .exti = 73, .irq_parent = 129 },
>>>> +};
>>>
>>>
>>> You can use an interrupt-map property rather than put this into the
>>> driver.
>>
>>
>> interrupt-map seemed interesting and promising like used in pci host.
>> At first sight this property can't be used into node with
>> "interrupt-controller" property (see in drivers/of/irq.c function:
>> of_irq_parse_raw) because "of_irq_parse_raw" checks if node got
>> it first, and after lookup the interrupt-map.
>>
>> Rob, Thomas, Jason, Marc what do you prefers or the right ways...?
>
> I believe the correct thing to do is simply drop "interrupt-controller".
if I drop "interrupt-controller" of my node, my driver will not be
initialized by "of_irq_init"
(start_kernel->init_IRQ->irqchip_init->of_irq_init).
Probably, we could replace "IRQCHIP_DECLARE" by a
"module_platform_driver" or "postcore_initcall" but I'm not a big fan of
this solution. what do you think ?
>
> Rob
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 07/11] irqchip: stm32: add stm32mp1 support with hierarchy domain
2018-05-03 9:55 ` Ludovic BARRE
@ 2018-05-04 20:38 ` Rob Herring
2018-05-14 12:40 ` Ludovic BARRE
0 siblings, 1 reply; 20+ messages in thread
From: Rob Herring @ 2018-05-04 20:38 UTC (permalink / raw)
To: Ludovic BARRE
Cc: Thomas Gleixner, Jason Cooper, Marc Zyngier, Maxime Coquelin,
Alexandre Torgue, Gerald BAEZA, Loic PALLARDY, linux-kernel,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
devicetree
On Thu, May 3, 2018 at 4:55 AM, Ludovic BARRE <ludovic.barre@st.com> wrote:
>
>
> On 05/02/2018 07:45 PM, Rob Herring wrote:
>>
>> On Wed, May 2, 2018 at 11:03 AM, Ludovic BARRE <ludovic.barre@st.com>
>> wrote:
>>>
>>> Hi Rob
>>>
>>>
>>>
>>> On 05/01/2018 04:56 PM, Rob Herring wrote:
>>>>
>>>>
>>>> On Thu, Apr 26, 2018 at 06:18:30PM +0200, Ludovic Barre wrote:
>>>>>
>>>>>
>>>>> From: Ludovic Barre <ludovic.barre@st.com>
>>>>>
>>>>> Exti controller has been differently integrated on stm32mp1 SoC.
>>>>> A parent irq has only one external interrupt. A hierachy domain could
>>>>> be used. Handlers are call by parent, each parent interrupt could be
>>>>> masked and unmasked according to the needs.
>>>>>
>>>>> Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
>>>>> ---
>>>>> .../interrupt-controller/st,stm32-exti.txt | 3 +
>>>>> drivers/irqchip/irq-stm32-exti.c | 322
>>>>> +++++++++++++++++++++
>>>>> 2 files changed, 325 insertions(+)
>>>>>
>>>>> diff --git
>>>>>
>>>>> a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>>>>>
>>>>> b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>>>>> index edf03f0..136bd61 100644
>>>>> ---
>>>>>
>>>>> a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>>>>> +++
>>>>>
>>>>> b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>>>>> @@ -5,11 +5,14 @@ Required properties:
>>>>> - compatible: Should be:
>>>>> "st,stm32-exti"
>>>>> "st,stm32h7-exti"
>>>>> + "st,stm32mp1-exti"
>>>>> - reg: Specifies base physical address and size of the registers
>>>>> - interrupt-controller: Indentifies the node as an interrupt
>>>>> controller
>>>>> - #interrupt-cells: Specifies the number of cells to encode an
>>>>> interrupt
>>>>> specifier, shall be 2
>>>>> - interrupts: interrupts references to primary interrupt controller
>>>>> + (only needed for exti controller with multiple exti under
>>>>> + same parent interrupt: st,stm32-exti and st,stm32h7-exti")
>>>>> Example:
>>>>> diff --git a/drivers/irqchip/irq-stm32-exti.c
>>>>> b/drivers/irqchip/irq-stm32-exti.c
>>>>> index b38c655..ebf7146 100644
>>>>> --- a/drivers/irqchip/irq-stm32-exti.c
>>>>> +++ b/drivers/irqchip/irq-stm32-exti.c
>>>>
>>>>
>>>>
>>>> [...]
>>>>
>>>>> +static const struct stm32_desc_irq stm32mp1_desc_irq[] = {
>>>>> + { .exti = 1, .irq_parent = 7 },
>>>>> + { .exti = 2, .irq_parent = 8 },
>>>>> + { .exti = 3, .irq_parent = 9 },
>>>>> + { .exti = 4, .irq_parent = 10 },
>>>>> + { .exti = 5, .irq_parent = 23 },
>>>>> + { .exti = 6, .irq_parent = 64 },
>>>>> + { .exti = 7, .irq_parent = 65 },
>>>>> + { .exti = 8, .irq_parent = 66 },
>>>>> + { .exti = 9, .irq_parent = 67 },
>>>>> + { .exti = 10, .irq_parent = 40 },
>>>>> + { .exti = 11, .irq_parent = 42 },
>>>>> + { .exti = 12, .irq_parent = 76 },
>>>>> + { .exti = 13, .irq_parent = 77 },
>>>>> + { .exti = 14, .irq_parent = 121 },
>>>>> + { .exti = 15, .irq_parent = 127 },
>>>>> + { .exti = 16, .irq_parent = 1 },
>>>>> + { .exti = 65, .irq_parent = 144 },
>>>>> + { .exti = 68, .irq_parent = 143 },
>>>>> + { .exti = 73, .irq_parent = 129 },
>>>>> +};
>>>>
>>>>
>>>>
>>>> You can use an interrupt-map property rather than put this into the
>>>> driver.
>>>
>>>
>>>
>>> interrupt-map seemed interesting and promising like used in pci host.
>>> At first sight this property can't be used into node with
>>> "interrupt-controller" property (see in drivers/of/irq.c function:
>>> of_irq_parse_raw) because "of_irq_parse_raw" checks if node got
>>> it first, and after lookup the interrupt-map.
>>>
>>> Rob, Thomas, Jason, Marc what do you prefers or the right ways...?
>>
>>
>> I believe the correct thing to do is simply drop "interrupt-controller".
>
Actually, that's not right.
> if I drop "interrupt-controller" of my node, my driver will not be
> initialized by "of_irq_init"
> (start_kernel->init_IRQ->irqchip_init->of_irq_init).
> Probably, we could replace "IRQCHIP_DECLARE" by a
> "module_platform_driver" or "postcore_initcall" but I'm not a big fan of
> this solution. what do you think ?
You'd have to parse 'interrupt-map' yourself to extract the data for
this to work because interrupt-map currently only works when the
translation is transparent (i.e. doesn't need s/w handling). So I
guess leave this in the driver. Sorry for the noise.
Rob
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 07/11] irqchip: stm32: add stm32mp1 support with hierarchy domain
2018-05-04 20:38 ` Rob Herring
@ 2018-05-14 12:40 ` Ludovic BARRE
0 siblings, 0 replies; 20+ messages in thread
From: Ludovic BARRE @ 2018-05-14 12:40 UTC (permalink / raw)
To: Rob Herring
Cc: Thomas Gleixner, Jason Cooper, Marc Zyngier, Maxime Coquelin,
Alexandre Torgue, Gerald BAEZA, Loic PALLARDY, linux-kernel,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
devicetree
On 05/04/2018 10:38 PM, Rob Herring wrote:
> On Thu, May 3, 2018 at 4:55 AM, Ludovic BARRE <ludovic.barre@st.com> wrote:
>>
>>
>> On 05/02/2018 07:45 PM, Rob Herring wrote:
>>>
>>> On Wed, May 2, 2018 at 11:03 AM, Ludovic BARRE <ludovic.barre@st.com>
>>> wrote:
>>>>
>>>> Hi Rob
>>>>
>>>>
>>>>
>>>> On 05/01/2018 04:56 PM, Rob Herring wrote:
>>>>>
>>>>>
>>>>> On Thu, Apr 26, 2018 at 06:18:30PM +0200, Ludovic Barre wrote:
>>>>>>
>>>>>>
>>>>>> From: Ludovic Barre <ludovic.barre@st.com>
>>>>>>
>>>>>> Exti controller has been differently integrated on stm32mp1 SoC.
>>>>>> A parent irq has only one external interrupt. A hierachy domain could
>>>>>> be used. Handlers are call by parent, each parent interrupt could be
>>>>>> masked and unmasked according to the needs.
>>>>>>
>>>>>> Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
>>>>>> ---
>>>>>> .../interrupt-controller/st,stm32-exti.txt | 3 +
>>>>>> drivers/irqchip/irq-stm32-exti.c | 322
>>>>>> +++++++++++++++++++++
>>>>>> 2 files changed, 325 insertions(+)
>>>>>>
>>>>>> diff --git
>>>>>>
>>>>>> a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>>>>>>
>>>>>> b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>>>>>> index edf03f0..136bd61 100644
>>>>>> ---
>>>>>>
>>>>>> a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>>>>>> +++
>>>>>>
>>>>>> b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
>>>>>> @@ -5,11 +5,14 @@ Required properties:
>>>>>> - compatible: Should be:
>>>>>> "st,stm32-exti"
>>>>>> "st,stm32h7-exti"
>>>>>> + "st,stm32mp1-exti"
>>>>>> - reg: Specifies base physical address and size of the registers
>>>>>> - interrupt-controller: Indentifies the node as an interrupt
>>>>>> controller
>>>>>> - #interrupt-cells: Specifies the number of cells to encode an
>>>>>> interrupt
>>>>>> specifier, shall be 2
>>>>>> - interrupts: interrupts references to primary interrupt controller
>>>>>> + (only needed for exti controller with multiple exti under
>>>>>> + same parent interrupt: st,stm32-exti and st,stm32h7-exti")
>>>>>> Example:
>>>>>> diff --git a/drivers/irqchip/irq-stm32-exti.c
>>>>>> b/drivers/irqchip/irq-stm32-exti.c
>>>>>> index b38c655..ebf7146 100644
>>>>>> --- a/drivers/irqchip/irq-stm32-exti.c
>>>>>> +++ b/drivers/irqchip/irq-stm32-exti.c
>>>>>
>>>>>
>>>>>
>>>>> [...]
>>>>>
>>>>>> +static const struct stm32_desc_irq stm32mp1_desc_irq[] = {
>>>>>> + { .exti = 1, .irq_parent = 7 },
>>>>>> + { .exti = 2, .irq_parent = 8 },
>>>>>> + { .exti = 3, .irq_parent = 9 },
>>>>>> + { .exti = 4, .irq_parent = 10 },
>>>>>> + { .exti = 5, .irq_parent = 23 },
>>>>>> + { .exti = 6, .irq_parent = 64 },
>>>>>> + { .exti = 7, .irq_parent = 65 },
>>>>>> + { .exti = 8, .irq_parent = 66 },
>>>>>> + { .exti = 9, .irq_parent = 67 },
>>>>>> + { .exti = 10, .irq_parent = 40 },
>>>>>> + { .exti = 11, .irq_parent = 42 },
>>>>>> + { .exti = 12, .irq_parent = 76 },
>>>>>> + { .exti = 13, .irq_parent = 77 },
>>>>>> + { .exti = 14, .irq_parent = 121 },
>>>>>> + { .exti = 15, .irq_parent = 127 },
>>>>>> + { .exti = 16, .irq_parent = 1 },
>>>>>> + { .exti = 65, .irq_parent = 144 },
>>>>>> + { .exti = 68, .irq_parent = 143 },
>>>>>> + { .exti = 73, .irq_parent = 129 },
>>>>>> +};
>>>>>
>>>>>
>>>>>
>>>>> You can use an interrupt-map property rather than put this into the
>>>>> driver.
>>>>
>>>>
>>>>
>>>> interrupt-map seemed interesting and promising like used in pci host.
>>>> At first sight this property can't be used into node with
>>>> "interrupt-controller" property (see in drivers/of/irq.c function:
>>>> of_irq_parse_raw) because "of_irq_parse_raw" checks if node got
>>>> it first, and after lookup the interrupt-map.
>>>>
>>>> Rob, Thomas, Jason, Marc what do you prefers or the right ways...?
>>>
>>>
>>> I believe the correct thing to do is simply drop "interrupt-controller".
>>
>
> Actually, that's not right.
>
>> if I drop "interrupt-controller" of my node, my driver will not be
>> initialized by "of_irq_init"
>> (start_kernel->init_IRQ->irqchip_init->of_irq_init).
>> Probably, we could replace "IRQCHIP_DECLARE" by a
>> "module_platform_driver" or "postcore_initcall" but I'm not a big fan of
>> this solution. what do you think ?
>
> You'd have to parse 'interrupt-map' yourself to extract the data for
> this to work because interrupt-map currently only works when the
> translation is transparent (i.e. doesn't need s/w handling). So I
> guess leave this in the driver. Sorry for the noise.
>
Sorry, I don't know if I've correctly understand the answer.
I hesitate between:
- keep the code like this, with stm32mp1_desc_irq tab.
- parse interrupt-map property into stm32 exti driver.
Just to be sure, and avoid misunderstand.
BR
Ludo
> Rob
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 08/11] irqchip: stm32: add suspend/resume support for hierarchy domain
2018-04-26 16:18 [PATCH 00/11] irqchip: stm32: add exti support for stm32mp157c Ludovic Barre
` (6 preceding siblings ...)
2018-04-26 16:18 ` [PATCH 07/11] irqchip: stm32: add stm32mp1 support with hierarchy domain Ludovic Barre
@ 2018-04-26 16:18 ` Ludovic Barre
2018-04-26 16:18 ` [PATCH 09/11] pinctrl: stm32: add irq_eoi for stm32gpio irqchip Ludovic Barre
` (2 subsequent siblings)
10 siblings, 0 replies; 20+ messages in thread
From: Ludovic Barre @ 2018-04-26 16:18 UTC (permalink / raw)
To: Thomas Gleixner, Jason Cooper, Marc Zyngier, Rob Herring
Cc: Maxime Coquelin, Alexandre Torgue, Gerald BAEZA, Loic PALLARDY,
linux-kernel, linux-arm-kernel, devicetree, Ludovic Barre
From: Ludovic Barre <ludovic.barre@st.com>
This patch adds suspend/resume feature for exti hierarchy domain.
-suspend function sets wake_active into imr of each banks
-resume function restores the mask_cache interrupt into
imr of each banks
Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
---
drivers/irqchip/irq-stm32-exti.c | 49 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
index ebf7146..5089c1e 100644
--- a/drivers/irqchip/irq-stm32-exti.c
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -14,6 +14,7 @@
#include <linux/irqdomain.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
+#include <linux/syscore_ops.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -59,6 +60,8 @@ struct stm32_exti_host_data {
const struct stm32_exti_drv_data *drv_data;
};
+static struct stm32_exti_host_data *stm32_host_data;
+
static const struct stm32_exti_bank stm32f4xx_exti_b1 = {
.imr_ofst = 0x00,
.emr_ofst = 0x04,
@@ -498,6 +501,48 @@ static int stm32_exti_h_set_affinity(struct irq_data *d,
return -EINVAL;
}
+#ifdef CONFIG_PM
+static int stm32_exti_h_suspend(void)
+{
+ struct stm32_exti_chip_data *chip_data;
+ int i;
+
+ for (i = 0; i < stm32_host_data->drv_data->bank_nr; i++) {
+ chip_data = &stm32_host_data->chips_data[i];
+ raw_spin_lock(&chip_data->rlock);
+ stm32_chip_suspend(chip_data, chip_data->wake_active);
+ raw_spin_unlock(&chip_data->rlock);
+ }
+
+ return 0;
+}
+
+static void stm32_exti_h_resume(void)
+{
+ struct stm32_exti_chip_data *chip_data;
+ int i;
+
+ for (i = 0; i < stm32_host_data->drv_data->bank_nr; i++) {
+ chip_data = &stm32_host_data->chips_data[i];
+ raw_spin_lock(&chip_data->rlock);
+ stm32_chip_resume(chip_data, chip_data->mask_cache);
+ raw_spin_unlock(&chip_data->rlock);
+ }
+}
+
+static struct syscore_ops stm32_exti_h_syscore_ops = {
+ .suspend = stm32_exti_h_suspend,
+ .resume = stm32_exti_h_resume,
+};
+
+static void stm32_exti_h_syscore_init(void)
+{
+ register_syscore_ops(&stm32_exti_h_syscore_ops);
+}
+#else
+static inline void stm32_exti_h_syscore_init(void) {}
+#endif
+
static struct irq_chip stm32_exti_h_chip = {
.name = "stm32-exti-h",
.irq_eoi = stm32_exti_h_eoi,
@@ -567,6 +612,8 @@ stm32_exti_host_data *stm32_exti_host_init(const struct stm32_exti_drv_data *dd,
return NULL;
}
+ stm32_host_data = host_data;
+
return host_data;
}
@@ -725,6 +772,8 @@ __init stm32_exti_hierarchy_init(const struct stm32_exti_drv_data *drv_data,
goto out_unmap;
}
+ stm32_exti_h_syscore_init();
+
return 0;
out_unmap:
--
2.7.4
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 09/11] pinctrl: stm32: add irq_eoi for stm32gpio irqchip
2018-04-26 16:18 [PATCH 00/11] irqchip: stm32: add exti support for stm32mp157c Ludovic Barre
` (7 preceding siblings ...)
2018-04-26 16:18 ` [PATCH 08/11] irqchip: stm32: add suspend/resume support for " Ludovic Barre
@ 2018-04-26 16:18 ` Ludovic Barre
2018-04-26 16:18 ` [PATCH 10/11] ARM: dts: stm32: add exti support for stm32mp157c Ludovic Barre
2018-04-26 16:18 ` [PATCH 11/11] ARM: dts: stm32: add exti support to stm32mp157 pinctrl Ludovic Barre
10 siblings, 0 replies; 20+ messages in thread
From: Ludovic Barre @ 2018-04-26 16:18 UTC (permalink / raw)
To: Thomas Gleixner, Jason Cooper, Marc Zyngier, Rob Herring
Cc: Maxime Coquelin, Alexandre Torgue, Gerald BAEZA, Loic PALLARDY,
linux-kernel, linux-arm-kernel, devicetree, Ludovic Barre
From: Ludovic Barre <ludovic.barre@st.com>
-Parent domain of stm32gpio evolves to hierarchy domain
and could have a handle_fasteoi_irq. So an irq_eoi parent callback
is needed for children.
-Replace space by tabulation.
Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
---
drivers/pinctrl/stm32/pinctrl-stm32.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c
index 6cbcff4..dfed609 100644
--- a/drivers/pinctrl/stm32/pinctrl-stm32.c
+++ b/drivers/pinctrl/stm32/pinctrl-stm32.c
@@ -267,12 +267,13 @@ static void stm32_gpio_irq_release_resources(struct irq_data *irq_data)
}
static struct irq_chip stm32_gpio_irq_chip = {
- .name = "stm32gpio",
- .irq_ack = irq_chip_ack_parent,
- .irq_mask = irq_chip_mask_parent,
- .irq_unmask = irq_chip_unmask_parent,
- .irq_set_type = irq_chip_set_type_parent,
- .irq_set_wake = irq_chip_set_wake_parent,
+ .name = "stm32gpio",
+ .irq_eoi = irq_chip_eoi_parent,
+ .irq_ack = irq_chip_ack_parent,
+ .irq_mask = irq_chip_mask_parent,
+ .irq_unmask = irq_chip_unmask_parent,
+ .irq_set_type = irq_chip_set_type_parent,
+ .irq_set_wake = irq_chip_set_wake_parent,
.irq_request_resources = stm32_gpio_irq_request_resources,
.irq_release_resources = stm32_gpio_irq_release_resources,
};
--
2.7.4
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 10/11] ARM: dts: stm32: add exti support for stm32mp157c
2018-04-26 16:18 [PATCH 00/11] irqchip: stm32: add exti support for stm32mp157c Ludovic Barre
` (8 preceding siblings ...)
2018-04-26 16:18 ` [PATCH 09/11] pinctrl: stm32: add irq_eoi for stm32gpio irqchip Ludovic Barre
@ 2018-04-26 16:18 ` Ludovic Barre
2018-04-26 16:18 ` [PATCH 11/11] ARM: dts: stm32: add exti support to stm32mp157 pinctrl Ludovic Barre
10 siblings, 0 replies; 20+ messages in thread
From: Ludovic Barre @ 2018-04-26 16:18 UTC (permalink / raw)
To: Thomas Gleixner, Jason Cooper, Marc Zyngier, Rob Herring
Cc: Maxime Coquelin, Alexandre Torgue, Gerald BAEZA, Loic PALLARDY,
linux-kernel, linux-arm-kernel, devicetree, Ludovic Barre
From: Ludovic Barre <ludovic.barre@st.com>
This patch adds external interrupt (exti) support
on stm32mp157c SoC.
Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
---
arch/arm/boot/dts/stm32mp157c.dtsi | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm/boot/dts/stm32mp157c.dtsi b/arch/arm/boot/dts/stm32mp157c.dtsi
index bfcf84b..e6fcf8f 100644
--- a/arch/arm/boot/dts/stm32mp157c.dtsi
+++ b/arch/arm/boot/dts/stm32mp157c.dtsi
@@ -167,6 +167,13 @@
#reset-cells = <1>;
};
+ exti: interrupt-controller@5000d000 {
+ compatible = "st,stm32mp1-exti", "syscon";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x5000d000 0x400>;
+ };
+
usart1: serial@5c000000 {
compatible = "st,stm32h7-uart";
reg = <0x5c000000 0x400>;
--
2.7.4
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 11/11] ARM: dts: stm32: add exti support to stm32mp157 pinctrl
2018-04-26 16:18 [PATCH 00/11] irqchip: stm32: add exti support for stm32mp157c Ludovic Barre
` (9 preceding siblings ...)
2018-04-26 16:18 ` [PATCH 10/11] ARM: dts: stm32: add exti support for stm32mp157c Ludovic Barre
@ 2018-04-26 16:18 ` Ludovic Barre
10 siblings, 0 replies; 20+ messages in thread
From: Ludovic Barre @ 2018-04-26 16:18 UTC (permalink / raw)
To: Thomas Gleixner, Jason Cooper, Marc Zyngier, Rob Herring
Cc: Maxime Coquelin, Alexandre Torgue, Gerald BAEZA, Loic PALLARDY,
linux-kernel, linux-arm-kernel, devicetree, Ludovic Barre
From: Ludovic Barre <ludovic.barre@st.com>
This patch adds support of external interrupt for
gpio[a..k], gpioz
Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
---
arch/arm/boot/dts/stm32mp157-pinctrl.dtsi | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm/boot/dts/stm32mp157-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp157-pinctrl.dtsi
index 6f044100..2f6872b 100644
--- a/arch/arm/boot/dts/stm32mp157-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stm32mp157-pinctrl.dtsi
@@ -12,6 +12,8 @@
#size-cells = <1>;
compatible = "st,stm32mp157-pinctrl";
ranges = <0 0x50002000 0xa400>;
+ interrupt-parent = <&exti>;
+ st,syscfg = <&exti 0x60 0xff>;
pins-are-numbered;
gpioa: gpio@50002000 {
@@ -166,6 +168,8 @@
compatible = "st,stm32mp157-z-pinctrl";
ranges = <0 0x54004000 0x400>;
pins-are-numbered;
+ interrupt-parent = <&exti>;
+ st,syscfg = <&exti 0x60 0xff>;
status = "disabled";
gpioz: gpio@54004000 {
--
2.7.4
^ permalink raw reply [flat|nested] 20+ messages in thread