summaryrefslogtreecommitdiff
path: root/drivers/spi/spi.c
diff options
context:
space:
mode:
authorSuper Liu <supercjliu@google.com>2019-05-22 09:30:14 +0300
committerMark Brown <broonie@kernel.org>2019-05-23 16:36:13 +0300
commitf3440d9a0da292dc4998d9393162fcfb996fd671 (patch)
tree0803d108bc69d81b4c68871af9dd23e7d39f9aa0 /drivers/spi/spi.c
parent44a042182cb1e9f7916e015c836967bf638b33c4 (diff)
downloadlinux-f3440d9a0da292dc4998d9393162fcfb996fd671.tar.xz
spi: abort spi_sync if failed to prepare_transfer_hardware
There is no chance to wait spi message complete if failed to prepare_transfer_hardware(). Therefore, finalize this message and abort transfer with corresponding return status to release this block case. Logs: [17400.283005] c7 3267 PM: PM: suspend entry 2019-05-04 03:01:14.403097147 UTC [17400.283013] c7 3267 PM: suspend entry (deep) [17400.283016] c6 3267 PM: Syncing filesystems ... done. [17400.584395] c1 753 spi_geni 890000.spi: spi_geni_prepare_transfer_hardware:Error enabling SE resources -13 [17400.584404] c1 753 spi_master spi1: failed to prepare transfer hardware [17400.664611] c4 3267 PM: PM: suspend exit 2019-05-04 03:01:15.235273018 UTC Flow: __spi_sync@spi.c | if (status == 0) { | /* Push out the messages in the calling context if we | * can. | */ | if (ctlr->transfer == spi_queued_transfer) { | SPI_STATISTICS_INCREMENT_FIELD(&ctlr->statistics, | spi_sync_immediate); | SPI_STATISTICS_INCREMENT_FIELD(&spi->statistics, | spi_sync_immediate); | __spi_pump_messages(ctlr, false); | } | | wait_for_completion(&done); <== stuck here!!! | status = message->status; | } | message->context = NULL; | return status; | --> __spi_pump_messages@spi.c | if (!was_busy && ctlr->prepare_transfer_hardware) { | ret = ctlr->prepare_transfer_hardware(ctlr); | if (ret) { | dev_err(&ctlr->dev, | "failed to prepare transfer hardware\n"); | | if (ctlr->auto_runtime_pm) | pm_runtime_put(ctlr->dev.parent); | mutex_unlock(&ctlr->io_mutex); | return; | } | } | --> spi_geni_prepare_transfer_hardware@spi-geni-qcom.c | ret = pm_runtime_get_sync(mas->dev); | if (ret < 0) { | dev_err(mas->dev, | "%s:Error enabling SE resources %d\n", | __func__, ret); | pm_runtime_put_noidle(mas->dev); | goto exit_prepare_transfer_hardware; Signed-off-by: Super Liu <supercjliu@google.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi/spi.c')
-rw-r--r--drivers/spi/spi.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 8eb7460dd744..5e4654032bfa 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1307,10 +1307,15 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread)
ret = ctlr->prepare_transfer_hardware(ctlr);
if (ret) {
dev_err(&ctlr->dev,
- "failed to prepare transfer hardware\n");
+ "failed to prepare transfer hardware: %d\n",
+ ret);
if (ctlr->auto_runtime_pm)
pm_runtime_put(ctlr->dev.parent);
+
+ ctlr->cur_msg->status = ret;
+ spi_finalize_current_message(ctlr);
+
mutex_unlock(&ctlr->io_mutex);
return;
}