Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.18 412 lines 10 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) Maxime Coquelin 2015 4 * Copyright (C) STMicroelectronics 2017-2024 5 * Author: Maxime Coquelin <mcoquelin.stm32@gmail.com> 6 */ 7 8#include <linux/bitops.h> 9#include <linux/interrupt.h> 10#include <linux/io.h> 11#include <linux/irq.h> 12#include <linux/irqchip.h> 13#include <linux/irqchip/chained_irq.h> 14#include <linux/irqdomain.h> 15#include <linux/of_address.h> 16#include <linux/of_irq.h> 17 18#define IRQS_PER_BANK 32 19 20struct stm32_exti_bank { 21 u32 imr_ofst; 22 u32 emr_ofst; 23 u32 rtsr_ofst; 24 u32 ftsr_ofst; 25 u32 swier_ofst; 26 u32 rpr_ofst; 27}; 28 29struct stm32_exti_drv_data { 30 const struct stm32_exti_bank **exti_banks; 31 const u8 *desc_irqs; 32 u32 bank_nr; 33}; 34 35struct stm32_exti_chip_data { 36 struct stm32_exti_host_data *host_data; 37 const struct stm32_exti_bank *reg_bank; 38 u32 wake_active; 39 u32 mask_cache; 40 u32 rtsr_cache; 41 u32 ftsr_cache; 42 u32 event_reserved; 43}; 44 45struct stm32_exti_host_data { 46 void __iomem *base; 47 struct device *dev; 48 struct stm32_exti_chip_data *chips_data; 49 const struct stm32_exti_drv_data *drv_data; 50}; 51 52static const struct stm32_exti_bank stm32f4xx_exti_b1 = { 53 .imr_ofst = 0x00, 54 .emr_ofst = 0x04, 55 .rtsr_ofst = 0x08, 56 .ftsr_ofst = 0x0C, 57 .swier_ofst = 0x10, 58 .rpr_ofst = 0x14, 59}; 60 61static const struct stm32_exti_bank *stm32f4xx_exti_banks[] = { 62 &stm32f4xx_exti_b1, 63}; 64 65static const struct stm32_exti_drv_data stm32f4xx_drv_data = { 66 .exti_banks = stm32f4xx_exti_banks, 67 .bank_nr = ARRAY_SIZE(stm32f4xx_exti_banks), 68}; 69 70static const struct stm32_exti_bank stm32h7xx_exti_b1 = { 71 .imr_ofst = 0x80, 72 .emr_ofst = 0x84, 73 .rtsr_ofst = 0x00, 74 .ftsr_ofst = 0x04, 75 .swier_ofst = 0x08, 76 .rpr_ofst = 0x88, 77}; 78 79static const struct stm32_exti_bank stm32h7xx_exti_b2 = { 80 .imr_ofst = 0x90, 81 .emr_ofst = 0x94, 82 .rtsr_ofst = 0x20, 83 .ftsr_ofst = 0x24, 84 .swier_ofst = 0x28, 85 .rpr_ofst = 0x98, 86}; 87 88static const struct stm32_exti_bank stm32h7xx_exti_b3 = { 89 .imr_ofst = 0xA0, 90 .emr_ofst = 0xA4, 91 .rtsr_ofst = 0x40, 92 .ftsr_ofst = 0x44, 93 .swier_ofst = 0x48, 94 .rpr_ofst = 0xA8, 95}; 96 97static const struct stm32_exti_bank *stm32h7xx_exti_banks[] = { 98 &stm32h7xx_exti_b1, 99 &stm32h7xx_exti_b2, 100 &stm32h7xx_exti_b3, 101}; 102 103static const struct stm32_exti_drv_data stm32h7xx_drv_data = { 104 .exti_banks = stm32h7xx_exti_banks, 105 .bank_nr = ARRAY_SIZE(stm32h7xx_exti_banks), 106}; 107 108static unsigned long stm32_exti_pending(struct irq_chip_generic *gc) 109{ 110 struct stm32_exti_chip_data *chip_data = gc->private; 111 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; 112 113 return irq_reg_readl(gc, stm32_bank->rpr_ofst); 114} 115 116static void stm32_irq_handler(struct irq_desc *desc) 117{ 118 struct irq_domain *domain = irq_desc_get_handler_data(desc); 119 struct irq_chip *chip = irq_desc_get_chip(desc); 120 unsigned int nbanks = domain->gc->num_chips; 121 struct irq_chip_generic *gc; 122 unsigned long pending; 123 int n, i, irq_base = 0; 124 125 chained_irq_enter(chip, desc); 126 127 for (i = 0; i < nbanks; i++, irq_base += IRQS_PER_BANK) { 128 gc = irq_get_domain_generic_chip(domain, irq_base); 129 130 while ((pending = stm32_exti_pending(gc))) { 131 for_each_set_bit(n, &pending, IRQS_PER_BANK) 132 generic_handle_domain_irq(domain, irq_base + n); 133 } 134 } 135 136 chained_irq_exit(chip, desc); 137} 138 139static int stm32_exti_set_type(struct irq_data *d, 140 unsigned int type, u32 *rtsr, u32 *ftsr) 141{ 142 u32 mask = BIT(d->hwirq % IRQS_PER_BANK); 143 144 switch (type) { 145 case IRQ_TYPE_EDGE_RISING: 146 *rtsr |= mask; 147 *ftsr &= ~mask; 148 break; 149 case IRQ_TYPE_EDGE_FALLING: 150 *rtsr &= ~mask; 151 *ftsr |= mask; 152 break; 153 case IRQ_TYPE_EDGE_BOTH: 154 *rtsr |= mask; 155 *ftsr |= mask; 156 break; 157 default: 158 return -EINVAL; 159 } 160 161 return 0; 162} 163 164static int stm32_irq_set_type(struct irq_data *d, unsigned int type) 165{ 166 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 167 struct stm32_exti_chip_data *chip_data = gc->private; 168 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; 169 u32 rtsr, ftsr; 170 int err; 171 172 guard(raw_spinlock)(&gc->lock); 173 174 rtsr = irq_reg_readl(gc, stm32_bank->rtsr_ofst); 175 ftsr = irq_reg_readl(gc, stm32_bank->ftsr_ofst); 176 177 err = stm32_exti_set_type(d, type, &rtsr, &ftsr); 178 if (err) 179 return err; 180 181 irq_reg_writel(gc, rtsr, stm32_bank->rtsr_ofst); 182 irq_reg_writel(gc, ftsr, stm32_bank->ftsr_ofst); 183 return 0; 184} 185 186static void stm32_chip_suspend(struct stm32_exti_chip_data *chip_data, 187 u32 wake_active) 188{ 189 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; 190 void __iomem *base = chip_data->host_data->base; 191 192 /* save rtsr, ftsr registers */ 193 chip_data->rtsr_cache = readl_relaxed(base + stm32_bank->rtsr_ofst); 194 chip_data->ftsr_cache = readl_relaxed(base + stm32_bank->ftsr_ofst); 195 196 writel_relaxed(wake_active, base + stm32_bank->imr_ofst); 197} 198 199static void stm32_chip_resume(struct stm32_exti_chip_data *chip_data, 200 u32 mask_cache) 201{ 202 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; 203 void __iomem *base = chip_data->host_data->base; 204 205 /* restore rtsr, ftsr, registers */ 206 writel_relaxed(chip_data->rtsr_cache, base + stm32_bank->rtsr_ofst); 207 writel_relaxed(chip_data->ftsr_cache, base + stm32_bank->ftsr_ofst); 208 209 writel_relaxed(mask_cache, base + stm32_bank->imr_ofst); 210} 211 212static void stm32_irq_suspend(struct irq_chip_generic *gc) 213{ 214 struct stm32_exti_chip_data *chip_data = gc->private; 215 216 guard(raw_spinlock)(&gc->lock); 217 stm32_chip_suspend(chip_data, gc->wake_active); 218} 219 220static void stm32_irq_resume(struct irq_chip_generic *gc) 221{ 222 struct stm32_exti_chip_data *chip_data = gc->private; 223 224 guard(raw_spinlock)(&gc->lock); 225 stm32_chip_resume(chip_data, gc->mask_cache); 226} 227 228static int stm32_exti_alloc(struct irq_domain *d, unsigned int virq, 229 unsigned int nr_irqs, void *data) 230{ 231 struct irq_fwspec *fwspec = data; 232 irq_hw_number_t hwirq; 233 234 hwirq = fwspec->param[0]; 235 236 irq_map_generic_chip(d, virq, hwirq); 237 238 return 0; 239} 240 241static void stm32_exti_free(struct irq_domain *d, unsigned int virq, 242 unsigned int nr_irqs) 243{ 244 struct irq_data *data = irq_domain_get_irq_data(d, virq); 245 246 irq_domain_reset_irq_data(data); 247} 248 249static const struct irq_domain_ops irq_exti_domain_ops = { 250 .map = irq_map_generic_chip, 251 .alloc = stm32_exti_alloc, 252 .free = stm32_exti_free, 253 .xlate = irq_domain_xlate_twocell, 254}; 255 256static void stm32_irq_ack(struct irq_data *d) 257{ 258 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 259 struct stm32_exti_chip_data *chip_data = gc->private; 260 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; 261 262 guard(raw_spinlock)(&gc->lock); 263 irq_reg_writel(gc, d->mask, stm32_bank->rpr_ofst); 264} 265 266static struct 267stm32_exti_host_data *stm32_exti_host_init(const struct stm32_exti_drv_data *dd, 268 struct device_node *node) 269{ 270 struct stm32_exti_host_data *host_data; 271 272 host_data = kzalloc(sizeof(*host_data), GFP_KERNEL); 273 if (!host_data) 274 return NULL; 275 276 host_data->drv_data = dd; 277 host_data->chips_data = kcalloc(dd->bank_nr, 278 sizeof(struct stm32_exti_chip_data), 279 GFP_KERNEL); 280 if (!host_data->chips_data) 281 goto free_host_data; 282 283 host_data->base = of_iomap(node, 0); 284 if (!host_data->base) { 285 pr_err("%pOF: Unable to map registers\n", node); 286 goto free_chips_data; 287 } 288 289 return host_data; 290 291free_chips_data: 292 kfree(host_data->chips_data); 293free_host_data: 294 kfree(host_data); 295 296 return NULL; 297} 298 299static struct 300stm32_exti_chip_data *stm32_exti_chip_init(struct stm32_exti_host_data *h_data, 301 u32 bank_idx, 302 struct device_node *node) 303{ 304 const struct stm32_exti_bank *stm32_bank; 305 struct stm32_exti_chip_data *chip_data; 306 void __iomem *base = h_data->base; 307 308 stm32_bank = h_data->drv_data->exti_banks[bank_idx]; 309 chip_data = &h_data->chips_data[bank_idx]; 310 chip_data->host_data = h_data; 311 chip_data->reg_bank = stm32_bank; 312 313 /* 314 * This IP has no reset, so after hot reboot we should 315 * clear registers to avoid residue 316 */ 317 writel_relaxed(0, base + stm32_bank->imr_ofst); 318 writel_relaxed(0, base + stm32_bank->emr_ofst); 319 320 pr_info("%pOF: bank%d\n", node, bank_idx); 321 322 return chip_data; 323} 324 325static int __init stm32_exti_init(const struct stm32_exti_drv_data *drv_data, 326 struct device_node *node) 327{ 328 struct stm32_exti_host_data *host_data; 329 unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; 330 int nr_irqs, ret, i; 331 struct irq_chip_generic *gc; 332 struct irq_domain *domain; 333 334 host_data = stm32_exti_host_init(drv_data, node); 335 if (!host_data) 336 return -ENOMEM; 337 338 domain = irq_domain_create_linear(of_fwnode_handle(node), drv_data->bank_nr * IRQS_PER_BANK, 339 &irq_exti_domain_ops, NULL); 340 if (!domain) { 341 pr_err("%pOFn: Could not register interrupt domain.\n", 342 node); 343 ret = -ENOMEM; 344 goto out_unmap; 345 } 346 347 ret = irq_alloc_domain_generic_chips(domain, IRQS_PER_BANK, 1, "exti", 348 handle_edge_irq, clr, 0, 0); 349 if (ret) { 350 pr_err("%pOF: Could not allocate generic interrupt chip.\n", 351 node); 352 goto out_free_domain; 353 } 354 355 for (i = 0; i < drv_data->bank_nr; i++) { 356 const struct stm32_exti_bank *stm32_bank; 357 struct stm32_exti_chip_data *chip_data; 358 359 stm32_bank = drv_data->exti_banks[i]; 360 chip_data = stm32_exti_chip_init(host_data, i, node); 361 362 gc = irq_get_domain_generic_chip(domain, i * IRQS_PER_BANK); 363 364 gc->reg_base = host_data->base; 365 gc->chip_types->type = IRQ_TYPE_EDGE_BOTH; 366 gc->chip_types->chip.irq_ack = stm32_irq_ack; 367 gc->chip_types->chip.irq_mask = irq_gc_mask_clr_bit; 368 gc->chip_types->chip.irq_unmask = irq_gc_mask_set_bit; 369 gc->chip_types->chip.irq_set_type = stm32_irq_set_type; 370 gc->chip_types->chip.irq_set_wake = irq_gc_set_wake; 371 gc->suspend = stm32_irq_suspend; 372 gc->resume = stm32_irq_resume; 373 gc->wake_enabled = IRQ_MSK(IRQS_PER_BANK); 374 375 gc->chip_types->regs.mask = stm32_bank->imr_ofst; 376 gc->private = (void *)chip_data; 377 } 378 379 nr_irqs = of_irq_count(node); 380 for (i = 0; i < nr_irqs; i++) { 381 unsigned int irq = irq_of_parse_and_map(node, i); 382 383 irq_set_handler_data(irq, domain); 384 irq_set_chained_handler(irq, stm32_irq_handler); 385 } 386 387 return 0; 388 389out_free_domain: 390 irq_domain_remove(domain); 391out_unmap: 392 iounmap(host_data->base); 393 kfree(host_data->chips_data); 394 kfree(host_data); 395 return ret; 396} 397 398static int __init stm32f4_exti_of_init(struct device_node *np, 399 struct device_node *parent) 400{ 401 return stm32_exti_init(&stm32f4xx_drv_data, np); 402} 403 404IRQCHIP_DECLARE(stm32f4_exti, "st,stm32-exti", stm32f4_exti_of_init); 405 406static int __init stm32h7_exti_of_init(struct device_node *np, 407 struct device_node *parent) 408{ 409 return stm32_exti_init(&stm32h7xx_drv_data, np); 410} 411 412IRQCHIP_DECLARE(stm32h7_exti, "st,stm32h7-exti", stm32h7_exti_of_init);