Tegra186 does not support pausing a channel, but the driver installs device_pause and device_resume for every variant. Both callbacks return -ENOSYS on Tegra186. dma_get_slave_caps() derives cmd_pause and cmd_resume from the presence of these callbacks. Clients such as generic 8250 therefore accept RX DMA channels that cannot satisfy their pause requirement. A receive timeout then reaches an unsupported pause operation instead of being excluded when the channel capabilities are checked. Only install the pause and resume callbacks when the matched chip data advertises hardware support. Keep them available on Tegra194 and later, and remove their now-redundant checks for unsupported hardware. Fixes: ee17028009d4 ("dmaengine: tegra: Add tegra gpcdma driver") Cc: stable@vger.kernel.org Signed-off-by: James Hilliard --- Changes in v2: - Remove the capability checks from the pause and resume callbacks now that they are registered only on hardware that supports them. - Link to v1: https://patch.msgid.link/20261108-submit-tegra186-dma-pause-caps-v1-v1-1-9cc9b17a033d@gmail.com To: Laxman Dewangan To: Jon Hunter To: Vinod Koul To: Frank Li To: Thierry Reding To: Akhil R To: Pavan Kunapuli To: Dmitry Osipenko Cc: Thierry Reding Cc: dmaengine@vger.kernel.org Cc: linux-tegra@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/dma/tegra186-gpc-dma.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/dma/tegra186-gpc-dma.c b/drivers/dma/tegra186-gpc-dma.c index e76c58f213d8..bd606b71e714 100644 --- a/drivers/dma/tegra186-gpc-dma.c +++ b/drivers/dma/tegra186-gpc-dma.c @@ -419,9 +419,6 @@ static int tegra_dma_device_pause(struct dma_chan *dc) unsigned long flags; int ret; - if (!tdc->tdma->chip_data->hw_support_pause) - return -ENOSYS; - spin_lock_irqsave(&tdc->vc.lock, flags); ret = tegra_dma_pause(tdc); spin_unlock_irqrestore(&tdc->vc.lock, flags); @@ -445,9 +442,6 @@ static int tegra_dma_device_resume(struct dma_chan *dc) struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); unsigned long flags; - if (!tdc->tdma->chip_data->hw_support_pause) - return -ENOSYS; - spin_lock_irqsave(&tdc->vc.lock, flags); tegra_dma_resume(tdc); spin_unlock_irqrestore(&tdc->vc.lock, flags); @@ -1518,8 +1512,10 @@ static int tegra_dma_probe(struct platform_device *pdev) tdma->dma_dev.device_terminate_all = tegra_dma_terminate_all; tdma->dma_dev.device_tx_status = tegra_dma_tx_status; tdma->dma_dev.device_issue_pending = tegra_dma_issue_pending; - tdma->dma_dev.device_pause = tegra_dma_device_pause; - tdma->dma_dev.device_resume = tegra_dma_device_resume; + if (cdata->hw_support_pause) { + tdma->dma_dev.device_pause = tegra_dma_device_pause; + tdma->dma_dev.device_resume = tegra_dma_device_resume; + } tdma->dma_dev.device_synchronize = tegra_dma_chan_synchronize; tdma->dma_dev.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; --- base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4 change-id: 20261108-submit-tegra186-dma-pause-caps-v1-664d1320d502 Best regards, -- James Hilliard