| From 4bbecc0ae5e66649d986459f984ccc748500282a Mon Sep 17 00:00:00 2001 |
| From: George Hilliard <thirtythreeforty@gmail.com> |
| Date: Tue, 26 Mar 2019 19:50:57 -0600 |
| Subject: staging: mt7621-mmc: Initialize completions a single time during |
| probe |
| |
| [ Upstream commit 7ca8c2c8bbeda2a2a2a9898cd35066bc1dc83836 ] |
| |
| The module was initializing completions whenever it was going to wait on |
| them, and not when the completion was allocated. This is incorrect |
| according to the completion docs: |
| |
| Calling init_completion() on the same completion object twice is |
| most likely a bug [...] |
| |
| Re-initialization is also unnecessary because the module never uses |
| complete_all(). Fix this by only ever initializing the completion a |
| single time, and log if the completions are not consumed as intended |
| (this is not a fatal problem, but should not go unnoticed). |
| |
| Signed-off-by: George Hilliard <thirtythreeforty@gmail.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/staging/mt7621-mmc/sd.c | 18 ++++++++++++++---- |
| 1 file changed, 14 insertions(+), 4 deletions(-) |
| |
| diff --git a/drivers/staging/mt7621-mmc/sd.c b/drivers/staging/mt7621-mmc/sd.c |
| index 4b26ec896a96f..74f0e57ad2f15 100644 |
| --- a/drivers/staging/mt7621-mmc/sd.c |
| +++ b/drivers/staging/mt7621-mmc/sd.c |
| @@ -468,7 +468,11 @@ static unsigned int msdc_command_start(struct msdc_host *host, |
| host->cmd = cmd; |
| host->cmd_rsp = resp; |
| |
| - init_completion(&host->cmd_done); |
| + // The completion should have been consumed by the previous command |
| + // response handler, because the mmc requests should be serialized |
| + if (completion_done(&host->cmd_done)) |
| + dev_err(mmc_dev(host->mmc), |
| + "previous command was not handled\n"); |
| |
| sdr_set_bits(host->base + MSDC_INTEN, wints); |
| sdc_send_cmd(rawcmd, cmd->arg); |
| @@ -490,7 +494,6 @@ static unsigned int msdc_command_resp(struct msdc_host *host, |
| MSDC_INT_ACMD19_DONE; |
| |
| BUG_ON(in_interrupt()); |
| - //init_completion(&host->cmd_done); |
| //sdr_set_bits(host->base + MSDC_INTEN, wints); |
| |
| spin_unlock(&host->lock); |
| @@ -674,7 +677,13 @@ static int msdc_do_request(struct mmc_host *mmc, struct mmc_request *mrq) |
| //msdc_clr_fifo(host); /* no need */ |
| |
| msdc_dma_on(); /* enable DMA mode first!! */ |
| - init_completion(&host->xfer_done); |
| + |
| + // The completion should have been consumed by the previous |
| + // xfer response handler, because the mmc requests should be |
| + // serialized |
| + if (completion_done(&host->cmd_done)) |
| + dev_err(mmc_dev(host->mmc), |
| + "previous transfer was not handled\n"); |
| |
| /* start the command first*/ |
| if (msdc_command_start(host, cmd, CMD_TIMEOUT) != 0) |
| @@ -693,7 +702,6 @@ static int msdc_do_request(struct mmc_host *mmc, struct mmc_request *mrq) |
| /* for read, the data coming too fast, then CRC error |
| * start DMA no business with CRC. |
| */ |
| - //init_completion(&host->xfer_done); |
| msdc_dma_start(host); |
| |
| spin_unlock(&host->lock); |
| @@ -1688,6 +1696,8 @@ static int msdc_drv_probe(struct platform_device *pdev) |
| } |
| msdc_init_gpd_bd(host, &host->dma); |
| |
| + init_completion(&host->cmd_done); |
| + init_completion(&host->xfer_done); |
| INIT_DELAYED_WORK(&host->card_delaywork, msdc_tasklet_card); |
| spin_lock_init(&host->lock); |
| msdc_init_hw(host); |
| -- |
| 2.20.1 |
| |