| From dhobsong@igel.co.jp Wed Nov 21 18:27:18 2012 |
| From: Damian Hobson-Garcia <dhobsong@igel.co.jp> |
| Date: Thu, 22 Nov 2012 11:26:50 +0900 |
| Subject: [PATCH 3/6] drivers: uio_dmem_genirq: Don't mix address spaces for dynamic region vaddr |
| To: gregkh@linuxfoundation.org |
| Cc: ltsi-dev@lists.linuxfoundation.org, Damian Hobson-Garcia <dhobsong@igel.co.jp> |
| Message-ID: <1353551213-17996-4-git-send-email-dhobsong@igel.co.jp> |
| |
| |
| Assigning the virtual address returned from dma_alloc_coherent to the the |
| internal_addr element of uioinfo produces the following sparse errors since |
| internal_addr is a void __iomem * and dma_alloc_coherent returns void *. |
| |
| + drivers/uio/uio_dmem_genirq.c:65:39: sparse: incorrect type in assignment (different address spaces) |
| drivers/uio/uio_dmem_genirq.c:65:39: expected void [noderef] <asn:2>*internal_addr |
| drivers/uio/uio_dmem_genirq.c:65:39: got void *[assigned] addr |
| + drivers/uio/uio_dmem_genirq.c:93:17: sparse: incorrect type in argument 3 (different address spaces) |
| drivers/uio/uio_dmem_genirq.c:93:17: expected void *vaddr |
| drivers/uio/uio_dmem_genirq.c:93:17: got void [noderef] <asn:2>*internal_addr |
| |
| Store the void * in the driver's private data instead. |
| |
| Reported-by: Fengguang Wu <fengguang.wu@intel.com> |
| |
| Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp> |
| --- |
| drivers/uio/uio_dmem_genirq.c | 9 ++++++--- |
| 1 file changed, 6 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/uio/uio_dmem_genirq.c |
| +++ b/drivers/uio/uio_dmem_genirq.c |
| @@ -37,6 +37,7 @@ struct uio_dmem_genirq_platdata { |
| struct platform_device *pdev; |
| unsigned int dmem_region_start; |
| unsigned int num_dmem_regions; |
| + void *dmem_region_vaddr[MAX_UIO_MAPS]; |
| struct mutex alloc_lock; |
| unsigned int refcnt; |
| }; |
| @@ -46,6 +47,7 @@ static int uio_dmem_genirq_open(struct u |
| struct uio_dmem_genirq_platdata *priv = info->priv; |
| struct uio_mem *uiomem; |
| int ret = 0; |
| + int dmem_region = priv->dmem_region_start; |
| |
| uiomem = &priv->uioinfo->mem[priv->dmem_region_start]; |
| |
| @@ -61,8 +63,7 @@ static int uio_dmem_genirq_open(struct u |
| ret = -ENOMEM; |
| break; |
| } |
| - |
| - uiomem->internal_addr = addr; |
| + priv->dmem_region_vaddr[dmem_region++] = addr; |
| ++uiomem; |
| } |
| priv->refcnt++; |
| @@ -77,6 +78,7 @@ static int uio_dmem_genirq_release(struc |
| { |
| struct uio_dmem_genirq_platdata *priv = info->priv; |
| struct uio_mem *uiomem; |
| + int dmem_region = priv->dmem_region_start; |
| |
| /* Tell the Runtime PM code that the device has become idle */ |
| pm_runtime_put_sync(&priv->pdev->dev); |
| @@ -91,7 +93,8 @@ static int uio_dmem_genirq_release(struc |
| break; |
| |
| dma_free_coherent(&priv->pdev->dev, uiomem->size, |
| - uiomem->internal_addr, uiomem->addr); |
| + priv->dmem_region_vaddr[dmem_region++], |
| + uiomem->addr); |
| uiomem->addr = DMA_ERROR_CODE; |
| ++uiomem; |
| } |