From: Vinod Koul <vinod.koul-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
To: Laxman Dewangan <ldewangan-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Cc: djbw-b10kYP2dOMg@public.gmane.org,
swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [PATCH] dma: tegra: implement suspend/resume callbacks
Date: Tue, 30 Apr 2013 16:00:46 +0530 [thread overview]
Message-ID: <20130430103046.GD1960@intel.com> (raw)
In-Reply-To: <1366797267-29567-1-git-send-email-ldewangan-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
On Wed, Apr 24, 2013 at 03:24:27PM +0530, Laxman Dewangan wrote:
> Implement suspend/resume callbacks to store APB DMA channel's
> register on suspend and restore APB DMA channel's register on
> resume.
>
> Signed-off-by: Laxman Dewangan <ldewangan-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> ---
> drivers/dma/tegra20-apb-dma.c | 65 +++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 65 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c
> index 5a0b66c..ce19340 100644
> --- a/drivers/dma/tegra20-apb-dma.c
> +++ b/drivers/dma/tegra20-apb-dma.c
> @@ -30,6 +30,7 @@
> #include <linux/of.h>
> #include <linux/of_device.h>
> #include <linux/platform_device.h>
> +#include <linux/pm.h>
> #include <linux/pm_runtime.h>
> #include <linux/slab.h>
> #include <linux/clk/tegra.h>
> @@ -199,6 +200,7 @@ struct tegra_dma_channel {
>
> /* Channel-slave specific configuration */
> struct dma_slave_config dma_sconfig;
> + struct tegra_dma_channel_regs channel_reg;
> };
>
> /* tegra_dma: Tegra DMA specific information */
> @@ -1440,11 +1442,74 @@ static int tegra_dma_runtime_resume(struct device *dev)
> return 0;
> }
>
> +#ifdef CONFIG_PM_SLEEP
> +static int tegra_dma_pm_suspend(struct device *dev)
> +{
> + struct tegra_dma *tdma = dev_get_drvdata(dev);
> + int i;
> + int ret;
> +
> + /* Enable clock before accessing register */
> + ret = tegra_dma_runtime_resume(dev);
> + if (ret < 0)
> + return ret;
You dont seem to handle suspend when DMA is active? Otherwise looks fine.
Stephen, you okay with this patch?
--
~Vinod
> +
> + tdma->reg_gen = tdma_read(tdma, TEGRA_APBDMA_GENERAL);
> + for (i = 0; i < tdma->chip_data->nr_channels; i++) {
> + struct tegra_dma_channel *tdc = &tdma->channels[i];
> + struct tegra_dma_channel_regs *ch_reg = &tdc->channel_reg;
> +
> + ch_reg->csr = tdc_read(tdc, TEGRA_APBDMA_CHAN_CSR);
> + ch_reg->ahb_ptr = tdc_read(tdc, TEGRA_APBDMA_CHAN_AHBPTR);
> + ch_reg->apb_ptr = tdc_read(tdc, TEGRA_APBDMA_CHAN_APBPTR);
> + ch_reg->ahb_seq = tdc_read(tdc, TEGRA_APBDMA_CHAN_AHBSEQ);
> + ch_reg->apb_seq = tdc_read(tdc, TEGRA_APBDMA_CHAN_APBSEQ);
> + }
> +
> + /* Disable clock */
> + tegra_dma_runtime_suspend(dev);
> + return 0;
> +}
> +
> +static int tegra_dma_pm_resume(struct device *dev)
> +{
> + struct tegra_dma *tdma = dev_get_drvdata(dev);
> + int i;
> + int ret;
> +
> + /* Enable clock before accessing register */
> + ret = tegra_dma_runtime_resume(dev);
> + if (ret < 0)
> + return ret;
> +
> + tdma_write(tdma, TEGRA_APBDMA_GENERAL, tdma->reg_gen);
> + tdma_write(tdma, TEGRA_APBDMA_CONTROL, 0);
> + tdma_write(tdma, TEGRA_APBDMA_IRQ_MASK_SET, 0xFFFFFFFFul);
> +
> + for (i = 0; i < tdma->chip_data->nr_channels; i++) {
> + struct tegra_dma_channel *tdc = &tdma->channels[i];
> + struct tegra_dma_channel_regs *ch_reg = &tdc->channel_reg;
> +
> + tdc_write(tdc, TEGRA_APBDMA_CHAN_APBSEQ, ch_reg->apb_seq);
> + tdc_write(tdc, TEGRA_APBDMA_CHAN_APBPTR, ch_reg->apb_ptr);
> + tdc_write(tdc, TEGRA_APBDMA_CHAN_AHBSEQ, ch_reg->ahb_seq);
> + tdc_write(tdc, TEGRA_APBDMA_CHAN_AHBPTR, ch_reg->ahb_ptr);
> + tdc_write(tdc, TEGRA_APBDMA_CHAN_CSR,
> + (ch_reg->csr & ~TEGRA_APBDMA_CSR_ENB));
> + }
> +
> + /* Disable clock */
> + tegra_dma_runtime_suspend(dev);
> + return 0;
> +}
> +#endif
> static const struct dev_pm_ops tegra_dma_dev_pm_ops = {
> #ifdef CONFIG_PM_RUNTIME
> .runtime_suspend = tegra_dma_runtime_suspend,
> .runtime_resume = tegra_dma_runtime_resume,
> #endif
> + SET_SYSTEM_SLEEP_PM_OPS(tegra_dma_pm_suspend, tegra_dma_pm_resume)
> };
>
> static struct platform_driver tegra_dmac_driver = {
> --
> 1.7.1.1
>
WARNING: multiple messages have this Message-ID (diff)
From: Vinod Koul <vinod.koul@intel.com>
To: Laxman Dewangan <ldewangan@nvidia.com>
Cc: djbw@fb.com, swarren@wwwdotorg.org, linux-tegra@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH] dma: tegra: implement suspend/resume callbacks
Date: Tue, 30 Apr 2013 16:00:46 +0530 [thread overview]
Message-ID: <20130430103046.GD1960@intel.com> (raw)
In-Reply-To: <1366797267-29567-1-git-send-email-ldewangan@nvidia.com>
On Wed, Apr 24, 2013 at 03:24:27PM +0530, Laxman Dewangan wrote:
> Implement suspend/resume callbacks to store APB DMA channel's
> register on suspend and restore APB DMA channel's register on
> resume.
>
> Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
> ---
> drivers/dma/tegra20-apb-dma.c | 65 +++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 65 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c
> index 5a0b66c..ce19340 100644
> --- a/drivers/dma/tegra20-apb-dma.c
> +++ b/drivers/dma/tegra20-apb-dma.c
> @@ -30,6 +30,7 @@
> #include <linux/of.h>
> #include <linux/of_device.h>
> #include <linux/platform_device.h>
> +#include <linux/pm.h>
> #include <linux/pm_runtime.h>
> #include <linux/slab.h>
> #include <linux/clk/tegra.h>
> @@ -199,6 +200,7 @@ struct tegra_dma_channel {
>
> /* Channel-slave specific configuration */
> struct dma_slave_config dma_sconfig;
> + struct tegra_dma_channel_regs channel_reg;
> };
>
> /* tegra_dma: Tegra DMA specific information */
> @@ -1440,11 +1442,74 @@ static int tegra_dma_runtime_resume(struct device *dev)
> return 0;
> }
>
> +#ifdef CONFIG_PM_SLEEP
> +static int tegra_dma_pm_suspend(struct device *dev)
> +{
> + struct tegra_dma *tdma = dev_get_drvdata(dev);
> + int i;
> + int ret;
> +
> + /* Enable clock before accessing register */
> + ret = tegra_dma_runtime_resume(dev);
> + if (ret < 0)
> + return ret;
You dont seem to handle suspend when DMA is active? Otherwise looks fine.
Stephen, you okay with this patch?
--
~Vinod
> +
> + tdma->reg_gen = tdma_read(tdma, TEGRA_APBDMA_GENERAL);
> + for (i = 0; i < tdma->chip_data->nr_channels; i++) {
> + struct tegra_dma_channel *tdc = &tdma->channels[i];
> + struct tegra_dma_channel_regs *ch_reg = &tdc->channel_reg;
> +
> + ch_reg->csr = tdc_read(tdc, TEGRA_APBDMA_CHAN_CSR);
> + ch_reg->ahb_ptr = tdc_read(tdc, TEGRA_APBDMA_CHAN_AHBPTR);
> + ch_reg->apb_ptr = tdc_read(tdc, TEGRA_APBDMA_CHAN_APBPTR);
> + ch_reg->ahb_seq = tdc_read(tdc, TEGRA_APBDMA_CHAN_AHBSEQ);
> + ch_reg->apb_seq = tdc_read(tdc, TEGRA_APBDMA_CHAN_APBSEQ);
> + }
> +
> + /* Disable clock */
> + tegra_dma_runtime_suspend(dev);
> + return 0;
> +}
> +
> +static int tegra_dma_pm_resume(struct device *dev)
> +{
> + struct tegra_dma *tdma = dev_get_drvdata(dev);
> + int i;
> + int ret;
> +
> + /* Enable clock before accessing register */
> + ret = tegra_dma_runtime_resume(dev);
> + if (ret < 0)
> + return ret;
> +
> + tdma_write(tdma, TEGRA_APBDMA_GENERAL, tdma->reg_gen);
> + tdma_write(tdma, TEGRA_APBDMA_CONTROL, 0);
> + tdma_write(tdma, TEGRA_APBDMA_IRQ_MASK_SET, 0xFFFFFFFFul);
> +
> + for (i = 0; i < tdma->chip_data->nr_channels; i++) {
> + struct tegra_dma_channel *tdc = &tdma->channels[i];
> + struct tegra_dma_channel_regs *ch_reg = &tdc->channel_reg;
> +
> + tdc_write(tdc, TEGRA_APBDMA_CHAN_APBSEQ, ch_reg->apb_seq);
> + tdc_write(tdc, TEGRA_APBDMA_CHAN_APBPTR, ch_reg->apb_ptr);
> + tdc_write(tdc, TEGRA_APBDMA_CHAN_AHBSEQ, ch_reg->ahb_seq);
> + tdc_write(tdc, TEGRA_APBDMA_CHAN_AHBPTR, ch_reg->ahb_ptr);
> + tdc_write(tdc, TEGRA_APBDMA_CHAN_CSR,
> + (ch_reg->csr & ~TEGRA_APBDMA_CSR_ENB));
> + }
> +
> + /* Disable clock */
> + tegra_dma_runtime_suspend(dev);
> + return 0;
> +}
> +#endif
> static const struct dev_pm_ops tegra_dma_dev_pm_ops = {
> #ifdef CONFIG_PM_RUNTIME
> .runtime_suspend = tegra_dma_runtime_suspend,
> .runtime_resume = tegra_dma_runtime_resume,
> #endif
> + SET_SYSTEM_SLEEP_PM_OPS(tegra_dma_pm_suspend, tegra_dma_pm_resume)
> };
>
> static struct platform_driver tegra_dmac_driver = {
> --
> 1.7.1.1
>
next prev parent reply other threads:[~2013-04-30 10:30 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-24 9:54 [PATCH] dma: tegra: implement suspend/resume callbacks Laxman Dewangan
2013-04-24 9:54 ` Laxman Dewangan
[not found] ` <1366797267-29567-1-git-send-email-ldewangan-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-04-30 10:30 ` Vinod Koul [this message]
2013-04-30 10:30 ` Vinod Koul
[not found] ` <20130430103046.GD1960-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2013-04-30 12:42 ` Laxman Dewangan
2013-04-30 12:42 ` Laxman Dewangan
2013-05-02 18:42 ` Stephen Warren
2013-05-02 18:42 ` Stephen Warren
[not found] ` <5182B396.308-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-05-03 3:50 ` Vinod Koul
2013-05-03 3:50 ` Vinod Koul
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=20130430103046.GD1960@intel.com \
--to=vinod.koul-ral2jqcrhueavxtiumwx3w@public.gmane.org \
--cc=djbw-b10kYP2dOMg@public.gmane.org \
--cc=ldewangan-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org \
/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: link
Be 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.