From patchwork Thu Oct 19 16:44:10 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Romain Izard X-Patchwork-Id: 10017725 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 044EB60224 for ; Thu, 19 Oct 2017 16:45:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EA34F28DA3 for ; Thu, 19 Oct 2017 16:45:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DEF6128DAD; Thu, 19 Oct 2017 16:45:37 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, DKIM_VALID, FREEMAIL_FROM, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 5CB2128DA3 for ; Thu, 19 Oct 2017 16:45:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Owner; bh=TpLpgEIyICY6Km8uMuCF6eLzqq8Lg0mMWll+fhqGCOI=; b=mPz MYwBqPWSRxqRb9WdLtv/7cxd85lCl5rpS7C4buJNp5oY5q2FdntKiuweWXnXSfRc8/pWCW2CtmJ/P g0hqPe5gkvFVhxkpVb3kmdJqT5tBB69cMiwVfetIETZWpg5s5d0cj91yKbiUg1Sz7vpa4UwVD6W9T YSZnngpajgEKu3mtyZYxB+5PEYAe8c7X6C7+aKvCYkWTHATyw72beW4sy5o3ElTx8RhPOrs+gcduu Y4Sjap7Fe+NnVioz5873CRZIa0m7Ujt1+E5TJkYgUgRyOxOlWioD2ADyQDudpuiE7m+RVfES94aqF B1bMsy0uya8hc97lnTsGQfKYygf982A==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1e5DwZ-0000aw-OM; Thu, 19 Oct 2017 16:45:15 +0000 Received: from mail-wm0-x241.google.com ([2a00:1450:400c:c09::241]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1e5DwD-0007zk-Bx for linux-arm-kernel@lists.infradead.org; Thu, 19 Oct 2017 16:45:11 +0000 Received: by mail-wm0-x241.google.com with SMTP id i124so17078394wmf.3 for ; Thu, 19 Oct 2017 09:44:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=IbU2TrM/015VFD9Z0rVrrDdNx3T412JrQZBLObSWjYI=; b=XBESX/NMvl3XjqZ7vFyEzAr1b1GHmxcVJ9lgZlmN8ODgU6OqA/EnVK89rvwnLOij6e cd/HgB+1/HatylTmRWOUO8uCnLCzv4oD7fdotVRlUOEIPPIzyh+ByeEcGbhpB6hDXHjX M+ulT/i4ORui86IprxpcQukPUJv/G5EH3kFvQvLm0eH5oPqGLtuRGdjwyOxv4iWJe7l2 580VSieiY734nmew4LzzvUEMcqhDwiJq3R/JiUSKj8M14bYQccNpHOdvyMKYShQkvCG4 mCjvZ2rjNNVL5waEwfUv/QWmNPJLAlJ6yNwyFitKeQeSQ5m1CGuu4IzUxfhJK81Uo9FQ gXKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=IbU2TrM/015VFD9Z0rVrrDdNx3T412JrQZBLObSWjYI=; b=Y6vf/rxzsFXXpTpK2/N7BDuvPktMSwIHMoekLsTXEDVHu98lu+hm22zKe4L/wHF8JX PRMugvs43M/J1jIKbuYdFkFWyiyxvO6OvNws4CcCPmqyNPboY+yw30cdrM+Us0+4GawK R74U3VY3fBeuBEo80BOGtATp1w6nGEvz8RXghC4CMz1Sn2jFvh5Ga4RWV3ENQxL5KTMl jkpSAkLC5I1gG32fwEJdBbP25P90e1IJ1j8h5UrIy7tMFV+oEkexhYdczdEZulOP+8qN 8AqESGtviXyjMpWVh6plZxazDYIjkKXAfQGYqP54oaoqDa1ooATlZWWI8OF4WTT1ReY7 ys0w== X-Gm-Message-State: AMCzsaUSMUK86yy/KrLFb7F0ncd5a+J7YXUB5jGOkGNFnHdB52K5h2q7 4SHkcJIgiQ3vDibaAgJxMq0= X-Google-Smtp-Source: ABhQp+S/Xre0tkhORhabn4ok9eZwsLw40xydFhAqYhbtX0p5y56yxsBlsionC1oov126HwjbGXBK0Q== X-Received: by 10.28.174.80 with SMTP id x77mr2347304wme.83.1508431471591; Thu, 19 Oct 2017 09:44:31 -0700 (PDT) Received: from localhost.localdomain (146.187.3.109.rev.sfr.net. [109.3.187.146]) by smtp.gmail.com with ESMTPSA id m28sm1549764wmi.20.2017.10.19.09.44.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 19 Oct 2017 09:44:31 -0700 (PDT) From: Romain Izard To: Thierry Reding , Alexandre Belloni , Nicolas Ferre Subject: [PATCH v5] pwm: atmel-tcb: Support backup mode Date: Thu, 19 Oct 2017 18:44:10 +0200 Message-Id: <20171019164410.423-1-romain.izard.pro@gmail.com> X-Mailer: git-send-email 2.11.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20171019_094453_791858_86EE85C4 X-CRM114-Status: GOOD ( 16.78 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-pwm@vger.kernel.org, Romain Izard , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Save and restore registers for the PWM on suspend and resume, which makes hibernation and backup modes possible. Signed-off-by: Romain Izard Acked-by: Nicolas Ferre --- Changes in v5: * extract from the patch series, and send as a standalone patch drivers/pwm/pwm-atmel-tcb.c | 63 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/drivers/pwm/pwm-atmel-tcb.c b/drivers/pwm/pwm-atmel-tcb.c index 75db585a2a94..acd3ce8ecf3f 100644 --- a/drivers/pwm/pwm-atmel-tcb.c +++ b/drivers/pwm/pwm-atmel-tcb.c @@ -37,11 +37,20 @@ struct atmel_tcb_pwm_device { unsigned period; /* PWM period expressed in clk cycles */ }; +struct atmel_tcb_channel { + u32 enabled; + u32 cmr; + u32 ra; + u32 rb; + u32 rc; +}; + struct atmel_tcb_pwm_chip { struct pwm_chip chip; spinlock_t lock; struct atmel_tc *tc; struct atmel_tcb_pwm_device *pwms[NPWM]; + struct atmel_tcb_channel bkup[NPWM / 2]; }; static inline struct atmel_tcb_pwm_chip *to_tcb_chip(struct pwm_chip *chip) @@ -175,12 +184,15 @@ static void atmel_tcb_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) * Use software trigger to apply the new setting. * If both PWM devices in this group are disabled we stop the clock. */ - if (!(cmr & (ATMEL_TC_ACPC | ATMEL_TC_BCPC))) + if (!(cmr & (ATMEL_TC_ACPC | ATMEL_TC_BCPC))) { __raw_writel(ATMEL_TC_SWTRG | ATMEL_TC_CLKDIS, regs + ATMEL_TC_REG(group, CCR)); - else + tcbpwmc->bkup[group].enabled = 1; + } else { __raw_writel(ATMEL_TC_SWTRG, regs + ATMEL_TC_REG(group, CCR)); + tcbpwmc->bkup[group].enabled = 0; + } spin_unlock(&tcbpwmc->lock); } @@ -263,6 +275,7 @@ static int atmel_tcb_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) /* Use software trigger to apply the new setting */ __raw_writel(ATMEL_TC_CLKEN | ATMEL_TC_SWTRG, regs + ATMEL_TC_REG(group, CCR)); + tcbpwmc->bkup[group].enabled = 1; spin_unlock(&tcbpwmc->lock); return 0; } @@ -445,10 +458,56 @@ static const struct of_device_id atmel_tcb_pwm_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, atmel_tcb_pwm_dt_ids); +#ifdef CONFIG_PM_SLEEP +static int atmel_tcb_pwm_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct atmel_tcb_pwm_chip *tcbpwm = platform_get_drvdata(pdev); + void __iomem *base = tcbpwm->tc->regs; + int i; + + for (i = 0; i < (NPWM / 2); i++) { + struct atmel_tcb_channel *chan = &tcbpwm->bkup[i]; + + chan->cmr = readl(base + ATMEL_TC_REG(i, CMR)); + chan->ra = readl(base + ATMEL_TC_REG(i, RA)); + chan->rb = readl(base + ATMEL_TC_REG(i, RB)); + chan->rc = readl(base + ATMEL_TC_REG(i, RC)); + } + return 0; +} + +static int atmel_tcb_pwm_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct atmel_tcb_pwm_chip *tcbpwm = platform_get_drvdata(pdev); + void __iomem *base = tcbpwm->tc->regs; + int i; + + for (i = 0; i < (NPWM / 2); i++) { + struct atmel_tcb_channel *chan = &tcbpwm->bkup[i]; + + writel(chan->cmr, base + ATMEL_TC_REG(i, CMR)); + writel(chan->ra, base + ATMEL_TC_REG(i, RA)); + writel(chan->rb, base + ATMEL_TC_REG(i, RB)); + writel(chan->rc, base + ATMEL_TC_REG(i, RC)); + if (chan->enabled) { + writel(ATMEL_TC_CLKEN | ATMEL_TC_SWTRG, + base + ATMEL_TC_REG(i, CCR)); + } + } + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(atmel_tcb_pwm_pm_ops, atmel_tcb_pwm_suspend, + atmel_tcb_pwm_resume); + static struct platform_driver atmel_tcb_pwm_driver = { .driver = { .name = "atmel-tcb-pwm", .of_match_table = atmel_tcb_pwm_dt_ids, + .pm = &atmel_tcb_pwm_pm_ops, }, .probe = atmel_tcb_pwm_probe, .remove = atmel_tcb_pwm_remove,