fsl-diu-fb: Pass the proper device for dma mapping routines
authorAnton Vorontsov <avorontsov@ru.mvista.com>
Sat, 4 Apr 2009 18:31:20 +0000 (22:31 +0400)
committerKumar Gala <galak@kernel.crashing.org>
Mon, 6 Apr 2009 14:12:38 +0000 (09:12 -0500)
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: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
drivers/video/fsl-diu-fb.c

index fb51197d1c98e227cabb96e8244585851a366ff2..f153c581cbd7bbe99f4558f98e5975b935463263 100644 (file)
@@ -1352,14 +1352,15 @@ static int fsl_diu_resume(struct of_device *ofdev)
 #endif                         /* CONFIG_PM */
 
 /* 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 mask;
        dma_addr_t paddr = 0;
 
        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);
        if (!buf->vaddr)
                return -ENOMEM;
@@ -1376,9 +1377,10 @@ static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align)
        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));
        return;
 }
@@ -1476,17 +1478,19 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev,
        machine_data->monitor_port = monitor_port;
 
        /* 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;
 
        /* 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;
                goto error;
        }
 
        /* 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;
                goto error;
        }
@@ -1554,11 +1558,13 @@ error:
                i > 0; i--)
                uninstall_fb(machine_data->fsl_diu_info[i - 1]);
        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)
-               free_buf(&pool.gamma, 768, 32);
+               free_buf(&ofdev->dev, &pool.gamma, 768, 32);
        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)
                fsl_diu_free(machine_data->dummy_aoi_virt, 64);
        iounmap(dr.diu_reg);
@@ -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--)
                uninstall_fb(machine_data->fsl_diu_info[i - 1]);
        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)
-               free_buf(&pool.gamma, 768, 32);
+               free_buf(&ofdev->dev, &pool.gamma, 768, 32);
        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)
                fsl_diu_free(machine_data->dummy_aoi_virt, 64);
        iounmap(dr.diu_reg);