dmaengine: altera-msgdma: make response port optional
The response slave port can be disabled in some configuration [1] and csr + MSGDMA_CSR_RESP_FILL_LEVEL will be 0 even if transfer has suceeded. We have to only rely on the interrupts in that scenario. This was tested on cyclone V with the controller resp port disabled. [1] https://www.intel.com/content/www/us/en/programmable/documentation/sfo1400787952932.html 30.3.1.2 30.3.1.3 30.5.5 Fixes: https://forum.rocketboards.org/t/ip-msgdma-linux-driver/1919 Signed-off-by: Olivier Dautricourt <olivier.dautricourt@orolia.com> Reviewed-by: Stefan Roese <sr@denx.de> Link: https://lore.kernel.org/r/8220756f2191ca08cb21702252d1f2d4f753a7f5.1623898678.git.olivier.dautricourt@orolia.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
committed by
Vinod Koul
parent
4aece33cac
commit
af2eec7502
@@ -691,10 +691,14 @@ static void msgdma_tasklet(struct tasklet_struct *t)
|
|||||||
|
|
||||||
spin_lock_irqsave(&mdev->lock, flags);
|
spin_lock_irqsave(&mdev->lock, flags);
|
||||||
|
|
||||||
/* Read number of responses that are available */
|
if (mdev->resp) {
|
||||||
count = ioread32(mdev->csr + MSGDMA_CSR_RESP_FILL_LEVEL);
|
/* Read number of responses that are available */
|
||||||
dev_dbg(mdev->dev, "%s (%d): response count=%d\n",
|
count = ioread32(mdev->csr + MSGDMA_CSR_RESP_FILL_LEVEL);
|
||||||
__func__, __LINE__, count);
|
dev_dbg(mdev->dev, "%s (%d): response count=%d\n",
|
||||||
|
__func__, __LINE__, count);
|
||||||
|
} else {
|
||||||
|
count = 1;
|
||||||
|
}
|
||||||
|
|
||||||
while (count--) {
|
while (count--) {
|
||||||
/*
|
/*
|
||||||
@@ -703,8 +707,12 @@ static void msgdma_tasklet(struct tasklet_struct *t)
|
|||||||
* have any real values, like transferred bytes or error
|
* have any real values, like transferred bytes or error
|
||||||
* bits. So we need to just drop these values.
|
* bits. So we need to just drop these values.
|
||||||
*/
|
*/
|
||||||
size = ioread32(mdev->resp + MSGDMA_RESP_BYTES_TRANSFERRED);
|
if (mdev->resp) {
|
||||||
status = ioread32(mdev->resp + MSGDMA_RESP_STATUS);
|
size = ioread32(mdev->resp +
|
||||||
|
MSGDMA_RESP_BYTES_TRANSFERRED);
|
||||||
|
status = ioread32(mdev->resp +
|
||||||
|
MSGDMA_RESP_STATUS);
|
||||||
|
}
|
||||||
|
|
||||||
msgdma_complete_descriptor(mdev);
|
msgdma_complete_descriptor(mdev);
|
||||||
msgdma_chan_desc_cleanup(mdev);
|
msgdma_chan_desc_cleanup(mdev);
|
||||||
@@ -757,14 +765,21 @@ static void msgdma_dev_remove(struct msgdma_device *mdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int request_and_map(struct platform_device *pdev, const char *name,
|
static int request_and_map(struct platform_device *pdev, const char *name,
|
||||||
struct resource **res, void __iomem **ptr)
|
struct resource **res, void __iomem **ptr,
|
||||||
|
bool optional)
|
||||||
{
|
{
|
||||||
struct resource *region;
|
struct resource *region;
|
||||||
struct device *device = &pdev->dev;
|
struct device *device = &pdev->dev;
|
||||||
|
|
||||||
*res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
|
*res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
|
||||||
if (*res == NULL) {
|
if (*res == NULL) {
|
||||||
dev_err(device, "resource %s not defined\n", name);
|
if (optional) {
|
||||||
|
*ptr = NULL;
|
||||||
|
dev_info(device, "optional resource %s not defined\n",
|
||||||
|
name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
dev_err(device, "mandatory resource %s not defined\n", name);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -805,17 +820,17 @@ static int msgdma_probe(struct platform_device *pdev)
|
|||||||
mdev->dev = &pdev->dev;
|
mdev->dev = &pdev->dev;
|
||||||
|
|
||||||
/* Map CSR space */
|
/* Map CSR space */
|
||||||
ret = request_and_map(pdev, "csr", &dma_res, &mdev->csr);
|
ret = request_and_map(pdev, "csr", &dma_res, &mdev->csr, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* Map (extended) descriptor space */
|
/* Map (extended) descriptor space */
|
||||||
ret = request_and_map(pdev, "desc", &dma_res, &mdev->desc);
|
ret = request_and_map(pdev, "desc", &dma_res, &mdev->desc, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* Map response space */
|
/* Map response space */
|
||||||
ret = request_and_map(pdev, "resp", &dma_res, &mdev->resp);
|
ret = request_and_map(pdev, "resp", &dma_res, &mdev->resp, true);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user