Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp3311891imu; Sun, 11 Nov 2018 12:08:08 -0800 (PST) X-Google-Smtp-Source: AJdET5fggPm0z8MTaLq1TXO3ZHK/J/9wbjrSx/tA4RUZKDZA/FC9G3/ggcQuLsxTyInUeNBg6cDw X-Received: by 2002:a17:902:7e4c:: with SMTP id a12-v6mr16979235pln.149.1541966887992; Sun, 11 Nov 2018 12:08:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1541966887; cv=none; d=google.com; s=arc-20160816; b=OtSp14iGRplCaPNa7m8AKRwG5qdK0m4rfUcepT2Nf80u5et0yJGOHNxHtpC3kBPE9q fjiVxt5Kn/5EisKwanG/Qa9IuX5LtZotu8RG8g5Y00R4h8B/I5kHjmFitOSVV1+ENNe0 0qW+I/7UAfX6fmseHalR/T+X7WOFkktPkfIsxSEMsPapfXKHqiPmJVi2/SZCWdchGdFt Ijpz2+cTIBjNXp4pEUMY8HxNKTMN7VxiEUDLy31UI4GEtRPdTTpujH7qav6D27XKnr94 pvOKEEjfOxlP7pfbdiyvASt6MdJLDCmjAt1LM5NhLKACbFkqxgls9kc/VSb/HCv1Esof caQA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:subject:message-id:date:cc:to :from:mime-version:content-transfer-encoding:content-disposition; bh=tdnefhcoYpso9pse7eSVXlUU4FX3eZG8RpQryGipgks=; b=KmeRigF9SXUytP2S7x9LeG9akKrUxuoxRlRx+BLFLwK56aueT0IJ4jYne3wqIhWmQ8 hBagM2uspLzdLALWzyyYWtHxTl1uahMmIGbAH20aA99Xq0vQoIvOSJF5LmwRDgFoqb7g 3un0/quaB8r/+9tXTZznJF3uxmwYEr3S8qZ0Rf2pwbW83CgVr4bAovRKxgv+s0YZk3xH QVEEG+aosz7KR4ZN/gBvsdv58rovDt6Jsi57VAqYu7rhuz1llm2l+aGuhZCLf5U6qcTs 4tEl+RAbln0fAlxU8a91Jzp6lF+tnDKlzZvVoyCEv4j7Ne7fmoCYslA5DNxukLJYIiTm nf1A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u21si13862123pgg.463.2018.11.11.12.07.52; Sun, 11 Nov 2018 12:08:07 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730974AbeKLFzu (ORCPT + 99 others); Mon, 12 Nov 2018 00:55:50 -0500 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:51954 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725905AbeKLFzu (ORCPT ); Mon, 12 Nov 2018 00:55:50 -0500 Received: from [192.168.4.242] (helo=deadeye) by shadbolt.decadent.org.uk with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1gLvt3-0000lG-DC; Sun, 11 Nov 2018 19:59:13 +0000 Received: from ben by deadeye with local (Exim 4.91) (envelope-from ) id 1gLvsR-0001Wa-Ga; Sun, 11 Nov 2018 19:58:35 +0000 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "Hans de Goede" , "Thierry Reding" , "Andy Shevchenko" Date: Sun, 11 Nov 2018 19:49:05 +0000 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) Subject: [PATCH 3.16 121/366] pwm: lpss: platform: Save/restore the ctrl register over a suspend/resume In-Reply-To: X-SA-Exim-Connect-IP: 192.168.4.242 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.16.61-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Hans de Goede commit 1d375b58c12f08d8570b30b865def4734517f04f upstream. On some devices the contents of the ctrl register get lost over a suspend/resume and the PWM comes back up disabled after the resume. This is seen on some Bay Trail devices with the PWM in ACPI enumerated mode, so it shows up as a platform device instead of a PCI device. If we still think it is enabled and then try to change the duty-cycle after this, we end up with a "PWM_SW_UPDATE was not cleared" error and the PWM is stuck in that state from then on. This commit adds suspend and resume pm callbacks to the pwm-lpss-platform code, which save/restore the ctrl register over a suspend/resume, fixing this. Note that: 1) There is no need to do this over a runtime suspend, since we only runtime suspend when disabled and then we properly set the enable bit and reprogram the timings when we re-enable the PWM. 2) This may be happening on more systems then we realize, but has been covered up sofar by a bug in the acpi-lpss.c code which was save/restoring the regular device registers instead of the lpss private registers due to lpss_device_desc.prv_offset not being set. This is fixed by a later patch in this series. Signed-off-by: Hans de Goede Reviewed-by: Andy Shevchenko Signed-off-by: Thierry Reding [bwh: Backported to 3.16: - pwm-lpss is a single module, so make the new functions static - Only one PWM per chip is supported; remove the npwm assertion and loops - Adjust filenames, context] Signed-off-by: Ben Hutchings --- --- a/drivers/pwm/pwm-lpss.c +++ b/drivers/pwm/pwm-lpss.c @@ -39,6 +39,7 @@ struct pwm_lpss_chip { void __iomem *regs; struct clk *clk; unsigned long clk_rate; + u32 saved_ctrl; }; struct pwm_lpss_boardinfo { @@ -177,6 +178,24 @@ static int pwm_lpss_remove(struct pwm_lp return pwmchip_remove(&lpwm->chip); } +static int pwm_lpss_suspend(struct device *dev) +{ + struct pwm_lpss_chip *lpwm = dev_get_drvdata(dev); + + lpwm->saved_ctrl = readl(lpwm->regs + PWM); + + return 0; +} + +static int pwm_lpss_resume(struct device *dev) +{ + struct pwm_lpss_chip *lpwm = dev_get_drvdata(dev); + + writel(lpwm->saved_ctrl, lpwm->regs + PWM); + + return 0; +} + static int pwm_lpss_probe_pci(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -241,6 +260,10 @@ static int pwm_lpss_remove_platform(stru return pwm_lpss_remove(lpwm); } +static SIMPLE_DEV_PM_OPS(pwm_lpss_platform_pm_ops, + pwm_lpss_suspend, + pwm_lpss_resume); + static const struct acpi_device_id pwm_lpss_acpi_match[] = { { "80860F09", 0 }, { }, @@ -251,6 +274,7 @@ static struct platform_driver pwm_lpss_d .driver = { .name = "pwm-lpss", .acpi_match_table = pwm_lpss_acpi_match, + .pm = &pwm_lpss_platform_pm_ops, }, .probe = pwm_lpss_probe_platform, .remove = pwm_lpss_remove_platform,