1 // SPDX-License-Identifier: GPL-2.0+ 2 // 3 // Exynos specific support for Samsung pinctrl/gpiolib driver with eint support. 4 // 5 // Copyright (c) 2012 Samsung Electronics Co., Ltd. 6 // http://www.samsung.com 7 // Copyright (c) 2012 Linaro Ltd 8 // http://www.linaro.org 9 // 10 // Author: Thomas Abraham <thomas.ab@samsung.com> 11 // 12 // This file contains the Samsung Exynos specific information required by the 13 // the Samsung pinctrl/gpiolib driver. It also includes the implementation of 14 // external gpio and wakeup interrupt support. 15 16 #include <linux/device.h> 17 #include <linux/interrupt.h> 18 #include <linux/irqdomain.h> 19 #include <linux/irq.h> 20 #include <linux/irqchip/chained_irq.h> 21 #include <linux/of.h> 22 #include <linux/of_irq.h> 23 #include <linux/slab.h> 24 #include <linux/spinlock.h> 25 #include <linux/regmap.h> 26 #include <linux/err.h> 27 #include <linux/soc/samsung/exynos-pmu.h> 28 #include <linux/soc/samsung/exynos-regs-pmu.h> 29 30 #include "pinctrl-samsung.h" 31 #include "pinctrl-exynos.h" 32 33 struct exynos_irq_chip { 34 struct irq_chip chip; 35 36 u32 eint_con; 37 u32 eint_mask; 38 u32 eint_pend; 39 u32 *eint_wake_mask_value; 40 u32 eint_wake_mask_reg; 41 void (*set_eint_wakeup_mask)(struct samsung_pinctrl_drv_data *drvdata, 42 struct exynos_irq_chip *irq_chip); 43 }; 44 45 static inline struct exynos_irq_chip *to_exynos_irq_chip(struct irq_chip *chip) 46 { 47 return container_of(chip, struct exynos_irq_chip, chip); 48 } 49 50 static void exynos_irq_mask(struct irq_data *irqd) 51 { 52 struct irq_chip *chip = irq_data_get_irq_chip(irqd); 53 struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); 54 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); 55 unsigned long reg_mask; 56 unsigned int mask; 57 unsigned long flags; 58 59 if (bank->eint_mask_offset) 60 reg_mask = bank->pctl_offset + bank->eint_mask_offset; 61 else 62 reg_mask = our_chip->eint_mask + bank->eint_offset; 63 64 raw_spin_lock_irqsave(&bank->slock, flags); 65 66 mask = readl(bank->eint_base + reg_mask); 67 mask |= 1 << irqd->hwirq; 68 writel(mask, bank->eint_base + reg_mask); 69 70 raw_spin_unlock_irqrestore(&bank->slock, flags); 71 } 72 73 static void exynos_irq_ack(struct irq_data *irqd) 74 { 75 struct irq_chip *chip = irq_data_get_irq_chip(irqd); 76 struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); 77 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); 78 unsigned long reg_pend; 79 80 if (bank->eint_pend_offset) 81 reg_pend = bank->pctl_offset + bank->eint_pend_offset; 82 else 83 reg_pend = our_chip->eint_pend + bank->eint_offset; 84 85 writel(1 << irqd->hwirq, bank->eint_base + reg_pend); 86 } 87 88 static void exynos_irq_unmask(struct irq_data *irqd) 89 { 90 struct irq_chip *chip = irq_data_get_irq_chip(irqd); 91 struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); 92 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); 93 unsigned long reg_mask; 94 unsigned int mask; 95 unsigned long flags; 96 97 /* 98 * Ack level interrupts right before unmask 99 * 100 * If we don't do this we'll get a double-interrupt. Level triggered 101 * interrupts must not fire an interrupt if the level is not 102 * _currently_ active, even if it was active while the interrupt was 103 * masked. 104 */ 105 if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK) 106 exynos_irq_ack(irqd); 107 108 if (bank->eint_mask_offset) 109 reg_mask = bank->pctl_offset + bank->eint_mask_offset; 110 else 111 reg_mask = our_chip->eint_mask + bank->eint_offset; 112 113 raw_spin_lock_irqsave(&bank->slock, flags); 114 115 mask = readl(bank->eint_base + reg_mask); 116 mask &= ~(1 << irqd->hwirq); 117 writel(mask, bank->eint_base + reg_mask); 118 119 raw_spin_unlock_irqrestore(&bank->slock, flags); 120 } 121 122 static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type) 123 { 124 struct irq_chip *chip = irq_data_get_irq_chip(irqd); 125 struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); 126 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); 127 unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq; 128 unsigned int con, trig_type; 129 unsigned long reg_con; 130 131 switch (type) { 132 case IRQ_TYPE_EDGE_RISING: 133 trig_type = EXYNOS_EINT_EDGE_RISING; 134 break; 135 case IRQ_TYPE_EDGE_FALLING: 136 trig_type = EXYNOS_EINT_EDGE_FALLING; 137 break; 138 case IRQ_TYPE_EDGE_BOTH: 139 trig_type = EXYNOS_EINT_EDGE_BOTH; 140 break; 141 case IRQ_TYPE_LEVEL_HIGH: 142 trig_type = EXYNOS_EINT_LEVEL_HIGH; 143 break; 144 case IRQ_TYPE_LEVEL_LOW: 145 trig_type = EXYNOS_EINT_LEVEL_LOW; 146 break; 147 default: 148 pr_err("unsupported external interrupt type\n"); 149 return -EINVAL; 150 } 151 152 if (type & IRQ_TYPE_EDGE_BOTH) 153 irq_set_handler_locked(irqd, handle_edge_irq); 154 else 155 irq_set_handler_locked(irqd, handle_level_irq); 156 157 if (bank->eint_con_offset) 158 reg_con = bank->pctl_offset + bank->eint_con_offset; 159 else 160 reg_con = our_chip->eint_con + bank->eint_offset; 161 162 con = readl(bank->eint_base + reg_con); 163 con &= ~(EXYNOS_EINT_CON_MASK << shift); 164 con |= trig_type << shift; 165 writel(con, bank->eint_base + reg_con); 166 167 return 0; 168 } 169 170 static int exynos_irq_set_affinity(struct irq_data *irqd, 171 const struct cpumask *dest, bool force) 172 { 173 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); 174 struct samsung_pinctrl_drv_data *d = bank->drvdata; 175 struct irq_data *parent = irq_get_irq_data(d->irq); 176 177 if (parent) 178 return parent->chip->irq_set_affinity(parent, dest, force); 179 180 return -EINVAL; 181 } 182 183 static int exynos_irq_request_resources(struct irq_data *irqd) 184 { 185 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); 186 const struct samsung_pin_bank_type *bank_type = bank->type; 187 unsigned long reg_con, flags; 188 unsigned int shift, mask, con; 189 int ret; 190 191 ret = gpiochip_lock_as_irq(&bank->gpio_chip, irqd->hwirq); 192 if (ret) { 193 dev_err(bank->gpio_chip.parent, 194 "unable to lock pin %s-%lu IRQ\n", 195 bank->name, irqd->hwirq); 196 return ret; 197 } 198 199 reg_con = bank->pctl_offset + bank_type->reg_offset[PINCFG_TYPE_FUNC]; 200 shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC]; 201 mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1; 202 203 raw_spin_lock_irqsave(&bank->slock, flags); 204 205 con = readl(bank->pctl_base + reg_con); 206 con &= ~(mask << shift); 207 con |= EXYNOS_PIN_CON_FUNC_EINT << shift; 208 writel(con, bank->pctl_base + reg_con); 209 210 raw_spin_unlock_irqrestore(&bank->slock, flags); 211 212 return 0; 213 } 214 215 static void exynos_irq_release_resources(struct irq_data *irqd) 216 { 217 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); 218 const struct samsung_pin_bank_type *bank_type = bank->type; 219 unsigned long reg_con, flags; 220 unsigned int shift, mask, con; 221 222 reg_con = bank->pctl_offset + bank_type->reg_offset[PINCFG_TYPE_FUNC]; 223 shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC]; 224 mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1; 225 226 raw_spin_lock_irqsave(&bank->slock, flags); 227 228 con = readl(bank->pctl_base + reg_con); 229 con &= ~(mask << shift); 230 con |= PIN_CON_FUNC_INPUT << shift; 231 writel(con, bank->pctl_base + reg_con); 232 233 raw_spin_unlock_irqrestore(&bank->slock, flags); 234 235 gpiochip_unlock_as_irq(&bank->gpio_chip, irqd->hwirq); 236 } 237 238 /* 239 * irq_chip for gpio interrupts. 240 */ 241 static const struct exynos_irq_chip exynos_gpio_irq_chip __initconst = { 242 .chip = { 243 .name = "exynos_gpio_irq_chip", 244 .irq_unmask = exynos_irq_unmask, 245 .irq_mask = exynos_irq_mask, 246 .irq_ack = exynos_irq_ack, 247 .irq_set_type = exynos_irq_set_type, 248 .irq_set_affinity = exynos_irq_set_affinity, 249 .irq_request_resources = exynos_irq_request_resources, 250 .irq_release_resources = exynos_irq_release_resources, 251 }, 252 .eint_con = EXYNOS_GPIO_ECON_OFFSET, 253 .eint_mask = EXYNOS_GPIO_EMASK_OFFSET, 254 .eint_pend = EXYNOS_GPIO_EPEND_OFFSET, 255 /* eint_wake_mask_value not used */ 256 }; 257 258 static int exynos_eint_irq_map(struct irq_domain *h, unsigned int virq, 259 irq_hw_number_t hw) 260 { 261 struct samsung_pin_bank *b = h->host_data; 262 263 irq_set_chip_data(virq, b); 264 irq_set_chip_and_handler(virq, &b->irq_chip->chip, 265 handle_level_irq); 266 return 0; 267 } 268 269 /* 270 * irq domain callbacks for external gpio and wakeup interrupt controllers. 271 */ 272 static const struct irq_domain_ops exynos_eint_irqd_ops = { 273 .map = exynos_eint_irq_map, 274 .xlate = irq_domain_xlate_twocell, 275 }; 276 277 static irqreturn_t exynos_eint_gpio_irq(int irq, void *data) 278 { 279 struct samsung_pinctrl_drv_data *d = data; 280 struct samsung_pin_bank *bank = d->pin_banks; 281 unsigned int svc, group, pin; 282 int ret; 283 284 if (bank->eint_con_offset) 285 svc = readl(bank->eint_base + EXYNOSAUTO_SVC_OFFSET); 286 else 287 svc = readl(bank->eint_base + EXYNOS_SVC_OFFSET); 288 group = EXYNOS_SVC_GROUP(svc); 289 pin = svc & EXYNOS_SVC_NUM_MASK; 290 291 if (!group) 292 return IRQ_HANDLED; 293 bank += (group - 1); 294 295 ret = generic_handle_domain_irq(bank->irq_domain, pin); 296 if (ret) 297 return IRQ_NONE; 298 299 return IRQ_HANDLED; 300 } 301 302 struct exynos_eint_gpio_save { 303 u32 eint_con; 304 u32 eint_fltcon0; 305 u32 eint_fltcon1; 306 u32 eint_mask; 307 }; 308 309 /* 310 * exynos_eint_gpio_init() - setup handling of external gpio interrupts. 311 * @d: driver data of samsung pinctrl driver. 312 */ 313 __init int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) 314 { 315 struct samsung_pin_bank *bank; 316 struct device *dev = d->dev; 317 int ret; 318 int i; 319 320 if (!d->irq) { 321 dev_err(dev, "irq number not available\n"); 322 return -EINVAL; 323 } 324 325 ret = devm_request_irq(dev, d->irq, exynos_eint_gpio_irq, 326 0, dev_name(dev), d); 327 if (ret) { 328 dev_err(dev, "irq request failed\n"); 329 return -ENXIO; 330 } 331 332 bank = d->pin_banks; 333 for (i = 0; i < d->nr_banks; ++i, ++bank) { 334 if (bank->eint_type != EINT_TYPE_GPIO) 335 continue; 336 337 bank->irq_chip = devm_kmemdup(dev, &exynos_gpio_irq_chip, 338 sizeof(*bank->irq_chip), GFP_KERNEL); 339 if (!bank->irq_chip) { 340 ret = -ENOMEM; 341 goto err_domains; 342 } 343 bank->irq_chip->chip.name = bank->name; 344 345 bank->irq_domain = irq_domain_create_linear(bank->fwnode, 346 bank->nr_pins, &exynos_eint_irqd_ops, bank); 347 if (!bank->irq_domain) { 348 dev_err(dev, "gpio irq domain add failed\n"); 349 ret = -ENXIO; 350 goto err_domains; 351 } 352 353 bank->soc_priv = devm_kzalloc(d->dev, 354 sizeof(struct exynos_eint_gpio_save), GFP_KERNEL); 355 if (!bank->soc_priv) { 356 irq_domain_remove(bank->irq_domain); 357 ret = -ENOMEM; 358 goto err_domains; 359 } 360 361 } 362 363 return 0; 364 365 err_domains: 366 for (--i, --bank; i >= 0; --i, --bank) { 367 if (bank->eint_type != EINT_TYPE_GPIO) 368 continue; 369 irq_domain_remove(bank->irq_domain); 370 } 371 372 return ret; 373 } 374 375 static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on) 376 { 377 struct irq_chip *chip = irq_data_get_irq_chip(irqd); 378 struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); 379 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); 380 unsigned long bit = 1UL << (2 * bank->eint_offset + irqd->hwirq); 381 382 pr_info("wake %s for irq %u (%s-%lu)\n", on ? "enabled" : "disabled", 383 irqd->irq, bank->name, irqd->hwirq); 384 385 if (!on) 386 *our_chip->eint_wake_mask_value |= bit; 387 else 388 *our_chip->eint_wake_mask_value &= ~bit; 389 390 return 0; 391 } 392 393 static void 394 exynos_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata, 395 struct exynos_irq_chip *irq_chip) 396 { 397 struct regmap *pmu_regs; 398 399 if (!drvdata->retention_ctrl || !drvdata->retention_ctrl->priv) { 400 dev_warn(drvdata->dev, 401 "No retention data configured bank with external wakeup interrupt. Wake-up mask will not be set.\n"); 402 return; 403 } 404 405 pmu_regs = drvdata->retention_ctrl->priv; 406 dev_info(drvdata->dev, 407 "Setting external wakeup interrupt mask: 0x%x\n", 408 *irq_chip->eint_wake_mask_value); 409 410 regmap_write(pmu_regs, irq_chip->eint_wake_mask_reg, 411 *irq_chip->eint_wake_mask_value); 412 } 413 414 static void 415 s5pv210_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata, 416 struct exynos_irq_chip *irq_chip) 417 418 { 419 void __iomem *clk_base; 420 421 if (!drvdata->retention_ctrl || !drvdata->retention_ctrl->priv) { 422 dev_warn(drvdata->dev, 423 "No retention data configured bank with external wakeup interrupt. Wake-up mask will not be set.\n"); 424 return; 425 } 426 427 428 clk_base = (void __iomem *) drvdata->retention_ctrl->priv; 429 430 __raw_writel(*irq_chip->eint_wake_mask_value, 431 clk_base + irq_chip->eint_wake_mask_reg); 432 } 433 434 static u32 eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED; 435 /* 436 * irq_chip for wakeup interrupts 437 */ 438 static const struct exynos_irq_chip s5pv210_wkup_irq_chip __initconst = { 439 .chip = { 440 .name = "s5pv210_wkup_irq_chip", 441 .irq_unmask = exynos_irq_unmask, 442 .irq_mask = exynos_irq_mask, 443 .irq_ack = exynos_irq_ack, 444 .irq_set_type = exynos_irq_set_type, 445 .irq_set_wake = exynos_wkup_irq_set_wake, 446 .irq_request_resources = exynos_irq_request_resources, 447 .irq_release_resources = exynos_irq_release_resources, 448 }, 449 .eint_con = EXYNOS_WKUP_ECON_OFFSET, 450 .eint_mask = EXYNOS_WKUP_EMASK_OFFSET, 451 .eint_pend = EXYNOS_WKUP_EPEND_OFFSET, 452 .eint_wake_mask_value = &eint_wake_mask_value, 453 /* Only differences with exynos4210_wkup_irq_chip: */ 454 .eint_wake_mask_reg = S5PV210_EINT_WAKEUP_MASK, 455 .set_eint_wakeup_mask = s5pv210_pinctrl_set_eint_wakeup_mask, 456 }; 457 458 static const struct exynos_irq_chip exynos4210_wkup_irq_chip __initconst = { 459 .chip = { 460 .name = "exynos4210_wkup_irq_chip", 461 .irq_unmask = exynos_irq_unmask, 462 .irq_mask = exynos_irq_mask, 463 .irq_ack = exynos_irq_ack, 464 .irq_set_type = exynos_irq_set_type, 465 .irq_set_wake = exynos_wkup_irq_set_wake, 466 .irq_request_resources = exynos_irq_request_resources, 467 .irq_release_resources = exynos_irq_release_resources, 468 }, 469 .eint_con = EXYNOS_WKUP_ECON_OFFSET, 470 .eint_mask = EXYNOS_WKUP_EMASK_OFFSET, 471 .eint_pend = EXYNOS_WKUP_EPEND_OFFSET, 472 .eint_wake_mask_value = &eint_wake_mask_value, 473 .eint_wake_mask_reg = EXYNOS_EINT_WAKEUP_MASK, 474 .set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask, 475 }; 476 477 static const struct exynos_irq_chip exynos7_wkup_irq_chip __initconst = { 478 .chip = { 479 .name = "exynos7_wkup_irq_chip", 480 .irq_unmask = exynos_irq_unmask, 481 .irq_mask = exynos_irq_mask, 482 .irq_ack = exynos_irq_ack, 483 .irq_set_type = exynos_irq_set_type, 484 .irq_set_wake = exynos_wkup_irq_set_wake, 485 .irq_request_resources = exynos_irq_request_resources, 486 .irq_release_resources = exynos_irq_release_resources, 487 }, 488 .eint_con = EXYNOS7_WKUP_ECON_OFFSET, 489 .eint_mask = EXYNOS7_WKUP_EMASK_OFFSET, 490 .eint_pend = EXYNOS7_WKUP_EPEND_OFFSET, 491 .eint_wake_mask_value = &eint_wake_mask_value, 492 .eint_wake_mask_reg = EXYNOS5433_EINT_WAKEUP_MASK, 493 .set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask, 494 }; 495 496 static const struct exynos_irq_chip exynosautov920_wkup_irq_chip __initconst = { 497 .chip = { 498 .name = "exynosautov920_wkup_irq_chip", 499 .irq_unmask = exynos_irq_unmask, 500 .irq_mask = exynos_irq_mask, 501 .irq_ack = exynos_irq_ack, 502 .irq_set_type = exynos_irq_set_type, 503 .irq_set_wake = exynos_wkup_irq_set_wake, 504 .irq_request_resources = exynos_irq_request_resources, 505 .irq_release_resources = exynos_irq_release_resources, 506 }, 507 .eint_wake_mask_value = &eint_wake_mask_value, 508 .eint_wake_mask_reg = EXYNOS5433_EINT_WAKEUP_MASK, 509 .set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask, 510 }; 511 512 /* list of external wakeup controllers supported */ 513 static const struct of_device_id exynos_wkup_irq_ids[] = { 514 { .compatible = "samsung,s5pv210-wakeup-eint", 515 .data = &s5pv210_wkup_irq_chip }, 516 { .compatible = "samsung,exynos4210-wakeup-eint", 517 .data = &exynos4210_wkup_irq_chip }, 518 { .compatible = "samsung,exynos7-wakeup-eint", 519 .data = &exynos7_wkup_irq_chip }, 520 { .compatible = "samsung,exynos850-wakeup-eint", 521 .data = &exynos7_wkup_irq_chip }, 522 { .compatible = "samsung,exynosautov9-wakeup-eint", 523 .data = &exynos7_wkup_irq_chip }, 524 { .compatible = "samsung,exynosautov920-wakeup-eint", 525 .data = &exynosautov920_wkup_irq_chip }, 526 { } 527 }; 528 529 /* interrupt handler for wakeup interrupts 0..15 */ 530 static void exynos_irq_eint0_15(struct irq_desc *desc) 531 { 532 struct exynos_weint_data *eintd = irq_desc_get_handler_data(desc); 533 struct samsung_pin_bank *bank = eintd->bank; 534 struct irq_chip *chip = irq_desc_get_chip(desc); 535 536 chained_irq_enter(chip, desc); 537 538 generic_handle_domain_irq(bank->irq_domain, eintd->irq); 539 540 chained_irq_exit(chip, desc); 541 } 542 543 static inline void exynos_irq_demux_eint(unsigned int pend, 544 struct irq_domain *domain) 545 { 546 unsigned int irq; 547 548 while (pend) { 549 irq = fls(pend) - 1; 550 generic_handle_domain_irq(domain, irq); 551 pend &= ~(1 << irq); 552 } 553 } 554 555 /* interrupt handler for wakeup interrupt 16 */ 556 static void exynos_irq_demux_eint16_31(struct irq_desc *desc) 557 { 558 struct irq_chip *chip = irq_desc_get_chip(desc); 559 struct exynos_muxed_weint_data *eintd = irq_desc_get_handler_data(desc); 560 unsigned int pend; 561 unsigned int mask; 562 int i; 563 564 chained_irq_enter(chip, desc); 565 566 for (i = 0; i < eintd->nr_banks; ++i) { 567 struct samsung_pin_bank *b = eintd->banks[i]; 568 pend = readl(b->eint_base + b->irq_chip->eint_pend 569 + b->eint_offset); 570 mask = readl(b->eint_base + b->irq_chip->eint_mask 571 + b->eint_offset); 572 exynos_irq_demux_eint(pend & ~mask, b->irq_domain); 573 } 574 575 chained_irq_exit(chip, desc); 576 } 577 578 /* 579 * exynos_eint_wkup_init() - setup handling of external wakeup interrupts. 580 * @d: driver data of samsung pinctrl driver. 581 */ 582 __init int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) 583 { 584 struct device *dev = d->dev; 585 struct device_node *wkup_np = NULL; 586 struct device_node *np; 587 struct samsung_pin_bank *bank; 588 struct exynos_weint_data *weint_data; 589 struct exynos_muxed_weint_data *muxed_data; 590 const struct exynos_irq_chip *irq_chip; 591 unsigned int muxed_banks = 0; 592 unsigned int i; 593 int idx, irq; 594 595 for_each_child_of_node(dev->of_node, np) { 596 const struct of_device_id *match; 597 598 match = of_match_node(exynos_wkup_irq_ids, np); 599 if (match) { 600 irq_chip = match->data; 601 wkup_np = np; 602 break; 603 } 604 } 605 if (!wkup_np) 606 return -ENODEV; 607 608 bank = d->pin_banks; 609 for (i = 0; i < d->nr_banks; ++i, ++bank) { 610 if (bank->eint_type != EINT_TYPE_WKUP) 611 continue; 612 613 bank->irq_chip = devm_kmemdup(dev, irq_chip, sizeof(*irq_chip), 614 GFP_KERNEL); 615 if (!bank->irq_chip) { 616 of_node_put(wkup_np); 617 return -ENOMEM; 618 } 619 bank->irq_chip->chip.name = bank->name; 620 621 bank->irq_domain = irq_domain_create_linear(bank->fwnode, 622 bank->nr_pins, &exynos_eint_irqd_ops, bank); 623 if (!bank->irq_domain) { 624 dev_err(dev, "wkup irq domain add failed\n"); 625 of_node_put(wkup_np); 626 return -ENXIO; 627 } 628 629 if (!fwnode_property_present(bank->fwnode, "interrupts")) { 630 bank->eint_type = EINT_TYPE_WKUP_MUX; 631 ++muxed_banks; 632 continue; 633 } 634 635 weint_data = devm_kcalloc(dev, 636 bank->nr_pins, sizeof(*weint_data), 637 GFP_KERNEL); 638 if (!weint_data) { 639 of_node_put(wkup_np); 640 return -ENOMEM; 641 } 642 643 for (idx = 0; idx < bank->nr_pins; ++idx) { 644 irq = irq_of_parse_and_map(to_of_node(bank->fwnode), idx); 645 if (!irq) { 646 dev_err(dev, "irq number for eint-%s-%d not found\n", 647 bank->name, idx); 648 continue; 649 } 650 weint_data[idx].irq = idx; 651 weint_data[idx].bank = bank; 652 irq_set_chained_handler_and_data(irq, 653 exynos_irq_eint0_15, 654 &weint_data[idx]); 655 } 656 } 657 658 if (!muxed_banks) { 659 of_node_put(wkup_np); 660 return 0; 661 } 662 663 irq = irq_of_parse_and_map(wkup_np, 0); 664 of_node_put(wkup_np); 665 if (!irq) { 666 dev_err(dev, "irq number for muxed EINTs not found\n"); 667 return 0; 668 } 669 670 muxed_data = devm_kzalloc(dev, sizeof(*muxed_data) 671 + muxed_banks*sizeof(struct samsung_pin_bank *), GFP_KERNEL); 672 if (!muxed_data) 673 return -ENOMEM; 674 muxed_data->nr_banks = muxed_banks; 675 676 irq_set_chained_handler_and_data(irq, exynos_irq_demux_eint16_31, 677 muxed_data); 678 679 bank = d->pin_banks; 680 idx = 0; 681 for (i = 0; i < d->nr_banks; ++i, ++bank) { 682 if (bank->eint_type != EINT_TYPE_WKUP_MUX) 683 continue; 684 685 muxed_data->banks[idx++] = bank; 686 } 687 688 return 0; 689 } 690 691 static void exynos_pinctrl_suspend_bank( 692 struct samsung_pinctrl_drv_data *drvdata, 693 struct samsung_pin_bank *bank) 694 { 695 struct exynos_eint_gpio_save *save = bank->soc_priv; 696 const void __iomem *regs = bank->eint_base; 697 698 save->eint_con = readl(regs + EXYNOS_GPIO_ECON_OFFSET 699 + bank->eint_offset); 700 save->eint_fltcon0 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET 701 + 2 * bank->eint_offset); 702 save->eint_fltcon1 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET 703 + 2 * bank->eint_offset + 4); 704 save->eint_mask = readl(regs + bank->irq_chip->eint_mask 705 + bank->eint_offset); 706 707 pr_debug("%s: save con %#010x\n", bank->name, save->eint_con); 708 pr_debug("%s: save fltcon0 %#010x\n", bank->name, save->eint_fltcon0); 709 pr_debug("%s: save fltcon1 %#010x\n", bank->name, save->eint_fltcon1); 710 pr_debug("%s: save mask %#010x\n", bank->name, save->eint_mask); 711 } 712 713 static void exynosauto_pinctrl_suspend_bank(struct samsung_pinctrl_drv_data *drvdata, 714 struct samsung_pin_bank *bank) 715 { 716 struct exynos_eint_gpio_save *save = bank->soc_priv; 717 const void __iomem *regs = bank->eint_base; 718 719 save->eint_con = readl(regs + bank->pctl_offset + bank->eint_con_offset); 720 save->eint_mask = readl(regs + bank->pctl_offset + bank->eint_mask_offset); 721 722 pr_debug("%s: save con %#010x\n", bank->name, save->eint_con); 723 pr_debug("%s: save mask %#010x\n", bank->name, save->eint_mask); 724 } 725 726 void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata) 727 { 728 struct samsung_pin_bank *bank = drvdata->pin_banks; 729 struct exynos_irq_chip *irq_chip = NULL; 730 int i; 731 732 for (i = 0; i < drvdata->nr_banks; ++i, ++bank) { 733 if (bank->eint_type == EINT_TYPE_GPIO) { 734 if (bank->eint_con_offset) 735 exynosauto_pinctrl_suspend_bank(drvdata, bank); 736 else 737 exynos_pinctrl_suspend_bank(drvdata, bank); 738 } 739 else if (bank->eint_type == EINT_TYPE_WKUP) { 740 if (!irq_chip) { 741 irq_chip = bank->irq_chip; 742 irq_chip->set_eint_wakeup_mask(drvdata, 743 irq_chip); 744 } 745 } 746 } 747 } 748 749 static void exynos_pinctrl_resume_bank( 750 struct samsung_pinctrl_drv_data *drvdata, 751 struct samsung_pin_bank *bank) 752 { 753 struct exynos_eint_gpio_save *save = bank->soc_priv; 754 void __iomem *regs = bank->eint_base; 755 756 pr_debug("%s: con %#010x => %#010x\n", bank->name, 757 readl(regs + EXYNOS_GPIO_ECON_OFFSET 758 + bank->eint_offset), save->eint_con); 759 pr_debug("%s: fltcon0 %#010x => %#010x\n", bank->name, 760 readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET 761 + 2 * bank->eint_offset), save->eint_fltcon0); 762 pr_debug("%s: fltcon1 %#010x => %#010x\n", bank->name, 763 readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET 764 + 2 * bank->eint_offset + 4), save->eint_fltcon1); 765 pr_debug("%s: mask %#010x => %#010x\n", bank->name, 766 readl(regs + bank->irq_chip->eint_mask 767 + bank->eint_offset), save->eint_mask); 768 769 writel(save->eint_con, regs + EXYNOS_GPIO_ECON_OFFSET 770 + bank->eint_offset); 771 writel(save->eint_fltcon0, regs + EXYNOS_GPIO_EFLTCON_OFFSET 772 + 2 * bank->eint_offset); 773 writel(save->eint_fltcon1, regs + EXYNOS_GPIO_EFLTCON_OFFSET 774 + 2 * bank->eint_offset + 4); 775 writel(save->eint_mask, regs + bank->irq_chip->eint_mask 776 + bank->eint_offset); 777 } 778 779 static void exynosauto_pinctrl_resume_bank(struct samsung_pinctrl_drv_data *drvdata, 780 struct samsung_pin_bank *bank) 781 { 782 struct exynos_eint_gpio_save *save = bank->soc_priv; 783 void __iomem *regs = bank->eint_base; 784 785 pr_debug("%s: con %#010x => %#010x\n", bank->name, 786 readl(regs + bank->pctl_offset + bank->eint_con_offset), save->eint_con); 787 pr_debug("%s: mask %#010x => %#010x\n", bank->name, 788 readl(regs + bank->pctl_offset + bank->eint_mask_offset), save->eint_mask); 789 790 writel(save->eint_con, regs + bank->pctl_offset + bank->eint_con_offset); 791 writel(save->eint_mask, regs + bank->pctl_offset + bank->eint_mask_offset); 792 } 793 794 void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata) 795 { 796 struct samsung_pin_bank *bank = drvdata->pin_banks; 797 int i; 798 799 for (i = 0; i < drvdata->nr_banks; ++i, ++bank) 800 if (bank->eint_type == EINT_TYPE_GPIO) { 801 if (bank->eint_con_offset) 802 exynosauto_pinctrl_resume_bank(drvdata, bank); 803 else 804 exynos_pinctrl_resume_bank(drvdata, bank); 805 } 806 } 807 808 static void exynos_retention_enable(struct samsung_pinctrl_drv_data *drvdata) 809 { 810 if (drvdata->retention_ctrl->refcnt) 811 atomic_inc(drvdata->retention_ctrl->refcnt); 812 } 813 814 static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata) 815 { 816 struct samsung_retention_ctrl *ctrl = drvdata->retention_ctrl; 817 struct regmap *pmu_regs = ctrl->priv; 818 int i; 819 820 if (ctrl->refcnt && !atomic_dec_and_test(ctrl->refcnt)) 821 return; 822 823 for (i = 0; i < ctrl->nr_regs; i++) 824 regmap_write(pmu_regs, ctrl->regs[i], ctrl->value); 825 } 826 827 struct samsung_retention_ctrl * 828 exynos_retention_init(struct samsung_pinctrl_drv_data *drvdata, 829 const struct samsung_retention_data *data) 830 { 831 struct samsung_retention_ctrl *ctrl; 832 struct regmap *pmu_regs; 833 int i; 834 835 ctrl = devm_kzalloc(drvdata->dev, sizeof(*ctrl), GFP_KERNEL); 836 if (!ctrl) 837 return ERR_PTR(-ENOMEM); 838 839 pmu_regs = exynos_get_pmu_regmap(); 840 if (IS_ERR(pmu_regs)) 841 return ERR_CAST(pmu_regs); 842 843 ctrl->priv = pmu_regs; 844 ctrl->regs = data->regs; 845 ctrl->nr_regs = data->nr_regs; 846 ctrl->value = data->value; 847 ctrl->refcnt = data->refcnt; 848 ctrl->enable = exynos_retention_enable; 849 ctrl->disable = exynos_retention_disable; 850 851 /* Ensure that retention is disabled on driver init */ 852 for (i = 0; i < ctrl->nr_regs; i++) 853 regmap_write(pmu_regs, ctrl->regs[i], ctrl->value); 854 855 return ctrl; 856 } 857