Commit f3791889 authored by Anton Vorontsov's avatar Anton Vorontsov Committed by Kumar Gala

fsl-diu-fb: Pass the proper device for dma mapping routines

The driver should pass a device that specifies internal DMA ops, but
currently NULL pointers are passed, and thus following bug pops up:

  Freescale DIU driver
  ------------[ cut here ]------------
  kernel BUG at arch/powerpc/include/asm/dma-mapping.h:237!
  Oops: Exception in kernel mode, sig: 5 [#1]
  ...
  NIP [c01658b4] allocate_buf+0x0/0x8
  LR [c0306554] fsl_diu_probe+0x2b4/0x518
  Call Trace:
  [df02be10] [c030638c] fsl_diu_probe+0xec/0x518 (unreliable)
  [df02be60] [c020cdec] of_platform_device_probe+0x5c/0x84
  [df02be80] [c018f5d0] really_probe+0x78/0x1a0
  [df02bea0] [c018f7c0] __driver_attach+0xa4/0xa8
  [df02bec0] [c018ea00] bus_for_each_dev+0x60/0x9c
  [df02bef0] [c018f414] driver_attach+0x24/0x34
  [df02bf00] [c018f168] bus_add_driver+0x12c/0x1cc
  [df02bf20] [c018fbdc] driver_register+0x6c/0x110
  [df02bf30] [c020ccb4] of_register_driver+0x54/0x70
  [df02bf40] [c03d0a50] fsl_diu_init+0x70/0xa4
  ...

This patch fixes the issue.
Signed-off-by: default avatarAnton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: default avatarKumar Gala <galak@kernel.crashing.org>
parent 65cc0fa3
...@@ -1352,14 +1352,15 @@ static int fsl_diu_resume(struct of_device *ofdev) ...@@ -1352,14 +1352,15 @@ static int fsl_diu_resume(struct of_device *ofdev)
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
/* Align to 64-bit(8-byte), 32-byte, etc. */ /* Align to 64-bit(8-byte), 32-byte, etc. */
static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align) static int allocate_buf(struct device *dev, struct diu_addr *buf, u32 size,
u32 bytes_align)
{ {
u32 offset, ssize; u32 offset, ssize;
u32 mask; u32 mask;
dma_addr_t paddr = 0; dma_addr_t paddr = 0;
ssize = size + bytes_align; ssize = size + bytes_align;
buf->vaddr = dma_alloc_coherent(NULL, ssize, &paddr, GFP_DMA | buf->vaddr = dma_alloc_coherent(dev, ssize, &paddr, GFP_DMA |
__GFP_ZERO); __GFP_ZERO);
if (!buf->vaddr) if (!buf->vaddr)
return -ENOMEM; return -ENOMEM;
...@@ -1376,9 +1377,10 @@ static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align) ...@@ -1376,9 +1377,10 @@ static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align)
return 0; return 0;
} }
static void free_buf(struct diu_addr *buf, u32 size, u32 bytes_align) static void free_buf(struct device *dev, struct diu_addr *buf, u32 size,
u32 bytes_align)
{ {
dma_free_coherent(NULL, size + bytes_align, dma_free_coherent(dev, size + bytes_align,
buf->vaddr, (buf->paddr - buf->offset)); buf->vaddr, (buf->paddr - buf->offset));
return; return;
} }
...@@ -1476,17 +1478,19 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev, ...@@ -1476,17 +1478,19 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev,
machine_data->monitor_port = monitor_port; machine_data->monitor_port = monitor_port;
/* Area descriptor memory pool aligns to 64-bit boundary */ /* Area descriptor memory pool aligns to 64-bit boundary */
if (allocate_buf(&pool.ad, sizeof(struct diu_ad) * FSL_AOI_NUM, 8)) if (allocate_buf(&ofdev->dev, &pool.ad,
sizeof(struct diu_ad) * FSL_AOI_NUM, 8))
return -ENOMEM; return -ENOMEM;
/* Get memory for Gamma Table - 32-byte aligned memory */ /* Get memory for Gamma Table - 32-byte aligned memory */
if (allocate_buf(&pool.gamma, 768, 32)) { if (allocate_buf(&ofdev->dev, &pool.gamma, 768, 32)) {
ret = -ENOMEM; ret = -ENOMEM;
goto error; goto error;
} }
/* For performance, cursor bitmap buffer aligns to 32-byte boundary */ /* For performance, cursor bitmap buffer aligns to 32-byte boundary */
if (allocate_buf(&pool.cursor, MAX_CURS * MAX_CURS * 2, 32)) { if (allocate_buf(&ofdev->dev, &pool.cursor, MAX_CURS * MAX_CURS * 2,
32)) {
ret = -ENOMEM; ret = -ENOMEM;
goto error; goto error;
} }
...@@ -1554,11 +1558,13 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev, ...@@ -1554,11 +1558,13 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev,
i > 0; i--) i > 0; i--)
uninstall_fb(machine_data->fsl_diu_info[i - 1]); uninstall_fb(machine_data->fsl_diu_info[i - 1]);
if (pool.ad.vaddr) if (pool.ad.vaddr)
free_buf(&pool.ad, sizeof(struct diu_ad) * FSL_AOI_NUM, 8); free_buf(&ofdev->dev, &pool.ad,
sizeof(struct diu_ad) * FSL_AOI_NUM, 8);
if (pool.gamma.vaddr) if (pool.gamma.vaddr)
free_buf(&pool.gamma, 768, 32); free_buf(&ofdev->dev, &pool.gamma, 768, 32);
if (pool.cursor.vaddr) if (pool.cursor.vaddr)
free_buf(&pool.cursor, MAX_CURS * MAX_CURS * 2, 32); free_buf(&ofdev->dev, &pool.cursor, MAX_CURS * MAX_CURS * 2,
32);
if (machine_data->dummy_aoi_virt) if (machine_data->dummy_aoi_virt)
fsl_diu_free(machine_data->dummy_aoi_virt, 64); fsl_diu_free(machine_data->dummy_aoi_virt, 64);
iounmap(dr.diu_reg); iounmap(dr.diu_reg);
...@@ -1584,11 +1590,13 @@ static int fsl_diu_remove(struct of_device *ofdev) ...@@ -1584,11 +1590,13 @@ static int fsl_diu_remove(struct of_device *ofdev)
for (i = ARRAY_SIZE(machine_data->fsl_diu_info); i > 0; i--) for (i = ARRAY_SIZE(machine_data->fsl_diu_info); i > 0; i--)
uninstall_fb(machine_data->fsl_diu_info[i - 1]); uninstall_fb(machine_data->fsl_diu_info[i - 1]);
if (pool.ad.vaddr) if (pool.ad.vaddr)
free_buf(&pool.ad, sizeof(struct diu_ad) * FSL_AOI_NUM, 8); free_buf(&ofdev->dev, &pool.ad,
sizeof(struct diu_ad) * FSL_AOI_NUM, 8);
if (pool.gamma.vaddr) if (pool.gamma.vaddr)
free_buf(&pool.gamma, 768, 32); free_buf(&ofdev->dev, &pool.gamma, 768, 32);
if (pool.cursor.vaddr) if (pool.cursor.vaddr)
free_buf(&pool.cursor, MAX_CURS * MAX_CURS * 2, 32); free_buf(&ofdev->dev, &pool.cursor, MAX_CURS * MAX_CURS * 2,
32);
if (machine_data->dummy_aoi_virt) if (machine_data->dummy_aoi_virt)
fsl_diu_free(machine_data->dummy_aoi_virt, 64); fsl_diu_free(machine_data->dummy_aoi_virt, 64);
iounmap(dr.diu_reg); iounmap(dr.diu_reg);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment