All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] mmc: Several fixes for bcm2835 driver
@ 2018-11-11 13:45 ` Stefan Wahren
  0 siblings, 0 replies; 16+ messages in thread
From: Stefan Wahren @ 2018-11-11 13:45 UTC (permalink / raw)
  To: Eric Anholt, Florian Fainelli, Ulf Hansson
  Cc: Stefan Wahren, Phil Elwell, linux-mmc, linux-rpi-kernel,
	Michal Suchanek, linux-arm-kernel

This patch series fixes several issues which has been discovered after
submission.

Michal Suchanek (1):
  mmc: bcm2835: reset host on timeout

Phil Elwell (1):
  mmc: bcm2835: Recover from MMC_SEND_EXT_CSD

Stefan Wahren (5):
  mmc: bcm2835: Release DMA channel on driver unload
  mmc: bcm2835: Avoid possible races on data requests
  mmc: bcm2835: Terminate timeout work synchronously
  mmc: bcm2835: Refactor dma_map_sg handling
  mmc: bcm2835: Properly handle dmaengine_prep_slave_sg

 drivers/mmc/host/bcm2835.c | 58 ++++++++++++++++++++++++++++++----------------
 1 file changed, 38 insertions(+), 20 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 0/7] mmc: Several fixes for bcm2835 driver
@ 2018-11-11 13:45 ` Stefan Wahren
  0 siblings, 0 replies; 16+ messages in thread
From: Stefan Wahren @ 2018-11-11 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series fixes several issues which has been discovered after
submission.

Michal Suchanek (1):
  mmc: bcm2835: reset host on timeout

Phil Elwell (1):
  mmc: bcm2835: Recover from MMC_SEND_EXT_CSD

Stefan Wahren (5):
  mmc: bcm2835: Release DMA channel on driver unload
  mmc: bcm2835: Avoid possible races on data requests
  mmc: bcm2835: Terminate timeout work synchronously
  mmc: bcm2835: Refactor dma_map_sg handling
  mmc: bcm2835: Properly handle dmaengine_prep_slave_sg

 drivers/mmc/host/bcm2835.c | 58 ++++++++++++++++++++++++++++++----------------
 1 file changed, 38 insertions(+), 20 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/7] mmc: bcm2835: reset host on timeout
  2018-11-11 13:45 ` Stefan Wahren
@ 2018-11-11 13:45     ` Stefan Wahren
  -1 siblings, 0 replies; 16+ messages in thread
From: Stefan Wahren @ 2018-11-11 13:45 UTC (permalink / raw)
  To: Eric Anholt, Florian Fainelli, Ulf Hansson
  Cc: linux-mmc-u79uwXL29TY76Z2rM5mHXA, Michal Suchanek,
	linux-rpi-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

From: Michal Suchanek <msuchanek-l3A5Bk7waGM@public.gmane.org>

The bcm2835 mmc host tends to lock up for unknown reason so reset it on
timeout. The upper mmc block layer tries retransimitting with single
blocks which tends to work out after a long wait.

This is better than giving up and leaving the machine broken for no
obvious reason.

Fixes: 660fc733bd74 ("mmc: bcm2835: Add new driver for the sdhost controller.")
Signed-off-by: Michal Suchanek <msuchanek-l3A5Bk7waGM@public.gmane.org>
---
 drivers/mmc/host/bcm2835.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
index 768972a..f1712df 100644
--- a/drivers/mmc/host/bcm2835.c
+++ b/drivers/mmc/host/bcm2835.c
@@ -286,6 +286,7 @@ static void bcm2835_reset(struct mmc_host *mmc)
 
 	if (host->dma_chan)
 		dmaengine_terminate_sync(host->dma_chan);
+	host->dma_chan = NULL;
 	bcm2835_reset_internal(host);
 }
 
@@ -837,6 +838,8 @@ static void bcm2835_timeout(struct work_struct *work)
 		dev_err(dev, "timeout waiting for hardware interrupt.\n");
 		bcm2835_dumpregs(host);
 
+		bcm2835_reset(host->mmc);
+
 		if (host->data) {
 			host->data->error = -ETIMEDOUT;
 			bcm2835_finish_data(host);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 1/7] mmc: bcm2835: reset host on timeout
@ 2018-11-11 13:45     ` Stefan Wahren
  0 siblings, 0 replies; 16+ messages in thread
From: Stefan Wahren @ 2018-11-11 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

From: Michal Suchanek <msuchanek@suse.de>

The bcm2835 mmc host tends to lock up for unknown reason so reset it on
timeout. The upper mmc block layer tries retransimitting with single
blocks which tends to work out after a long wait.

This is better than giving up and leaving the machine broken for no
obvious reason.

Fixes: 660fc733bd74 ("mmc: bcm2835: Add new driver for the sdhost controller.")
Signed-off-by: Michal Suchanek <msuchanek@suse.de>
---
 drivers/mmc/host/bcm2835.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
index 768972a..f1712df 100644
--- a/drivers/mmc/host/bcm2835.c
+++ b/drivers/mmc/host/bcm2835.c
@@ -286,6 +286,7 @@ static void bcm2835_reset(struct mmc_host *mmc)
 
 	if (host->dma_chan)
 		dmaengine_terminate_sync(host->dma_chan);
+	host->dma_chan = NULL;
 	bcm2835_reset_internal(host);
 }
 
@@ -837,6 +838,8 @@ static void bcm2835_timeout(struct work_struct *work)
 		dev_err(dev, "timeout waiting for hardware interrupt.\n");
 		bcm2835_dumpregs(host);
 
+		bcm2835_reset(host->mmc);
+
 		if (host->data) {
 			host->data->error = -ETIMEDOUT;
 			bcm2835_finish_data(host);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/7] mmc: bcm2835: Recover from MMC_SEND_EXT_CSD
  2018-11-11 13:45 ` Stefan Wahren
@ 2018-11-11 13:45   ` Stefan Wahren
  -1 siblings, 0 replies; 16+ messages in thread
From: Stefan Wahren @ 2018-11-11 13:45 UTC (permalink / raw)
  To: Eric Anholt, Florian Fainelli, Ulf Hansson
  Cc: linux-mmc, Michal Suchanek, Phil Elwell, linux-rpi-kernel,
	linux-arm-kernel

From: Phil Elwell <phil@raspberrypi.org>

If the user issues an "mmc extcsd read", the SD controller receives
what it thinks is a SEND_IF_COND command with an unexpected data block.
The resulting operations leave the FSM stuck in READWAIT, a state which
persists until the MMC framework resets the controller, by which point
the root filesystem is likely to have been unmounted.

A less heavyweight solution is to detect the condition and nudge the
FSM by asserting the (self-clearing) FORCE_DATA_MODE bit.

Link: https://github.com/raspberrypi/linux/issues/2728
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
---
 drivers/mmc/host/bcm2835.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
index f1712df..a251be2 100644
--- a/drivers/mmc/host/bcm2835.c
+++ b/drivers/mmc/host/bcm2835.c
@@ -773,6 +773,8 @@ static void bcm2835_finish_command(struct bcm2835_host *host)
 
 		if (!(sdhsts & SDHSTS_CRC7_ERROR) ||
 		    (host->cmd->opcode != MMC_SEND_OP_COND)) {
+			u32 edm, fsm;
+
 			if (sdhsts & SDHSTS_CMD_TIME_OUT) {
 				host->cmd->error = -ETIMEDOUT;
 			} else {
@@ -781,6 +783,13 @@ static void bcm2835_finish_command(struct bcm2835_host *host)
 				bcm2835_dumpregs(host);
 				host->cmd->error = -EILSEQ;
 			}
+			edm = readl(host->ioaddr + SDEDM);
+			fsm = edm & SDEDM_FSM_MASK;
+			if (fsm == SDEDM_FSM_READWAIT ||
+			    fsm == SDEDM_FSM_WRITESTART1)
+				/* Kick the FSM out of its wait */
+				writel(edm | SDEDM_FORCE_DATA_MODE,
+				       host->ioaddr + SDEDM);
 			bcm2835_finish_request(host);
 			return;
 		}
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/7] mmc: bcm2835: Recover from MMC_SEND_EXT_CSD
@ 2018-11-11 13:45   ` Stefan Wahren
  0 siblings, 0 replies; 16+ messages in thread
From: Stefan Wahren @ 2018-11-11 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

From: Phil Elwell <phil@raspberrypi.org>

If the user issues an "mmc extcsd read", the SD controller receives
what it thinks is a SEND_IF_COND command with an unexpected data block.
The resulting operations leave the FSM stuck in READWAIT, a state which
persists until the MMC framework resets the controller, by which point
the root filesystem is likely to have been unmounted.

A less heavyweight solution is to detect the condition and nudge the
FSM by asserting the (self-clearing) FORCE_DATA_MODE bit.

Link: https://github.com/raspberrypi/linux/issues/2728
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
---
 drivers/mmc/host/bcm2835.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
index f1712df..a251be2 100644
--- a/drivers/mmc/host/bcm2835.c
+++ b/drivers/mmc/host/bcm2835.c
@@ -773,6 +773,8 @@ static void bcm2835_finish_command(struct bcm2835_host *host)
 
 		if (!(sdhsts & SDHSTS_CRC7_ERROR) ||
 		    (host->cmd->opcode != MMC_SEND_OP_COND)) {
+			u32 edm, fsm;
+
 			if (sdhsts & SDHSTS_CMD_TIME_OUT) {
 				host->cmd->error = -ETIMEDOUT;
 			} else {
@@ -781,6 +783,13 @@ static void bcm2835_finish_command(struct bcm2835_host *host)
 				bcm2835_dumpregs(host);
 				host->cmd->error = -EILSEQ;
 			}
+			edm = readl(host->ioaddr + SDEDM);
+			fsm = edm & SDEDM_FSM_MASK;
+			if (fsm == SDEDM_FSM_READWAIT ||
+			    fsm == SDEDM_FSM_WRITESTART1)
+				/* Kick the FSM out of its wait */
+				writel(edm | SDEDM_FORCE_DATA_MODE,
+				       host->ioaddr + SDEDM);
 			bcm2835_finish_request(host);
 			return;
 		}
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 3/7] mmc: bcm2835: Release DMA channel on driver unload
  2018-11-11 13:45 ` Stefan Wahren
@ 2018-11-11 13:45   ` Stefan Wahren
  -1 siblings, 0 replies; 16+ messages in thread
From: Stefan Wahren @ 2018-11-11 13:45 UTC (permalink / raw)
  To: Eric Anholt, Florian Fainelli, Ulf Hansson
  Cc: Stefan Wahren, Phil Elwell, linux-mmc, linux-rpi-kernel,
	Michal Suchanek, linux-arm-kernel

We need to release the slave DMA channel during driver unload.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
 drivers/mmc/host/bcm2835.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
index a251be2..45724ef 100644
--- a/drivers/mmc/host/bcm2835.c
+++ b/drivers/mmc/host/bcm2835.c
@@ -1457,6 +1457,9 @@ static int bcm2835_remove(struct platform_device *pdev)
 	cancel_work_sync(&host->dma_work);
 	cancel_delayed_work_sync(&host->timeout_work);
 
+	if (host->dma_chan_rxtx)
+		dma_release_channel(host->dma_chan_rxtx);
+
 	mmc_free_host(host->mmc);
 	platform_set_drvdata(pdev, NULL);
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 3/7] mmc: bcm2835: Release DMA channel on driver unload
@ 2018-11-11 13:45   ` Stefan Wahren
  0 siblings, 0 replies; 16+ messages in thread
From: Stefan Wahren @ 2018-11-11 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

We need to release the slave DMA channel during driver unload.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
 drivers/mmc/host/bcm2835.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
index a251be2..45724ef 100644
--- a/drivers/mmc/host/bcm2835.c
+++ b/drivers/mmc/host/bcm2835.c
@@ -1457,6 +1457,9 @@ static int bcm2835_remove(struct platform_device *pdev)
 	cancel_work_sync(&host->dma_work);
 	cancel_delayed_work_sync(&host->timeout_work);
 
+	if (host->dma_chan_rxtx)
+		dma_release_channel(host->dma_chan_rxtx);
+
 	mmc_free_host(host->mmc);
 	platform_set_drvdata(pdev, NULL);
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 4/7] mmc: bcm2835: Avoid possible races on data requests
  2018-11-11 13:45 ` Stefan Wahren
@ 2018-11-11 13:45   ` Stefan Wahren
  -1 siblings, 0 replies; 16+ messages in thread
From: Stefan Wahren @ 2018-11-11 13:45 UTC (permalink / raw)
  To: Eric Anholt, Florian Fainelli, Ulf Hansson
  Cc: Stefan Wahren, Phil Elwell, linux-mmc, linux-rpi-kernel,
	Michal Suchanek, linux-arm-kernel

There are two accesses on the data requests which are not protected by
the mutex. So fix this accordingly.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
 drivers/mmc/host/bcm2835.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
index 45724ef..1c60798 100644
--- a/drivers/mmc/host/bcm2835.c
+++ b/drivers/mmc/host/bcm2835.c
@@ -1064,10 +1064,12 @@ static void bcm2835_dma_complete_work(struct work_struct *work)
 {
 	struct bcm2835_host *host =
 		container_of(work, struct bcm2835_host, dma_work);
-	struct mmc_data *data = host->data;
+	struct mmc_data *data;
 
 	mutex_lock(&host->mutex);
 
+	data = host->data;
+
 	if (host->dma_chan) {
 		dma_unmap_sg(host->dma_chan->device->dev,
 			     data->sg, data->sg_len,
@@ -1192,9 +1194,6 @@ static void bcm2835_request(struct mmc_host *mmc, struct mmc_request *mrq)
 		return;
 	}
 
-	if (host->use_dma && mrq->data && (mrq->data->blocks > PIO_THRESHOLD))
-		bcm2835_prepare_dma(host, mrq->data);
-
 	mutex_lock(&host->mutex);
 
 	WARN_ON(host->mrq);
@@ -1218,6 +1217,9 @@ static void bcm2835_request(struct mmc_host *mmc, struct mmc_request *mrq)
 		return;
 	}
 
+	if (host->use_dma && mrq->data && (mrq->data->blocks > PIO_THRESHOLD))
+		bcm2835_prepare_dma(host, mrq->data);
+
 	host->use_sbc = !!mrq->sbc && host->mrq->data &&
 			(host->mrq->data->flags & MMC_DATA_READ);
 	if (host->use_sbc) {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 4/7] mmc: bcm2835: Avoid possible races on data requests
@ 2018-11-11 13:45   ` Stefan Wahren
  0 siblings, 0 replies; 16+ messages in thread
From: Stefan Wahren @ 2018-11-11 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

There are two accesses on the data requests which are not protected by
the mutex. So fix this accordingly.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
 drivers/mmc/host/bcm2835.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
index 45724ef..1c60798 100644
--- a/drivers/mmc/host/bcm2835.c
+++ b/drivers/mmc/host/bcm2835.c
@@ -1064,10 +1064,12 @@ static void bcm2835_dma_complete_work(struct work_struct *work)
 {
 	struct bcm2835_host *host =
 		container_of(work, struct bcm2835_host, dma_work);
-	struct mmc_data *data = host->data;
+	struct mmc_data *data;
 
 	mutex_lock(&host->mutex);
 
+	data = host->data;
+
 	if (host->dma_chan) {
 		dma_unmap_sg(host->dma_chan->device->dev,
 			     data->sg, data->sg_len,
@@ -1192,9 +1194,6 @@ static void bcm2835_request(struct mmc_host *mmc, struct mmc_request *mrq)
 		return;
 	}
 
-	if (host->use_dma && mrq->data && (mrq->data->blocks > PIO_THRESHOLD))
-		bcm2835_prepare_dma(host, mrq->data);
-
 	mutex_lock(&host->mutex);
 
 	WARN_ON(host->mrq);
@@ -1218,6 +1217,9 @@ static void bcm2835_request(struct mmc_host *mmc, struct mmc_request *mrq)
 		return;
 	}
 
+	if (host->use_dma && mrq->data && (mrq->data->blocks > PIO_THRESHOLD))
+		bcm2835_prepare_dma(host, mrq->data);
+
 	host->use_sbc = !!mrq->sbc && host->mrq->data &&
 			(host->mrq->data->flags & MMC_DATA_READ);
 	if (host->use_sbc) {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 5/7] mmc: bcm2835: Terminate timeout work synchronously
  2018-11-11 13:45 ` Stefan Wahren
@ 2018-11-11 13:45     ` Stefan Wahren
  -1 siblings, 0 replies; 16+ messages in thread
From: Stefan Wahren @ 2018-11-11 13:45 UTC (permalink / raw)
  To: Eric Anholt, Florian Fainelli, Ulf Hansson
  Cc: linux-mmc-u79uwXL29TY76Z2rM5mHXA,
	linux-rpi-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Michal Suchanek,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

It's better to make sure that the timeout work is really terminated
before calling mmc_request_done.

Signed-off-by: Stefan Wahren <stefan.wahren-eS4NqCHxEME@public.gmane.org>
---
 drivers/mmc/host/bcm2835.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
index 1c60798..2c7589f 100644
--- a/drivers/mmc/host/bcm2835.c
+++ b/drivers/mmc/host/bcm2835.c
@@ -608,7 +608,7 @@ static void bcm2835_finish_request(struct bcm2835_host *host)
 	struct dma_chan *terminate_chan = NULL;
 	struct mmc_request *mrq;
 
-	cancel_delayed_work(&host->timeout_work);
+	cancel_delayed_work_sync(&host->timeout_work);
 
 	mrq = host->mrq;
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 5/7] mmc: bcm2835: Terminate timeout work synchronously
@ 2018-11-11 13:45     ` Stefan Wahren
  0 siblings, 0 replies; 16+ messages in thread
From: Stefan Wahren @ 2018-11-11 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

It's better to make sure that the timeout work is really terminated
before calling mmc_request_done.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
 drivers/mmc/host/bcm2835.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
index 1c60798..2c7589f 100644
--- a/drivers/mmc/host/bcm2835.c
+++ b/drivers/mmc/host/bcm2835.c
@@ -608,7 +608,7 @@ static void bcm2835_finish_request(struct bcm2835_host *host)
 	struct dma_chan *terminate_chan = NULL;
 	struct mmc_request *mrq;
 
-	cancel_delayed_work(&host->timeout_work);
+	cancel_delayed_work_sync(&host->timeout_work);
 
 	mrq = host->mrq;
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 6/7] mmc: bcm2835: Refactor dma_map_sg handling
  2018-11-11 13:45 ` Stefan Wahren
@ 2018-11-11 13:45   ` Stefan Wahren
  -1 siblings, 0 replies; 16+ messages in thread
From: Stefan Wahren @ 2018-11-11 13:45 UTC (permalink / raw)
  To: Eric Anholt, Florian Fainelli, Ulf Hansson
  Cc: Stefan Wahren, Phil Elwell, linux-mmc, linux-rpi-kernel,
	Michal Suchanek, linux-arm-kernel

There are two variables len within bcm2835_prepare_dma. So rename the result
of dma_map_sg to sg_len. While we are at this add a bail out to simplify the
following change.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
 drivers/mmc/host/bcm2835.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
index 2c7589f..c42bdaa 100644
--- a/drivers/mmc/host/bcm2835.c
+++ b/drivers/mmc/host/bcm2835.c
@@ -464,7 +464,7 @@ static void bcm2835_transfer_pio(struct bcm2835_host *host)
 static
 void bcm2835_prepare_dma(struct bcm2835_host *host, struct mmc_data *data)
 {
-	int len, dir_data, dir_slave;
+	int sg_len, dir_data, dir_slave;
 	struct dma_async_tx_descriptor *desc = NULL;
 	struct dma_chan *dma_chan;
 
@@ -510,15 +510,13 @@ void bcm2835_prepare_dma(struct bcm2835_host *host, struct mmc_data *data)
 				     &host->dma_cfg_rx :
 				     &host->dma_cfg_tx);
 
-	len = dma_map_sg(dma_chan->device->dev, data->sg, data->sg_len,
-			 dir_data);
+	sg_len = dma_map_sg(dma_chan->device->dev, data->sg, data->sg_len,
+			    dir_data);
+	if (!sg_len)
+		return;
 
-	if (len > 0) {
-		desc = dmaengine_prep_slave_sg(dma_chan, data->sg,
-					       len, dir_slave,
-					       DMA_PREP_INTERRUPT |
-					       DMA_CTRL_ACK);
-	}
+	desc = dmaengine_prep_slave_sg(dma_chan, data->sg, sg_len, dir_slave,
+				       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 
 	if (desc) {
 		desc->callback = bcm2835_dma_complete;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 6/7] mmc: bcm2835: Refactor dma_map_sg handling
@ 2018-11-11 13:45   ` Stefan Wahren
  0 siblings, 0 replies; 16+ messages in thread
From: Stefan Wahren @ 2018-11-11 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

There are two variables len within bcm2835_prepare_dma. So rename the result
of dma_map_sg to sg_len. While we are at this add a bail out to simplify the
following change.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
 drivers/mmc/host/bcm2835.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
index 2c7589f..c42bdaa 100644
--- a/drivers/mmc/host/bcm2835.c
+++ b/drivers/mmc/host/bcm2835.c
@@ -464,7 +464,7 @@ static void bcm2835_transfer_pio(struct bcm2835_host *host)
 static
 void bcm2835_prepare_dma(struct bcm2835_host *host, struct mmc_data *data)
 {
-	int len, dir_data, dir_slave;
+	int sg_len, dir_data, dir_slave;
 	struct dma_async_tx_descriptor *desc = NULL;
 	struct dma_chan *dma_chan;
 
@@ -510,15 +510,13 @@ void bcm2835_prepare_dma(struct bcm2835_host *host, struct mmc_data *data)
 				     &host->dma_cfg_rx :
 				     &host->dma_cfg_tx);
 
-	len = dma_map_sg(dma_chan->device->dev, data->sg, data->sg_len,
-			 dir_data);
+	sg_len = dma_map_sg(dma_chan->device->dev, data->sg, data->sg_len,
+			    dir_data);
+	if (!sg_len)
+		return;
 
-	if (len > 0) {
-		desc = dmaengine_prep_slave_sg(dma_chan, data->sg,
-					       len, dir_slave,
-					       DMA_PREP_INTERRUPT |
-					       DMA_CTRL_ACK);
-	}
+	desc = dmaengine_prep_slave_sg(dma_chan, data->sg, sg_len, dir_slave,
+				       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 
 	if (desc) {
 		desc->callback = bcm2835_dma_complete;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 7/7] mmc: bcm2835: Properly handle dmaengine_prep_slave_sg
  2018-11-11 13:45 ` Stefan Wahren
@ 2018-11-11 13:45   ` Stefan Wahren
  -1 siblings, 0 replies; 16+ messages in thread
From: Stefan Wahren @ 2018-11-11 13:45 UTC (permalink / raw)
  To: Eric Anholt, Florian Fainelli, Ulf Hansson
  Cc: Stefan Wahren, Phil Elwell, linux-mmc, linux-rpi-kernel,
	Michal Suchanek, linux-arm-kernel

In case dmaengine_prep_slave_sg fails we need to call dma_unmap_sg.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
 drivers/mmc/host/bcm2835.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
index c42bdaa..82e4b08 100644
--- a/drivers/mmc/host/bcm2835.c
+++ b/drivers/mmc/host/bcm2835.c
@@ -518,13 +518,16 @@ void bcm2835_prepare_dma(struct bcm2835_host *host, struct mmc_data *data)
 	desc = dmaengine_prep_slave_sg(dma_chan, data->sg, sg_len, dir_slave,
 				       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 
-	if (desc) {
-		desc->callback = bcm2835_dma_complete;
-		desc->callback_param = host;
-		host->dma_desc = desc;
-		host->dma_chan = dma_chan;
-		host->dma_dir = dir_data;
+	if (!desc) {
+		dma_unmap_sg(dma_chan->device->dev, data->sg, sg_len, dir_data);
+		return;
 	}
+
+	desc->callback = bcm2835_dma_complete;
+	desc->callback_param = host;
+	host->dma_desc = desc;
+	host->dma_chan = dma_chan;
+	host->dma_dir = dir_data;
 }
 
 static void bcm2835_start_dma(struct bcm2835_host *host)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 7/7] mmc: bcm2835: Properly handle dmaengine_prep_slave_sg
@ 2018-11-11 13:45   ` Stefan Wahren
  0 siblings, 0 replies; 16+ messages in thread
From: Stefan Wahren @ 2018-11-11 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

In case dmaengine_prep_slave_sg fails we need to call dma_unmap_sg.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
 drivers/mmc/host/bcm2835.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
index c42bdaa..82e4b08 100644
--- a/drivers/mmc/host/bcm2835.c
+++ b/drivers/mmc/host/bcm2835.c
@@ -518,13 +518,16 @@ void bcm2835_prepare_dma(struct bcm2835_host *host, struct mmc_data *data)
 	desc = dmaengine_prep_slave_sg(dma_chan, data->sg, sg_len, dir_slave,
 				       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 
-	if (desc) {
-		desc->callback = bcm2835_dma_complete;
-		desc->callback_param = host;
-		host->dma_desc = desc;
-		host->dma_chan = dma_chan;
-		host->dma_dir = dir_data;
+	if (!desc) {
+		dma_unmap_sg(dma_chan->device->dev, data->sg, sg_len, dir_data);
+		return;
 	}
+
+	desc->callback = bcm2835_dma_complete;
+	desc->callback_param = host;
+	host->dma_desc = desc;
+	host->dma_chan = dma_chan;
+	host->dma_dir = dir_data;
 }
 
 static void bcm2835_start_dma(struct bcm2835_host *host)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2018-11-11 13:45 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-11 13:45 [PATCH 0/7] mmc: Several fixes for bcm2835 driver Stefan Wahren
2018-11-11 13:45 ` Stefan Wahren
     [not found] ` <1541943930-23873-1-git-send-email-stefan.wahren-eS4NqCHxEME@public.gmane.org>
2018-11-11 13:45   ` [PATCH 1/7] mmc: bcm2835: reset host on timeout Stefan Wahren
2018-11-11 13:45     ` Stefan Wahren
2018-11-11 13:45   ` [PATCH 5/7] mmc: bcm2835: Terminate timeout work synchronously Stefan Wahren
2018-11-11 13:45     ` Stefan Wahren
2018-11-11 13:45 ` [PATCH 2/7] mmc: bcm2835: Recover from MMC_SEND_EXT_CSD Stefan Wahren
2018-11-11 13:45   ` Stefan Wahren
2018-11-11 13:45 ` [PATCH 3/7] mmc: bcm2835: Release DMA channel on driver unload Stefan Wahren
2018-11-11 13:45   ` Stefan Wahren
2018-11-11 13:45 ` [PATCH 4/7] mmc: bcm2835: Avoid possible races on data requests Stefan Wahren
2018-11-11 13:45   ` Stefan Wahren
2018-11-11 13:45 ` [PATCH 6/7] mmc: bcm2835: Refactor dma_map_sg handling Stefan Wahren
2018-11-11 13:45   ` Stefan Wahren
2018-11-11 13:45 ` [PATCH 7/7] mmc: bcm2835: Properly handle dmaengine_prep_slave_sg Stefan Wahren
2018-11-11 13:45   ` Stefan Wahren

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.