diff options
author | Nilesh Bacchewar <nilesh.bacchewar@intel.com> | 2016-09-22 01:35:23 +0200 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2016-09-23 15:14:21 +0200 |
commit | 01dabe91b1fef93130207e1a04bdf0a092a9fb21 (patch) | |
tree | e376e5acadb0e35969aa18ba5f8c2187ca282b44 | |
parent | pinctrl: cherryview: Convert to use devm_gpiochip_add_data() (diff) | |
download | linux-01dabe91b1fef93130207e1a04bdf0a092a9fb21.tar.xz linux-01dabe91b1fef93130207e1a04bdf0a092a9fb21.zip |
pinctrl: intel: Configure GPIO chip IRQ as wakeup interrupts
On some Intel BXT platform, wake-up from suspend-to-idle on pressing
power-button is not working. Its noticed that gpio-keys driver marking the
second level IRQ/power-button as wake capable but Intel pintctrl
driver is missing to mark GPIO chip/controller IRQ which first level IRQ
as wake cable if its GPIO pin IRQ is wakeble. So, though the first level
IRQ gets generated on power-button press, since it is not marked as
wake capable resume/wake-up flow is not happening.
Intel pintctrl/GPIO driver need to mark GPIO chip/controller IRQ (first
level IRQ) as wake capable iff GPIO pin's IRQ (second level IRQ) is marked
as wake cable.
Changes in v2:
- Add missing irq initialisation.
Signed-off-by: Nilesh Bacchewar <nilesh.bacchewar@intel.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-intel.c | 33 |
1 files changed, 5 insertions, 28 deletions
diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 257cab129692..63387a40b973 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -86,6 +86,7 @@ struct intel_pinctrl_context { * @communities: All communities in this pin controller * @ncommunities: Number of communities in this pin controller * @context: Configuration saved over system sleep + * @irq: pinctrl/GPIO chip irq number */ struct intel_pinctrl { struct device *dev; @@ -97,6 +98,7 @@ struct intel_pinctrl { struct intel_community *communities; size_t ncommunities; struct intel_pinctrl_context context; + int irq; }; #define pin_to_padno(c, p) ((p) - (c)->pin_base) @@ -793,38 +795,12 @@ static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct intel_pinctrl *pctrl = gpiochip_get_data(gc); - const struct intel_community *community; unsigned pin = irqd_to_hwirq(d); - unsigned padno, gpp, gpp_offset; - unsigned long flags; - u32 gpe_en; - - community = intel_get_community(pctrl, pin); - if (!community) - return -EINVAL; - - raw_spin_lock_irqsave(&pctrl->lock, flags); - padno = pin_to_padno(community, pin); - gpp = padno / community->gpp_size; - gpp_offset = padno % community->gpp_size; - - /* Clear the existing wake status */ - writel(BIT(gpp_offset), community->regs + GPI_GPE_STS + gpp * 4); - - /* - * The controller will generate wake when GPE of the corresponding - * pad is enabled and it is not routed to SCI (GPIROUTSCI is not - * set). - */ - gpe_en = readl(community->regs + GPI_GPE_EN + gpp * 4); if (on) - gpe_en |= BIT(gpp_offset); + enable_irq_wake(pctrl->irq); else - gpe_en &= ~BIT(gpp_offset); - writel(gpe_en, community->regs + GPI_GPE_EN + gpp * 4); - - raw_spin_unlock_irqrestore(&pctrl->lock, flags); + disable_irq_wake(pctrl->irq); dev_dbg(pctrl->dev, "%sable wake for pin %u\n", on ? "en" : "dis", pin); return 0; @@ -905,6 +881,7 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq) pctrl->chip.label = dev_name(pctrl->dev); pctrl->chip.parent = pctrl->dev; pctrl->chip.base = -1; + pctrl->irq = irq; ret = gpiochip_add_data(&pctrl->chip, pctrl); if (ret) { |