aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLudovic Barre <ludovic.barre@st.com>2018-04-26 12:18:26 -0400
committerMarc Zyngier <marc.zyngier@arm.com>2018-05-24 07:38:20 -0400
commitbe6230f0c2bd5d2fe7530d04d015d454f235f21d (patch)
tree0232fd99da6d7694562ab9e655f1f1c890e51b02 /drivers
parentea80aa2a1a594fb21c8b5aec192e1d6deee686b0 (diff)
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/irqchip/irq-stm32-exti.c47
1 files changed, 36 insertions, 11 deletions
diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
index b91a8c289836..69a4453c2952 100644
--- a/drivers/irqchip/irq-stm32-exti.c
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -23,16 +23,20 @@ struct stm32_exti_bank {
23 u32 rtsr_ofst; 23 u32 rtsr_ofst;
24 u32 ftsr_ofst; 24 u32 ftsr_ofst;
25 u32 swier_ofst; 25 u32 swier_ofst;
26 u32 pr_ofst; 26 u32 rpr_ofst;
27 u32 fpr_ofst;
27}; 28};
28 29
30#define UNDEF_REG ~0
31
29static const struct stm32_exti_bank stm32f4xx_exti_b1 = { 32static const struct stm32_exti_bank stm32f4xx_exti_b1 = {
30 .imr_ofst = 0x00, 33 .imr_ofst = 0x00,
31 .emr_ofst = 0x04, 34 .emr_ofst = 0x04,
32 .rtsr_ofst = 0x08, 35 .rtsr_ofst = 0x08,
33 .ftsr_ofst = 0x0C, 36 .ftsr_ofst = 0x0C,
34 .swier_ofst = 0x10, 37 .swier_ofst = 0x10,
35 .pr_ofst = 0x14, 38 .rpr_ofst = 0x14,
39 .fpr_ofst = UNDEF_REG,
36}; 40};
37 41
38static const struct stm32_exti_bank *stm32f4xx_exti_banks[] = { 42static const struct stm32_exti_bank *stm32f4xx_exti_banks[] = {
@@ -45,7 +49,8 @@ static const struct stm32_exti_bank stm32h7xx_exti_b1 = {
45 .rtsr_ofst = 0x00, 49 .rtsr_ofst = 0x00,
46 .ftsr_ofst = 0x04, 50 .ftsr_ofst = 0x04,
47 .swier_ofst = 0x08, 51 .swier_ofst = 0x08,
48 .pr_ofst = 0x88, 52 .rpr_ofst = 0x88,
53 .fpr_ofst = UNDEF_REG,
49}; 54};
50 55
51static const struct stm32_exti_bank stm32h7xx_exti_b2 = { 56static const struct stm32_exti_bank stm32h7xx_exti_b2 = {
@@ -54,7 +59,8 @@ static const struct stm32_exti_bank stm32h7xx_exti_b2 = {
54 .rtsr_ofst = 0x20, 59 .rtsr_ofst = 0x20,
55 .ftsr_ofst = 0x24, 60 .ftsr_ofst = 0x24,
56 .swier_ofst = 0x28, 61 .swier_ofst = 0x28,
57 .pr_ofst = 0x98, 62 .rpr_ofst = 0x98,
63 .fpr_ofst = UNDEF_REG,
58}; 64};
59 65
60static const struct stm32_exti_bank stm32h7xx_exti_b3 = { 66static const struct stm32_exti_bank stm32h7xx_exti_b3 = {
@@ -63,7 +69,8 @@ static const struct stm32_exti_bank stm32h7xx_exti_b3 = {
63 .rtsr_ofst = 0x40, 69 .rtsr_ofst = 0x40,
64 .ftsr_ofst = 0x44, 70 .ftsr_ofst = 0x44,
65 .swier_ofst = 0x48, 71 .swier_ofst = 0x48,
66 .pr_ofst = 0xA8, 72 .rpr_ofst = 0xA8,
73 .fpr_ofst = UNDEF_REG,
67}; 74};
68 75
69static const struct stm32_exti_bank *stm32h7xx_exti_banks[] = { 76static const struct stm32_exti_bank *stm32h7xx_exti_banks[] = {
@@ -75,8 +82,13 @@ static const struct stm32_exti_bank *stm32h7xx_exti_banks[] = {
75static unsigned long stm32_exti_pending(struct irq_chip_generic *gc) 82static unsigned long stm32_exti_pending(struct irq_chip_generic *gc)
76{ 83{
77 const struct stm32_exti_bank *stm32_bank = gc->private; 84 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);
78 90
79 return irq_reg_readl(gc, stm32_bank->pr_ofst); 91 return pending;
80} 92}
81 93
82static void stm32_irq_handler(struct irq_desc *desc) 94static void stm32_irq_handler(struct irq_desc *desc)
@@ -85,7 +97,6 @@ static void stm32_irq_handler(struct irq_desc *desc)
85 struct irq_chip *chip = irq_desc_get_chip(desc); 97 struct irq_chip *chip = irq_desc_get_chip(desc);
86 unsigned int virq, nbanks = domain->gc->num_chips; 98 unsigned int virq, nbanks = domain->gc->num_chips;
87 struct irq_chip_generic *gc; 99 struct irq_chip_generic *gc;
88 const struct stm32_exti_bank *stm32_bank;
89 unsigned long pending; 100 unsigned long pending;
90 int n, i, irq_base = 0; 101 int n, i, irq_base = 0;
91 102
@@ -93,7 +104,6 @@ static void stm32_irq_handler(struct irq_desc *desc)
93 104
94 for (i = 0; i < nbanks; i++, irq_base += IRQS_PER_BANK) { 105 for (i = 0; i < nbanks; i++, irq_base += IRQS_PER_BANK) {
95 gc = irq_get_domain_generic_chip(domain, irq_base); 106 gc = irq_get_domain_generic_chip(domain, irq_base);
96 stm32_bank = gc->private;
97 107
98 while ((pending = stm32_exti_pending(gc))) { 108 while ((pending = stm32_exti_pending(gc))) {
99 for_each_set_bit(n, &pending, IRQS_PER_BANK) { 109 for_each_set_bit(n, &pending, IRQS_PER_BANK) {
@@ -192,6 +202,20 @@ static const struct irq_domain_ops irq_exti_domain_ops = {
192 .free = stm32_exti_free, 202 .free = stm32_exti_free,
193}; 203};
194 204
205static 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
195static int 219static int
196__init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks, 220__init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks,
197 int bank_nr, struct device_node *node) 221 int bank_nr, struct device_node *node)
@@ -233,12 +257,11 @@ __init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks,
233 257
234 gc->reg_base = base; 258 gc->reg_base = base;
235 gc->chip_types->type = IRQ_TYPE_EDGE_BOTH; 259 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;
237 gc->chip_types->chip.irq_mask = irq_gc_mask_clr_bit; 261 gc->chip_types->chip.irq_mask = irq_gc_mask_clr_bit;
238 gc->chip_types->chip.irq_unmask = irq_gc_mask_set_bit; 262 gc->chip_types->chip.irq_unmask = irq_gc_mask_set_bit;
239 gc->chip_types->chip.irq_set_type = stm32_irq_set_type; 263 gc->chip_types->chip.irq_set_type = stm32_irq_set_type;
240 gc->chip_types->chip.irq_set_wake = stm32_irq_set_wake; 264 gc->chip_types->chip.irq_set_wake = stm32_irq_set_wake;
241 gc->chip_types->regs.ack = stm32_bank->pr_ofst;
242 gc->chip_types->regs.mask = stm32_bank->imr_ofst; 265 gc->chip_types->regs.mask = stm32_bank->imr_ofst;
243 gc->private = (void *)stm32_bank; 266 gc->private = (void *)stm32_bank;
244 267
@@ -255,7 +278,9 @@ __init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks,
255 writel_relaxed(0, base + stm32_bank->emr_ofst); 278 writel_relaxed(0, base + stm32_bank->emr_ofst);
256 writel_relaxed(0, base + stm32_bank->rtsr_ofst); 279 writel_relaxed(0, base + stm32_bank->rtsr_ofst);
257 writel_relaxed(0, base + stm32_bank->ftsr_ofst); 280 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);
259 284
260 pr_info("%s: bank%d, External IRQs available:%#x\n", 285 pr_info("%s: bank%d, External IRQs available:%#x\n",
261 node->full_name, i, irqs_mask); 286 node->full_name, i, irqs_mask);