Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S966260AbcJZM2l (ORCPT ); Wed, 26 Oct 2016 08:28:41 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:55380 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S966210AbcJZM2g (ORCPT ); Wed, 26 Oct 2016 08:28:36 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, AceLan Kao , Mika Westerberg , Linus Walleij Subject: [PATCH 4.8 106/140] pinctrl: intel: Only restore pins that are used by the driver Date: Wed, 26 Oct 2016 14:22:46 +0200 Message-Id: <20161026122224.918032401@linuxfoundation.org> X-Mailer: git-send-email 2.10.1 In-Reply-To: <20161026122220.384323763@linuxfoundation.org> References: <20161026122220.384323763@linuxfoundation.org> User-Agent: quilt/0.64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3238 Lines: 92 4.8-stable review patch. If anyone has any objections, please let me know. ------------------ From: Mika Westerberg commit c538b9436751a0be2e1246b48353bc23156bdbcc upstream. Dell XPS 13 (and maybe some others) uses a GPIO (CPU_GP_1) during suspend to explicitly disable USB touchscreen interrupt. This is done to prevent situation where the lid is closed the touchscreen is left functional. The pinctrl driver (wrongly) assumes it owns all pins which are owned by host and not locked down. It is perfectly fine for BIOS to use those pins as it is also considered as host in this context. What happens is that when the lid of Dell XPS 13 is closed, the BIOS configures CPU_GP_1 low disabling the touchscreen interrupt. During resume we restore all host owned pins to the known state which includes CPU_GP_1 and this overwrites what the BIOS has programmed there causing the touchscreen to fail as no interrupts are reaching the CPU anymore. Fix this by restoring only those pins we know are explicitly requested by the kernel one way or other. Link: https://bugzilla.kernel.org/show_bug.cgi?id=176361 Reported-by: AceLan Kao Tested-by: AceLan Kao Signed-off-by: Mika Westerberg Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- drivers/pinctrl/intel/pinctrl-intel.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -19,6 +19,7 @@ #include #include +#include "../core.h" #include "pinctrl-intel.h" /* Offset from regs */ @@ -1079,6 +1080,26 @@ int intel_pinctrl_remove(struct platform EXPORT_SYMBOL_GPL(intel_pinctrl_remove); #ifdef CONFIG_PM_SLEEP +static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned pin) +{ + const struct pin_desc *pd = pin_desc_get(pctrl->pctldev, pin); + + if (!pd || !intel_pad_usable(pctrl, pin)) + return false; + + /* + * Only restore the pin if it is actually in use by the kernel (or + * by userspace). It is possible that some pins are used by the + * BIOS during resume and those are not always locked down so leave + * them alone. + */ + if (pd->mux_owner || pd->gpio_owner || + gpiochip_line_is_irq(&pctrl->chip, pin)) + return true; + + return false; +} + int intel_pinctrl_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); @@ -1092,7 +1113,7 @@ int intel_pinctrl_suspend(struct device const struct pinctrl_pin_desc *desc = &pctrl->soc->pins[i]; u32 val; - if (!intel_pad_usable(pctrl, desc->number)) + if (!intel_pinctrl_should_save(pctrl, desc->number)) continue; val = readl(intel_get_padcfg(pctrl, desc->number, PADCFG0)); @@ -1153,7 +1174,7 @@ int intel_pinctrl_resume(struct device * void __iomem *padcfg; u32 val; - if (!intel_pad_usable(pctrl, desc->number)) + if (!intel_pinctrl_should_save(pctrl, desc->number)) continue; padcfg = intel_get_padcfg(pctrl, desc->number, PADCFG0);