Patch "dmaengine: dw: Select only supported masters for ACPI devices" has been added to the 5.10-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    dmaengine: dw: Select only supported masters for ACPI devices

to the 5.10-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     dmaengine-dw-select-only-supported-masters-for-acpi-.patch
and it can be found in the queue-5.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit bee5b0ce12cf11481d83023cc811691e6bd77f1f
Author: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>
Date:   Mon Nov 4 11:50:50 2024 +0200

    dmaengine: dw: Select only supported masters for ACPI devices
    
    [ Upstream commit f0e870a0e9c5521f2952ea9f3ea9d3d122631a89 ]
    
    The recently submitted fix-commit revealed a problem in the iDMA 32-bit
    platform code. Even though the controller supported only a single master
    the dw_dma_acpi_filter() method hard-coded two master interfaces with IDs
    0 and 1. As a result the sanity check implemented in the commit
    b336268dde75 ("dmaengine: dw: Add peripheral bus width verification")
    got incorrect interface data width and thus prevented the client drivers
    from configuring the DMA-channel with the EINVAL error returned. E.g.,
    the next error was printed for the PXA2xx SPI controller driver trying
    to configure the requested channels:
    
    > [  164.525604] pxa2xx_spi_pci 0000:00:07.1: DMA slave config failed
    > [  164.536105] pxa2xx_spi_pci 0000:00:07.1: failed to get DMA TX descriptor
    > [  164.543213] spidev spi-SPT0001:00: SPI transfer failed: -16
    
    The problem would have been spotted much earlier if the iDMA 32-bit
    controller supported more than one master interfaces. But since it
    supports just a single master and the iDMA 32-bit specific code just
    ignores the master IDs in the CTLLO preparation method, the issue has
    been gone unnoticed so far.
    
    Fix the problem by specifying the default master ID for both memory
    and peripheral devices in the driver data. Thus the issue noticed for
    the iDMA 32-bit controllers will be eliminated and the ACPI-probed
    DW DMA controllers will be configured with the correct master ID by
    default.
    
    Cc: stable@xxxxxxxxxxxxxxx
    Fixes: b336268dde75 ("dmaengine: dw: Add peripheral bus width verification")
    Fixes: 199244d69458 ("dmaengine: dw: add support of iDMA 32-bit hardware")
    Reported-by: Ferry Toth <fntoth@xxxxxxxxx>
    Closes: https://lore.kernel.org/dmaengine/ZuXbCKUs1iOqFu51@xxxxxxxxxxxxxxxxxx/
    Reported-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>
    Closes: https://lore.kernel.org/dmaengine/ZuXgI-VcHpMgbZ91@xxxxxxxxxxxxxxxxxx/
    Tested-by: Ferry Toth <fntoth@xxxxxxxxx>
    Signed-off-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>
    Link: https://lore.kernel.org/r/20241104095142.157925-1-andriy.shevchenko@xxxxxxxxxxxxxxx
    Signed-off-by: Vinod Koul <vkoul@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/dma/dw/acpi.c b/drivers/dma/dw/acpi.c
index c510c109d2c3..b6452fffa657 100644
--- a/drivers/dma/dw/acpi.c
+++ b/drivers/dma/dw/acpi.c
@@ -8,13 +8,15 @@
 
 static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param)
 {
+	struct dw_dma *dw = to_dw_dma(chan->device);
+	struct dw_dma_chip_pdata *data = dev_get_drvdata(dw->dma.dev);
 	struct acpi_dma_spec *dma_spec = param;
 	struct dw_dma_slave slave = {
 		.dma_dev = dma_spec->dev,
 		.src_id = dma_spec->slave_id,
 		.dst_id = dma_spec->slave_id,
-		.m_master = 0,
-		.p_master = 1,
+		.m_master = data->m_master,
+		.p_master = data->p_master,
 	};
 
 	return dw_dma_filter(chan, &slave);
diff --git a/drivers/dma/dw/internal.h b/drivers/dma/dw/internal.h
index 2e1c52eefdeb..8c79a1d015cd 100644
--- a/drivers/dma/dw/internal.h
+++ b/drivers/dma/dw/internal.h
@@ -51,11 +51,15 @@ struct dw_dma_chip_pdata {
 	int (*probe)(struct dw_dma_chip *chip);
 	int (*remove)(struct dw_dma_chip *chip);
 	struct dw_dma_chip *chip;
+	u8 m_master;
+	u8 p_master;
 };
 
 static __maybe_unused const struct dw_dma_chip_pdata dw_dma_chip_pdata = {
 	.probe = dw_dma_probe,
 	.remove = dw_dma_remove,
+	.m_master = 0,
+	.p_master = 1,
 };
 
 static const struct dw_dma_platform_data idma32_pdata = {
@@ -72,6 +76,8 @@ static __maybe_unused const struct dw_dma_chip_pdata idma32_chip_pdata = {
 	.pdata = &idma32_pdata,
 	.probe = idma32_dma_probe,
 	.remove = idma32_dma_remove,
+	.m_master = 0,
+	.p_master = 0,
 };
 
 #endif /* _DMA_DW_INTERNAL_H */
diff --git a/drivers/dma/dw/pci.c b/drivers/dma/dw/pci.c
index 1142aa6f8c4a..47f0bbe8b1fe 100644
--- a/drivers/dma/dw/pci.c
+++ b/drivers/dma/dw/pci.c
@@ -60,10 +60,10 @@ static int dw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
 	if (ret)
 		return ret;
 
-	dw_dma_acpi_controller_register(chip->dw);
-
 	pci_set_drvdata(pdev, data);
 
+	dw_dma_acpi_controller_register(chip->dw);
+
 	return 0;
 }
 




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux