* [PATCH] spi: omap2-mcspi: Fix transfers if DMADEVICES is not set
@ 2013-04-13 0:25 Tony Lindgren
2013-04-15 16:11 ` Mark Brown
0 siblings, 1 reply; 2+ messages in thread
From: Tony Lindgren @ 2013-04-13 0:25 UTC (permalink / raw)
To: Grant Likely, Mark Brown; +Cc: spi-devel-general, linux-omap, Jon Hunter
Selecting CONFIG_DMADEVICES is optional, and we must
be able to continue even without DMA. Otherwise things
like omap4430sdp nfsroot will fail if DMA is not
selected.
Note that the driver already supports PIO mode, but
we fail to fall back to PIO if requesting DMA channels
fails.
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
Does this look OK to get in for v3.10? There should not
be any urgent need for this for v3.9-rc.
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -809,6 +809,10 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
return 0;
}
+/*
+ * Note that we currently allow DMA only if we get a channel
+ * for both rx and tx. Otherwise we'll do PIO for both rx and tx.
+ */
static int omap2_mcspi_request_dma(struct spi_device *spi)
{
struct spi_master *master = spi->master;
@@ -827,21 +831,22 @@ static int omap2_mcspi_request_dma(struct spi_device *spi)
dma_cap_set(DMA_SLAVE, mask);
sig = mcspi_dma->dma_rx_sync_dev;
mcspi_dma->dma_rx = dma_request_channel(mask, omap_dma_filter_fn, &sig);
- if (!mcspi_dma->dma_rx) {
- dev_err(&spi->dev, "no RX DMA engine channel for McSPI\n");
- return -EAGAIN;
- }
+ if (!mcspi_dma->dma_rx)
+ goto no_dma;
sig = mcspi_dma->dma_tx_sync_dev;
mcspi_dma->dma_tx = dma_request_channel(mask, omap_dma_filter_fn, &sig);
if (!mcspi_dma->dma_tx) {
- dev_err(&spi->dev, "no TX DMA engine channel for McSPI\n");
dma_release_channel(mcspi_dma->dma_rx);
mcspi_dma->dma_rx = NULL;
- return -EAGAIN;
+ goto no_dma;
}
return 0;
+
+no_dma:
+ dev_warn(&spi->dev, "not using DMA for McSPI\n");
+ return -EAGAIN;
}
static int omap2_mcspi_setup(struct spi_device *spi)
@@ -874,7 +879,7 @@ static int omap2_mcspi_setup(struct spi_device *spi)
if (!mcspi_dma->dma_rx || !mcspi_dma->dma_tx) {
ret = omap2_mcspi_request_dma(spi);
- if (ret < 0)
+ if (ret < 0 && ret != -EAGAIN)
return ret;
}
@@ -932,6 +937,7 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m)
struct spi_device *spi;
struct spi_transfer *t = NULL;
struct spi_master *master;
+ struct omap2_mcspi_dma *mcspi_dma;
int cs_active = 0;
struct omap2_mcspi_cs *cs;
struct omap2_mcspi_device_config *cd;
@@ -941,6 +947,7 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m)
spi = m->spi;
master = spi->master;
+ mcspi_dma = mcspi->dma_channels + spi->chip_select;
cs = spi->controller_state;
cd = spi->controller_data;
@@ -997,7 +1004,8 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m)
__raw_writel(0, cs->base
+ OMAP2_MCSPI_TX0);
- if (m->is_dma_mapped || t->len >= DMA_MIN_BYTES)
+ if ((mcspi_dma->dma_rx && mcspi_dma->dma_tx) &&
+ (m->is_dma_mapped || t->len >= DMA_MIN_BYTES))
count = omap2_mcspi_txrx_dma(spi, t);
else
count = omap2_mcspi_txrx_pio(spi, t);
@@ -1044,10 +1052,14 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m)
static int omap2_mcspi_transfer_one_message(struct spi_master *master,
struct spi_message *m)
{
+ struct spi_device *spi;
struct omap2_mcspi *mcspi;
+ struct omap2_mcspi_dma *mcspi_dma;
struct spi_transfer *t;
+ spi = m->spi;
mcspi = spi_master_get_devdata(master);
+ mcspi_dma = mcspi->dma_channels + spi->chip_select;
m->actual_length = 0;
m->status = 0;
@@ -1082,7 +1094,7 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
if (m->is_dma_mapped || len < DMA_MIN_BYTES)
continue;
- if (tx_buf != NULL) {
+ if (mcspi_dma->dma_tx && tx_buf != NULL) {
t->tx_dma = dma_map_single(mcspi->dev, (void *) tx_buf,
len, DMA_TO_DEVICE);
if (dma_mapping_error(mcspi->dev, t->tx_dma)) {
@@ -1091,7 +1103,7 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
return -EINVAL;
}
}
- if (rx_buf != NULL) {
+ if (mcspi_dma->dma_rx && rx_buf != NULL) {
t->rx_dma = dma_map_single(mcspi->dev, rx_buf, t->len,
DMA_FROM_DEVICE);
if (dma_mapping_error(mcspi->dev, t->rx_dma)) {
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] spi: omap2-mcspi: Fix transfers if DMADEVICES is not set
2013-04-13 0:25 [PATCH] spi: omap2-mcspi: Fix transfers if DMADEVICES is not set Tony Lindgren
@ 2013-04-15 16:11 ` Mark Brown
0 siblings, 0 replies; 2+ messages in thread
From: Mark Brown @ 2013-04-15 16:11 UTC (permalink / raw)
To: Tony Lindgren; +Cc: Grant Likely, spi-devel-general, linux-omap, Jon Hunter
[-- Attachment #1: Type: text/plain, Size: 257 bytes --]
On Fri, Apr 12, 2013 at 05:25:07PM -0700, Tony Lindgren wrote:
> Selecting CONFIG_DMADEVICES is optional, and we must
> be able to continue even without DMA. Otherwise things
> like omap4430sdp nfsroot will fail if DMA is not
> selected.
Applied, thanks.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2013-04-15 16:11 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-04-13 0:25 [PATCH] spi: omap2-mcspi: Fix transfers if DMADEVICES is not set Tony Lindgren
2013-04-15 16:11 ` Mark Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).