aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLudovic Barre <ludovic.barre@st.com>2018-04-26 12:18:27 -0400
committerMarc Zyngier <marc.zyngier@arm.com>2018-05-24 07:38:20 -0400
commitd9e2b19b02744068b1cc16ca7d5249a62e789601 (patch)
tree2b9b363d6174e550c665a1f3173418aa0897eff1
parentbe6230f0c2bd5d2fe7530d04d015d454f235f21d (diff)
irqchip/stm32: Add suspend support
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> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
-rw-r--r--drivers/irqchip/irq-stm32-exti.c69
1 files changed, 52 insertions, 17 deletions
diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
index 69a4453c2952..1e0966714e83 100644
--- a/drivers/irqchip/irq-stm32-exti.c
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -29,6 +29,14 @@ struct stm32_exti_bank {
29 29
30#define UNDEF_REG ~0 30#define UNDEF_REG ~0
31 31
32struct stm32_exti_chip_data {
33 const struct stm32_exti_bank *reg_bank;
34 u32 rtsr_cache;
35 u32 ftsr_cache;
36};
37
38static struct stm32_exti_chip_data *stm32_exti_data;
39
32static const struct stm32_exti_bank stm32f4xx_exti_b1 = { 40static const struct stm32_exti_bank stm32f4xx_exti_b1 = {
33 .imr_ofst = 0x00, 41 .imr_ofst = 0x00,
34 .emr_ofst = 0x04, 42 .emr_ofst = 0x04,
@@ -81,7 +89,8 @@ static const struct stm32_exti_bank *stm32h7xx_exti_banks[] = {
81 89
82static unsigned long stm32_exti_pending(struct irq_chip_generic *gc) 90static unsigned long stm32_exti_pending(struct irq_chip_generic *gc)
83{ 91{
84 const struct stm32_exti_bank *stm32_bank = gc->private; 92 struct stm32_exti_chip_data *chip_data = gc->private;
93 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
85 unsigned long pending; 94 unsigned long pending;
86 95
87 pending = irq_reg_readl(gc, stm32_bank->rpr_ofst); 96 pending = irq_reg_readl(gc, stm32_bank->rpr_ofst);
@@ -119,7 +128,8 @@ static void stm32_irq_handler(struct irq_desc *desc)
119static int stm32_irq_set_type(struct irq_data *data, unsigned int type) 128static int stm32_irq_set_type(struct irq_data *data, unsigned int type)
120{ 129{
121 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data); 130 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
122 const struct stm32_exti_bank *stm32_bank = gc->private; 131 struct stm32_exti_chip_data *chip_data = gc->private;
132 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
123 int pin = data->hwirq % IRQS_PER_BANK; 133 int pin = data->hwirq % IRQS_PER_BANK;
124 u32 rtsr, ftsr; 134 u32 rtsr, ftsr;
125 135
@@ -154,25 +164,36 @@ static int stm32_irq_set_type(struct irq_data *data, unsigned int type)
154 return 0; 164 return 0;
155} 165}
156 166
157static int stm32_irq_set_wake(struct irq_data *data, unsigned int on) 167static void stm32_irq_suspend(struct irq_chip_generic *gc)
158{ 168{
159 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data); 169 struct stm32_exti_chip_data *chip_data = gc->private;
160 const struct stm32_exti_bank *stm32_bank = gc->private; 170 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
161 int pin = data->hwirq % IRQS_PER_BANK;
162 u32 imr;
163 171
164 irq_gc_lock(gc); 172 irq_gc_lock(gc);
165 173
166 imr = irq_reg_readl(gc, stm32_bank->imr_ofst); 174 /* save rtsr, ftsr registers */
167 if (on) 175 chip_data->rtsr_cache = irq_reg_readl(gc, stm32_bank->rtsr_ofst);
168 imr |= BIT(pin); 176 chip_data->ftsr_cache = irq_reg_readl(gc, stm32_bank->ftsr_ofst);
169 else 177
170 imr &= ~BIT(pin); 178 irq_reg_writel(gc, gc->wake_active, stm32_bank->imr_ofst);
171 irq_reg_writel(gc, imr, stm32_bank->imr_ofst);
172 179
173 irq_gc_unlock(gc); 180 irq_gc_unlock(gc);
181}
174 182
175 return 0; 183static void stm32_irq_resume(struct irq_chip_generic *gc)
184{
185 struct stm32_exti_chip_data *chip_data = gc->private;
186 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
187
188 irq_gc_lock(gc);
189
190 /* restore rtsr, ftsr registers */
191 irq_reg_writel(gc, chip_data->rtsr_cache, stm32_bank->rtsr_ofst);
192 irq_reg_writel(gc, chip_data->ftsr_cache, stm32_bank->ftsr_ofst);
193
194 irq_reg_writel(gc, gc->mask_cache, stm32_bank->imr_ofst);
195
196 irq_gc_unlock(gc);
176} 197}
177 198
178static int stm32_exti_alloc(struct irq_domain *d, unsigned int virq, 199static 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 = {
205static void stm32_irq_ack(struct irq_data *d) 226static void stm32_irq_ack(struct irq_data *d)
206{ 227{
207 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 228 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
208 const struct stm32_exti_bank *stm32_bank = gc->private; 229 struct stm32_exti_chip_data *chip_data = gc->private;
230 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
209 231
210 irq_gc_lock(gc); 232 irq_gc_lock(gc);
211 233
@@ -232,6 +254,11 @@ __init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks,
232 return -ENOMEM; 254 return -ENOMEM;
233 } 255 }
234 256
257 stm32_exti_data = kcalloc(bank_nr, sizeof(*stm32_exti_data),
258 GFP_KERNEL);
259 if (!stm32_exti_data)
260 return -ENOMEM;
261
235 domain = irq_domain_add_linear(node, bank_nr * IRQS_PER_BANK, 262 domain = irq_domain_add_linear(node, bank_nr * IRQS_PER_BANK,
236 &irq_exti_domain_ops, NULL); 263 &irq_exti_domain_ops, NULL);
237 if (!domain) { 264 if (!domain) {
@@ -251,8 +278,11 @@ __init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks,
251 278
252 for (i = 0; i < bank_nr; i++) { 279 for (i = 0; i < bank_nr; i++) {
253 const struct stm32_exti_bank *stm32_bank = stm32_exti_banks[i]; 280 const struct stm32_exti_bank *stm32_bank = stm32_exti_banks[i];
281 struct stm32_exti_chip_data *chip_data = &stm32_exti_data[i];
254 u32 irqs_mask; 282 u32 irqs_mask;
255 283
284 chip_data->reg_bank = stm32_bank;
285
256 gc = irq_get_domain_generic_chip(domain, i * IRQS_PER_BANK); 286 gc = irq_get_domain_generic_chip(domain, i * IRQS_PER_BANK);
257 287
258 gc->reg_base = base; 288 gc->reg_base = base;
@@ -261,9 +291,13 @@ __init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks,
261 gc->chip_types->chip.irq_mask = irq_gc_mask_clr_bit; 291 gc->chip_types->chip.irq_mask = irq_gc_mask_clr_bit;
262 gc->chip_types->chip.irq_unmask = irq_gc_mask_set_bit; 292 gc->chip_types->chip.irq_unmask = irq_gc_mask_set_bit;
263 gc->chip_types->chip.irq_set_type = stm32_irq_set_type; 293 gc->chip_types->chip.irq_set_type = stm32_irq_set_type;
264 gc->chip_types->chip.irq_set_wake = stm32_irq_set_wake; 294 gc->chip_types->chip.irq_set_wake = irq_gc_set_wake;
295 gc->suspend = stm32_irq_suspend;
296 gc->resume = stm32_irq_resume;
297 gc->wake_enabled = IRQ_MSK(IRQS_PER_BANK);
298
265 gc->chip_types->regs.mask = stm32_bank->imr_ofst; 299 gc->chip_types->regs.mask = stm32_bank->imr_ofst;
266 gc->private = (void *)stm32_bank; 300 gc->private = (void *)chip_data;
267 301
268 /* Determine number of irqs supported */ 302 /* Determine number of irqs supported */
269 writel_relaxed(~0UL, base + stm32_bank->rtsr_ofst); 303 writel_relaxed(~0UL, base + stm32_bank->rtsr_ofst);
@@ -300,6 +334,7 @@ out_free_domain:
300 irq_domain_remove(domain); 334 irq_domain_remove(domain);
301out_unmap: 335out_unmap:
302 iounmap(base); 336 iounmap(base);
337 kfree(stm32_exti_data);
303 return ret; 338 return ret;
304} 339}
305 340