.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (c) 2013, Sony Mobile Communications AB. |
---|
3 | 4 | * Copyright (c) 2013, The Linux Foundation. All rights reserved. |
---|
4 | | - * |
---|
5 | | - * This program is free software; you can redistribute it and/or modify |
---|
6 | | - * it under the terms of the GNU General Public License version 2 and |
---|
7 | | - * only version 2 as published by the Free Software Foundation. |
---|
8 | | - * |
---|
9 | | - * This program is distributed in the hope that it will be useful, |
---|
10 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
11 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
12 | | - * GNU General Public License for more details. |
---|
13 | 5 | */ |
---|
14 | 6 | |
---|
15 | 7 | #include <linux/delay.h> |
---|
.. | .. |
---|
24 | 16 | #include <linux/pinctrl/pinconf.h> |
---|
25 | 17 | #include <linux/pinctrl/pinconf-generic.h> |
---|
26 | 18 | #include <linux/slab.h> |
---|
27 | | -#include <linux/gpio.h> |
---|
| 19 | +#include <linux/gpio/driver.h> |
---|
28 | 20 | #include <linux/interrupt.h> |
---|
29 | 21 | #include <linux/spinlock.h> |
---|
30 | 22 | #include <linux/reboot.h> |
---|
31 | 23 | #include <linux/pm.h> |
---|
32 | 24 | #include <linux/log2.h> |
---|
| 25 | +#include <linux/qcom_scm.h> |
---|
| 26 | + |
---|
| 27 | +#include <linux/soc/qcom/irq.h> |
---|
33 | 28 | |
---|
34 | 29 | #include "../core.h" |
---|
35 | 30 | #include "../pinconf.h" |
---|
.. | .. |
---|
37 | 32 | #include "../pinctrl-utils.h" |
---|
38 | 33 | |
---|
39 | 34 | #define MAX_NR_GPIO 300 |
---|
| 35 | +#define MAX_NR_TILES 4 |
---|
40 | 36 | #define PS_HOLD_OFFSET 0x820 |
---|
41 | 37 | |
---|
42 | 38 | /** |
---|
.. | .. |
---|
44 | 40 | * @dev: device handle. |
---|
45 | 41 | * @pctrl: pinctrl handle. |
---|
46 | 42 | * @chip: gpiochip handle. |
---|
| 43 | + * @desc: pin controller descriptor |
---|
47 | 44 | * @restart_nb: restart notifier block. |
---|
| 45 | + * @irq_chip: irq chip information |
---|
48 | 46 | * @irq: parent irq for the TLMM irq_chip. |
---|
| 47 | + * @intr_target_use_scm: route irq to application cpu using scm calls |
---|
49 | 48 | * @lock: Spinlock to protect register resources as well |
---|
50 | 49 | * as msm_pinctrl data structures. |
---|
51 | 50 | * @enabled_irqs: Bitmap of currently enabled irqs. |
---|
52 | 51 | * @dual_edge_irqs: Bitmap of irqs that need sw emulated dual edge |
---|
53 | 52 | * detection. |
---|
54 | | - * @soc; Reference to soc_data of platform specific data. |
---|
55 | | - * @regs: Base address for the TLMM register map. |
---|
| 53 | + * @skip_wake_irqs: Skip IRQs that are handled by wakeup interrupt controller |
---|
| 54 | + * @disabled_for_mux: These IRQs were disabled because we muxed away. |
---|
| 55 | + * @soc: Reference to soc_data of platform specific data. |
---|
| 56 | + * @regs: Base addresses for the TLMM tiles. |
---|
| 57 | + * @phys_base: Physical base address |
---|
56 | 58 | */ |
---|
57 | 59 | struct msm_pinctrl { |
---|
58 | 60 | struct device *dev; |
---|
.. | .. |
---|
64 | 66 | struct irq_chip irq_chip; |
---|
65 | 67 | int irq; |
---|
66 | 68 | |
---|
| 69 | + bool intr_target_use_scm; |
---|
| 70 | + |
---|
67 | 71 | raw_spinlock_t lock; |
---|
68 | 72 | |
---|
69 | 73 | DECLARE_BITMAP(dual_edge_irqs, MAX_NR_GPIO); |
---|
70 | 74 | DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO); |
---|
| 75 | + DECLARE_BITMAP(skip_wake_irqs, MAX_NR_GPIO); |
---|
| 76 | + DECLARE_BITMAP(disabled_for_mux, MAX_NR_GPIO); |
---|
71 | 77 | |
---|
72 | 78 | const struct msm_pinctrl_soc_data *soc; |
---|
73 | | - void __iomem *regs; |
---|
| 79 | + void __iomem *regs[MAX_NR_TILES]; |
---|
| 80 | + u32 phys_base[MAX_NR_TILES]; |
---|
74 | 81 | }; |
---|
| 82 | + |
---|
| 83 | +#define MSM_ACCESSOR(name) \ |
---|
| 84 | +static u32 msm_readl_##name(struct msm_pinctrl *pctrl, \ |
---|
| 85 | + const struct msm_pingroup *g) \ |
---|
| 86 | +{ \ |
---|
| 87 | + return readl(pctrl->regs[g->tile] + g->name##_reg); \ |
---|
| 88 | +} \ |
---|
| 89 | +static void msm_writel_##name(u32 val, struct msm_pinctrl *pctrl, \ |
---|
| 90 | + const struct msm_pingroup *g) \ |
---|
| 91 | +{ \ |
---|
| 92 | + writel(val, pctrl->regs[g->tile] + g->name##_reg); \ |
---|
| 93 | +} |
---|
| 94 | + |
---|
| 95 | +MSM_ACCESSOR(ctl) |
---|
| 96 | +MSM_ACCESSOR(io) |
---|
| 97 | +MSM_ACCESSOR(intr_cfg) |
---|
| 98 | +MSM_ACCESSOR(intr_status) |
---|
| 99 | +MSM_ACCESSOR(intr_target) |
---|
| 100 | + |
---|
| 101 | +static void msm_ack_intr_status(struct msm_pinctrl *pctrl, |
---|
| 102 | + const struct msm_pingroup *g) |
---|
| 103 | +{ |
---|
| 104 | + u32 val = g->intr_ack_high ? BIT(g->intr_status_bit) : 0; |
---|
| 105 | + |
---|
| 106 | + msm_writel_intr_status(val, pctrl, g); |
---|
| 107 | +} |
---|
75 | 108 | |
---|
76 | 109 | static int msm_get_groups_count(struct pinctrl_dev *pctldev) |
---|
77 | 110 | { |
---|
.. | .. |
---|
148 | 181 | unsigned group) |
---|
149 | 182 | { |
---|
150 | 183 | struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); |
---|
| 184 | + struct gpio_chip *gc = &pctrl->chip; |
---|
| 185 | + unsigned int irq = irq_find_mapping(gc->irq.domain, group); |
---|
| 186 | + struct irq_data *d = irq_get_irq_data(irq); |
---|
| 187 | + unsigned int gpio_func = pctrl->soc->gpio_func; |
---|
151 | 188 | const struct msm_pingroup *g; |
---|
152 | 189 | unsigned long flags; |
---|
153 | 190 | u32 val, mask; |
---|
.. | .. |
---|
164 | 201 | if (WARN_ON(i == g->nfuncs)) |
---|
165 | 202 | return -EINVAL; |
---|
166 | 203 | |
---|
| 204 | + /* |
---|
| 205 | + * If an GPIO interrupt is setup on this pin then we need special |
---|
| 206 | + * handling. Specifically interrupt detection logic will still see |
---|
| 207 | + * the pin twiddle even when we're muxed away. |
---|
| 208 | + * |
---|
| 209 | + * When we see a pin with an interrupt setup on it then we'll disable |
---|
| 210 | + * (mask) interrupts on it when we mux away until we mux back. Note |
---|
| 211 | + * that disable_irq() refcounts and interrupts are disabled as long as |
---|
| 212 | + * at least one disable_irq() has been called. |
---|
| 213 | + */ |
---|
| 214 | + if (d && i != gpio_func && |
---|
| 215 | + !test_and_set_bit(d->hwirq, pctrl->disabled_for_mux)) |
---|
| 216 | + disable_irq(irq); |
---|
| 217 | + |
---|
167 | 218 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
---|
168 | 219 | |
---|
169 | | - val = readl(pctrl->regs + g->ctl_reg); |
---|
| 220 | + val = msm_readl_ctl(pctrl, g); |
---|
170 | 221 | val &= ~mask; |
---|
171 | 222 | val |= i << g->mux_bit; |
---|
172 | | - writel(val, pctrl->regs + g->ctl_reg); |
---|
| 223 | + msm_writel_ctl(val, pctrl, g); |
---|
173 | 224 | |
---|
174 | 225 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
---|
175 | 226 | |
---|
| 227 | + if (d && i == gpio_func && |
---|
| 228 | + test_and_clear_bit(d->hwirq, pctrl->disabled_for_mux)) { |
---|
| 229 | + /* |
---|
| 230 | + * Clear interrupts detected while not GPIO since we only |
---|
| 231 | + * masked things. |
---|
| 232 | + */ |
---|
| 233 | + if (d->parent_data && test_bit(d->hwirq, pctrl->skip_wake_irqs)) |
---|
| 234 | + irq_chip_set_parent_state(d, IRQCHIP_STATE_PENDING, false); |
---|
| 235 | + else |
---|
| 236 | + msm_ack_intr_status(pctrl, g); |
---|
| 237 | + |
---|
| 238 | + enable_irq(irq); |
---|
| 239 | + } |
---|
| 240 | + |
---|
176 | 241 | return 0; |
---|
| 242 | +} |
---|
| 243 | + |
---|
| 244 | +static int msm_pinmux_request_gpio(struct pinctrl_dev *pctldev, |
---|
| 245 | + struct pinctrl_gpio_range *range, |
---|
| 246 | + unsigned offset) |
---|
| 247 | +{ |
---|
| 248 | + struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); |
---|
| 249 | + const struct msm_pingroup *g = &pctrl->soc->groups[offset]; |
---|
| 250 | + |
---|
| 251 | + /* No funcs? Probably ACPI so can't do anything here */ |
---|
| 252 | + if (!g->nfuncs) |
---|
| 253 | + return 0; |
---|
| 254 | + |
---|
| 255 | + return msm_pinmux_set_mux(pctldev, g->funcs[pctrl->soc->gpio_func], offset); |
---|
177 | 256 | } |
---|
178 | 257 | |
---|
179 | 258 | static const struct pinmux_ops msm_pinmux_ops = { |
---|
.. | .. |
---|
181 | 260 | .get_functions_count = msm_get_functions_count, |
---|
182 | 261 | .get_function_name = msm_get_function_name, |
---|
183 | 262 | .get_function_groups = msm_get_function_groups, |
---|
| 263 | + .gpio_request_enable = msm_pinmux_request_gpio, |
---|
184 | 264 | .set_mux = msm_pinmux_set_mux, |
---|
185 | 265 | }; |
---|
186 | 266 | |
---|
.. | .. |
---|
197 | 277 | case PIN_CONFIG_BIAS_PULL_UP: |
---|
198 | 278 | *bit = g->pull_bit; |
---|
199 | 279 | *mask = 3; |
---|
| 280 | + break; |
---|
| 281 | + case PIN_CONFIG_DRIVE_OPEN_DRAIN: |
---|
| 282 | + *bit = g->od_bit; |
---|
| 283 | + *mask = 1; |
---|
200 | 284 | break; |
---|
201 | 285 | case PIN_CONFIG_DRIVE_STRENGTH: |
---|
202 | 286 | *bit = g->drv_bit; |
---|
.. | .. |
---|
244 | 328 | if (ret < 0) |
---|
245 | 329 | return ret; |
---|
246 | 330 | |
---|
247 | | - val = readl(pctrl->regs + g->ctl_reg); |
---|
| 331 | + val = msm_readl_ctl(pctrl, g); |
---|
248 | 332 | arg = (val >> bit) & mask; |
---|
249 | 333 | |
---|
250 | 334 | /* Convert register value to pinconf value */ |
---|
.. | .. |
---|
275 | 359 | if (!arg) |
---|
276 | 360 | return -EINVAL; |
---|
277 | 361 | break; |
---|
| 362 | + case PIN_CONFIG_DRIVE_OPEN_DRAIN: |
---|
| 363 | + /* Pin is not open-drain */ |
---|
| 364 | + if (!arg) |
---|
| 365 | + return -EINVAL; |
---|
| 366 | + arg = 1; |
---|
| 367 | + break; |
---|
278 | 368 | case PIN_CONFIG_DRIVE_STRENGTH: |
---|
279 | 369 | arg = msm_regval_to_drive(arg); |
---|
280 | 370 | break; |
---|
.. | .. |
---|
283 | 373 | if (!arg) |
---|
284 | 374 | return -EINVAL; |
---|
285 | 375 | |
---|
286 | | - val = readl(pctrl->regs + g->io_reg); |
---|
| 376 | + val = msm_readl_io(pctrl, g); |
---|
287 | 377 | arg = !!(val & BIT(g->in_bit)); |
---|
288 | 378 | break; |
---|
289 | 379 | case PIN_CONFIG_INPUT_ENABLE: |
---|
.. | .. |
---|
347 | 437 | else |
---|
348 | 438 | arg = MSM_PULL_UP; |
---|
349 | 439 | break; |
---|
| 440 | + case PIN_CONFIG_DRIVE_OPEN_DRAIN: |
---|
| 441 | + arg = 1; |
---|
| 442 | + break; |
---|
350 | 443 | case PIN_CONFIG_DRIVE_STRENGTH: |
---|
351 | 444 | /* Check for invalid values */ |
---|
352 | 445 | if (arg > 16 || arg < 2 || (arg % 2) != 0) |
---|
.. | .. |
---|
357 | 450 | case PIN_CONFIG_OUTPUT: |
---|
358 | 451 | /* set output value */ |
---|
359 | 452 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
---|
360 | | - val = readl(pctrl->regs + g->io_reg); |
---|
| 453 | + val = msm_readl_io(pctrl, g); |
---|
361 | 454 | if (arg) |
---|
362 | 455 | val |= BIT(g->out_bit); |
---|
363 | 456 | else |
---|
364 | 457 | val &= ~BIT(g->out_bit); |
---|
365 | | - writel(val, pctrl->regs + g->io_reg); |
---|
| 458 | + msm_writel_io(val, pctrl, g); |
---|
366 | 459 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
---|
367 | 460 | |
---|
368 | 461 | /* enable output */ |
---|
.. | .. |
---|
385 | 478 | } |
---|
386 | 479 | |
---|
387 | 480 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
---|
388 | | - val = readl(pctrl->regs + g->ctl_reg); |
---|
| 481 | + val = msm_readl_ctl(pctrl, g); |
---|
389 | 482 | val &= ~(mask << bit); |
---|
390 | 483 | val |= arg << bit; |
---|
391 | | - writel(val, pctrl->regs + g->ctl_reg); |
---|
| 484 | + msm_writel_ctl(val, pctrl, g); |
---|
392 | 485 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
---|
393 | 486 | } |
---|
394 | 487 | |
---|
.. | .. |
---|
412 | 505 | |
---|
413 | 506 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
---|
414 | 507 | |
---|
415 | | - val = readl(pctrl->regs + g->ctl_reg); |
---|
| 508 | + val = msm_readl_ctl(pctrl, g); |
---|
416 | 509 | val &= ~BIT(g->oe_bit); |
---|
417 | | - writel(val, pctrl->regs + g->ctl_reg); |
---|
| 510 | + msm_writel_ctl(val, pctrl, g); |
---|
418 | 511 | |
---|
419 | 512 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
---|
420 | 513 | |
---|
.. | .. |
---|
432 | 525 | |
---|
433 | 526 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
---|
434 | 527 | |
---|
435 | | - val = readl(pctrl->regs + g->io_reg); |
---|
| 528 | + val = msm_readl_io(pctrl, g); |
---|
436 | 529 | if (value) |
---|
437 | 530 | val |= BIT(g->out_bit); |
---|
438 | 531 | else |
---|
439 | 532 | val &= ~BIT(g->out_bit); |
---|
440 | | - writel(val, pctrl->regs + g->io_reg); |
---|
| 533 | + msm_writel_io(val, pctrl, g); |
---|
441 | 534 | |
---|
442 | | - val = readl(pctrl->regs + g->ctl_reg); |
---|
| 535 | + val = msm_readl_ctl(pctrl, g); |
---|
443 | 536 | val |= BIT(g->oe_bit); |
---|
444 | | - writel(val, pctrl->regs + g->ctl_reg); |
---|
| 537 | + msm_writel_ctl(val, pctrl, g); |
---|
445 | 538 | |
---|
446 | 539 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
---|
447 | 540 | |
---|
.. | .. |
---|
456 | 549 | |
---|
457 | 550 | g = &pctrl->soc->groups[offset]; |
---|
458 | 551 | |
---|
459 | | - val = readl(pctrl->regs + g->ctl_reg); |
---|
| 552 | + val = msm_readl_ctl(pctrl, g); |
---|
460 | 553 | |
---|
461 | | - /* 0 = output, 1 = input */ |
---|
462 | | - return val & BIT(g->oe_bit) ? 0 : 1; |
---|
| 554 | + return val & BIT(g->oe_bit) ? GPIO_LINE_DIRECTION_OUT : |
---|
| 555 | + GPIO_LINE_DIRECTION_IN; |
---|
463 | 556 | } |
---|
464 | 557 | |
---|
465 | 558 | static int msm_gpio_get(struct gpio_chip *chip, unsigned offset) |
---|
.. | .. |
---|
470 | 563 | |
---|
471 | 564 | g = &pctrl->soc->groups[offset]; |
---|
472 | 565 | |
---|
473 | | - val = readl(pctrl->regs + g->io_reg); |
---|
| 566 | + val = msm_readl_io(pctrl, g); |
---|
474 | 567 | return !!(val & BIT(g->in_bit)); |
---|
475 | 568 | } |
---|
476 | 569 | |
---|
.. | .. |
---|
485 | 578 | |
---|
486 | 579 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
---|
487 | 580 | |
---|
488 | | - val = readl(pctrl->regs + g->io_reg); |
---|
| 581 | + val = msm_readl_io(pctrl, g); |
---|
489 | 582 | if (value) |
---|
490 | 583 | val |= BIT(g->out_bit); |
---|
491 | 584 | else |
---|
492 | 585 | val &= ~BIT(g->out_bit); |
---|
493 | | - writel(val, pctrl->regs + g->io_reg); |
---|
| 586 | + msm_writel_io(val, pctrl, g); |
---|
494 | 587 | |
---|
495 | 588 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
---|
496 | 589 | } |
---|
.. | .. |
---|
530 | 623 | return; |
---|
531 | 624 | |
---|
532 | 625 | g = &pctrl->soc->groups[offset]; |
---|
533 | | - ctl_reg = readl(pctrl->regs + g->ctl_reg); |
---|
534 | | - io_reg = readl(pctrl->regs + g->io_reg); |
---|
| 626 | + ctl_reg = msm_readl_ctl(pctrl, g); |
---|
| 627 | + io_reg = msm_readl_io(pctrl, g); |
---|
535 | 628 | |
---|
536 | 629 | is_out = !!(ctl_reg & BIT(g->oe_bit)); |
---|
537 | 630 | func = (ctl_reg >> g->mux_bit) & 7; |
---|
.. | .. |
---|
565 | 658 | #else |
---|
566 | 659 | #define msm_gpio_dbg_show NULL |
---|
567 | 660 | #endif |
---|
| 661 | + |
---|
| 662 | +static int msm_gpio_init_valid_mask(struct gpio_chip *gc, |
---|
| 663 | + unsigned long *valid_mask, |
---|
| 664 | + unsigned int ngpios) |
---|
| 665 | +{ |
---|
| 666 | + struct msm_pinctrl *pctrl = gpiochip_get_data(gc); |
---|
| 667 | + int ret; |
---|
| 668 | + unsigned int len, i; |
---|
| 669 | + const int *reserved = pctrl->soc->reserved_gpios; |
---|
| 670 | + u16 *tmp; |
---|
| 671 | + |
---|
| 672 | + /* Driver provided reserved list overrides DT and ACPI */ |
---|
| 673 | + if (reserved) { |
---|
| 674 | + bitmap_fill(valid_mask, ngpios); |
---|
| 675 | + for (i = 0; reserved[i] >= 0; i++) { |
---|
| 676 | + if (i >= ngpios || reserved[i] >= ngpios) { |
---|
| 677 | + dev_err(pctrl->dev, "invalid list of reserved GPIOs\n"); |
---|
| 678 | + return -EINVAL; |
---|
| 679 | + } |
---|
| 680 | + clear_bit(reserved[i], valid_mask); |
---|
| 681 | + } |
---|
| 682 | + |
---|
| 683 | + return 0; |
---|
| 684 | + } |
---|
| 685 | + |
---|
| 686 | + /* The number of GPIOs in the ACPI tables */ |
---|
| 687 | + len = ret = device_property_count_u16(pctrl->dev, "gpios"); |
---|
| 688 | + if (ret < 0) |
---|
| 689 | + return 0; |
---|
| 690 | + |
---|
| 691 | + if (ret > ngpios) |
---|
| 692 | + return -EINVAL; |
---|
| 693 | + |
---|
| 694 | + tmp = kmalloc_array(len, sizeof(*tmp), GFP_KERNEL); |
---|
| 695 | + if (!tmp) |
---|
| 696 | + return -ENOMEM; |
---|
| 697 | + |
---|
| 698 | + ret = device_property_read_u16_array(pctrl->dev, "gpios", tmp, len); |
---|
| 699 | + if (ret < 0) { |
---|
| 700 | + dev_err(pctrl->dev, "could not read list of GPIOs\n"); |
---|
| 701 | + goto out; |
---|
| 702 | + } |
---|
| 703 | + |
---|
| 704 | + bitmap_zero(valid_mask, ngpios); |
---|
| 705 | + for (i = 0; i < len; i++) |
---|
| 706 | + set_bit(tmp[i], valid_mask); |
---|
| 707 | + |
---|
| 708 | +out: |
---|
| 709 | + kfree(tmp); |
---|
| 710 | + return ret; |
---|
| 711 | +} |
---|
568 | 712 | |
---|
569 | 713 | static const struct gpio_chip msm_gpio_template = { |
---|
570 | 714 | .direction_input = msm_gpio_direction_input, |
---|
.. | .. |
---|
606 | 750 | unsigned pol; |
---|
607 | 751 | |
---|
608 | 752 | do { |
---|
609 | | - val = readl(pctrl->regs + g->io_reg) & BIT(g->in_bit); |
---|
| 753 | + val = msm_readl_io(pctrl, g) & BIT(g->in_bit); |
---|
610 | 754 | |
---|
611 | | - pol = readl(pctrl->regs + g->intr_cfg_reg); |
---|
| 755 | + pol = msm_readl_intr_cfg(pctrl, g); |
---|
612 | 756 | pol ^= BIT(g->intr_polarity_bit); |
---|
613 | | - writel(pol, pctrl->regs + g->intr_cfg_reg); |
---|
| 757 | + msm_writel_intr_cfg(pol, pctrl, g); |
---|
614 | 758 | |
---|
615 | | - val2 = readl(pctrl->regs + g->io_reg) & BIT(g->in_bit); |
---|
616 | | - intstat = readl(pctrl->regs + g->intr_status_reg); |
---|
| 759 | + val2 = msm_readl_io(pctrl, g) & BIT(g->in_bit); |
---|
| 760 | + intstat = msm_readl_intr_status(pctrl, g); |
---|
617 | 761 | if (intstat || (val == val2)) |
---|
618 | 762 | return; |
---|
619 | 763 | } while (loop_limit-- > 0); |
---|
.. | .. |
---|
629 | 773 | unsigned long flags; |
---|
630 | 774 | u32 val; |
---|
631 | 775 | |
---|
| 776 | + if (d->parent_data) |
---|
| 777 | + irq_chip_mask_parent(d); |
---|
| 778 | + |
---|
| 779 | + if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) |
---|
| 780 | + return; |
---|
| 781 | + |
---|
632 | 782 | g = &pctrl->soc->groups[d->hwirq]; |
---|
633 | 783 | |
---|
634 | 784 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
---|
635 | 785 | |
---|
636 | | - val = readl(pctrl->regs + g->intr_cfg_reg); |
---|
| 786 | + val = msm_readl_intr_cfg(pctrl, g); |
---|
637 | 787 | /* |
---|
638 | 788 | * There are two bits that control interrupt forwarding to the CPU. The |
---|
639 | 789 | * RAW_STATUS_EN bit causes the level or edge sensed on the line to be |
---|
.. | .. |
---|
658 | 808 | val &= ~BIT(g->intr_raw_status_bit); |
---|
659 | 809 | |
---|
660 | 810 | val &= ~BIT(g->intr_enable_bit); |
---|
661 | | - writel(val, pctrl->regs + g->intr_cfg_reg); |
---|
| 811 | + msm_writel_intr_cfg(val, pctrl, g); |
---|
662 | 812 | |
---|
663 | 813 | clear_bit(d->hwirq, pctrl->enabled_irqs); |
---|
664 | 814 | |
---|
.. | .. |
---|
673 | 823 | unsigned long flags; |
---|
674 | 824 | u32 val; |
---|
675 | 825 | |
---|
| 826 | + if (d->parent_data) |
---|
| 827 | + irq_chip_unmask_parent(d); |
---|
| 828 | + |
---|
| 829 | + if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) |
---|
| 830 | + return; |
---|
| 831 | + |
---|
676 | 832 | g = &pctrl->soc->groups[d->hwirq]; |
---|
677 | 833 | |
---|
678 | 834 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
---|
679 | 835 | |
---|
680 | | - val = readl(pctrl->regs + g->intr_cfg_reg); |
---|
| 836 | + val = msm_readl_intr_cfg(pctrl, g); |
---|
681 | 837 | val |= BIT(g->intr_raw_status_bit); |
---|
682 | 838 | val |= BIT(g->intr_enable_bit); |
---|
683 | | - writel(val, pctrl->regs + g->intr_cfg_reg); |
---|
| 839 | + msm_writel_intr_cfg(val, pctrl, g); |
---|
684 | 840 | |
---|
685 | 841 | set_bit(d->hwirq, pctrl->enabled_irqs); |
---|
686 | 842 | |
---|
687 | 843 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
---|
| 844 | +} |
---|
| 845 | + |
---|
| 846 | +static void msm_gpio_irq_enable(struct irq_data *d) |
---|
| 847 | +{ |
---|
| 848 | + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
---|
| 849 | + struct msm_pinctrl *pctrl = gpiochip_get_data(gc); |
---|
| 850 | + |
---|
| 851 | + if (d->parent_data) |
---|
| 852 | + irq_chip_enable_parent(d); |
---|
| 853 | + |
---|
| 854 | + if (!test_bit(d->hwirq, pctrl->skip_wake_irqs)) |
---|
| 855 | + msm_gpio_irq_unmask(d); |
---|
| 856 | +} |
---|
| 857 | + |
---|
| 858 | +static void msm_gpio_irq_disable(struct irq_data *d) |
---|
| 859 | +{ |
---|
| 860 | + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
---|
| 861 | + struct msm_pinctrl *pctrl = gpiochip_get_data(gc); |
---|
| 862 | + |
---|
| 863 | + if (d->parent_data) |
---|
| 864 | + irq_chip_disable_parent(d); |
---|
| 865 | + |
---|
| 866 | + if (!test_bit(d->hwirq, pctrl->skip_wake_irqs)) |
---|
| 867 | + msm_gpio_irq_mask(d); |
---|
| 868 | +} |
---|
| 869 | + |
---|
| 870 | +/** |
---|
| 871 | + * msm_gpio_update_dual_edge_parent() - Prime next edge for IRQs handled by parent. |
---|
| 872 | + * @d: The irq dta. |
---|
| 873 | + * |
---|
| 874 | + * This is much like msm_gpio_update_dual_edge_pos() but for IRQs that are |
---|
| 875 | + * normally handled by the parent irqchip. The logic here is slightly |
---|
| 876 | + * different due to what's easy to do with our parent, but in principle it's |
---|
| 877 | + * the same. |
---|
| 878 | + */ |
---|
| 879 | +static void msm_gpio_update_dual_edge_parent(struct irq_data *d) |
---|
| 880 | +{ |
---|
| 881 | + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
---|
| 882 | + struct msm_pinctrl *pctrl = gpiochip_get_data(gc); |
---|
| 883 | + const struct msm_pingroup *g = &pctrl->soc->groups[d->hwirq]; |
---|
| 884 | + int loop_limit = 100; |
---|
| 885 | + unsigned int val; |
---|
| 886 | + unsigned int type; |
---|
| 887 | + |
---|
| 888 | + /* Read the value and make a guess about what edge we need to catch */ |
---|
| 889 | + val = msm_readl_io(pctrl, g) & BIT(g->in_bit); |
---|
| 890 | + type = val ? IRQ_TYPE_EDGE_FALLING : IRQ_TYPE_EDGE_RISING; |
---|
| 891 | + |
---|
| 892 | + do { |
---|
| 893 | + /* Set the parent to catch the next edge */ |
---|
| 894 | + irq_chip_set_type_parent(d, type); |
---|
| 895 | + |
---|
| 896 | + /* |
---|
| 897 | + * Possibly the line changed between when we last read "val" |
---|
| 898 | + * (and decided what edge we needed) and when set the edge. |
---|
| 899 | + * If the value didn't change (or changed and then changed |
---|
| 900 | + * back) then we're done. |
---|
| 901 | + */ |
---|
| 902 | + val = msm_readl_io(pctrl, g) & BIT(g->in_bit); |
---|
| 903 | + if (type == IRQ_TYPE_EDGE_RISING) { |
---|
| 904 | + if (!val) |
---|
| 905 | + return; |
---|
| 906 | + type = IRQ_TYPE_EDGE_FALLING; |
---|
| 907 | + } else if (type == IRQ_TYPE_EDGE_FALLING) { |
---|
| 908 | + if (val) |
---|
| 909 | + return; |
---|
| 910 | + type = IRQ_TYPE_EDGE_RISING; |
---|
| 911 | + } |
---|
| 912 | + } while (loop_limit-- > 0); |
---|
| 913 | + dev_warn_once(pctrl->dev, "dual-edge irq failed to stabilize\n"); |
---|
688 | 914 | } |
---|
689 | 915 | |
---|
690 | 916 | static void msm_gpio_irq_ack(struct irq_data *d) |
---|
.. | .. |
---|
693 | 919 | struct msm_pinctrl *pctrl = gpiochip_get_data(gc); |
---|
694 | 920 | const struct msm_pingroup *g; |
---|
695 | 921 | unsigned long flags; |
---|
696 | | - u32 val; |
---|
| 922 | + |
---|
| 923 | + if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) { |
---|
| 924 | + if (test_bit(d->hwirq, pctrl->dual_edge_irqs)) |
---|
| 925 | + msm_gpio_update_dual_edge_parent(d); |
---|
| 926 | + return; |
---|
| 927 | + } |
---|
697 | 928 | |
---|
698 | 929 | g = &pctrl->soc->groups[d->hwirq]; |
---|
699 | 930 | |
---|
700 | 931 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
---|
701 | 932 | |
---|
702 | | - val = readl(pctrl->regs + g->intr_status_reg); |
---|
703 | | - if (g->intr_ack_high) |
---|
704 | | - val |= BIT(g->intr_status_bit); |
---|
705 | | - else |
---|
706 | | - val &= ~BIT(g->intr_status_bit); |
---|
707 | | - writel(val, pctrl->regs + g->intr_status_reg); |
---|
| 933 | + msm_ack_intr_status(pctrl, g); |
---|
708 | 934 | |
---|
709 | 935 | if (test_bit(d->hwirq, pctrl->dual_edge_irqs)) |
---|
710 | 936 | msm_gpio_update_dual_edge_pos(pctrl, g, d); |
---|
711 | 937 | |
---|
712 | 938 | raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
---|
| 939 | +} |
---|
| 940 | + |
---|
| 941 | +static bool msm_gpio_needs_dual_edge_parent_workaround(struct irq_data *d, |
---|
| 942 | + unsigned int type) |
---|
| 943 | +{ |
---|
| 944 | + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
---|
| 945 | + struct msm_pinctrl *pctrl = gpiochip_get_data(gc); |
---|
| 946 | + |
---|
| 947 | + return type == IRQ_TYPE_EDGE_BOTH && |
---|
| 948 | + pctrl->soc->wakeirq_dual_edge_errata && d->parent_data && |
---|
| 949 | + test_bit(d->hwirq, pctrl->skip_wake_irqs); |
---|
713 | 950 | } |
---|
714 | 951 | |
---|
715 | 952 | static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type) |
---|
.. | .. |
---|
718 | 955 | struct msm_pinctrl *pctrl = gpiochip_get_data(gc); |
---|
719 | 956 | const struct msm_pingroup *g; |
---|
720 | 957 | unsigned long flags; |
---|
| 958 | + bool was_enabled; |
---|
721 | 959 | u32 val; |
---|
| 960 | + |
---|
| 961 | + if (msm_gpio_needs_dual_edge_parent_workaround(d, type)) { |
---|
| 962 | + set_bit(d->hwirq, pctrl->dual_edge_irqs); |
---|
| 963 | + irq_set_handler_locked(d, handle_fasteoi_ack_irq); |
---|
| 964 | + msm_gpio_update_dual_edge_parent(d); |
---|
| 965 | + return 0; |
---|
| 966 | + } |
---|
| 967 | + |
---|
| 968 | + if (d->parent_data) |
---|
| 969 | + irq_chip_set_type_parent(d, type); |
---|
| 970 | + |
---|
| 971 | + if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) { |
---|
| 972 | + clear_bit(d->hwirq, pctrl->dual_edge_irqs); |
---|
| 973 | + irq_set_handler_locked(d, handle_fasteoi_irq); |
---|
| 974 | + return 0; |
---|
| 975 | + } |
---|
722 | 976 | |
---|
723 | 977 | g = &pctrl->soc->groups[d->hwirq]; |
---|
724 | 978 | |
---|
.. | .. |
---|
732 | 986 | else |
---|
733 | 987 | clear_bit(d->hwirq, pctrl->dual_edge_irqs); |
---|
734 | 988 | |
---|
735 | | - /* Route interrupts to application cpu */ |
---|
736 | | - val = readl(pctrl->regs + g->intr_target_reg); |
---|
737 | | - val &= ~(7 << g->intr_target_bit); |
---|
738 | | - val |= g->intr_target_kpss_val << g->intr_target_bit; |
---|
739 | | - writel(val, pctrl->regs + g->intr_target_reg); |
---|
| 989 | + /* Route interrupts to application cpu. |
---|
| 990 | + * With intr_target_use_scm interrupts are routed to |
---|
| 991 | + * application cpu using scm calls. |
---|
| 992 | + */ |
---|
| 993 | + if (pctrl->intr_target_use_scm) { |
---|
| 994 | + u32 addr = pctrl->phys_base[0] + g->intr_target_reg; |
---|
| 995 | + int ret; |
---|
| 996 | + |
---|
| 997 | + qcom_scm_io_readl(addr, &val); |
---|
| 998 | + |
---|
| 999 | + val &= ~(7 << g->intr_target_bit); |
---|
| 1000 | + val |= g->intr_target_kpss_val << g->intr_target_bit; |
---|
| 1001 | + |
---|
| 1002 | + ret = qcom_scm_io_writel(addr, val); |
---|
| 1003 | + if (ret) |
---|
| 1004 | + dev_err(pctrl->dev, |
---|
| 1005 | + "Failed routing %lu interrupt to Apps proc", |
---|
| 1006 | + d->hwirq); |
---|
| 1007 | + } else { |
---|
| 1008 | + val = msm_readl_intr_target(pctrl, g); |
---|
| 1009 | + val &= ~(7 << g->intr_target_bit); |
---|
| 1010 | + val |= g->intr_target_kpss_val << g->intr_target_bit; |
---|
| 1011 | + msm_writel_intr_target(val, pctrl, g); |
---|
| 1012 | + } |
---|
740 | 1013 | |
---|
741 | 1014 | /* Update configuration for gpio. |
---|
742 | 1015 | * RAW_STATUS_EN is left on for all gpio irqs. Due to the |
---|
743 | 1016 | * internal circuitry of TLMM, toggling the RAW_STATUS |
---|
744 | 1017 | * could cause the INTR_STATUS to be set for EDGE interrupts. |
---|
745 | 1018 | */ |
---|
746 | | - val = readl(pctrl->regs + g->intr_cfg_reg); |
---|
| 1019 | + val = msm_readl_intr_cfg(pctrl, g); |
---|
| 1020 | + was_enabled = val & BIT(g->intr_raw_status_bit); |
---|
747 | 1021 | val |= BIT(g->intr_raw_status_bit); |
---|
748 | 1022 | if (g->intr_detection_width == 2) { |
---|
749 | 1023 | val &= ~(3 << g->intr_detection_bit); |
---|
.. | .. |
---|
791 | 1065 | } else { |
---|
792 | 1066 | BUG(); |
---|
793 | 1067 | } |
---|
794 | | - writel(val, pctrl->regs + g->intr_cfg_reg); |
---|
| 1068 | + msm_writel_intr_cfg(val, pctrl, g); |
---|
| 1069 | + |
---|
| 1070 | + /* |
---|
| 1071 | + * The first time we set RAW_STATUS_EN it could trigger an interrupt. |
---|
| 1072 | + * Clear the interrupt. This is safe because we have |
---|
| 1073 | + * IRQCHIP_SET_TYPE_MASKED. |
---|
| 1074 | + */ |
---|
| 1075 | + if (!was_enabled) |
---|
| 1076 | + msm_ack_intr_status(pctrl, g); |
---|
795 | 1077 | |
---|
796 | 1078 | if (test_bit(d->hwirq, pctrl->dual_edge_irqs)) |
---|
797 | 1079 | msm_gpio_update_dual_edge_pos(pctrl, g, d); |
---|
.. | .. |
---|
810 | 1092 | { |
---|
811 | 1093 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
---|
812 | 1094 | struct msm_pinctrl *pctrl = gpiochip_get_data(gc); |
---|
813 | | - unsigned long flags; |
---|
814 | 1095 | |
---|
815 | | - raw_spin_lock_irqsave(&pctrl->lock, flags); |
---|
| 1096 | + /* |
---|
| 1097 | + * While they may not wake up when the TLMM is powered off, |
---|
| 1098 | + * some GPIOs would like to wakeup the system from suspend |
---|
| 1099 | + * when TLMM is powered on. To allow that, enable the GPIO |
---|
| 1100 | + * summary line to be wakeup capable at GIC. |
---|
| 1101 | + */ |
---|
| 1102 | + if (d->parent_data && test_bit(d->hwirq, pctrl->skip_wake_irqs)) |
---|
| 1103 | + return irq_chip_set_wake_parent(d, on); |
---|
816 | 1104 | |
---|
817 | | - irq_set_irq_wake(pctrl->irq, on); |
---|
| 1105 | + return irq_set_irq_wake(pctrl->irq, on); |
---|
| 1106 | +} |
---|
818 | 1107 | |
---|
819 | | - raw_spin_unlock_irqrestore(&pctrl->lock, flags); |
---|
| 1108 | +static int msm_gpio_irq_reqres(struct irq_data *d) |
---|
| 1109 | +{ |
---|
| 1110 | + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
---|
| 1111 | + struct msm_pinctrl *pctrl = gpiochip_get_data(gc); |
---|
| 1112 | + int ret; |
---|
| 1113 | + |
---|
| 1114 | + if (!try_module_get(gc->owner)) |
---|
| 1115 | + return -ENODEV; |
---|
| 1116 | + |
---|
| 1117 | + ret = msm_pinmux_request_gpio(pctrl->pctrl, NULL, d->hwirq); |
---|
| 1118 | + if (ret) |
---|
| 1119 | + goto out; |
---|
| 1120 | + msm_gpio_direction_input(gc, d->hwirq); |
---|
| 1121 | + |
---|
| 1122 | + if (gpiochip_lock_as_irq(gc, d->hwirq)) { |
---|
| 1123 | + dev_err(gc->parent, |
---|
| 1124 | + "unable to lock HW IRQ %lu for IRQ\n", |
---|
| 1125 | + d->hwirq); |
---|
| 1126 | + ret = -EINVAL; |
---|
| 1127 | + goto out; |
---|
| 1128 | + } |
---|
| 1129 | + |
---|
| 1130 | + /* |
---|
| 1131 | + * The disable / clear-enable workaround we do in msm_pinmux_set_mux() |
---|
| 1132 | + * only works if disable is not lazy since we only clear any bogus |
---|
| 1133 | + * interrupt in hardware. Explicitly mark the interrupt as UNLAZY. |
---|
| 1134 | + */ |
---|
| 1135 | + irq_set_status_flags(d->irq, IRQ_DISABLE_UNLAZY); |
---|
| 1136 | + |
---|
| 1137 | + return 0; |
---|
| 1138 | +out: |
---|
| 1139 | + module_put(gc->owner); |
---|
| 1140 | + return ret; |
---|
| 1141 | +} |
---|
| 1142 | + |
---|
| 1143 | +static void msm_gpio_irq_relres(struct irq_data *d) |
---|
| 1144 | +{ |
---|
| 1145 | + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
---|
| 1146 | + |
---|
| 1147 | + gpiochip_unlock_as_irq(gc, d->hwirq); |
---|
| 1148 | + module_put(gc->owner); |
---|
| 1149 | +} |
---|
| 1150 | + |
---|
| 1151 | +static int msm_gpio_irq_set_affinity(struct irq_data *d, |
---|
| 1152 | + const struct cpumask *dest, bool force) |
---|
| 1153 | +{ |
---|
| 1154 | + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
---|
| 1155 | + struct msm_pinctrl *pctrl = gpiochip_get_data(gc); |
---|
| 1156 | + |
---|
| 1157 | + if (d->parent_data && test_bit(d->hwirq, pctrl->skip_wake_irqs)) |
---|
| 1158 | + return irq_chip_set_affinity_parent(d, dest, force); |
---|
| 1159 | + |
---|
| 1160 | + return 0; |
---|
| 1161 | +} |
---|
| 1162 | + |
---|
| 1163 | +static int msm_gpio_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info) |
---|
| 1164 | +{ |
---|
| 1165 | + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
---|
| 1166 | + struct msm_pinctrl *pctrl = gpiochip_get_data(gc); |
---|
| 1167 | + |
---|
| 1168 | + if (d->parent_data && test_bit(d->hwirq, pctrl->skip_wake_irqs)) |
---|
| 1169 | + return irq_chip_set_vcpu_affinity_parent(d, vcpu_info); |
---|
820 | 1170 | |
---|
821 | 1171 | return 0; |
---|
822 | 1172 | } |
---|
.. | .. |
---|
840 | 1190 | */ |
---|
841 | 1191 | for_each_set_bit(i, pctrl->enabled_irqs, pctrl->chip.ngpio) { |
---|
842 | 1192 | g = &pctrl->soc->groups[i]; |
---|
843 | | - val = readl(pctrl->regs + g->intr_status_reg); |
---|
| 1193 | + val = msm_readl_intr_status(pctrl, g); |
---|
844 | 1194 | if (val & BIT(g->intr_status_bit)) { |
---|
845 | 1195 | irq_pin = irq_find_mapping(gc->irq.domain, i); |
---|
846 | 1196 | generic_handle_irq(irq_pin); |
---|
.. | .. |
---|
855 | 1205 | chained_irq_exit(chip, desc); |
---|
856 | 1206 | } |
---|
857 | 1207 | |
---|
858 | | -static int msm_gpio_init_valid_mask(struct gpio_chip *chip, |
---|
859 | | - struct msm_pinctrl *pctrl) |
---|
| 1208 | +static int msm_gpio_wakeirq(struct gpio_chip *gc, |
---|
| 1209 | + unsigned int child, |
---|
| 1210 | + unsigned int child_type, |
---|
| 1211 | + unsigned int *parent, |
---|
| 1212 | + unsigned int *parent_type) |
---|
860 | 1213 | { |
---|
861 | | - int ret; |
---|
862 | | - unsigned int len, i; |
---|
863 | | - unsigned int max_gpios = pctrl->soc->ngpios; |
---|
864 | | - u16 *tmp; |
---|
| 1214 | + struct msm_pinctrl *pctrl = gpiochip_get_data(gc); |
---|
| 1215 | + const struct msm_gpio_wakeirq_map *map; |
---|
| 1216 | + int i; |
---|
865 | 1217 | |
---|
866 | | - /* The number of GPIOs in the ACPI tables */ |
---|
867 | | - len = ret = device_property_read_u16_array(pctrl->dev, "gpios", NULL, 0); |
---|
868 | | - if (ret < 0) |
---|
869 | | - return 0; |
---|
| 1218 | + *parent = GPIO_NO_WAKE_IRQ; |
---|
| 1219 | + *parent_type = IRQ_TYPE_EDGE_RISING; |
---|
870 | 1220 | |
---|
871 | | - if (ret > max_gpios) |
---|
872 | | - return -EINVAL; |
---|
873 | | - |
---|
874 | | - tmp = kmalloc_array(len, sizeof(*tmp), GFP_KERNEL); |
---|
875 | | - if (!tmp) |
---|
876 | | - return -ENOMEM; |
---|
877 | | - |
---|
878 | | - ret = device_property_read_u16_array(pctrl->dev, "gpios", tmp, len); |
---|
879 | | - if (ret < 0) { |
---|
880 | | - dev_err(pctrl->dev, "could not read list of GPIOs\n"); |
---|
881 | | - goto out; |
---|
| 1221 | + for (i = 0; i < pctrl->soc->nwakeirq_map; i++) { |
---|
| 1222 | + map = &pctrl->soc->wakeirq_map[i]; |
---|
| 1223 | + if (map->gpio == child) { |
---|
| 1224 | + *parent = map->wakeirq; |
---|
| 1225 | + break; |
---|
| 1226 | + } |
---|
882 | 1227 | } |
---|
883 | 1228 | |
---|
884 | | - bitmap_zero(chip->valid_mask, max_gpios); |
---|
885 | | - for (i = 0; i < len; i++) |
---|
886 | | - set_bit(tmp[i], chip->valid_mask); |
---|
887 | | - |
---|
888 | | -out: |
---|
889 | | - kfree(tmp); |
---|
890 | | - return ret; |
---|
| 1229 | + return 0; |
---|
891 | 1230 | } |
---|
892 | 1231 | |
---|
893 | 1232 | static bool msm_gpio_needs_valid_mask(struct msm_pinctrl *pctrl) |
---|
894 | 1233 | { |
---|
895 | | - return device_property_read_u16_array(pctrl->dev, "gpios", NULL, 0) > 0; |
---|
| 1234 | + if (pctrl->soc->reserved_gpios) |
---|
| 1235 | + return true; |
---|
| 1236 | + |
---|
| 1237 | + return device_property_count_u16(pctrl->dev, "gpios") > 0; |
---|
896 | 1238 | } |
---|
897 | 1239 | |
---|
898 | 1240 | static int msm_gpio_init(struct msm_pinctrl *pctrl) |
---|
899 | 1241 | { |
---|
900 | 1242 | struct gpio_chip *chip; |
---|
901 | | - int ret; |
---|
902 | | - unsigned ngpio = pctrl->soc->ngpios; |
---|
| 1243 | + struct gpio_irq_chip *girq; |
---|
| 1244 | + int i, ret; |
---|
| 1245 | + unsigned gpio, ngpio = pctrl->soc->ngpios; |
---|
| 1246 | + struct device_node *np; |
---|
| 1247 | + bool skip; |
---|
903 | 1248 | |
---|
904 | 1249 | if (WARN_ON(ngpio > MAX_NR_GPIO)) |
---|
905 | 1250 | return -EINVAL; |
---|
.. | .. |
---|
911 | 1256 | chip->parent = pctrl->dev; |
---|
912 | 1257 | chip->owner = THIS_MODULE; |
---|
913 | 1258 | chip->of_node = pctrl->dev->of_node; |
---|
914 | | - chip->need_valid_mask = msm_gpio_needs_valid_mask(pctrl); |
---|
| 1259 | + if (msm_gpio_needs_valid_mask(pctrl)) |
---|
| 1260 | + chip->init_valid_mask = msm_gpio_init_valid_mask; |
---|
915 | 1261 | |
---|
916 | 1262 | pctrl->irq_chip.name = "msmgpio"; |
---|
| 1263 | + pctrl->irq_chip.irq_enable = msm_gpio_irq_enable; |
---|
| 1264 | + pctrl->irq_chip.irq_disable = msm_gpio_irq_disable; |
---|
917 | 1265 | pctrl->irq_chip.irq_mask = msm_gpio_irq_mask; |
---|
918 | 1266 | pctrl->irq_chip.irq_unmask = msm_gpio_irq_unmask; |
---|
919 | 1267 | pctrl->irq_chip.irq_ack = msm_gpio_irq_ack; |
---|
920 | 1268 | pctrl->irq_chip.irq_set_type = msm_gpio_irq_set_type; |
---|
921 | 1269 | pctrl->irq_chip.irq_set_wake = msm_gpio_irq_set_wake; |
---|
| 1270 | + pctrl->irq_chip.irq_request_resources = msm_gpio_irq_reqres; |
---|
| 1271 | + pctrl->irq_chip.irq_release_resources = msm_gpio_irq_relres; |
---|
| 1272 | + pctrl->irq_chip.irq_set_affinity = msm_gpio_irq_set_affinity; |
---|
| 1273 | + pctrl->irq_chip.irq_set_vcpu_affinity = msm_gpio_irq_set_vcpu_affinity; |
---|
| 1274 | + pctrl->irq_chip.flags = IRQCHIP_MASK_ON_SUSPEND | |
---|
| 1275 | + IRQCHIP_SET_TYPE_MASKED | |
---|
| 1276 | + IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND; |
---|
| 1277 | + |
---|
| 1278 | + np = of_parse_phandle(pctrl->dev->of_node, "wakeup-parent", 0); |
---|
| 1279 | + if (np) { |
---|
| 1280 | + chip->irq.parent_domain = irq_find_matching_host(np, |
---|
| 1281 | + DOMAIN_BUS_WAKEUP); |
---|
| 1282 | + of_node_put(np); |
---|
| 1283 | + if (!chip->irq.parent_domain) |
---|
| 1284 | + return -EPROBE_DEFER; |
---|
| 1285 | + chip->irq.child_to_parent_hwirq = msm_gpio_wakeirq; |
---|
| 1286 | + pctrl->irq_chip.irq_eoi = irq_chip_eoi_parent; |
---|
| 1287 | + /* |
---|
| 1288 | + * Let's skip handling the GPIOs, if the parent irqchip |
---|
| 1289 | + * is handling the direct connect IRQ of the GPIO. |
---|
| 1290 | + */ |
---|
| 1291 | + skip = irq_domain_qcom_handle_wakeup(chip->irq.parent_domain); |
---|
| 1292 | + for (i = 0; skip && i < pctrl->soc->nwakeirq_map; i++) { |
---|
| 1293 | + gpio = pctrl->soc->wakeirq_map[i].gpio; |
---|
| 1294 | + set_bit(gpio, pctrl->skip_wake_irqs); |
---|
| 1295 | + } |
---|
| 1296 | + } |
---|
| 1297 | + |
---|
| 1298 | + girq = &chip->irq; |
---|
| 1299 | + girq->chip = &pctrl->irq_chip; |
---|
| 1300 | + girq->parent_handler = msm_gpio_irq_handler; |
---|
| 1301 | + girq->fwnode = pctrl->dev->fwnode; |
---|
| 1302 | + girq->num_parents = 1; |
---|
| 1303 | + girq->parents = devm_kcalloc(pctrl->dev, 1, sizeof(*girq->parents), |
---|
| 1304 | + GFP_KERNEL); |
---|
| 1305 | + if (!girq->parents) |
---|
| 1306 | + return -ENOMEM; |
---|
| 1307 | + girq->default_type = IRQ_TYPE_NONE; |
---|
| 1308 | + girq->handler = handle_bad_irq; |
---|
| 1309 | + girq->parents[0] = pctrl->irq; |
---|
922 | 1310 | |
---|
923 | 1311 | ret = gpiochip_add_data(&pctrl->chip, pctrl); |
---|
924 | 1312 | if (ret) { |
---|
925 | 1313 | dev_err(pctrl->dev, "Failed register gpiochip\n"); |
---|
926 | | - return ret; |
---|
927 | | - } |
---|
928 | | - |
---|
929 | | - ret = msm_gpio_init_valid_mask(chip, pctrl); |
---|
930 | | - if (ret) { |
---|
931 | | - dev_err(pctrl->dev, "Failed to setup irq valid bits\n"); |
---|
932 | | - gpiochip_remove(&pctrl->chip); |
---|
933 | 1314 | return ret; |
---|
934 | 1315 | } |
---|
935 | 1316 | |
---|
.. | .. |
---|
953 | 1334 | } |
---|
954 | 1335 | } |
---|
955 | 1336 | |
---|
956 | | - ret = gpiochip_irqchip_add(chip, |
---|
957 | | - &pctrl->irq_chip, |
---|
958 | | - 0, |
---|
959 | | - handle_edge_irq, |
---|
960 | | - IRQ_TYPE_NONE); |
---|
961 | | - if (ret) { |
---|
962 | | - dev_err(pctrl->dev, "Failed to add irqchip to gpiochip\n"); |
---|
963 | | - gpiochip_remove(&pctrl->chip); |
---|
964 | | - return -ENOSYS; |
---|
965 | | - } |
---|
966 | | - |
---|
967 | | - gpiochip_set_chained_irqchip(chip, &pctrl->irq_chip, pctrl->irq, |
---|
968 | | - msm_gpio_irq_handler); |
---|
969 | | - |
---|
970 | 1337 | return 0; |
---|
971 | 1338 | } |
---|
972 | 1339 | |
---|
.. | .. |
---|
975 | 1342 | { |
---|
976 | 1343 | struct msm_pinctrl *pctrl = container_of(nb, struct msm_pinctrl, restart_nb); |
---|
977 | 1344 | |
---|
978 | | - writel(0, pctrl->regs + PS_HOLD_OFFSET); |
---|
| 1345 | + writel(0, pctrl->regs[0] + PS_HOLD_OFFSET); |
---|
979 | 1346 | mdelay(1000); |
---|
980 | 1347 | return NOTIFY_DONE; |
---|
981 | 1348 | } |
---|
.. | .. |
---|
1005 | 1372 | } |
---|
1006 | 1373 | } |
---|
1007 | 1374 | |
---|
| 1375 | +static __maybe_unused int msm_pinctrl_suspend(struct device *dev) |
---|
| 1376 | +{ |
---|
| 1377 | + struct msm_pinctrl *pctrl = dev_get_drvdata(dev); |
---|
| 1378 | + |
---|
| 1379 | + return pinctrl_force_sleep(pctrl->pctrl); |
---|
| 1380 | +} |
---|
| 1381 | + |
---|
| 1382 | +static __maybe_unused int msm_pinctrl_resume(struct device *dev) |
---|
| 1383 | +{ |
---|
| 1384 | + struct msm_pinctrl *pctrl = dev_get_drvdata(dev); |
---|
| 1385 | + |
---|
| 1386 | + return pinctrl_force_default(pctrl->pctrl); |
---|
| 1387 | +} |
---|
| 1388 | + |
---|
| 1389 | +SIMPLE_DEV_PM_OPS(msm_pinctrl_dev_pm_ops, msm_pinctrl_suspend, |
---|
| 1390 | + msm_pinctrl_resume); |
---|
| 1391 | + |
---|
| 1392 | +EXPORT_SYMBOL(msm_pinctrl_dev_pm_ops); |
---|
| 1393 | + |
---|
1008 | 1394 | int msm_pinctrl_probe(struct platform_device *pdev, |
---|
1009 | 1395 | const struct msm_pinctrl_soc_data *soc_data) |
---|
1010 | 1396 | { |
---|
1011 | 1397 | struct msm_pinctrl *pctrl; |
---|
1012 | 1398 | struct resource *res; |
---|
1013 | 1399 | int ret; |
---|
| 1400 | + int i; |
---|
1014 | 1401 | |
---|
1015 | 1402 | pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL); |
---|
1016 | 1403 | if (!pctrl) |
---|
.. | .. |
---|
1019 | 1406 | pctrl->dev = &pdev->dev; |
---|
1020 | 1407 | pctrl->soc = soc_data; |
---|
1021 | 1408 | pctrl->chip = msm_gpio_template; |
---|
| 1409 | + pctrl->intr_target_use_scm = of_device_is_compatible( |
---|
| 1410 | + pctrl->dev->of_node, |
---|
| 1411 | + "qcom,ipq8064-pinctrl"); |
---|
1022 | 1412 | |
---|
1023 | 1413 | raw_spin_lock_init(&pctrl->lock); |
---|
1024 | 1414 | |
---|
1025 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
1026 | | - pctrl->regs = devm_ioremap_resource(&pdev->dev, res); |
---|
1027 | | - if (IS_ERR(pctrl->regs)) |
---|
1028 | | - return PTR_ERR(pctrl->regs); |
---|
| 1415 | + if (soc_data->tiles) { |
---|
| 1416 | + for (i = 0; i < soc_data->ntiles; i++) { |
---|
| 1417 | + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
---|
| 1418 | + soc_data->tiles[i]); |
---|
| 1419 | + pctrl->regs[i] = devm_ioremap_resource(&pdev->dev, res); |
---|
| 1420 | + if (IS_ERR(pctrl->regs[i])) |
---|
| 1421 | + return PTR_ERR(pctrl->regs[i]); |
---|
| 1422 | + } |
---|
| 1423 | + } else { |
---|
| 1424 | + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
| 1425 | + pctrl->regs[0] = devm_ioremap_resource(&pdev->dev, res); |
---|
| 1426 | + if (IS_ERR(pctrl->regs[0])) |
---|
| 1427 | + return PTR_ERR(pctrl->regs[0]); |
---|
| 1428 | + |
---|
| 1429 | + pctrl->phys_base[0] = res->start; |
---|
| 1430 | + } |
---|
1029 | 1431 | |
---|
1030 | 1432 | msm_pinctrl_setup_pm_reset(pctrl); |
---|
1031 | 1433 | |
---|
1032 | 1434 | pctrl->irq = platform_get_irq(pdev, 0); |
---|
1033 | | - if (pctrl->irq < 0) { |
---|
1034 | | - dev_err(&pdev->dev, "No interrupt defined for msmgpio\n"); |
---|
| 1435 | + if (pctrl->irq < 0) |
---|
1035 | 1436 | return pctrl->irq; |
---|
1036 | | - } |
---|
1037 | 1437 | |
---|
1038 | 1438 | pctrl->desc.owner = THIS_MODULE; |
---|
1039 | 1439 | pctrl->desc.pctlops = &msm_pinctrl_ops; |
---|
.. | .. |
---|
1073 | 1473 | } |
---|
1074 | 1474 | EXPORT_SYMBOL(msm_pinctrl_remove); |
---|
1075 | 1475 | |
---|
| 1476 | +MODULE_DESCRIPTION("Qualcomm Technologies, Inc. pinctrl-msm driver"); |
---|
| 1477 | +MODULE_LICENSE("GPL v2"); |
---|
| 1478 | + |
---|