1 /* 2 * regmap based irq_chip 3 * 4 * Copyright 2011 Wolfson Microelectronics plc 5 * 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 */ 12 13 #include <linux/export.h> 14 #include <linux/device.h> 15 #include <linux/regmap.h> 16 #include <linux/irq.h> 17 #include <linux/interrupt.h> 18 #include <linux/irqdomain.h> 19 #include <linux/pm_runtime.h> 20 #include <linux/slab.h> 21 22 #include "internal.h" 23 24 struct regmap_irq_chip_data { 25 struct mutex lock; 26 struct irq_chip irq_chip; 27 28 struct regmap *map; 29 const struct regmap_irq_chip *chip; 30 31 int irq_base; 32 struct irq_domain *domain; 33 34 int irq; 35 int wake_count; 36 37 unsigned int *status_buf; 38 unsigned int *mask_buf; 39 unsigned int *mask_buf_def; 40 unsigned int *wake_buf; 41 42 unsigned int irq_reg_stride; 43 }; 44 45 static inline const 46 struct regmap_irq *irq_to_regmap_irq(struct regmap_irq_chip_data *data, 47 int irq) 48 { 49 return &data->chip->irqs[irq]; 50 } 51 52 static void regmap_irq_lock(struct irq_data *data) 53 { 54 struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); 55 56 mutex_lock(&d->lock); 57 } 58 59 static void regmap_irq_sync_unlock(struct irq_data *data) 60 { 61 struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); 62 struct regmap *map = d->map; 63 int i, ret; 64 u32 reg; 65 66 if (d->chip->runtime_pm) { 67 ret = pm_runtime_get_sync(map->dev); 68 if (ret < 0) 69 dev_err(map->dev, "IRQ sync failed to resume: %d\n", 70 ret); 71 } 72 73 /* 74 * If there's been a change in the mask write it back to the 75 * hardware. We rely on the use of the regmap core cache to 76 * suppress pointless writes. 77 */ 78 for (i = 0; i < d->chip->num_regs; i++) { 79 reg = d->chip->mask_base + 80 (i * map->reg_stride * d->irq_reg_stride); 81 if (d->chip->mask_invert) 82 ret = regmap_update_bits(d->map, reg, 83 d->mask_buf_def[i], ~d->mask_buf[i]); 84 else 85 ret = regmap_update_bits(d->map, reg, 86 d->mask_buf_def[i], d->mask_buf[i]); 87 if (ret != 0) 88 dev_err(d->map->dev, "Failed to sync masks in %x\n", 89 reg); 90 } 91 92 if (d->chip->runtime_pm) 93 pm_runtime_put(map->dev); 94 95 /* If we've changed our wakeup count propagate it to the parent */ 96 if (d->wake_count < 0) 97 for (i = d->wake_count; i < 0; i++) 98 irq_set_irq_wake(d->irq, 0); 99 else if (d->wake_count > 0) 100 for (i = 0; i < d->wake_count; i++) 101 irq_set_irq_wake(d->irq, 1); 102 103 d->wake_count = 0; 104 105 mutex_unlock(&d->lock); 106 } 107 108 static void regmap_irq_enable(struct irq_data *data) 109 { 110 struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); 111 struct regmap *map = d->map; 112 const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq); 113 114 d->mask_buf[irq_data->reg_offset / map->reg_stride] &= ~irq_data->mask; 115 } 116 117 static void regmap_irq_disable(struct irq_data *data) 118 { 119 struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); 120 struct regmap *map = d->map; 121 const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq); 122 123 d->mask_buf[irq_data->reg_offset / map->reg_stride] |= irq_data->mask; 124 } 125 126 static int regmap_irq_set_wake(struct irq_data *data, unsigned int on) 127 { 128 struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); 129 struct regmap *map = d->map; 130 const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq); 131 132 if (!d->chip->wake_base) 133 return -EINVAL; 134 135 if (on) { 136 d->wake_buf[irq_data->reg_offset / map->reg_stride] 137 &= ~irq_data->mask; 138 d->wake_count++; 139 } else { 140 d->wake_buf[irq_data->reg_offset / map->reg_stride] 141 |= irq_data->mask; 142 d->wake_count--; 143 } 144 145 return 0; 146 } 147 148 static const struct irq_chip regmap_irq_chip = { 149 .irq_bus_lock = regmap_irq_lock, 150 .irq_bus_sync_unlock = regmap_irq_sync_unlock, 151 .irq_disable = regmap_irq_disable, 152 .irq_enable = regmap_irq_enable, 153 .irq_set_wake = regmap_irq_set_wake, 154 }; 155 156 static irqreturn_t regmap_irq_thread(int irq, void *d) 157 { 158 struct regmap_irq_chip_data *data = d; 159 const struct regmap_irq_chip *chip = data->chip; 160 struct regmap *map = data->map; 161 int ret, i; 162 bool handled = false; 163 u32 reg; 164 165 if (chip->runtime_pm) { 166 ret = pm_runtime_get_sync(map->dev); 167 if (ret < 0) { 168 dev_err(map->dev, "IRQ thread failed to resume: %d\n", 169 ret); 170 return IRQ_NONE; 171 } 172 } 173 174 /* 175 * Ignore masked IRQs and ack if we need to; we ack early so 176 * there is no race between handling and acknowleding the 177 * interrupt. We assume that typically few of the interrupts 178 * will fire simultaneously so don't worry about overhead from 179 * doing a write per register. 180 */ 181 for (i = 0; i < data->chip->num_regs; i++) { 182 ret = regmap_read(map, chip->status_base + (i * map->reg_stride 183 * data->irq_reg_stride), 184 &data->status_buf[i]); 185 186 if (ret != 0) { 187 dev_err(map->dev, "Failed to read IRQ status: %d\n", 188 ret); 189 if (chip->runtime_pm) 190 pm_runtime_put(map->dev); 191 return IRQ_NONE; 192 } 193 194 data->status_buf[i] &= ~data->mask_buf[i]; 195 196 if (data->status_buf[i] && chip->ack_base) { 197 reg = chip->ack_base + 198 (i * map->reg_stride * data->irq_reg_stride); 199 ret = regmap_write(map, reg, data->status_buf[i]); 200 if (ret != 0) 201 dev_err(map->dev, "Failed to ack 0x%x: %d\n", 202 reg, ret); 203 } 204 } 205 206 for (i = 0; i < chip->num_irqs; i++) { 207 if (data->status_buf[chip->irqs[i].reg_offset / 208 map->reg_stride] & chip->irqs[i].mask) { 209 handle_nested_irq(irq_find_mapping(data->domain, i)); 210 handled = true; 211 } 212 } 213 214 if (chip->runtime_pm) 215 pm_runtime_put(map->dev); 216 217 if (handled) 218 return IRQ_HANDLED; 219 else 220 return IRQ_NONE; 221 } 222 223 static int regmap_irq_map(struct irq_domain *h, unsigned int virq, 224 irq_hw_number_t hw) 225 { 226 struct regmap_irq_chip_data *data = h->host_data; 227 228 irq_set_chip_data(virq, data); 229 irq_set_chip(virq, &data->irq_chip); 230 irq_set_nested_thread(virq, 1); 231 232 /* ARM needs us to explicitly flag the IRQ as valid 233 * and will set them noprobe when we do so. */ 234 #ifdef CONFIG_ARM 235 set_irq_flags(virq, IRQF_VALID); 236 #else 237 irq_set_noprobe(virq); 238 #endif 239 240 return 0; 241 } 242 243 static struct irq_domain_ops regmap_domain_ops = { 244 .map = regmap_irq_map, 245 .xlate = irq_domain_xlate_twocell, 246 }; 247 248 /** 249 * regmap_add_irq_chip(): Use standard regmap IRQ controller handling 250 * 251 * map: The regmap for the device. 252 * irq: The IRQ the device uses to signal interrupts 253 * irq_flags: The IRQF_ flags to use for the primary interrupt. 254 * chip: Configuration for the interrupt controller. 255 * data: Runtime data structure for the controller, allocated on success 256 * 257 * Returns 0 on success or an errno on failure. 258 * 259 * In order for this to be efficient the chip really should use a 260 * register cache. The chip driver is responsible for restoring the 261 * register values used by the IRQ controller over suspend and resume. 262 */ 263 int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, 264 int irq_base, const struct regmap_irq_chip *chip, 265 struct regmap_irq_chip_data **data) 266 { 267 struct regmap_irq_chip_data *d; 268 int i; 269 int ret = -ENOMEM; 270 u32 reg; 271 272 for (i = 0; i < chip->num_irqs; i++) { 273 if (chip->irqs[i].reg_offset % map->reg_stride) 274 return -EINVAL; 275 if (chip->irqs[i].reg_offset / map->reg_stride >= 276 chip->num_regs) 277 return -EINVAL; 278 } 279 280 if (irq_base) { 281 irq_base = irq_alloc_descs(irq_base, 0, chip->num_irqs, 0); 282 if (irq_base < 0) { 283 dev_warn(map->dev, "Failed to allocate IRQs: %d\n", 284 irq_base); 285 return irq_base; 286 } 287 } 288 289 d = kzalloc(sizeof(*d), GFP_KERNEL); 290 if (!d) 291 return -ENOMEM; 292 293 *data = d; 294 295 d->status_buf = kzalloc(sizeof(unsigned int) * chip->num_regs, 296 GFP_KERNEL); 297 if (!d->status_buf) 298 goto err_alloc; 299 300 d->mask_buf = kzalloc(sizeof(unsigned int) * chip->num_regs, 301 GFP_KERNEL); 302 if (!d->mask_buf) 303 goto err_alloc; 304 305 d->mask_buf_def = kzalloc(sizeof(unsigned int) * chip->num_regs, 306 GFP_KERNEL); 307 if (!d->mask_buf_def) 308 goto err_alloc; 309 310 if (chip->wake_base) { 311 d->wake_buf = kzalloc(sizeof(unsigned int) * chip->num_regs, 312 GFP_KERNEL); 313 if (!d->wake_buf) 314 goto err_alloc; 315 } 316 317 d->irq_chip = regmap_irq_chip; 318 d->irq_chip.name = chip->name; 319 if (!chip->wake_base) { 320 d->irq_chip.irq_set_wake = NULL; 321 d->irq_chip.flags |= IRQCHIP_MASK_ON_SUSPEND | 322 IRQCHIP_SKIP_SET_WAKE; 323 } 324 d->irq = irq; 325 d->map = map; 326 d->chip = chip; 327 d->irq_base = irq_base; 328 329 if (chip->irq_reg_stride) 330 d->irq_reg_stride = chip->irq_reg_stride; 331 else 332 d->irq_reg_stride = 1; 333 334 mutex_init(&d->lock); 335 336 for (i = 0; i < chip->num_irqs; i++) 337 d->mask_buf_def[chip->irqs[i].reg_offset / map->reg_stride] 338 |= chip->irqs[i].mask; 339 340 /* Mask all the interrupts by default */ 341 for (i = 0; i < chip->num_regs; i++) { 342 d->mask_buf[i] = d->mask_buf_def[i]; 343 reg = chip->mask_base + 344 (i * map->reg_stride * d->irq_reg_stride); 345 if (chip->mask_invert) 346 ret = regmap_update_bits(map, reg, 347 d->mask_buf[i], ~d->mask_buf[i]); 348 else 349 ret = regmap_update_bits(map, reg, 350 d->mask_buf[i], d->mask_buf[i]); 351 if (ret != 0) { 352 dev_err(map->dev, "Failed to set masks in 0x%x: %d\n", 353 reg, ret); 354 goto err_alloc; 355 } 356 } 357 358 /* Wake is disabled by default */ 359 if (d->wake_buf) { 360 for (i = 0; i < chip->num_regs; i++) { 361 d->wake_buf[i] = d->mask_buf_def[i]; 362 reg = chip->wake_base + 363 (i * map->reg_stride * d->irq_reg_stride); 364 ret = regmap_update_bits(map, reg, d->wake_buf[i], 365 d->wake_buf[i]); 366 if (ret != 0) { 367 dev_err(map->dev, "Failed to set masks in 0x%x: %d\n", 368 reg, ret); 369 goto err_alloc; 370 } 371 } 372 } 373 374 if (irq_base) 375 d->domain = irq_domain_add_legacy(map->dev->of_node, 376 chip->num_irqs, irq_base, 0, 377 ®map_domain_ops, d); 378 else 379 d->domain = irq_domain_add_linear(map->dev->of_node, 380 chip->num_irqs, 381 ®map_domain_ops, d); 382 if (!d->domain) { 383 dev_err(map->dev, "Failed to create IRQ domain\n"); 384 ret = -ENOMEM; 385 goto err_alloc; 386 } 387 388 ret = request_threaded_irq(irq, NULL, regmap_irq_thread, irq_flags, 389 chip->name, d); 390 if (ret != 0) { 391 dev_err(map->dev, "Failed to request IRQ %d: %d\n", irq, ret); 392 goto err_domain; 393 } 394 395 return 0; 396 397 err_domain: 398 /* Should really dispose of the domain but... */ 399 err_alloc: 400 kfree(d->wake_buf); 401 kfree(d->mask_buf_def); 402 kfree(d->mask_buf); 403 kfree(d->status_buf); 404 kfree(d); 405 return ret; 406 } 407 EXPORT_SYMBOL_GPL(regmap_add_irq_chip); 408 409 /** 410 * regmap_del_irq_chip(): Stop interrupt handling for a regmap IRQ chip 411 * 412 * @irq: Primary IRQ for the device 413 * @d: regmap_irq_chip_data allocated by regmap_add_irq_chip() 414 */ 415 void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d) 416 { 417 if (!d) 418 return; 419 420 free_irq(irq, d); 421 /* We should unmap the domain but... */ 422 kfree(d->wake_buf); 423 kfree(d->mask_buf_def); 424 kfree(d->mask_buf); 425 kfree(d->status_buf); 426 kfree(d); 427 } 428 EXPORT_SYMBOL_GPL(regmap_del_irq_chip); 429 430 /** 431 * regmap_irq_chip_get_base(): Retrieve interrupt base for a regmap IRQ chip 432 * 433 * Useful for drivers to request their own IRQs. 434 * 435 * @data: regmap_irq controller to operate on. 436 */ 437 int regmap_irq_chip_get_base(struct regmap_irq_chip_data *data) 438 { 439 WARN_ON(!data->irq_base); 440 return data->irq_base; 441 } 442 EXPORT_SYMBOL_GPL(regmap_irq_chip_get_base); 443 444 /** 445 * regmap_irq_get_virq(): Map an interrupt on a chip to a virtual IRQ 446 * 447 * Useful for drivers to request their own IRQs. 448 * 449 * @data: regmap_irq controller to operate on. 450 * @irq: index of the interrupt requested in the chip IRQs 451 */ 452 int regmap_irq_get_virq(struct regmap_irq_chip_data *data, int irq) 453 { 454 /* Handle holes in the IRQ list */ 455 if (!data->chip->irqs[irq].mask) 456 return -EINVAL; 457 458 return irq_create_mapping(data->domain, irq); 459 } 460 EXPORT_SYMBOL_GPL(regmap_irq_get_virq); 461