From: Romain Izard <romain.izard.pro@gmail.com> To: Nicolas Ferre <nicolas.ferre@microchip.com>, Alexandre Belloni <alexandre.belloni@free-electrons.com>, Boris Brezillon <boris.brezillon@free-electrons.com>, Michael Turquette <mturquette@baylibre.com>, Stephen Boyd <sboyd@codeaurora.org>, Ludovic Desroches <ludovic.desroches@microchip.com>, Wenyou Yang <wenyou.yang@atmel.com>, Josh Wu <rainyfeeling@outlook.com>, David Woodhouse <dwmw2@infradead.org>, Brian Norris <computersforpeace@gmail.com>, Marek Vasut <marek.vasut@gmail.com>, Cyrille Pitchen <cyrille.pitchen@wedev4u.fr>, Thierry Reding <thierry.reding@gmail.com>, Richard Genoud <richard.genoud@gmail.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Alan Stern <stern@rowland.harvard.edu> Cc: linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org, linux-pwm@vger.kernel.org, linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Romain Izard <romain.izard.pro@gmail.com> Subject: [PATCH v2 7/9] pwm: atmel-tcb: Support backup mode Date: Fri, 15 Sep 2017 16:04:09 +0200 [thread overview] Message-ID: <20170915140411.31716-8-romain.izard.pro@gmail.com> (raw) In-Reply-To: <20170915140411.31716-1-romain.izard.pro@gmail.com> Save and restore registers for the PWM on suspend and resume, which makes hibernation and backup modes possible. Signed-off-by: Romain Izard <romain.izard.pro@gmail.com> --- 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, -- 2.11.0
WARNING: multiple messages have this Message-ID (diff)
From: romain.izard.pro@gmail.com (Romain Izard) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH v2 7/9] pwm: atmel-tcb: Support backup mode Date: Fri, 15 Sep 2017 16:04:09 +0200 [thread overview] Message-ID: <20170915140411.31716-8-romain.izard.pro@gmail.com> (raw) In-Reply-To: <20170915140411.31716-1-romain.izard.pro@gmail.com> Save and restore registers for the PWM on suspend and resume, which makes hibernation and backup modes possible. Signed-off-by: Romain Izard <romain.izard.pro@gmail.com> --- 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, -- 2.11.0
next prev parent reply other threads:[~2017-09-15 14:05 UTC|newest] Thread overview: 64+ messages / expand[flat|nested] mbox.gz Atom feed top 2017-09-15 14:04 [PATCH v2 0/9] Various patches for SAMA5D2 backup mode Romain Izard 2017-09-15 14:04 ` Romain Izard 2017-09-15 14:04 ` [PATCH v2 1/9] clk: at91: pmc: Wait for clocks when resuming Romain Izard 2017-09-15 14:04 ` Romain Izard 2017-09-22 12:05 ` Ludovic Desroches 2017-09-22 12:05 ` Ludovic Desroches 2017-09-22 12:05 ` Ludovic Desroches 2017-09-22 12:13 ` Nicolas Ferre 2017-09-22 12:13 ` Nicolas Ferre 2017-09-22 12:13 ` Nicolas Ferre 2017-09-15 14:04 ` [PATCH v2 2/9] clk: at91: pmc: Save SCSR during suspend Romain Izard 2017-09-15 14:04 ` Romain Izard 2017-09-15 14:04 ` [PATCH v2 3/9] clk: at91: pmc: Support backup for programmable clocks Romain Izard 2017-09-15 14:04 ` Romain Izard 2017-09-22 10:31 ` Nicolas Ferre 2017-09-22 10:31 ` Nicolas Ferre 2017-09-22 10:31 ` Nicolas Ferre 2017-09-25 8:25 ` Romain Izard 2017-09-25 8:25 ` Romain Izard 2017-09-25 8:25 ` Romain Izard 2017-09-15 14:04 ` [PATCH v2 4/9] mtd: nand: atmel: Avoid ECC errors when leaving backup mode Romain Izard 2017-09-15 14:04 ` Romain Izard 2017-09-18 9:50 ` Boris Brezillon 2017-09-18 9:50 ` Boris Brezillon 2017-09-18 9:50 ` Boris Brezillon 2017-09-15 14:04 ` [PATCH v2 5/9] mtd: nand: atmel: Report PMECC failures as errors Romain Izard 2017-09-15 14:04 ` Romain Izard 2017-09-18 10:00 ` Boris Brezillon 2017-09-18 10:00 ` Boris Brezillon 2017-09-18 10:00 ` Boris Brezillon 2017-09-21 9:22 ` Romain Izard 2017-09-21 9:22 ` Romain Izard 2017-09-21 9:22 ` Romain Izard 2017-09-15 14:04 ` [PATCH v2 6/9] ehci-atmel: Power down during suspend is normal Romain Izard 2017-09-15 14:04 ` Romain Izard 2017-09-22 12:40 ` Nicolas Ferre 2017-09-22 12:40 ` Nicolas Ferre 2017-09-22 12:40 ` Nicolas Ferre 2017-09-15 14:04 ` Romain Izard [this message] 2017-09-15 14:04 ` [PATCH v2 7/9] pwm: atmel-tcb: Support backup mode Romain Izard 2017-09-22 12:42 ` Nicolas Ferre 2017-09-22 12:42 ` Nicolas Ferre 2017-09-22 12:42 ` Nicolas Ferre 2017-09-15 14:04 ` [PATCH v2 8/9] atmel_flexcom: " Romain Izard 2017-09-15 14:04 ` Romain Izard 2017-09-19 9:29 ` Nicolas Ferre 2017-09-19 9:29 ` Nicolas Ferre 2017-09-19 9:29 ` Nicolas Ferre 2017-09-19 15:25 ` Lee Jones 2017-09-19 15:25 ` Lee Jones 2017-09-19 15:25 ` Lee Jones 2017-09-20 8:30 ` Romain Izard 2017-09-20 8:30 ` Romain Izard 2017-09-20 8:30 ` Romain Izard 2017-09-20 9:18 ` Alexandre Belloni 2017-09-20 9:18 ` Alexandre Belloni 2017-09-20 9:18 ` Alexandre Belloni 2017-09-15 14:04 ` [PATCH v2 9/9] tty/serial: atmel: Prevent a warning on suspend Romain Izard 2017-09-15 14:04 ` Romain Izard 2017-09-19 10:19 ` Nicolas Ferre 2017-09-19 10:19 ` Nicolas Ferre 2017-09-19 10:19 ` Nicolas Ferre 2017-09-20 14:35 ` Richard Genoud 2017-09-20 14:35 ` Richard Genoud
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20170915140411.31716-8-romain.izard.pro@gmail.com \ --to=romain.izard.pro@gmail.com \ --cc=alexandre.belloni@free-electrons.com \ --cc=boris.brezillon@free-electrons.com \ --cc=computersforpeace@gmail.com \ --cc=cyrille.pitchen@wedev4u.fr \ --cc=dwmw2@infradead.org \ --cc=gregkh@linuxfoundation.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-clk@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-mtd@lists.infradead.org \ --cc=linux-pwm@vger.kernel.org \ --cc=linux-serial@vger.kernel.org \ --cc=linux-usb@vger.kernel.org \ --cc=ludovic.desroches@microchip.com \ --cc=marek.vasut@gmail.com \ --cc=mturquette@baylibre.com \ --cc=nicolas.ferre@microchip.com \ --cc=rainyfeeling@outlook.com \ --cc=richard.genoud@gmail.com \ --cc=sboyd@codeaurora.org \ --cc=stern@rowland.harvard.edu \ --cc=thierry.reding@gmail.com \ --cc=wenyou.yang@atmel.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.