From: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
To: "Emilio López" <emilio-0Z03zUJReD5OxF6Tv1QG9Q@public.gmane.org>
Cc: vinod.koul-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org,
dan.j.williams-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org,
broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
linux-spi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
dmaengine-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
sunny-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf@public.gmane.org,
kevin.z.m.zh-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
shuge-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf@public.gmane.org,
zhuzhenhua-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf@public.gmane.org
Subject: Re: [PATCH v3 2/8] spi: sun4i: add DMA support
Date: Tue, 5 Aug 2014 22:23:54 +0200 [thread overview]
Message-ID: <20140805202354.GA2019@lukather> (raw)
In-Reply-To: <1407183002-29420-3-git-send-email-emilio-0Z03zUJReD5OxF6Tv1QG9Q@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 6167 bytes --]
Hi,
On Mon, Aug 04, 2014 at 05:09:56PM -0300, Emilio López wrote:
> + if (sun4i_spi_can_dma(master, spi, tfr)) {
> + dev_dbg(&sspi->master->dev, "Using DMA mode for transfer\n");
> +
> + if (sspi->tx_buf) {
> + desc_tx = dmaengine_prep_slave_sg(sspi->tx_dma_chan,
> + tfr->tx_sg.sgl, tfr->tx_sg.nents,
> + DMA_TO_DEVICE,
> + DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> + if (!desc_tx) {
> + dev_err(&sspi->master->dev,
> + "Couldn't prepare dma slave\n");
> + return -EIO;
> + }
> +
> + dmaengine_submit(desc_tx);
> + }
> +
> + if (sspi->rx_buf) {
> + desc_rx = dmaengine_prep_slave_sg(sspi->rx_dma_chan,
> + tfr->rx_sg.sgl, tfr->rx_sg.nents,
> + DMA_FROM_DEVICE,
> + DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> + if (!desc_rx) {
> + dev_err(&sspi->master->dev,
> + "Couldn't prepare dma slave\n");
> + return -EIO;
> + }
> +
> + dmaengine_submit(desc_rx);
> + }
> +
> + /* Enable DMA requests */
> + reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
> + sun4i_spi_write(sspi, SUN4I_CTL_REG,
> + reg | SUN4I_CTL_DMAMC_DEDICATED);
> + sun4i_spi_write(sspi, SUN4I_DMA_CTL_REG,
> + SUN4I_DMA_CTL_TF_NOT_FULL |
> + SUN4I_DMA_CTL_RF_READY);
> +
> + dma_async_issue_pending(sspi->rx_dma_chan);
> + dma_async_issue_pending(sspi->tx_dma_chan);
I guess the DMA levels setup and the issue pending calls could be
moved to the if statements above about wether the RX and TX buffers
are here or not.
> + } else {
> + dev_dbg(&sspi->master->dev, "Using PIO mode for transfer\n");
> +
> + /* Disable DMA requests */
> + reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
> + sun4i_spi_write(sspi, SUN4I_CTL_REG,
> + reg & ~SUN4I_CTL_DMAMC_DEDICATED);
> + sun4i_spi_write(sspi, SUN4I_DMA_CTL_REG, 0);
> +
> + /* Fill the TX FIFO */
> + sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH);
> + }
> +
> /* Start the transfer */
> reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
> sun4i_spi_write(sspi, SUN4I_CTL_REG, reg | SUN4I_CTL_XCH);
> @@ -286,7 +359,12 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
> goto out;
> }
>
> - sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
> + if (sun4i_spi_can_dma(master, spi, tfr) && desc_rx) {
> + /* The receive transfer should be the last one to finish */
> + dma_wait_for_async_tx(desc_rx);
> + } else {
> + sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
> + }
>
> out:
> sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, 0);
> @@ -351,6 +429,7 @@ static int sun4i_spi_runtime_suspend(struct device *dev)
>
> static int sun4i_spi_probe(struct platform_device *pdev)
> {
> + struct dma_slave_config dma_sconfig;
> struct spi_master *master;
> struct sun4i_spi *sspi;
> struct resource *res;
> @@ -386,7 +465,10 @@ static int sun4i_spi_probe(struct platform_device *pdev)
> goto err_free_master;
> }
>
> + init_completion(&sspi->done);
> sspi->master = master;
> + master->can_dma = sun4i_spi_can_dma;
> + master->prepare_message = sun4i_spi_prepare_message;
> master->set_cs = sun4i_spi_set_cs;
> master->transfer_one = sun4i_spi_transfer_one;
> master->num_chipselect = 4;
> @@ -409,7 +491,45 @@ static int sun4i_spi_probe(struct platform_device *pdev)
> goto err_free_master;
> }
>
> - init_completion(&sspi->done);
> + sspi->tx_dma_chan = dma_request_slave_channel_reason(&pdev->dev, "tx");
> + if (IS_ERR(sspi->tx_dma_chan)) {
> + dev_err(&pdev->dev, "Unable to acquire DMA channel TX\n");
> + ret = PTR_ERR(sspi->tx_dma_chan);
> + goto err_free_master;
> + }
> +
> + dma_sconfig.direction = DMA_MEM_TO_DEV;
> + dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
> + dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
> + dma_sconfig.dst_addr = res->start + SUN4I_TXDATA_REG;
> + dma_sconfig.src_maxburst = 1;
> + dma_sconfig.dst_maxburst = 1;
> +
> + ret = dmaengine_slave_config(sspi->tx_dma_chan, &dma_sconfig);
> + if (ret) {
> + dev_err(&pdev->dev, "Unable to configure TX DMA slave\n");
> + goto err_tx_dma_release;
> + }
> +
> + sspi->rx_dma_chan = dma_request_slave_channel_reason(&pdev->dev, "rx");
> + if (IS_ERR(sspi->rx_dma_chan)) {
> + dev_err(&pdev->dev, "Unable to acquire DMA channel RX\n");
> + ret = PTR_ERR(sspi->rx_dma_chan);
> + goto err_tx_dma_release;
> + }
> +
> + dma_sconfig.direction = DMA_DEV_TO_MEM;
> + dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
> + dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
> + dma_sconfig.src_addr = res->start + SUN4I_RXDATA_REG;
> + dma_sconfig.src_maxburst = 1;
> + dma_sconfig.dst_maxburst = 1;
> +
> + ret = dmaengine_slave_config(sspi->rx_dma_chan, &dma_sconfig);
> + if (ret) {
> + dev_err(&pdev->dev, "Unable to configure RX DMA slave\n");
> + goto err_rx_dma_release;
> + }
>
> /*
> * This wake-up/shutdown pattern is to be able to have the
> @@ -418,7 +538,7 @@ static int sun4i_spi_probe(struct platform_device *pdev)
> ret = sun4i_spi_runtime_resume(&pdev->dev);
> if (ret) {
> dev_err(&pdev->dev, "Couldn't resume the device\n");
> - goto err_free_master;
> + goto err_rx_dma_release;
> }
>
> pm_runtime_set_active(&pdev->dev);
> @@ -436,6 +556,10 @@ static int sun4i_spi_probe(struct platform_device *pdev)
> err_pm_disable:
> pm_runtime_disable(&pdev->dev);
> sun4i_spi_runtime_suspend(&pdev->dev);
> +err_rx_dma_release:
> + dma_release_channel(sspi->rx_dma_chan);
> +err_tx_dma_release:
> + dma_release_channel(sspi->tx_dma_chan);
> err_free_master:
> spi_master_put(master);
> return ret;
> @@ -443,8 +567,17 @@ err_free_master:
>
> static int sun4i_spi_remove(struct platform_device *pdev)
> {
> + struct spi_master *master = platform_get_drvdata(pdev);
> + struct sun4i_spi *sspi = spi_master_get_devdata(master);
> +
> + if (pm_runtime_active(&pdev->dev))
> + sun4i_spi_runtime_suspend(&pdev->dev);
> +
This doesn't really belong in this patch, please send a separate one.
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
WARNING: multiple messages have this Message-ID (diff)
From: maxime.ripard@free-electrons.com (Maxime Ripard)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 2/8] spi: sun4i: add DMA support
Date: Tue, 5 Aug 2014 22:23:54 +0200 [thread overview]
Message-ID: <20140805202354.GA2019@lukather> (raw)
In-Reply-To: <1407183002-29420-3-git-send-email-emilio@elopez.com.ar>
Hi,
On Mon, Aug 04, 2014 at 05:09:56PM -0300, Emilio L?pez wrote:
> + if (sun4i_spi_can_dma(master, spi, tfr)) {
> + dev_dbg(&sspi->master->dev, "Using DMA mode for transfer\n");
> +
> + if (sspi->tx_buf) {
> + desc_tx = dmaengine_prep_slave_sg(sspi->tx_dma_chan,
> + tfr->tx_sg.sgl, tfr->tx_sg.nents,
> + DMA_TO_DEVICE,
> + DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> + if (!desc_tx) {
> + dev_err(&sspi->master->dev,
> + "Couldn't prepare dma slave\n");
> + return -EIO;
> + }
> +
> + dmaengine_submit(desc_tx);
> + }
> +
> + if (sspi->rx_buf) {
> + desc_rx = dmaengine_prep_slave_sg(sspi->rx_dma_chan,
> + tfr->rx_sg.sgl, tfr->rx_sg.nents,
> + DMA_FROM_DEVICE,
> + DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> + if (!desc_rx) {
> + dev_err(&sspi->master->dev,
> + "Couldn't prepare dma slave\n");
> + return -EIO;
> + }
> +
> + dmaengine_submit(desc_rx);
> + }
> +
> + /* Enable DMA requests */
> + reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
> + sun4i_spi_write(sspi, SUN4I_CTL_REG,
> + reg | SUN4I_CTL_DMAMC_DEDICATED);
> + sun4i_spi_write(sspi, SUN4I_DMA_CTL_REG,
> + SUN4I_DMA_CTL_TF_NOT_FULL |
> + SUN4I_DMA_CTL_RF_READY);
> +
> + dma_async_issue_pending(sspi->rx_dma_chan);
> + dma_async_issue_pending(sspi->tx_dma_chan);
I guess the DMA levels setup and the issue pending calls could be
moved to the if statements above about wether the RX and TX buffers
are here or not.
> + } else {
> + dev_dbg(&sspi->master->dev, "Using PIO mode for transfer\n");
> +
> + /* Disable DMA requests */
> + reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
> + sun4i_spi_write(sspi, SUN4I_CTL_REG,
> + reg & ~SUN4I_CTL_DMAMC_DEDICATED);
> + sun4i_spi_write(sspi, SUN4I_DMA_CTL_REG, 0);
> +
> + /* Fill the TX FIFO */
> + sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH);
> + }
> +
> /* Start the transfer */
> reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
> sun4i_spi_write(sspi, SUN4I_CTL_REG, reg | SUN4I_CTL_XCH);
> @@ -286,7 +359,12 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
> goto out;
> }
>
> - sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
> + if (sun4i_spi_can_dma(master, spi, tfr) && desc_rx) {
> + /* The receive transfer should be the last one to finish */
> + dma_wait_for_async_tx(desc_rx);
> + } else {
> + sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
> + }
>
> out:
> sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, 0);
> @@ -351,6 +429,7 @@ static int sun4i_spi_runtime_suspend(struct device *dev)
>
> static int sun4i_spi_probe(struct platform_device *pdev)
> {
> + struct dma_slave_config dma_sconfig;
> struct spi_master *master;
> struct sun4i_spi *sspi;
> struct resource *res;
> @@ -386,7 +465,10 @@ static int sun4i_spi_probe(struct platform_device *pdev)
> goto err_free_master;
> }
>
> + init_completion(&sspi->done);
> sspi->master = master;
> + master->can_dma = sun4i_spi_can_dma;
> + master->prepare_message = sun4i_spi_prepare_message;
> master->set_cs = sun4i_spi_set_cs;
> master->transfer_one = sun4i_spi_transfer_one;
> master->num_chipselect = 4;
> @@ -409,7 +491,45 @@ static int sun4i_spi_probe(struct platform_device *pdev)
> goto err_free_master;
> }
>
> - init_completion(&sspi->done);
> + sspi->tx_dma_chan = dma_request_slave_channel_reason(&pdev->dev, "tx");
> + if (IS_ERR(sspi->tx_dma_chan)) {
> + dev_err(&pdev->dev, "Unable to acquire DMA channel TX\n");
> + ret = PTR_ERR(sspi->tx_dma_chan);
> + goto err_free_master;
> + }
> +
> + dma_sconfig.direction = DMA_MEM_TO_DEV;
> + dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
> + dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
> + dma_sconfig.dst_addr = res->start + SUN4I_TXDATA_REG;
> + dma_sconfig.src_maxburst = 1;
> + dma_sconfig.dst_maxburst = 1;
> +
> + ret = dmaengine_slave_config(sspi->tx_dma_chan, &dma_sconfig);
> + if (ret) {
> + dev_err(&pdev->dev, "Unable to configure TX DMA slave\n");
> + goto err_tx_dma_release;
> + }
> +
> + sspi->rx_dma_chan = dma_request_slave_channel_reason(&pdev->dev, "rx");
> + if (IS_ERR(sspi->rx_dma_chan)) {
> + dev_err(&pdev->dev, "Unable to acquire DMA channel RX\n");
> + ret = PTR_ERR(sspi->rx_dma_chan);
> + goto err_tx_dma_release;
> + }
> +
> + dma_sconfig.direction = DMA_DEV_TO_MEM;
> + dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
> + dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
> + dma_sconfig.src_addr = res->start + SUN4I_RXDATA_REG;
> + dma_sconfig.src_maxburst = 1;
> + dma_sconfig.dst_maxburst = 1;
> +
> + ret = dmaengine_slave_config(sspi->rx_dma_chan, &dma_sconfig);
> + if (ret) {
> + dev_err(&pdev->dev, "Unable to configure RX DMA slave\n");
> + goto err_rx_dma_release;
> + }
>
> /*
> * This wake-up/shutdown pattern is to be able to have the
> @@ -418,7 +538,7 @@ static int sun4i_spi_probe(struct platform_device *pdev)
> ret = sun4i_spi_runtime_resume(&pdev->dev);
> if (ret) {
> dev_err(&pdev->dev, "Couldn't resume the device\n");
> - goto err_free_master;
> + goto err_rx_dma_release;
> }
>
> pm_runtime_set_active(&pdev->dev);
> @@ -436,6 +556,10 @@ static int sun4i_spi_probe(struct platform_device *pdev)
> err_pm_disable:
> pm_runtime_disable(&pdev->dev);
> sun4i_spi_runtime_suspend(&pdev->dev);
> +err_rx_dma_release:
> + dma_release_channel(sspi->rx_dma_chan);
> +err_tx_dma_release:
> + dma_release_channel(sspi->tx_dma_chan);
> err_free_master:
> spi_master_put(master);
> return ret;
> @@ -443,8 +567,17 @@ err_free_master:
>
> static int sun4i_spi_remove(struct platform_device *pdev)
> {
> + struct spi_master *master = platform_get_drvdata(pdev);
> + struct sun4i_spi *sspi = spi_master_get_devdata(master);
> +
> + if (pm_runtime_active(&pdev->dev))
> + sun4i_spi_runtime_suspend(&pdev->dev);
> +
This doesn't really belong in this patch, please send a separate one.
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140805/523c6850/attachment.sig>
next prev parent reply other threads:[~2014-08-05 20:23 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-04 20:09 [PATCH v3 0/8] DMAEngine support for sun4i, sun5i & sun7i Emilio López
2014-08-04 20:09 ` Emilio López
[not found] ` <1407183002-29420-1-git-send-email-emilio-0Z03zUJReD5OxF6Tv1QG9Q@public.gmane.org>
2014-08-04 20:09 ` [PATCH v3 1/8] dma: sun4i: Add support for the DMA engine on sun[457]i SoCs Emilio López
2014-08-04 20:09 ` Emilio López
[not found] ` <1407183002-29420-2-git-send-email-emilio-0Z03zUJReD5OxF6Tv1QG9Q@public.gmane.org>
2014-08-05 20:00 ` Maxime Ripard
2014-08-05 20:00 ` Maxime Ripard
2014-08-07 19:37 ` Emilio López
2014-08-07 19:37 ` Emilio López
[not found] ` <53E3D56C.5030204-0Z03zUJReD5OxF6Tv1QG9Q@public.gmane.org>
2014-08-09 15:11 ` jonsmirl-Re5JQEeQqe8AvxtiuMwx3w
2014-08-09 15:11 ` jonsmirl at gmail.com
2014-08-11 11:40 ` Maxime Ripard
2014-08-11 11:40 ` Maxime Ripard
2014-08-11 12:36 ` jonsmirl-Re5JQEeQqe8AvxtiuMwx3w
2014-08-11 12:36 ` jonsmirl at gmail.com
2014-08-04 20:09 ` [PATCH v3 2/8] spi: sun4i: add DMA support Emilio López
2014-08-04 20:09 ` Emilio López
[not found] ` <1407183002-29420-3-git-send-email-emilio-0Z03zUJReD5OxF6Tv1QG9Q@public.gmane.org>
2014-08-05 20:23 ` Maxime Ripard [this message]
2014-08-05 20:23 ` Maxime Ripard
2014-08-07 20:37 ` Emilio López
2014-08-07 20:37 ` Emilio López
2014-08-07 17:44 ` Mark Brown
2014-08-07 17:44 ` Mark Brown
2014-08-04 20:09 ` [PATCH v3 3/8] ARM: sun4i: dt: Add node to represent the DMA controller Emilio López
2014-08-04 20:09 ` Emilio López
[not found] ` <1407183002-29420-4-git-send-email-emilio-0Z03zUJReD5OxF6Tv1QG9Q@public.gmane.org>
2014-08-05 20:25 ` Maxime Ripard
2014-08-05 20:25 ` Maxime Ripard
2014-08-04 20:09 ` [PATCH v3 4/8] ARM: sun5i: dt: Add nodes to represent the DMA controllers Emilio López
2014-08-04 20:09 ` Emilio López
2014-08-04 20:09 ` [PATCH v3 5/8] ARM: sun7i: dt: Add node to represent the DMA controller Emilio López
2014-08-04 20:09 ` Emilio López
2014-08-04 20:10 ` [PATCH v3 6/8] ARM: sun4i: dt: enable DMA on SPI Emilio López
2014-08-04 20:10 ` Emilio López
2014-08-04 20:10 ` [PATCH v3 7/8] ARM: sun5i: " Emilio López
2014-08-04 20:10 ` Emilio López
2014-08-04 20:10 ` [PATCH v3 8/8] ARM: sun7i: " Emilio López
2014-08-04 20:10 ` Emilio López
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=20140805202354.GA2019@lukather \
--to=maxime.ripard-wi1+55scjutkeb57/3fjtnbpr1lh4cv8@public.gmane.org \
--cc=broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
--cc=dan.j.williams-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org \
--cc=dmaengine-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=emilio-0Z03zUJReD5OxF6Tv1QG9Q@public.gmane.org \
--cc=kevin.z.m.zh-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
--cc=linux-spi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=shuge-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf@public.gmane.org \
--cc=sunny-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf@public.gmane.org \
--cc=vinod.koul-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org \
--cc=zhuzhenhua-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf@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.