diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-06 13:06:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-06 13:06:37 -0400 |
commit | 2692982b0800c6f6446e9edd4743239666e69f2e (patch) | |
tree | 28b683f9276f13c2612068f812dd9027a96f6ae8 | |
parent | 4f8b49092c37cf0c87c43bb2698d43c71cf0e4e5 (diff) | |
parent | f6034225442c4a87906d36e975fd9e99a8f95487 (diff) |
Merge tag 'dmaengine-fix-5.2' of git://git.infradead.org/users/vkoul/slave-dma
Pull dmaengine fixes from Vinod Koul:
- bam_dma fix for completed descriptor count
- fix for imx-sdma remove BD_INTR for channel0 and use-after-free on
probe error path
- endian bug fix in jz4780 IRQ handler
* tag 'dmaengine-fix-5.2' of git://git.infradead.org/users/vkoul/slave-dma:
dmaengine: qcom: bam_dma: Fix completed descriptors count
dmaengine: imx-sdma: remove BD_INTR for channel0
dmaengine: imx-sdma: fix use-after-free on probe error path
dmaengine: jz4780: Fix an endian bug in IRQ handler
-rw-r--r-- | drivers/dma/dma-jz4780.c | 5 | ||||
-rw-r--r-- | drivers/dma/imx-sdma.c | 52 | ||||
-rw-r--r-- | drivers/dma/qcom/bam_dma.c | 3 |
3 files changed, 35 insertions, 25 deletions
diff --git a/drivers/dma/dma-jz4780.c b/drivers/dma/dma-jz4780.c index 263bee76ef0d..6b8c4c458e8a 100644 --- a/drivers/dma/dma-jz4780.c +++ b/drivers/dma/dma-jz4780.c | |||
@@ -718,12 +718,13 @@ static irqreturn_t jz4780_dma_irq_handler(int irq, void *data) | |||
718 | { | 718 | { |
719 | struct jz4780_dma_dev *jzdma = data; | 719 | struct jz4780_dma_dev *jzdma = data; |
720 | unsigned int nb_channels = jzdma->soc_data->nb_channels; | 720 | unsigned int nb_channels = jzdma->soc_data->nb_channels; |
721 | uint32_t pending, dmac; | 721 | unsigned long pending; |
722 | uint32_t dmac; | ||
722 | int i; | 723 | int i; |
723 | 724 | ||
724 | pending = jz4780_dma_ctrl_readl(jzdma, JZ_DMA_REG_DIRQP); | 725 | pending = jz4780_dma_ctrl_readl(jzdma, JZ_DMA_REG_DIRQP); |
725 | 726 | ||
726 | for_each_set_bit(i, (unsigned long *)&pending, nb_channels) { | 727 | for_each_set_bit(i, &pending, nb_channels) { |
727 | if (jz4780_dma_chan_irq(jzdma, &jzdma->chan[i])) | 728 | if (jz4780_dma_chan_irq(jzdma, &jzdma->chan[i])) |
728 | pending &= ~BIT(i); | 729 | pending &= ~BIT(i); |
729 | } | 730 | } |
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 99d9f431ae2c..4ec84a633bd3 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c | |||
@@ -703,7 +703,7 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size, | |||
703 | spin_lock_irqsave(&sdma->channel_0_lock, flags); | 703 | spin_lock_irqsave(&sdma->channel_0_lock, flags); |
704 | 704 | ||
705 | bd0->mode.command = C0_SETPM; | 705 | bd0->mode.command = C0_SETPM; |
706 | bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD; | 706 | bd0->mode.status = BD_DONE | BD_WRAP | BD_EXTD; |
707 | bd0->mode.count = size / 2; | 707 | bd0->mode.count = size / 2; |
708 | bd0->buffer_addr = buf_phys; | 708 | bd0->buffer_addr = buf_phys; |
709 | bd0->ext_buffer_addr = address; | 709 | bd0->ext_buffer_addr = address; |
@@ -1025,7 +1025,7 @@ static int sdma_load_context(struct sdma_channel *sdmac) | |||
1025 | context->gReg[7] = sdmac->watermark_level; | 1025 | context->gReg[7] = sdmac->watermark_level; |
1026 | 1026 | ||
1027 | bd0->mode.command = C0_SETDM; | 1027 | bd0->mode.command = C0_SETDM; |
1028 | bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD; | 1028 | bd0->mode.status = BD_DONE | BD_WRAP | BD_EXTD; |
1029 | bd0->mode.count = sizeof(*context) / 4; | 1029 | bd0->mode.count = sizeof(*context) / 4; |
1030 | bd0->buffer_addr = sdma->context_phys; | 1030 | bd0->buffer_addr = sdma->context_phys; |
1031 | bd0->ext_buffer_addr = 2048 + (sizeof(*context) / 4) * channel; | 1031 | bd0->ext_buffer_addr = 2048 + (sizeof(*context) / 4) * channel; |
@@ -2096,27 +2096,6 @@ static int sdma_probe(struct platform_device *pdev) | |||
2096 | if (pdata && pdata->script_addrs) | 2096 | if (pdata && pdata->script_addrs) |
2097 | sdma_add_scripts(sdma, pdata->script_addrs); | 2097 | sdma_add_scripts(sdma, pdata->script_addrs); |
2098 | 2098 | ||
2099 | if (pdata) { | ||
2100 | ret = sdma_get_firmware(sdma, pdata->fw_name); | ||
2101 | if (ret) | ||
2102 | dev_warn(&pdev->dev, "failed to get firmware from platform data\n"); | ||
2103 | } else { | ||
2104 | /* | ||
2105 | * Because that device tree does not encode ROM script address, | ||
2106 | * the RAM script in firmware is mandatory for device tree | ||
2107 | * probe, otherwise it fails. | ||
2108 | */ | ||
2109 | ret = of_property_read_string(np, "fsl,sdma-ram-script-name", | ||
2110 | &fw_name); | ||
2111 | if (ret) | ||
2112 | dev_warn(&pdev->dev, "failed to get firmware name\n"); | ||
2113 | else { | ||
2114 | ret = sdma_get_firmware(sdma, fw_name); | ||
2115 | if (ret) | ||
2116 | dev_warn(&pdev->dev, "failed to get firmware from device tree\n"); | ||
2117 | } | ||
2118 | } | ||
2119 | |||
2120 | sdma->dma_device.dev = &pdev->dev; | 2099 | sdma->dma_device.dev = &pdev->dev; |
2121 | 2100 | ||
2122 | sdma->dma_device.device_alloc_chan_resources = sdma_alloc_chan_resources; | 2101 | sdma->dma_device.device_alloc_chan_resources = sdma_alloc_chan_resources; |
@@ -2161,6 +2140,33 @@ static int sdma_probe(struct platform_device *pdev) | |||
2161 | of_node_put(spba_bus); | 2140 | of_node_put(spba_bus); |
2162 | } | 2141 | } |
2163 | 2142 | ||
2143 | /* | ||
2144 | * Kick off firmware loading as the very last step: | ||
2145 | * attempt to load firmware only if we're not on the error path, because | ||
2146 | * the firmware callback requires a fully functional and allocated sdma | ||
2147 | * instance. | ||
2148 | */ | ||
2149 | if (pdata) { | ||
2150 | ret = sdma_get_firmware(sdma, pdata->fw_name); | ||
2151 | if (ret) | ||
2152 | dev_warn(&pdev->dev, "failed to get firmware from platform data\n"); | ||
2153 | } else { | ||
2154 | /* | ||
2155 | * Because that device tree does not encode ROM script address, | ||
2156 | * the RAM script in firmware is mandatory for device tree | ||
2157 | * probe, otherwise it fails. | ||
2158 | */ | ||
2159 | ret = of_property_read_string(np, "fsl,sdma-ram-script-name", | ||
2160 | &fw_name); | ||
2161 | if (ret) { | ||
2162 | dev_warn(&pdev->dev, "failed to get firmware name\n"); | ||
2163 | } else { | ||
2164 | ret = sdma_get_firmware(sdma, fw_name); | ||
2165 | if (ret) | ||
2166 | dev_warn(&pdev->dev, "failed to get firmware from device tree\n"); | ||
2167 | } | ||
2168 | } | ||
2169 | |||
2164 | return 0; | 2170 | return 0; |
2165 | 2171 | ||
2166 | err_register: | 2172 | err_register: |
diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c index 4b43844f6af5..8e90a405939d 100644 --- a/drivers/dma/qcom/bam_dma.c +++ b/drivers/dma/qcom/bam_dma.c | |||
@@ -799,6 +799,9 @@ static u32 process_channel_irqs(struct bam_device *bdev) | |||
799 | /* Number of bytes available to read */ | 799 | /* Number of bytes available to read */ |
800 | avail = CIRC_CNT(offset, bchan->head, MAX_DESCRIPTORS + 1); | 800 | avail = CIRC_CNT(offset, bchan->head, MAX_DESCRIPTORS + 1); |
801 | 801 | ||
802 | if (offset < bchan->head) | ||
803 | avail--; | ||
804 | |||
802 | list_for_each_entry_safe(async_desc, tmp, | 805 | list_for_each_entry_safe(async_desc, tmp, |
803 | &bchan->desc_list, desc_node) { | 806 | &bchan->desc_list, desc_node) { |
804 | /* Not enough data to read */ | 807 | /* Not enough data to read */ |