diff options
author | Anton Vorontsov <avorontsov@ru.mvista.com> | 2009-04-04 14:31:20 -0400 |
---|---|---|
committer | Kumar Gala <galak@kernel.crashing.org> | 2009-04-06 10:12:38 -0400 |
commit | f379188958ae8af30105eb1f27d0e0abf6a51558 (patch) | |
tree | e9914076c03302aba3283c9f78601671d43df72c /drivers/video/fsl-diu-fb.c | |
parent | 65cc0fa3bde00e81f83348ef162a83ab9fff2079 (diff) |
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: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'drivers/video/fsl-diu-fb.c')
-rw-r--r-- | drivers/video/fsl-diu-fb.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index fb51197d1c98..f153c581cbd7 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c | |||
@@ -1352,14 +1352,15 @@ static int fsl_diu_resume(struct of_device *ofdev) | |||
1352 | #endif /* CONFIG_PM */ | 1352 | #endif /* CONFIG_PM */ |
1353 | 1353 | ||
1354 | /* Align to 64-bit(8-byte), 32-byte, etc. */ | 1354 | /* Align to 64-bit(8-byte), 32-byte, etc. */ |
1355 | static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align) | 1355 | static int allocate_buf(struct device *dev, struct diu_addr *buf, u32 size, |
1356 | u32 bytes_align) | ||
1356 | { | 1357 | { |
1357 | u32 offset, ssize; | 1358 | u32 offset, ssize; |
1358 | u32 mask; | 1359 | u32 mask; |
1359 | dma_addr_t paddr = 0; | 1360 | dma_addr_t paddr = 0; |
1360 | 1361 | ||
1361 | ssize = size + bytes_align; | 1362 | ssize = size + bytes_align; |
1362 | buf->vaddr = dma_alloc_coherent(NULL, ssize, &paddr, GFP_DMA | | 1363 | buf->vaddr = dma_alloc_coherent(dev, ssize, &paddr, GFP_DMA | |
1363 | __GFP_ZERO); | 1364 | __GFP_ZERO); |
1364 | if (!buf->vaddr) | 1365 | if (!buf->vaddr) |
1365 | return -ENOMEM; | 1366 | return -ENOMEM; |
@@ -1376,9 +1377,10 @@ static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align) | |||
1376 | return 0; | 1377 | return 0; |
1377 | } | 1378 | } |
1378 | 1379 | ||
1379 | static void free_buf(struct diu_addr *buf, u32 size, u32 bytes_align) | 1380 | static void free_buf(struct device *dev, struct diu_addr *buf, u32 size, |
1381 | u32 bytes_align) | ||
1380 | { | 1382 | { |
1381 | dma_free_coherent(NULL, size + bytes_align, | 1383 | dma_free_coherent(dev, size + bytes_align, |
1382 | buf->vaddr, (buf->paddr - buf->offset)); | 1384 | buf->vaddr, (buf->paddr - buf->offset)); |
1383 | return; | 1385 | return; |
1384 | } | 1386 | } |
@@ -1476,17 +1478,19 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev, | |||
1476 | machine_data->monitor_port = monitor_port; | 1478 | machine_data->monitor_port = monitor_port; |
1477 | 1479 | ||
1478 | /* Area descriptor memory pool aligns to 64-bit boundary */ | 1480 | /* Area descriptor memory pool aligns to 64-bit boundary */ |
1479 | if (allocate_buf(&pool.ad, sizeof(struct diu_ad) * FSL_AOI_NUM, 8)) | 1481 | if (allocate_buf(&ofdev->dev, &pool.ad, |
1482 | sizeof(struct diu_ad) * FSL_AOI_NUM, 8)) | ||
1480 | return -ENOMEM; | 1483 | return -ENOMEM; |
1481 | 1484 | ||
1482 | /* Get memory for Gamma Table - 32-byte aligned memory */ | 1485 | /* Get memory for Gamma Table - 32-byte aligned memory */ |
1483 | if (allocate_buf(&pool.gamma, 768, 32)) { | 1486 | if (allocate_buf(&ofdev->dev, &pool.gamma, 768, 32)) { |
1484 | ret = -ENOMEM; | 1487 | ret = -ENOMEM; |
1485 | goto error; | 1488 | goto error; |
1486 | } | 1489 | } |
1487 | 1490 | ||
1488 | /* For performance, cursor bitmap buffer aligns to 32-byte boundary */ | 1491 | /* For performance, cursor bitmap buffer aligns to 32-byte boundary */ |
1489 | if (allocate_buf(&pool.cursor, MAX_CURS * MAX_CURS * 2, 32)) { | 1492 | if (allocate_buf(&ofdev->dev, &pool.cursor, MAX_CURS * MAX_CURS * 2, |
1493 | 32)) { | ||
1490 | ret = -ENOMEM; | 1494 | ret = -ENOMEM; |
1491 | goto error; | 1495 | goto error; |
1492 | } | 1496 | } |
@@ -1554,11 +1558,13 @@ error: | |||
1554 | i > 0; i--) | 1558 | i > 0; i--) |
1555 | uninstall_fb(machine_data->fsl_diu_info[i - 1]); | 1559 | uninstall_fb(machine_data->fsl_diu_info[i - 1]); |
1556 | if (pool.ad.vaddr) | 1560 | if (pool.ad.vaddr) |
1557 | free_buf(&pool.ad, sizeof(struct diu_ad) * FSL_AOI_NUM, 8); | 1561 | free_buf(&ofdev->dev, &pool.ad, |
1562 | sizeof(struct diu_ad) * FSL_AOI_NUM, 8); | ||
1558 | if (pool.gamma.vaddr) | 1563 | if (pool.gamma.vaddr) |
1559 | free_buf(&pool.gamma, 768, 32); | 1564 | free_buf(&ofdev->dev, &pool.gamma, 768, 32); |
1560 | if (pool.cursor.vaddr) | 1565 | if (pool.cursor.vaddr) |
1561 | free_buf(&pool.cursor, MAX_CURS * MAX_CURS * 2, 32); | 1566 | free_buf(&ofdev->dev, &pool.cursor, MAX_CURS * MAX_CURS * 2, |
1567 | 32); | ||
1562 | if (machine_data->dummy_aoi_virt) | 1568 | if (machine_data->dummy_aoi_virt) |
1563 | fsl_diu_free(machine_data->dummy_aoi_virt, 64); | 1569 | fsl_diu_free(machine_data->dummy_aoi_virt, 64); |
1564 | iounmap(dr.diu_reg); | 1570 | iounmap(dr.diu_reg); |
@@ -1584,11 +1590,13 @@ static int fsl_diu_remove(struct of_device *ofdev) | |||
1584 | for (i = ARRAY_SIZE(machine_data->fsl_diu_info); i > 0; i--) | 1590 | for (i = ARRAY_SIZE(machine_data->fsl_diu_info); i > 0; i--) |
1585 | uninstall_fb(machine_data->fsl_diu_info[i - 1]); | 1591 | uninstall_fb(machine_data->fsl_diu_info[i - 1]); |
1586 | if (pool.ad.vaddr) | 1592 | if (pool.ad.vaddr) |
1587 | free_buf(&pool.ad, sizeof(struct diu_ad) * FSL_AOI_NUM, 8); | 1593 | free_buf(&ofdev->dev, &pool.ad, |
1594 | sizeof(struct diu_ad) * FSL_AOI_NUM, 8); | ||
1588 | if (pool.gamma.vaddr) | 1595 | if (pool.gamma.vaddr) |
1589 | free_buf(&pool.gamma, 768, 32); | 1596 | free_buf(&ofdev->dev, &pool.gamma, 768, 32); |
1590 | if (pool.cursor.vaddr) | 1597 | if (pool.cursor.vaddr) |
1591 | free_buf(&pool.cursor, MAX_CURS * MAX_CURS * 2, 32); | 1598 | free_buf(&ofdev->dev, &pool.cursor, MAX_CURS * MAX_CURS * 2, |
1599 | 32); | ||
1592 | if (machine_data->dummy_aoi_virt) | 1600 | if (machine_data->dummy_aoi_virt) |
1593 | fsl_diu_free(machine_data->dummy_aoi_virt, 64); | 1601 | fsl_diu_free(machine_data->dummy_aoi_virt, 64); |
1594 | iounmap(dr.diu_reg); | 1602 | iounmap(dr.diu_reg); |