From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Vignesh Raghavendra <vigneshr@ti.com>,
Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>,
linux-spi@vger.kernel.org
Subject: [PATCH AUTOSEL 5.5 02/41] spi: spi-omap2-mcspi: Support probe deferral for DMA channels
Date: Sun, 15 Mar 2020 22:32:40 -0400 [thread overview]
Message-ID: <20200316023319.749-2-sashal@kernel.org> (raw)
In-Reply-To: <20200316023319.749-1-sashal@kernel.org>
From: Vignesh Raghavendra <vigneshr@ti.com>
[ Upstream commit 32f2fc5dc3992b4b60cc6b1a6a31be605cc9c3a2 ]
dma_request_channel() can return -EPROBE_DEFER, if DMA driver is not
ready. Currently driver just falls back to PIO mode on probe deferral.
Fix this by requesting all required channels during probe and
propagating EPROBE_DEFER error code.
Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
Link: https://lore.kernel.org/r/20200204124816.16735-3-vigneshr@ti.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/spi-omap2-mcspi.c | 77 +++++++++++++++++------------------
1 file changed, 38 insertions(+), 39 deletions(-)
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index e9bc9cf984d60..e9e256718ef4a 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -975,20 +975,12 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
* 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)
+static int omap2_mcspi_request_dma(struct omap2_mcspi *mcspi,
+ struct omap2_mcspi_dma *mcspi_dma)
{
- struct spi_master *master = spi->master;
- struct omap2_mcspi *mcspi;
- struct omap2_mcspi_dma *mcspi_dma;
int ret = 0;
- mcspi = spi_master_get_devdata(master);
- mcspi_dma = mcspi->dma_channels + spi->chip_select;
-
- init_completion(&mcspi_dma->dma_rx_completion);
- init_completion(&mcspi_dma->dma_tx_completion);
-
- mcspi_dma->dma_rx = dma_request_chan(&master->dev,
+ mcspi_dma->dma_rx = dma_request_chan(mcspi->dev,
mcspi_dma->dma_rx_ch_name);
if (IS_ERR(mcspi_dma->dma_rx)) {
ret = PTR_ERR(mcspi_dma->dma_rx);
@@ -996,7 +988,7 @@ static int omap2_mcspi_request_dma(struct spi_device *spi)
goto no_dma;
}
- mcspi_dma->dma_tx = dma_request_chan(&master->dev,
+ mcspi_dma->dma_tx = dma_request_chan(mcspi->dev,
mcspi_dma->dma_tx_ch_name);
if (IS_ERR(mcspi_dma->dma_tx)) {
ret = PTR_ERR(mcspi_dma->dma_tx);
@@ -1005,20 +997,40 @@ static int omap2_mcspi_request_dma(struct spi_device *spi)
mcspi_dma->dma_rx = NULL;
}
+ init_completion(&mcspi_dma->dma_rx_completion);
+ init_completion(&mcspi_dma->dma_tx_completion);
+
no_dma:
return ret;
}
+static void omap2_mcspi_release_dma(struct spi_master *master)
+{
+ struct omap2_mcspi *mcspi = spi_master_get_devdata(master);
+ struct omap2_mcspi_dma *mcspi_dma;
+ int i;
+
+ for (i = 0; i < master->num_chipselect; i++) {
+ mcspi_dma = &mcspi->dma_channels[i];
+
+ if (mcspi_dma->dma_rx) {
+ dma_release_channel(mcspi_dma->dma_rx);
+ mcspi_dma->dma_rx = NULL;
+ }
+ if (mcspi_dma->dma_tx) {
+ dma_release_channel(mcspi_dma->dma_tx);
+ mcspi_dma->dma_tx = NULL;
+ }
+ }
+}
+
static int omap2_mcspi_setup(struct spi_device *spi)
{
int ret;
struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master);
struct omap2_mcspi_regs *ctx = &mcspi->ctx;
- struct omap2_mcspi_dma *mcspi_dma;
struct omap2_mcspi_cs *cs = spi->controller_state;
- mcspi_dma = &mcspi->dma_channels[spi->chip_select];
-
if (!cs) {
cs = kzalloc(sizeof *cs, GFP_KERNEL);
if (!cs)
@@ -1043,13 +1055,6 @@ 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)
- dev_warn(&spi->dev, "not using DMA for McSPI (%d)\n",
- ret);
- }
-
ret = pm_runtime_get_sync(mcspi->dev);
if (ret < 0) {
pm_runtime_put_noidle(mcspi->dev);
@@ -1066,12 +1071,8 @@ static int omap2_mcspi_setup(struct spi_device *spi)
static void omap2_mcspi_cleanup(struct spi_device *spi)
{
- struct omap2_mcspi *mcspi;
- struct omap2_mcspi_dma *mcspi_dma;
struct omap2_mcspi_cs *cs;
- mcspi = spi_master_get_devdata(spi->master);
-
if (spi->controller_state) {
/* Unlink controller state from context save list */
cs = spi->controller_state;
@@ -1080,19 +1081,6 @@ static void omap2_mcspi_cleanup(struct spi_device *spi)
kfree(cs);
}
- if (spi->chip_select < spi->master->num_chipselect) {
- mcspi_dma = &mcspi->dma_channels[spi->chip_select];
-
- if (mcspi_dma->dma_rx) {
- dma_release_channel(mcspi_dma->dma_rx);
- mcspi_dma->dma_rx = NULL;
- }
- if (mcspi_dma->dma_tx) {
- dma_release_channel(mcspi_dma->dma_tx);
- mcspi_dma->dma_tx = NULL;
- }
- }
-
if (gpio_is_valid(spi->cs_gpio))
gpio_free(spi->cs_gpio);
}
@@ -1303,6 +1291,9 @@ static bool omap2_mcspi_can_dma(struct spi_master *master,
if (spi_controller_is_slave(master))
return true;
+ master->dma_rx = mcspi_dma->dma_rx;
+ master->dma_tx = mcspi_dma->dma_tx;
+
return (xfer->len >= DMA_MIN_BYTES);
}
@@ -1490,6 +1481,11 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
for (i = 0; i < master->num_chipselect; i++) {
sprintf(mcspi->dma_channels[i].dma_rx_ch_name, "rx%d", i);
sprintf(mcspi->dma_channels[i].dma_tx_ch_name, "tx%d", i);
+
+ status = omap2_mcspi_request_dma(mcspi,
+ &mcspi->dma_channels[i]);
+ if (status == -EPROBE_DEFER)
+ goto free_master;
}
status = platform_get_irq(pdev, 0);
@@ -1527,6 +1523,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
free_master:
+ omap2_mcspi_release_dma(master);
spi_master_put(master);
return status;
}
@@ -1536,6 +1533,8 @@ static int omap2_mcspi_remove(struct platform_device *pdev)
struct spi_master *master = platform_get_drvdata(pdev);
struct omap2_mcspi *mcspi = spi_master_get_devdata(master);
+ omap2_mcspi_release_dma(master);
+
pm_runtime_dont_use_autosuspend(mcspi->dev);
pm_runtime_put_sync(mcspi->dev);
pm_runtime_disable(&pdev->dev);
--
2.20.1
next prev parent reply other threads:[~2020-03-16 2:33 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-16 2:32 [PATCH AUTOSEL 5.5 01/41] spi: spi-omap2-mcspi: Handle DMA size restriction on AM65x Sasha Levin
2020-03-16 2:32 ` Sasha Levin [this message]
2020-03-16 2:32 ` [PATCH AUTOSEL 5.5 03/41] drm/mediatek: Find the cursor plane instead of hard coding it Sasha Levin
2020-03-16 2:32 ` [PATCH AUTOSEL 5.5 04/41] drm/mediatek: Ensure the cursor plane is on top of other overlays Sasha Levin
2020-03-16 2:32 ` [PATCH AUTOSEL 5.5 05/41] ARM: dts: imx6dl-colibri-eval-v3: fix sram compatible properties Sasha Levin
2020-03-16 7:21 ` Johan Hovold
2020-03-22 12:54 ` Sasha Levin
2020-03-16 2:32 ` [PATCH AUTOSEL 5.5 06/41] phy: ti: gmii-sel: fix set of copy-paste errors Sasha Levin
2020-03-16 2:32 ` [PATCH AUTOSEL 5.5 07/41] phy: ti: gmii-sel: do not fail in case of gmii Sasha Levin
2020-03-16 2:32 ` [PATCH AUTOSEL 5.5 08/41] ARM: dts: dra7-l4: mark timer13-16 as pwm capable Sasha Levin
2020-03-16 2:32 ` [PATCH AUTOSEL 5.5 09/41] ASoC: meson: g12a: add tohdmitx reset Sasha Levin
2020-03-16 2:32 ` [PATCH AUTOSEL 5.5 10/41] spi: qup: call spi_qup_pm_resume_runtime before suspending Sasha Levin
2020-03-16 2:32 ` [PATCH AUTOSEL 5.5 11/41] powerpc: Include .BTF section Sasha Levin
2020-03-16 2:32 ` [PATCH AUTOSEL 5.5 12/41] cifs: fix potential mismatch of UNC paths Sasha Levin
2020-03-16 2:32 ` [PATCH AUTOSEL 5.5 13/41] cifs: add missing mount option to /proc/mounts Sasha Levin
2020-03-16 2:32 ` [PATCH AUTOSEL 5.5 14/41] ARM: dts: dra7: Add "dma-ranges" property to PCIe RC DT nodes Sasha Levin
2020-03-16 2:32 ` [PATCH AUTOSEL 5.5 15/41] spi: pxa2xx: Add CS control clock quirk Sasha Levin
2020-03-16 2:32 ` [PATCH AUTOSEL 5.5 16/41] spi/zynqmp: remove entry that causes a cs glitch Sasha Levin
2020-03-16 2:32 ` [PATCH AUTOSEL 5.5 17/41] ARM: dts: bcm283x: Add missing properties to the PWR LED Sasha Levin
2020-03-16 2:32 ` [PATCH AUTOSEL 5.5 18/41] drm/exynos: dsi: propagate error value and silence meaningless warning Sasha Levin
2020-03-16 2:32 ` [PATCH AUTOSEL 5.5 19/41] drm/exynos: dsi: fix workaround for the legacy clock name Sasha Levin
2020-03-16 2:32 ` [PATCH AUTOSEL 5.5 20/41] drm/exynos: hdmi: don't leak enable HDMI_EN regulator if probe fails Sasha Levin
2020-03-16 2:32 ` [PATCH AUTOSEL 5.5 21/41] drivers/perf: fsl_imx8_ddr: Correct the CLEAR bit definition Sasha Levin
2020-03-16 2:33 ` [PATCH AUTOSEL 5.5 22/41] drivers/perf: arm_pmu_acpi: Fix incorrect checking of gicc pointer Sasha Levin
2020-03-16 2:33 ` [PATCH AUTOSEL 5.5 23/41] io-wq: fix IO_WQ_WORK_NO_CANCEL cancellation Sasha Levin
2020-03-16 2:33 ` [PATCH AUTOSEL 5.5 24/41] ARM: bcm2835_defconfig: Explicitly restore CONFIG_DEBUG_FS Sasha Levin
2020-03-16 2:33 ` [PATCH AUTOSEL 5.5 25/41] altera-stapl: altera_get_note: prevent write beyond end of 'key' Sasha Levin
2020-03-16 2:33 ` [PATCH AUTOSEL 5.5 26/41] dm bio record: save/restore bi_end_io and bi_integrity Sasha Levin
2020-03-16 2:33 ` [PATCH AUTOSEL 5.5 27/41] dm integrity: use dm_bio_record and dm_bio_restore Sasha Levin
2020-03-16 2:33 ` [PATCH AUTOSEL 5.5 28/41] riscv: avoid the PIC offset of static percpu data in module beyond 2G limits Sasha Levin
2020-03-16 2:33 ` [PATCH AUTOSEL 5.5 29/41] ASoC: stm32: sai: manage rebind issue Sasha Levin
2020-03-16 2:33 ` [PATCH AUTOSEL 5.5 30/41] spi: spi_register_controller(): free bus id on error paths Sasha Levin
2020-03-16 2:33 ` [PATCH AUTOSEL 5.5 31/41] riscv: Force flat memory model with no-mmu Sasha Levin
2020-03-16 2:33 ` [PATCH AUTOSEL 5.5 32/41] riscv: Fix range looking for kernel image memblock Sasha Levin
2020-03-16 2:33 ` [PATCH AUTOSEL 5.5 33/41] drm/amdgpu: clean wptr on wb when gpu recovery Sasha Levin
2020-03-16 2:33 ` [PATCH AUTOSEL 5.5 34/41] drm/amd/display: Clear link settings on MST disable connector Sasha Levin
2020-03-16 2:33 ` [PATCH AUTOSEL 5.5 35/41] drm/amd/display: fix dcc swath size calculations on dcn1 Sasha Levin
2020-03-16 2:33 ` [PATCH AUTOSEL 5.5 36/41] xenbus: req->body should be updated before req->state Sasha Levin
2020-03-16 2:33 ` [PATCH AUTOSEL 5.5 37/41] xenbus: req->err " Sasha Levin
2020-03-16 2:33 ` [PATCH AUTOSEL 5.5 38/41] riscv: fix seccomp reject syscall code path Sasha Levin
2020-03-16 2:33 ` [PATCH AUTOSEL 5.5 39/41] block, bfq: fix overwrite of bfq_group pointer in bfq_find_set_group() Sasha Levin
2020-03-16 2:33 ` [PATCH AUTOSEL 5.5 40/41] parse-maintainers: Mark as executable Sasha Levin
2020-03-16 2:33 ` [PATCH AUTOSEL 5.5 41/41] io_uring: fix lockup with timeouts Sasha Levin
2020-03-16 11:50 ` [PATCH AUTOSEL 5.5 01/41] spi: spi-omap2-mcspi: Handle DMA size restriction on AM65x Mark Brown
2020-03-22 19:37 ` Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200316023319.749-2-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=broonie@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-spi@vger.kernel.org \
--cc=stable@vger.kernel.org \
--cc=vigneshr@ti.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).