Skip to content

Commit be6230f

Browse files
ludovicbarreMarc Zyngier
authored andcommitted
irqchip/stm32: Add falling pending register support
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> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
1 parent ea80aa2 commit be6230f

File tree

1 file changed

+36
-11
lines changed

1 file changed

+36
-11
lines changed

drivers/irqchip/irq-stm32-exti.c

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,20 @@ struct stm32_exti_bank {
2323
u32 rtsr_ofst;
2424
u32 ftsr_ofst;
2525
u32 swier_ofst;
26-
u32 pr_ofst;
26+
u32 rpr_ofst;
27+
u32 fpr_ofst;
2728
};
2829

30+
#define UNDEF_REG ~0
31+
2932
static const struct stm32_exti_bank stm32f4xx_exti_b1 = {
3033
.imr_ofst = 0x00,
3134
.emr_ofst = 0x04,
3235
.rtsr_ofst = 0x08,
3336
.ftsr_ofst = 0x0C,
3437
.swier_ofst = 0x10,
35-
.pr_ofst = 0x14,
38+
.rpr_ofst = 0x14,
39+
.fpr_ofst = UNDEF_REG,
3640
};
3741

3842
static const struct stm32_exti_bank *stm32f4xx_exti_banks[] = {
@@ -45,7 +49,8 @@ static const struct stm32_exti_bank stm32h7xx_exti_b1 = {
4549
.rtsr_ofst = 0x00,
4650
.ftsr_ofst = 0x04,
4751
.swier_ofst = 0x08,
48-
.pr_ofst = 0x88,
52+
.rpr_ofst = 0x88,
53+
.fpr_ofst = UNDEF_REG,
4954
};
5055

5156
static const struct stm32_exti_bank stm32h7xx_exti_b2 = {
@@ -54,7 +59,8 @@ static const struct stm32_exti_bank stm32h7xx_exti_b2 = {
5459
.rtsr_ofst = 0x20,
5560
.ftsr_ofst = 0x24,
5661
.swier_ofst = 0x28,
57-
.pr_ofst = 0x98,
62+
.rpr_ofst = 0x98,
63+
.fpr_ofst = UNDEF_REG,
5864
};
5965

6066
static const struct stm32_exti_bank stm32h7xx_exti_b3 = {
@@ -63,7 +69,8 @@ static const struct stm32_exti_bank stm32h7xx_exti_b3 = {
6369
.rtsr_ofst = 0x40,
6470
.ftsr_ofst = 0x44,
6571
.swier_ofst = 0x48,
66-
.pr_ofst = 0xA8,
72+
.rpr_ofst = 0xA8,
73+
.fpr_ofst = UNDEF_REG,
6774
};
6875

6976
static const struct stm32_exti_bank *stm32h7xx_exti_banks[] = {
@@ -75,8 +82,13 @@ static const struct stm32_exti_bank *stm32h7xx_exti_banks[] = {
7582
static unsigned long stm32_exti_pending(struct irq_chip_generic *gc)
7683
{
7784
const struct stm32_exti_bank *stm32_bank = gc->private;
85+
unsigned long pending;
86+
87+
pending = irq_reg_readl(gc, stm32_bank->rpr_ofst);
88+
if (stm32_bank->fpr_ofst != UNDEF_REG)
89+
pending |= irq_reg_readl(gc, stm32_bank->fpr_ofst);
7890

79-
return irq_reg_readl(gc, stm32_bank->pr_ofst);
91+
return pending;
8092
}
8193

8294
static void stm32_irq_handler(struct irq_desc *desc)
@@ -85,15 +97,13 @@ static void stm32_irq_handler(struct irq_desc *desc)
8597
struct irq_chip *chip = irq_desc_get_chip(desc);
8698
unsigned int virq, nbanks = domain->gc->num_chips;
8799
struct irq_chip_generic *gc;
88-
const struct stm32_exti_bank *stm32_bank;
89100
unsigned long pending;
90101
int n, i, irq_base = 0;
91102

92103
chained_irq_enter(chip, desc);
93104

94105
for (i = 0; i < nbanks; i++, irq_base += IRQS_PER_BANK) {
95106
gc = irq_get_domain_generic_chip(domain, irq_base);
96-
stm32_bank = gc->private;
97107

98108
while ((pending = stm32_exti_pending(gc))) {
99109
for_each_set_bit(n, &pending, IRQS_PER_BANK) {
@@ -192,6 +202,20 @@ static const struct irq_domain_ops irq_exti_domain_ops = {
192202
.free = stm32_exti_free,
193203
};
194204

205+
static void stm32_irq_ack(struct irq_data *d)
206+
{
207+
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
208+
const struct stm32_exti_bank *stm32_bank = gc->private;
209+
210+
irq_gc_lock(gc);
211+
212+
irq_reg_writel(gc, d->mask, stm32_bank->rpr_ofst);
213+
if (stm32_bank->fpr_ofst != UNDEF_REG)
214+
irq_reg_writel(gc, d->mask, stm32_bank->fpr_ofst);
215+
216+
irq_gc_unlock(gc);
217+
}
218+
195219
static int
196220
__init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks,
197221
int bank_nr, struct device_node *node)
@@ -233,12 +257,11 @@ __init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks,
233257

234258
gc->reg_base = base;
235259
gc->chip_types->type = IRQ_TYPE_EDGE_BOTH;
236-
gc->chip_types->chip.irq_ack = irq_gc_ack_set_bit;
260+
gc->chip_types->chip.irq_ack = stm32_irq_ack;
237261
gc->chip_types->chip.irq_mask = irq_gc_mask_clr_bit;
238262
gc->chip_types->chip.irq_unmask = irq_gc_mask_set_bit;
239263
gc->chip_types->chip.irq_set_type = stm32_irq_set_type;
240264
gc->chip_types->chip.irq_set_wake = stm32_irq_set_wake;
241-
gc->chip_types->regs.ack = stm32_bank->pr_ofst;
242265
gc->chip_types->regs.mask = stm32_bank->imr_ofst;
243266
gc->private = (void *)stm32_bank;
244267

@@ -255,7 +278,9 @@ __init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks,
255278
writel_relaxed(0, base + stm32_bank->emr_ofst);
256279
writel_relaxed(0, base + stm32_bank->rtsr_ofst);
257280
writel_relaxed(0, base + stm32_bank->ftsr_ofst);
258-
writel_relaxed(~0UL, base + stm32_bank->pr_ofst);
281+
writel_relaxed(~0UL, base + stm32_bank->rpr_ofst);
282+
if (stm32_bank->fpr_ofst != UNDEF_REG)
283+
writel_relaxed(~0UL, base + stm32_bank->fpr_ofst);
259284

260285
pr_info("%s: bank%d, External IRQs available:%#x\n",
261286
node->full_name, i, irqs_mask);

0 commit comments

Comments
 (0)