From patchwork Mon Oct 2 09:51:47 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ed Blake X-Patchwork-Id: 820404 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pwm-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=sondrel.onmicrosoft.com header.i=@sondrel.onmicrosoft.com header.b="JGhB6mdI"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3y5HWd1MQQz9t3f for ; Mon, 2 Oct 2017 20:52:13 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751106AbdJBJwL (ORCPT ); Mon, 2 Oct 2017 05:52:11 -0400 Received: from mail-db5eur01on0043.outbound.protection.outlook.com ([104.47.2.43]:46624 "EHLO EUR01-DB5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751313AbdJBJwH (ORCPT ); Mon, 2 Oct 2017 05:52:07 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sondrel.onmicrosoft.com; s=selector1-sondrel-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=A8T5Oy27RD3SCwm0D2Si78laiQGHN+Ii/4na+B7F8/Q=; b=JGhB6mdIBOIj7+joxQjjR8fdbx/ZSF2vMwq7/DBf2so5CEliFVfyJRfidenjZCGUY1bkPXVnW6cu/fQfaedeZjkYghPhKIEp1YAoOkkbwbxcwvADB90fpWsGKA2lkgZQuCcWDI5JS9kvGRIzAaVCjTEkAqgKEBWAT0khrkmHIWY= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=ed.blake@sondrel.com; Received: from iw-build-2.sondrel.com (195.88.9.101) by AM4P191MB0002.EURP191.PROD.OUTLOOK.COM (2603:10a6:200:64::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.77.7; Mon, 2 Oct 2017 09:52:05 +0000 From: Ed Blake To: thierry.reding@gmail.com Cc: linux-pwm@vger.kernel.org, Ed Blake Subject: [PATCH 1/2] pwm: img: Add suspend / resume handling Date: Mon, 2 Oct 2017 10:51:47 +0100 Message-Id: <1506937908-360-2-git-send-email-ed.blake@sondrel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1506937908-360-1-git-send-email-ed.blake@sondrel.com> References: <1506937908-360-1-git-send-email-ed.blake@sondrel.com> MIME-Version: 1.0 X-Originating-IP: [195.88.9.101] X-ClientProxiedBy: DB6PR06CA0011.eurprd06.prod.outlook.com (2603:10a6:6:1::24) To AM4P191MB0002.EURP191.PROD.OUTLOOK.COM (2603:10a6:200:64::10) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 55a3567c-ba3b-4ed2-da47-08d5097b3d0f X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(2017030254152)(2017052603199)(201703131423075)(201703031133081)(201702281549075); SRVR:AM4P191MB0002; X-Microsoft-Exchange-Diagnostics: 1; AM4P191MB0002; 3:P+MYi+R6/4de1OrtEi3eDo6oHt52a0qt7PK1yLZrQJyINDBAjYVdD0sGyZgNi1+p68ckkuFAMDS0SJCU64mLdx1Tj/SnF/o1+faSPitciofccdT8PLep1bhDeNzMU8jyGGCvu2y5a0ugcOExXRXfe4CweNjH5sKqexbK2bny6afb+fGJes1T+FwSfHj2L0kGGBubcGOt1QtDbp2zKqYVoInYm1uEulVxvJZb0DhsAzNPWJwjmYHIOAu9ruJFv1W+; 25:nhPxiAJvkHus/BsTMymvXNh2SoF7sUf6SixsQ7waUFeYRvb37/Pl7Q542kqS5SrW6BlOzyMfTHBDFffjAwDOqLdsIgd6z/UGV5PPKdjyJOoWe+dD6Aj5cMa6pjgs357V9VE32NQzTzRiE6sSurbciqatJbV9q4cvqz8XPauWhQ+a927NtZgpbWlUv1jHtVgygDUJ8+YpeVddfqrQ5g/f+ZFP9ht7pZ7SmrlIji33lDF9hzqKm3vlbdIWxXH4YMgmcI0i05jVTD7oFo5mKV97ai5JyXLA+npkSruPQG39p/NcLt3lXk8qsBP9KDfwHC/oknz8aovs9kKfdsQ+880uCA==; 31:KZuB8pqfaCHvhYiPUW1xfnuaXICJqnBmRyRe69mmkozCl1KKFbuiwlotgLKbhsUiTby8LPJtYOFzG4s+wS5Tsio1a5tuxahiSlCtPDrxIP15Kx0w+w66CdaigqQx9jN2fhnDw962KZghQnKSU5qtxlBSmv/Lx+LmVztLg8Y7UlDguPY34krqXbgMIb6/h0kB6SLaz+OLYr7Pn5BkWpViui08c4BeFGPEZ4GOdQd0K0o= X-MS-TrafficTypeDiagnostic: AM4P191MB0002: X-Microsoft-Exchange-Diagnostics: 1; AM4P191MB0002; 20:qerlcl8Z5nRbcwW3UTY3blTsba8mLuoW1vUUDE2EZpr1T5zEwpxoBWs2yTebhYFbMr4oWJECbbDFwJuefwpEDZLjv/kX4o3kcK8HY6Qj5Moby+DEP9o5cf98rdMpKiuVu0F+ifVvtMxVciWVqQX+2uJF3CRglUNzcZJaES5mjrss+xvONotvRij5jOzNOJfspIeH6JXVbtbfC0BO9NE5vsmpVgvO+SGwcShr6u8g0s5mHZ91TSOsTtnPW27uP1N8; 4:2k7XhK2nkMX3q3gep+BagjCjK1TQxsWLF9cozO5KdIJkX2E4eNw6Uu3Dkfk5XB4U1iXCztUlikb/3zNosJoIqD9cPOEZztsZgi7q7pegwLH2QlVCqhP2KYPyVzTC5VPx3uoUkeKYr0jJbNXxNQshfOIq0RWQtf6NaS90gdiwFE9iTp+Ek25XP1KRPmAm12zfXq9GsGl1simPntYWlw+iAKqPHu/SCEzRDUzSN4YuJYzOxhSiyMvXN3Ke4KtBqY6o X-Exchange-Antispam-Report-Test: UriScan:; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(5005006)(8121501046)(10201501046)(100000703101)(100105400095)(3002001)(93006095)(93001095)(6041248)(20161123560025)(20161123564025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123558100)(20161123562025)(20161123555025)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095); SRVR:AM4P191MB0002; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:AM4P191MB0002; X-Forefront-PRVS: 0448A97BF2 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(6009001)(346002)(376002)(39830400002)(199003)(189002)(53416004)(5003940100001)(66066001)(50466002)(53936002)(4326008)(2906002)(81156014)(7736002)(8676002)(6666003)(81166006)(5660300001)(305945005)(47776003)(6486002)(69596002)(86362001)(478600001)(189998001)(8936002)(36756003)(25786009)(16526017)(2361001)(16586007)(316002)(50986999)(15650500001)(50226002)(97736004)(48376002)(101416001)(33646002)(3846002)(76176999)(39060400002)(6116002)(68736007)(107886003)(2950100002)(6916009)(105586002)(106356001)(2351001); DIR:OUT; SFP:1101; SCL:1; SRVR:AM4P191MB0002; H:iw-build-2.sondrel.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: sondrel.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: 1; AM4P191MB0002; 23:oZRLTcGQJNmitFl/q5LxQWmmTjC0Vv9WQKycPIljAvL2fExd/ttgRzqRfsTy7OQp1TxqzOK9Wg8rsszniIq97Zzr1X5OyaITo/mXVon6Ks3aknXsxvl9axkN1+iQHmruEZspVE+QRnLYgLhunjTtuDkT5v9RwVf2LP37gcSyBgZ80y1vrbrXPk9o41dj75coPTPRXSn56kajDgeQMyJEh4xCd48ioVJ33fJ0YjFPHoBEbG+f8c2MDf4aHyKWjvm2hcxMMF1DRzHL1fAtLCm408kr0U8vBu+T8/OdEF/EX92PvuW9tcvzdipSg6m/FWBq3rKJ5WzjyccwhMPrmq9Qipx3iyvAya/8h02nakNuBtJY25cSszpdC0z0zNuc2bZsUWniobUzJGaAndrTqPuxQONDAx0SRx8kjboQ1HubH2Ef4mzGJjiiAHeonkApphuLvP/nNpdoFOsKtPunce21mrAR8BD6d2HZ60RMCZss5d2xcSk5dv3m+ERo5DF105k8+265q9rCFIww+Bf2XHw4pgmWqq+0ISVMmmx8Sl4h03AtUBglb697cyQu0rMZAfzMFAdDJztPUQyjeeFqfM6YewreW8a2PELvGhsyRO6wBt7U3kpUulihXl/9TMMt1q7szqEtZarmHP5ZaeXE8bk5jlEwGlZ3r84DQ/9IPpAZKeDMXPGxRn1T7dXbPaXZKF0Y9MGsIEMQkAuLypJhRsRN4B90a8VJzll5a+NdRNHTuaVwQJsTrq9NYk2hhW8y8dJVUe7EiQqXUtjHbfetJXI1+mE2rEPJ+eEHlkHhxsP2BDkEvec/136vWbm7xtaveqK7+DRv86ies/ORsGRGIWhkCRV6RTQ+AhC3GGPx2ArQ7m+cl/m0IT6X93/wznuvqVDoZ9z9Vs8ej3AfKJ8PjeYrvCzwf08Ay5X7xLbX6CDz3m3kKA2FQGpMOYBH7Aba8NiSjNL8NvGQOpJHoskf4QOYeupmqk9GXMwXKa8DOmnKryqDWfeHiJDKzIRxWUsitOPLm7O/AzbHWopo5V/hDyVmpn5p4l0XXROS8D7PPetqIIZvBFMVtIbsDbn4JVi5/lM4/fUYbLRk8yIeUdkcyMHBdDZnQb0qT94X8Z2moSIow+7p9zetP/s3wfFK/Ofu24Bh2IBloX0wM/cWXAPAZ3hK0QuvX0pyijs6eyflT1QZCBRKodnv8qc/J+NGWBTi9tH3 X-Microsoft-Exchange-Diagnostics: 1; AM4P191MB0002; 6:6xgeton4CpoKxXu3cCLo19EqQVqy0memt4boAUzpYjkk1KiOHHfbMXJol7bkc0CwUGVIcHM14NojHReQIiBaezyOXLZ7E9dgIxJ41Hd8+tewosXRDuzDUmURrXg1+x42hpPApaf2vKC7Gx1nZ0HpzvpjHbIAuHDSjW6zmjEN9oqqX7qOunt9d670k5g9HZgLkZKyBN+wNQp/rHEJUrPjhoDy1gyxE+006SncCsQhgc0ioN4lt85v5nD35lySFkx2CtcQP6dWxVa5jLl66BmG3pRkYOUP/TES7ixDSgf7iTYFLELzdexiXePymRktQ05W+fkb+F7kLI4H1rQrLvQ15Q==; 5:WxN78k7T+SqodtmTqHLyfsCYUGh6ABMYyCMfQfLG3FyLO5O38n2ZD97soJF/jE8/iOinSpXqlB6w9Rt+zAOdPcS8KQIOj9XfP+dbsFikLBzXDfWABAY3tUU1b2LSqYHZODKsrmKpN2tnWQeyTHAMQg==; 24:IprMgjL33hidpPFmICHk/T0EIl/dSNu8eml8GfZOXjdWMkQP33XKS58eObKbDxRSMJ9eYhWYkJcowxAj++s0NJmkoDazSVXq3YG61tyT/2c=; 7:7jx2Pe/Z/Jj7K2o0w+u5HorPVT0LQpyb01ww1SZEwXoLjWDVnqy9qh2wCVxeHKfMKlX94MOafkFjXbBeaGxtEqiIkstVYMX7Ysh1gOZlxFkaaspBhJd1JLmEgoGMbxtLHBbJe9B3oZkTTGnITZKQTOPN3WSEdL72iM5nP7s+0kaRuPdQ+Jswth1gjjxIPhXAnkl9RerazcXJQ6vnObv5V5hoEP23etAfUpj0QGRdlas= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: sondrel.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 02 Oct 2017 09:52:05.0838 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4faa3872-698e-4896-80ec-148b916cb1ba X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM4P191MB0002 Sender: linux-pwm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pwm@vger.kernel.org The power may be disabled during suspend, so implement suspend and resume callbacks to save and restore register state. Signed-off-by: Ed Blake --- drivers/pwm/pwm-img.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/drivers/pwm/pwm-img.c b/drivers/pwm/pwm-img.c index 2fb30de..a6d7915 100644 --- a/drivers/pwm/pwm-img.c +++ b/drivers/pwm/pwm-img.c @@ -52,6 +52,8 @@ */ #define MIN_TMBASE_STEPS 16 +#define IMG_PWM_NPWM 4 + struct img_pwm_soc_data { u32 max_timebase; }; @@ -66,6 +68,8 @@ struct img_pwm_chip { int max_period_ns; int min_period_ns; const struct img_pwm_soc_data *data; + u32 suspend_ctrl_cfg; + u32 suspend_ch_cfg[IMG_PWM_NPWM]; }; static inline struct img_pwm_chip *to_img_pwm_chip(struct pwm_chip *chip) @@ -255,7 +259,7 @@ static int img_pwm_probe(struct platform_device *pdev) pwm->chip.dev = &pdev->dev; pwm->chip.ops = &img_pwm_ops; pwm->chip.base = -1; - pwm->chip.npwm = 4; + pwm->chip.npwm = IMG_PWM_NPWM; ret = pwmchip_add(&pwm->chip); if (ret < 0) { @@ -291,9 +295,69 @@ static int img_pwm_remove(struct platform_device *pdev) return pwmchip_remove(&pwm_chip->chip); } +#ifdef CONFIG_PM +static int img_pwm_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct img_pwm_chip *pwm_chip = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < pwm_chip->chip.npwm; i++) + pwm_chip->suspend_ch_cfg[i] = img_pwm_readl(pwm_chip, + PWM_CH_CFG(i)); + + pwm_chip->suspend_ctrl_cfg = img_pwm_readl(pwm_chip, PWM_CTRL_CFG); + + clk_disable_unprepare(pwm_chip->pwm_clk); + clk_disable_unprepare(pwm_chip->sys_clk); + + return 0; +} + +static int img_pwm_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct img_pwm_chip *pwm_chip = platform_get_drvdata(pdev); + int ret; + int i; + + ret = clk_prepare_enable(pwm_chip->sys_clk); + if (ret < 0) { + dev_err(&pdev->dev, "could not prepare or enable sys clock\n"); + return ret; + } + + ret = clk_prepare_enable(pwm_chip->pwm_clk); + if (ret < 0) { + dev_err(&pdev->dev, "could not prepare or enable pwm clock\n"); + clk_disable_unprepare(pwm_chip->sys_clk); + return ret; + } + + for (i = 0; i < pwm_chip->chip.npwm; i++) + img_pwm_writel(pwm_chip, PWM_CH_CFG(i), + pwm_chip->suspend_ch_cfg[i]); + + img_pwm_writel(pwm_chip, PWM_CTRL_CFG, pwm_chip->suspend_ctrl_cfg); + + for (i = 0; i < pwm_chip->chip.npwm; i++) + if (pwm_chip->suspend_ctrl_cfg & BIT(i)) + regmap_update_bits(pwm_chip->periph_regs, + PERIP_PWM_PDM_CONTROL, + PERIP_PWM_PDM_CONTROL_CH_MASK << + PERIP_PWM_PDM_CONTROL_CH_SHIFT(i), + 0); + + return 0; +} +#endif /* CONFIG_PM */ + +SIMPLE_DEV_PM_OPS(img_pwm_pm_ops, img_pwm_suspend, img_pwm_resume); + static struct platform_driver img_pwm_driver = { .driver = { .name = "img-pwm", + .pm = &img_pwm_pm_ops, .of_match_table = img_pwm_of_match, }, .probe = img_pwm_probe, From patchwork Mon Oct 2 09:51:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ed Blake X-Patchwork-Id: 820405 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pwm-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=sondrel.onmicrosoft.com header.i=@sondrel.onmicrosoft.com header.b="fbQlzVCm"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3y5HWj6r8Hz9t4X for ; Mon, 2 Oct 2017 20:52:17 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750983AbdJBJwN (ORCPT ); Mon, 2 Oct 2017 05:52:13 -0400 Received: from mail-db5eur01on0043.outbound.protection.outlook.com ([104.47.2.43]:46624 "EHLO EUR01-DB5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751104AbdJBJwJ (ORCPT ); Mon, 2 Oct 2017 05:52:09 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sondrel.onmicrosoft.com; s=selector1-sondrel-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=uwUP6G6gDZeLpcxhVn4PdeDHe+Wpg22wZh6epAQI/5E=; b=fbQlzVCmcNgZf3x9Bh0EC5PD4F+fE63vUnAso+mqhcZiyNIOLYeCE6GxyNIyoYzGb3yWu7YW378pYOx++kUCetiMv/nDt4NV1Q7IoWsPfaW30hq6LKqIIO/SSq/HIwLPUyDMzHZfpKmriILw+/m+ThXQhA01iP0FAfEs3H67Zfc= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=ed.blake@sondrel.com; Received: from iw-build-2.sondrel.com (195.88.9.101) by AM4P191MB0002.EURP191.PROD.OUTLOOK.COM (2603:10a6:200:64::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.77.7; Mon, 2 Oct 2017 09:52:06 +0000 From: Ed Blake To: thierry.reding@gmail.com Cc: linux-pwm@vger.kernel.org, Ed Blake Subject: [PATCH 2/2] pwm: img: Add runtime PM Date: Mon, 2 Oct 2017 10:51:48 +0100 Message-Id: <1506937908-360-3-git-send-email-ed.blake@sondrel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1506937908-360-1-git-send-email-ed.blake@sondrel.com> References: <1506937908-360-1-git-send-email-ed.blake@sondrel.com> MIME-Version: 1.0 X-Originating-IP: [195.88.9.101] X-ClientProxiedBy: DB6PR06CA0011.eurprd06.prod.outlook.com (2603:10a6:6:1::24) To AM4P191MB0002.EURP191.PROD.OUTLOOK.COM (2603:10a6:200:64::10) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 3668059c-fe8f-4fa9-e609-08d5097b3dbd X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(2017030254152)(2017052603199)(201703131423075)(201703031133081)(201702281549075); SRVR:AM4P191MB0002; X-Microsoft-Exchange-Diagnostics: 1; AM4P191MB0002; 3:BTF72KSdwhDzE49OPW2WKZEQKqPYV5yWpai76F0uAeaDVJ5PLz4ssiZmZJ9rs6ZztPy7xO8TvKepjSyDksIiEvRPn3rcH9Q38wDEi3OUkKaiPUXJT84V/9NVu3linIs0xfbuzjs8/NNb1Fw9qWlTaDc3iAEm0vIHuiP+Es2ZSm7sCBt3PwZg+H6MtgB1eXgPXzAUQSEfGFPKhG5ihpmdEr2I1UCYLCilp08eBDB8Axq0zvv2JHi9zXqp/UpJOCjx; 25:W9kyqMIqQjRsYeBVFFc4ZlqL4Vn28K8vTeS/5sAF8k4B9D1x35zS0E9EhQongU3W9BAeelotFfCEtfqarXfCoiMVpj2dWDNBTbLl6j38PB90dbX+9N9Lb1biUUwLNvUgUjhLZh0HxrgU0CBhJACNMyKLu2DQdbnuJZLV+Y9PWVjk8xfw2gHed+1DViqvTvan5jL633kYyWauyI+seIentU8SgcLyqCBlzaZSwwSw5t64jYWi0PPcCAu8QmkQq/xf69U+VE1S+IzmL7Z0kz8paWkadFwhqZ1ZqqR4dZ7EymwkeRsxW0A6LmMgWIg2NhXuc6t54pT67imgHmjen/WzHQ==; 31:ha4WOonbmbzzQCI3d2qnP1qZkMjRAW1oPIPuYWXMav53MZaBavDs4p/Da9AYP/YzoXFwmQozEkMd94QpoGF92jRwviZiVUTAPMCORFA68XZf/2T442z1oLN3gyiZ5jIgyXgLNUG2d2ZKnXdY/MAM/jmfY1aL4gE4ywVseyJ4TNGgeoCU0JhzP/8wr2W2B5FnsoqD2lxI/5qsuDOjZSnL5lqaxlPqgKAmWtqvS030v/g= X-MS-TrafficTypeDiagnostic: AM4P191MB0002: X-Microsoft-Exchange-Diagnostics: 1; AM4P191MB0002; 20:ANfFponOnRwjq6em37vi7OI1SmNZNAb9Kquj1pcA4LN+k8Eq1I6b1x5/O0hO9aWhophDdMAJMI7YV1/ZLEW5xScjw9X8qQNQeFFEpEmNuEwbPw8EqKBdlI97hIZVC44bmHmy9D3a06ZoQ4gCRZi8Ga81+HdyYW8cGiKM73B4WvVIoOnXHBhitzcS4NcJJWpAJNNvwd6AQu9Geu7SMldBPg0FOX3p9HxeDSae2kCtPCSP00VVSdVAbvWmqOa/Euid; 4:G49bGtdZBDXjHXWnKBvCXlLNipUy/52VboxyeJ85xLU0zgC72iM4Eso75RNzA6D7oCN4e0lvEQMrfpd+GbVLRv57RXiIKcVKQrSCqN+GN0/1YkJ4R0m8PoyOBQ03pzR7f4HOD28IEA9tkuUi1gfcH+vtlwD4P+gYFjqimOY/cFcuvOZM73Qva1eykIu5FzG67Sa7WjBX7mfQs3avRAbXfq04nPjyxuVxnKET5oxDBUk9rijt4RrC6UvqnjK06Ezi X-Exchange-Antispam-Report-Test: UriScan:; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(5005006)(8121501046)(10201501046)(100000703101)(100105400095)(3002001)(93006095)(93001095)(6041248)(20161123560025)(20161123564025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123558100)(20161123562025)(20161123555025)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095); SRVR:AM4P191MB0002; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:AM4P191MB0002; X-Forefront-PRVS: 0448A97BF2 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(6009001)(346002)(376002)(39830400002)(23433003)(199003)(189002)(53416004)(5003940100001)(66066001)(50466002)(53936002)(4326008)(2906002)(81156014)(7736002)(8676002)(6666003)(81166006)(5660300001)(305945005)(47776003)(6486002)(69596002)(86362001)(478600001)(189998001)(8936002)(36756003)(25786009)(16526017)(2361001)(16586007)(316002)(50986999)(50226002)(97736004)(48376002)(101416001)(33646002)(3846002)(76176999)(39060400002)(6116002)(68736007)(107886003)(2950100002)(6916009)(105586002)(106356001)(2351001); DIR:OUT; SFP:1101; SCL:1; SRVR:AM4P191MB0002; H:iw-build-2.sondrel.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: sondrel.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: 1; AM4P191MB0002; 23:cIOjJ7oHVRFYjqd6mgnqb9VbAvv7APTFS6+HyhXQnJ99GoWJTlivDrEcHXOM76nQEdet4evks4MDVE0Crjg/L2ptILQ0yIzkYL+fm0RZDGFS60pLZepAY9s1SpLUwk+mR/xTy4a9oG2tlHnnNlHL84uOu7rdcdhrLDkAmKaEa6byvzDl4p//r5DbReVrHftbILyl7evKMuqUnY32NBS2Rv4J5ikNgdiEnHqDhoHnC27rciEybggpd/JyFVqASmLIDQUAzvB2KteEdJlBPNiZQl8E+dD8xzg8qU9IZA8rCMRfCVzv4y46liQ65TJ3iNbgUYyEFC+MwlLZBtGdD4Dq083QxcposaBw8tw9yYjB0fcXagwSXszaj/TeOXl7qaycnatL6qQEdOIwlJeeI2cxDs7aO60zb2sEwz3DNoUMCE8W5yqhikI8YC5sx2BGqMPH0Cg1630z9EjvleaG8ng7Cz4I8LotPTW8EwH/hFoNIBe+NZWCSLkLV6qVgtowuXX6yaN+W4ci5+JSN7KronJYMmnjGczYCx92EBN4bTOg5xN6bNPwE3cjhdpDfZ872JUcGxghoE1f97v+KPBPrkzpcYubIncEyss8HgoFjlZ7ix+5bfF04H9tv5WQX7e+ckteDzBCTDFcS5tNwIeyVImn7zVZrusF0qFFpMlDFYKx8lk3TiwmVmsWhPB6ylODRNtU6TaILZQ11plu1CpVeUUgiNjqaYMnqobjUXX80nLwfgKj+YByGkiNdyEAQ2prZhUEMGC0THD+KKBMZC5Ttyg/Yz5TBi/aopCXUaoTsI6ppKowVx1tfLeFB46YJozZhLoNR99hwwQx4XOnsISF7l5HrOUvk0ZWo6N7dE//HxvXJeRkTr9DqlsEMrlTKB5J/abpQHurqdAVC+gnj8nY+E2VPa0o9+VwimKoDpTn8TIjIJRl3yFjoBJOr8gNm31TkIsRZ0QplAUKVCcZtn5PgKDEb4+o7hZTxdSp6G7uh7W1CVzA2h1vtihOhNMeMq1C1y8d+Q8b9TsJblkR7yADrggQyoYzBZS6X5K9BAK7MGHdFPBuoqXsha9ylNfJTq2BooH96nTjWI4RlLVwaJYu/mGNhHeCVEp56VEbx4hBTcLG/bIrMbVB1fvdeqjBO4ao6PTnDGaGZbl6G1aSahJkCApO4rC/k6aJR0VKxTDtgrg5YORhn+LA3TfLT9z2Sa0rxbvf X-Microsoft-Exchange-Diagnostics: 1; AM4P191MB0002; 6:AR32izRkD3ZAnxMWocZ4DImXWkJRJp1v9chHpthQZ+fBB/7uR+kNnTEUKcGICof+GNwbjSjytaqN4aZ6swbDHJ7N6v4seh2N8pn87ymnNM0/kJ+HrcqqmGgtbHaf0Fdckqjooj6U6ywNafAs/3Io6Ml/GbvrLu9szNQqa86CxC8dcUFiFMdRbLoNlnJ7i9txwbLr+BzTf+T1fGbWZQ5dQ29w2OASrnytAfSyYEmHYEC7f9sRpGExYuOdZuGG5ZTvYR4BsNInDfFOy5rBTh8sQucIFLeoexca0ZaiDQIXaoArhNqQjqexm623b6AE+kKQD2axib8QctjWumqSSeaWiw==; 5:jRij/mje3djM5+LZDF1yW8y7GxnFmzxIYeHKsKWvgLutGEvvfMdJPqVNnKb+0U6M6ACFgtoRfmOK8YuHAYVggvvUes++gHLMGmhJN4Nm/jKuzprcAWTUh0XlM7+ZlpKvX5GGxCdagOVFi1WYgoKgag==; 24:z8seKUEilVeAQSLk+csvBx9vt8vqyw9Hd6Pgj1EIic351ZmoJ3BtA7Wivalnire5Vt+c/9hIQbRaCJCU4Zm7J4Y+zOrXLFb1qy0HGq60XQ8=; 7:nawoC42eUSSsdqdc87Wz12/+oMQAhRRY197W5TcH6LSP/WKBhOzYCLLZgkzUGw9eVnHAh04TmK25rs4/86Td2opDobr9oXNvkMqFyue3TUNnIC3Z5O8CawoiJbcM1EHmsYErtyJYCxPsXERfO57W+sDzkm842xUbs+cBUkSUpAuR01jm2PuoHaO3cNuNUL0XPjRfmudcQMPjL0OTyxoaCeU3u68u5F5FDgwwESYvIUA= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: sondrel.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 02 Oct 2017 09:52:06.2400 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4faa3872-698e-4896-80ec-148b916cb1ba X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM4P191MB0002 Sender: linux-pwm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pwm@vger.kernel.org Add runtime PM to disable the clocks when the h/w is not in use. Signed-off-by: Ed Blake --- drivers/pwm/pwm-img.c | 132 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 95 insertions(+), 37 deletions(-) diff --git a/drivers/pwm/pwm-img.c b/drivers/pwm/pwm-img.c index a6d7915..a9dce2f 100644 --- a/drivers/pwm/pwm-img.c +++ b/drivers/pwm/pwm-img.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -39,6 +40,8 @@ #define PERIP_PWM_PDM_CONTROL_CH_MASK 0x1 #define PERIP_PWM_PDM_CONTROL_CH_SHIFT(ch) ((ch) * 4) +#define IMG_PWM_PM_TIMEOUT 1000 /* ms */ + /* * PWM period is specified with a timebase register, * in number of step periods. The PWM duty cycle is also @@ -96,6 +99,7 @@ static int img_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, unsigned long mul, output_clk_hz, input_clk_hz; struct img_pwm_chip *pwm_chip = to_img_pwm_chip(chip); unsigned int max_timebase = pwm_chip->data->max_timebase; + int ret; if (period_ns < pwm_chip->min_period_ns || period_ns > pwm_chip->max_period_ns) { @@ -127,6 +131,10 @@ static int img_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, duty = DIV_ROUND_UP(timebase * duty_ns, period_ns); + ret = pm_runtime_get_sync(chip->dev); + if (ret < 0) + return ret; + val = img_pwm_readl(pwm_chip, PWM_CTRL_CFG); val &= ~(PWM_CTRL_CFG_DIV_MASK << PWM_CTRL_CFG_DIV_SHIFT(pwm->hwpwm)); val |= (div & PWM_CTRL_CFG_DIV_MASK) << @@ -137,6 +145,9 @@ static int img_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, (timebase << PWM_CH_CFG_TMBASE_SHIFT); img_pwm_writel(pwm_chip, PWM_CH_CFG(pwm->hwpwm), val); + pm_runtime_mark_last_busy(chip->dev); + pm_runtime_put_autosuspend(chip->dev); + return 0; } @@ -144,6 +155,11 @@ static int img_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) { u32 val; struct img_pwm_chip *pwm_chip = to_img_pwm_chip(chip); + int ret; + + ret = pm_runtime_get_sync(chip->dev); + if (ret < 0) + return ret; val = img_pwm_readl(pwm_chip, PWM_CTRL_CFG); val |= BIT(pwm->hwpwm); @@ -164,6 +180,9 @@ static void img_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) val = img_pwm_readl(pwm_chip, PWM_CTRL_CFG); val &= ~BIT(pwm->hwpwm); img_pwm_writel(pwm_chip, PWM_CTRL_CFG, val); + + pm_runtime_mark_last_busy(chip->dev); + pm_runtime_put_autosuspend(chip->dev); } static const struct pwm_ops img_pwm_ops = { @@ -186,6 +205,37 @@ static void img_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) }; MODULE_DEVICE_TABLE(of, img_pwm_of_match); +static int img_pwm_runtime_suspend(struct device *dev) +{ + struct img_pwm_chip *pwm_chip = dev_get_drvdata(dev); + + clk_disable_unprepare(pwm_chip->pwm_clk); + clk_disable_unprepare(pwm_chip->sys_clk); + + return 0; +} + +static int img_pwm_runtime_resume(struct device *dev) +{ + struct img_pwm_chip *pwm_chip = dev_get_drvdata(dev); + int ret; + + ret = clk_prepare_enable(pwm_chip->sys_clk); + if (ret < 0) { + dev_err(dev, "could not prepare or enable sys clock\n"); + return ret; + } + + ret = clk_prepare_enable(pwm_chip->pwm_clk); + if (ret < 0) { + dev_err(dev, "could not prepare or enable pwm clock\n"); + clk_disable_unprepare(pwm_chip->sys_clk); + return ret; + } + + return 0; +} + static int img_pwm_probe(struct platform_device *pdev) { int ret; @@ -228,23 +278,20 @@ static int img_pwm_probe(struct platform_device *pdev) return PTR_ERR(pwm->pwm_clk); } - ret = clk_prepare_enable(pwm->sys_clk); - if (ret < 0) { - dev_err(&pdev->dev, "could not prepare or enable sys clock\n"); - return ret; - } - - ret = clk_prepare_enable(pwm->pwm_clk); - if (ret < 0) { - dev_err(&pdev->dev, "could not prepare or enable pwm clock\n"); - goto disable_sysclk; + pm_runtime_set_autosuspend_delay(&pdev->dev, IMG_PWM_PM_TIMEOUT); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_enable(&pdev->dev); + if (!pm_runtime_enabled(&pdev->dev)) { + ret = img_pwm_runtime_resume(&pdev->dev); + if (ret) + goto err_pm_disable; } clk_rate = clk_get_rate(pwm->pwm_clk); if (!clk_rate) { dev_err(&pdev->dev, "pwm clock has no frequency\n"); ret = -EINVAL; - goto disable_pwmclk; + goto err_suspend; } /* The maximum input clock divider is 512 */ @@ -264,16 +311,18 @@ static int img_pwm_probe(struct platform_device *pdev) ret = pwmchip_add(&pwm->chip); if (ret < 0) { dev_err(&pdev->dev, "pwmchip_add failed: %d\n", ret); - goto disable_pwmclk; + goto err_suspend; } platform_set_drvdata(pdev, pwm); return 0; -disable_pwmclk: - clk_disable_unprepare(pwm->pwm_clk); -disable_sysclk: - clk_disable_unprepare(pwm->sys_clk); +err_suspend: + if (!pm_runtime_enabled(&pdev->dev)) + img_pwm_runtime_suspend(&pdev->dev); +err_pm_disable: + pm_runtime_disable(&pdev->dev); + pm_runtime_dont_use_autosuspend(&pdev->dev); return ret; } @@ -282,6 +331,11 @@ static int img_pwm_remove(struct platform_device *pdev) struct img_pwm_chip *pwm_chip = platform_get_drvdata(pdev); u32 val; unsigned int i; + int ret; + + ret = pm_runtime_get_sync(&pdev->dev); + if (ret < 0) + return ret; for (i = 0; i < pwm_chip->chip.npwm; i++) { val = img_pwm_readl(pwm_chip, PWM_CTRL_CFG); @@ -289,8 +343,10 @@ static int img_pwm_remove(struct platform_device *pdev) img_pwm_writel(pwm_chip, PWM_CTRL_CFG, val); } - clk_disable_unprepare(pwm_chip->pwm_clk); - clk_disable_unprepare(pwm_chip->sys_clk); + pm_runtime_put(&pdev->dev); + pm_runtime_disable(&pdev->dev); + if (!pm_runtime_status_suspended(&pdev->dev)) + img_pwm_runtime_suspend(&pdev->dev); return pwmchip_remove(&pwm_chip->chip); } @@ -298,9 +354,14 @@ static int img_pwm_remove(struct platform_device *pdev) #ifdef CONFIG_PM static int img_pwm_suspend(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct img_pwm_chip *pwm_chip = platform_get_drvdata(pdev); - int i; + struct img_pwm_chip *pwm_chip = dev_get_drvdata(dev); + int i, ret; + + if (pm_runtime_status_suspended(dev)) { + ret = img_pwm_runtime_resume(dev); + if (ret) + return ret; + } for (i = 0; i < pwm_chip->chip.npwm; i++) pwm_chip->suspend_ch_cfg[i] = img_pwm_readl(pwm_chip, @@ -308,31 +369,20 @@ static int img_pwm_suspend(struct device *dev) pwm_chip->suspend_ctrl_cfg = img_pwm_readl(pwm_chip, PWM_CTRL_CFG); - clk_disable_unprepare(pwm_chip->pwm_clk); - clk_disable_unprepare(pwm_chip->sys_clk); + img_pwm_runtime_suspend(dev); return 0; } static int img_pwm_resume(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct img_pwm_chip *pwm_chip = platform_get_drvdata(pdev); + struct img_pwm_chip *pwm_chip = dev_get_drvdata(dev); int ret; int i; - ret = clk_prepare_enable(pwm_chip->sys_clk); - if (ret < 0) { - dev_err(&pdev->dev, "could not prepare or enable sys clock\n"); + ret = img_pwm_runtime_resume(dev); + if (ret) return ret; - } - - ret = clk_prepare_enable(pwm_chip->pwm_clk); - if (ret < 0) { - dev_err(&pdev->dev, "could not prepare or enable pwm clock\n"); - clk_disable_unprepare(pwm_chip->sys_clk); - return ret; - } for (i = 0; i < pwm_chip->chip.npwm; i++) img_pwm_writel(pwm_chip, PWM_CH_CFG(i), @@ -348,11 +398,19 @@ static int img_pwm_resume(struct device *dev) PERIP_PWM_PDM_CONTROL_CH_SHIFT(i), 0); + if (pm_runtime_status_suspended(dev)) + img_pwm_runtime_suspend(dev); + return 0; } #endif /* CONFIG_PM */ -SIMPLE_DEV_PM_OPS(img_pwm_pm_ops, img_pwm_suspend, img_pwm_resume); +static const struct dev_pm_ops img_pwm_pm_ops = { + SET_RUNTIME_PM_OPS(img_pwm_runtime_suspend, + img_pwm_runtime_resume, + NULL) + SET_SYSTEM_SLEEP_PM_OPS(img_pwm_suspend, img_pwm_resume) +}; static struct platform_driver img_pwm_driver = { .driver = {