spi: atmel: remove the use of private channel fields
For DMA transfers, we now use the core DMA framework which provides channel fields in the spi_master structure. Remove the private channels from atmel_spi stucture which were located in a sub-structure. This last one (atmel_spi_dma) which is now empty is also removed. Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
d5fab59cab
commit
768f3d9d80
|
@ -265,11 +265,6 @@
|
||||||
|
|
||||||
#define AUTOSUSPEND_TIMEOUT 2000
|
#define AUTOSUSPEND_TIMEOUT 2000
|
||||||
|
|
||||||
struct atmel_spi_dma {
|
|
||||||
struct dma_chan *chan_rx;
|
|
||||||
struct dma_chan *chan_tx;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct atmel_spi_caps {
|
struct atmel_spi_caps {
|
||||||
bool is_spi2;
|
bool is_spi2;
|
||||||
bool has_wdrbt;
|
bool has_wdrbt;
|
||||||
|
@ -302,8 +297,6 @@ struct atmel_spi {
|
||||||
bool use_dma;
|
bool use_dma;
|
||||||
bool use_pdc;
|
bool use_pdc;
|
||||||
bool use_cs_gpios;
|
bool use_cs_gpios;
|
||||||
/* dmaengine data */
|
|
||||||
struct atmel_spi_dma dma;
|
|
||||||
|
|
||||||
bool keep_cs;
|
bool keep_cs;
|
||||||
bool cs_active;
|
bool cs_active;
|
||||||
|
@ -460,6 +453,7 @@ static int atmel_spi_dma_slave_config(struct atmel_spi *as,
|
||||||
struct dma_slave_config *slave_config,
|
struct dma_slave_config *slave_config,
|
||||||
u8 bits_per_word)
|
u8 bits_per_word)
|
||||||
{
|
{
|
||||||
|
struct spi_master *master = platform_get_drvdata(as->pdev);
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (bits_per_word > 8) {
|
if (bits_per_word > 8) {
|
||||||
|
@ -491,7 +485,7 @@ static int atmel_spi_dma_slave_config(struct atmel_spi *as,
|
||||||
* path works the same whether FIFOs are available (and enabled) or not.
|
* path works the same whether FIFOs are available (and enabled) or not.
|
||||||
*/
|
*/
|
||||||
slave_config->direction = DMA_MEM_TO_DEV;
|
slave_config->direction = DMA_MEM_TO_DEV;
|
||||||
if (dmaengine_slave_config(as->dma.chan_tx, slave_config)) {
|
if (dmaengine_slave_config(master->dma_tx, slave_config)) {
|
||||||
dev_err(&as->pdev->dev,
|
dev_err(&as->pdev->dev,
|
||||||
"failed to configure tx dma channel\n");
|
"failed to configure tx dma channel\n");
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
|
@ -506,7 +500,7 @@ static int atmel_spi_dma_slave_config(struct atmel_spi *as,
|
||||||
* enabled) or not.
|
* enabled) or not.
|
||||||
*/
|
*/
|
||||||
slave_config->direction = DMA_DEV_TO_MEM;
|
slave_config->direction = DMA_DEV_TO_MEM;
|
||||||
if (dmaengine_slave_config(as->dma.chan_rx, slave_config)) {
|
if (dmaengine_slave_config(master->dma_rx, slave_config)) {
|
||||||
dev_err(&as->pdev->dev,
|
dev_err(&as->pdev->dev,
|
||||||
"failed to configure rx dma channel\n");
|
"failed to configure rx dma channel\n");
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
|
@ -515,7 +509,8 @@ static int atmel_spi_dma_slave_config(struct atmel_spi *as,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int atmel_spi_configure_dma(struct atmel_spi *as)
|
static int atmel_spi_configure_dma(struct spi_master *master,
|
||||||
|
struct atmel_spi *as)
|
||||||
{
|
{
|
||||||
struct dma_slave_config slave_config;
|
struct dma_slave_config slave_config;
|
||||||
struct device *dev = &as->pdev->dev;
|
struct device *dev = &as->pdev->dev;
|
||||||
|
@ -525,26 +520,26 @@ static int atmel_spi_configure_dma(struct atmel_spi *as)
|
||||||
dma_cap_zero(mask);
|
dma_cap_zero(mask);
|
||||||
dma_cap_set(DMA_SLAVE, mask);
|
dma_cap_set(DMA_SLAVE, mask);
|
||||||
|
|
||||||
as->dma.chan_tx = dma_request_slave_channel_reason(dev, "tx");
|
master->dma_tx = dma_request_slave_channel_reason(dev, "tx");
|
||||||
if (IS_ERR(as->dma.chan_tx)) {
|
if (IS_ERR(master->dma_tx)) {
|
||||||
err = PTR_ERR(as->dma.chan_tx);
|
err = PTR_ERR(master->dma_tx);
|
||||||
if (err == -EPROBE_DEFER) {
|
if (err == -EPROBE_DEFER) {
|
||||||
dev_warn(dev, "no DMA channel available at the moment\n");
|
dev_warn(dev, "no DMA channel available at the moment\n");
|
||||||
return err;
|
goto error_clear;
|
||||||
}
|
}
|
||||||
dev_err(dev,
|
dev_err(dev,
|
||||||
"DMA TX channel not available, SPI unable to use DMA\n");
|
"DMA TX channel not available, SPI unable to use DMA\n");
|
||||||
err = -EBUSY;
|
err = -EBUSY;
|
||||||
goto error;
|
goto error_clear;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* No reason to check EPROBE_DEFER here since we have already requested
|
* No reason to check EPROBE_DEFER here since we have already requested
|
||||||
* tx channel. If it fails here, it's for another reason.
|
* tx channel. If it fails here, it's for another reason.
|
||||||
*/
|
*/
|
||||||
as->dma.chan_rx = dma_request_slave_channel(dev, "rx");
|
master->dma_rx = dma_request_slave_channel(dev, "rx");
|
||||||
|
|
||||||
if (!as->dma.chan_rx) {
|
if (!master->dma_rx) {
|
||||||
dev_err(dev,
|
dev_err(dev,
|
||||||
"DMA RX channel not available, SPI unable to use DMA\n");
|
"DMA RX channel not available, SPI unable to use DMA\n");
|
||||||
err = -EBUSY;
|
err = -EBUSY;
|
||||||
|
@ -557,31 +552,38 @@ static int atmel_spi_configure_dma(struct atmel_spi *as)
|
||||||
|
|
||||||
dev_info(&as->pdev->dev,
|
dev_info(&as->pdev->dev,
|
||||||
"Using %s (tx) and %s (rx) for DMA transfers\n",
|
"Using %s (tx) and %s (rx) for DMA transfers\n",
|
||||||
dma_chan_name(as->dma.chan_tx),
|
dma_chan_name(master->dma_tx),
|
||||||
dma_chan_name(as->dma.chan_rx));
|
dma_chan_name(master->dma_rx));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
error:
|
error:
|
||||||
if (as->dma.chan_rx)
|
if (master->dma_rx)
|
||||||
dma_release_channel(as->dma.chan_rx);
|
dma_release_channel(master->dma_rx);
|
||||||
if (!IS_ERR(as->dma.chan_tx))
|
if (!IS_ERR(master->dma_tx))
|
||||||
dma_release_channel(as->dma.chan_tx);
|
dma_release_channel(master->dma_tx);
|
||||||
|
error_clear:
|
||||||
|
master->dma_tx = master->dma_rx = NULL;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void atmel_spi_stop_dma(struct atmel_spi *as)
|
static void atmel_spi_stop_dma(struct spi_master *master)
|
||||||
{
|
{
|
||||||
if (as->dma.chan_rx)
|
if (master->dma_rx)
|
||||||
dmaengine_terminate_all(as->dma.chan_rx);
|
dmaengine_terminate_all(master->dma_rx);
|
||||||
if (as->dma.chan_tx)
|
if (master->dma_tx)
|
||||||
dmaengine_terminate_all(as->dma.chan_tx);
|
dmaengine_terminate_all(master->dma_tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void atmel_spi_release_dma(struct atmel_spi *as)
|
static void atmel_spi_release_dma(struct spi_master *master)
|
||||||
{
|
{
|
||||||
if (as->dma.chan_rx)
|
if (master->dma_rx) {
|
||||||
dma_release_channel(as->dma.chan_rx);
|
dma_release_channel(master->dma_rx);
|
||||||
if (as->dma.chan_tx)
|
master->dma_rx = NULL;
|
||||||
dma_release_channel(as->dma.chan_tx);
|
}
|
||||||
|
if (master->dma_tx) {
|
||||||
|
dma_release_channel(master->dma_tx);
|
||||||
|
master->dma_tx = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function is called by the DMA driver from tasklet context */
|
/* This function is called by the DMA driver from tasklet context */
|
||||||
|
@ -717,8 +719,8 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master,
|
||||||
u32 *plen)
|
u32 *plen)
|
||||||
{
|
{
|
||||||
struct atmel_spi *as = spi_master_get_devdata(master);
|
struct atmel_spi *as = spi_master_get_devdata(master);
|
||||||
struct dma_chan *rxchan = as->dma.chan_rx;
|
struct dma_chan *rxchan = master->dma_rx;
|
||||||
struct dma_chan *txchan = as->dma.chan_tx;
|
struct dma_chan *txchan = master->dma_tx;
|
||||||
struct dma_async_tx_descriptor *rxdesc;
|
struct dma_async_tx_descriptor *rxdesc;
|
||||||
struct dma_async_tx_descriptor *txdesc;
|
struct dma_async_tx_descriptor *txdesc;
|
||||||
struct dma_slave_config slave_config;
|
struct dma_slave_config slave_config;
|
||||||
|
@ -782,7 +784,7 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master,
|
||||||
|
|
||||||
err_dma:
|
err_dma:
|
||||||
spi_writel(as, IDR, SPI_BIT(OVRES));
|
spi_writel(as, IDR, SPI_BIT(OVRES));
|
||||||
atmel_spi_stop_dma(as);
|
atmel_spi_stop_dma(master);
|
||||||
err_exit:
|
err_exit:
|
||||||
atmel_spi_lock(as);
|
atmel_spi_lock(as);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -1310,7 +1312,7 @@ static int atmel_spi_one_transfer(struct spi_master *master,
|
||||||
spi_readl(as, SR);
|
spi_readl(as, SR);
|
||||||
|
|
||||||
} else if (atmel_spi_use_dma(as, xfer)) {
|
} else if (atmel_spi_use_dma(as, xfer)) {
|
||||||
atmel_spi_stop_dma(as);
|
atmel_spi_stop_dma(master);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!msg->is_dma_mapped
|
if (!msg->is_dma_mapped
|
||||||
|
@ -1539,10 +1541,8 @@ static int atmel_spi_probe(struct platform_device *pdev)
|
||||||
as->use_dma = false;
|
as->use_dma = false;
|
||||||
as->use_pdc = false;
|
as->use_pdc = false;
|
||||||
if (as->caps.has_dma_support) {
|
if (as->caps.has_dma_support) {
|
||||||
ret = atmel_spi_configure_dma(as);
|
ret = atmel_spi_configure_dma(master, as);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
master->dma_tx = as->dma.chan_tx;
|
|
||||||
master->dma_rx = as->dma.chan_rx;
|
|
||||||
as->use_dma = true;
|
as->use_dma = true;
|
||||||
} else if (ret == -EPROBE_DEFER) {
|
} else if (ret == -EPROBE_DEFER) {
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1608,7 +1608,7 @@ static int atmel_spi_probe(struct platform_device *pdev)
|
||||||
pm_runtime_set_suspended(&pdev->dev);
|
pm_runtime_set_suspended(&pdev->dev);
|
||||||
|
|
||||||
if (as->use_dma)
|
if (as->use_dma)
|
||||||
atmel_spi_release_dma(as);
|
atmel_spi_release_dma(master);
|
||||||
|
|
||||||
spi_writel(as, CR, SPI_BIT(SWRST));
|
spi_writel(as, CR, SPI_BIT(SWRST));
|
||||||
spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
|
spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
|
||||||
|
@ -1630,8 +1630,8 @@ static int atmel_spi_remove(struct platform_device *pdev)
|
||||||
/* reset the hardware and block queue progress */
|
/* reset the hardware and block queue progress */
|
||||||
spin_lock_irq(&as->lock);
|
spin_lock_irq(&as->lock);
|
||||||
if (as->use_dma) {
|
if (as->use_dma) {
|
||||||
atmel_spi_stop_dma(as);
|
atmel_spi_stop_dma(master);
|
||||||
atmel_spi_release_dma(as);
|
atmel_spi_release_dma(master);
|
||||||
}
|
}
|
||||||
|
|
||||||
spi_writel(as, CR, SPI_BIT(SWRST));
|
spi_writel(as, CR, SPI_BIT(SWRST));
|
||||||
|
|
Loading…
Reference in New Issue