No drivers should use virt_to_bus() any more. This converts
one of the few remaining ones to the DMA mapping interface.

Signed-off-by: Arnd Bergmann <a...@arndb.de>
---
 drivers/media/pci/zoran/Kconfig        |  2 +-
 drivers/media/pci/zoran/zoran.h        | 10 +++++--
 drivers/media/pci/zoran/zoran_card.c   | 10 +++++--
 drivers/media/pci/zoran/zoran_device.c | 16 +++++-----
 drivers/media/pci/zoran/zoran_driver.c | 54 +++++++++++++++++++++++++---------
 5 files changed, 63 insertions(+), 29 deletions(-)

diff --git a/drivers/media/pci/zoran/Kconfig b/drivers/media/pci/zoran/Kconfig
index 39ec35bd21a5..26f40e124a32 100644
--- a/drivers/media/pci/zoran/Kconfig
+++ b/drivers/media/pci/zoran/Kconfig
@@ -1,6 +1,6 @@
 config VIDEO_ZORAN
        tristate "Zoran ZR36057/36067 Video For Linux"
-       depends on PCI && I2C_ALGOBIT && VIDEO_V4L2 && VIRT_TO_BUS
+       depends on PCI && I2C_ALGOBIT && VIDEO_V4L2
        depends on !ALPHA
        help
          Say Y for support for MJPEG capture cards based on the Zoran
diff --git a/drivers/media/pci/zoran/zoran.h b/drivers/media/pci/zoran/zoran.h
index 9bb3c21aa275..9ff3a9acb60a 100644
--- a/drivers/media/pci/zoran/zoran.h
+++ b/drivers/media/pci/zoran/zoran.h
@@ -183,13 +183,14 @@ struct zoran_buffer {
        struct zoran_sync bs;           /* DONE: info to return to application 
*/
        union {
                struct {
-                       __le32 *frag_tab;       /* addresses of frag table */
-                       u32 frag_tab_bus;       /* same value cached to save 
time in ISR */
+                       __le32 *frag_tab;       /* DMA addresses of frag table 
*/
+                       void **frag_virt_tab;   /* virtual addresses of frag 
table */
+                       dma_addr_t frag_tab_dma;/* same value cached to save 
time in ISR */
                } jpg;
                struct {
                        char *fbuffer;          /* virtual address of frame 
buffer */
                        unsigned long fbuffer_phys;/* physical address of frame 
buffer */
-                       unsigned long fbuffer_bus;/* bus address of frame 
buffer */
+                       dma_addr_t fbuffer_dma;/* bus address of frame buffer */
                } v4l;
        };
 };
@@ -221,6 +222,7 @@ struct zoran_fh {
 
        struct zoran_overlay_settings overlay_settings;
        u32 *overlay_mask;                      /* overlay mask */
+       dma_addr_t overlay_mask_dma;
        enum zoran_lock_activity overlay_active;/* feature currently in use? */
 
        struct zoran_buffer_col buffers;        /* buffers' info */
@@ -307,6 +309,7 @@ struct zoran {
 
        struct zoran_overlay_settings overlay_settings;
        u32 *overlay_mask;      /* overlay mask */
+       dma_addr_t overlay_mask_dma;
        enum zoran_lock_activity overlay_active;        /* feature currently in 
use? */
 
        wait_queue_head_t v4l_capq;
@@ -346,6 +349,7 @@ struct zoran {
 
        /* zr36057's code buffer table */
        __le32 *stat_com;               /* stat_com[i] is indexed by 
dma_head/tail & BUZ_MASK_STAT_COM */
+       dma_addr_t stat_com_dma;
 
        /* (value & BUZ_MASK_FRAME) corresponds to index in pend[] queue */
        int jpg_pend[BUZ_MAX_FRAME];
diff --git a/drivers/media/pci/zoran/zoran_card.c 
b/drivers/media/pci/zoran/zoran_card.c
index a6b9ebd20263..dabd8bf77472 100644
--- a/drivers/media/pci/zoran/zoran_card.c
+++ b/drivers/media/pci/zoran/zoran_card.c
@@ -890,6 +890,7 @@ zoran_open_init_params (struct zoran *zr)
        /* User must explicitly set a window */
        zr->overlay_settings.is_set = 0;
        zr->overlay_mask = NULL;
+       zr->overlay_mask_dma = 0;
        zr->overlay_active = ZORAN_FREE;
 
        zr->v4l_memgrab_active = 0;
@@ -1028,7 +1029,8 @@ static int zr36057_init (struct zoran *zr)
 
        /* allocate memory *before* doing anything to the hardware
         * in case allocation fails */
-       zr->stat_com = kzalloc(BUZ_NUM_STAT_COM * 4, GFP_KERNEL);
+       zr->stat_com = dma_alloc_coherent(&zr->pci_dev->dev,
+                               BUZ_NUM_STAT_COM * 4, &zr->stat_com_dma, 
GFP_KERNEL);
        zr->video_dev = video_device_alloc();
        if (!zr->stat_com || !zr->video_dev) {
                dprintk(1,
@@ -1072,7 +1074,8 @@ static int zr36057_init (struct zoran *zr)
        return 0;
 
 exit_free:
-       kfree(zr->stat_com);
+       dma_free_coherent(&zr->pci_dev->dev, BUZ_NUM_STAT_COM * 4,
+                         zr->stat_com, zr->stat_com_dma);
        kfree(zr->video_dev);
        return err;
 }
@@ -1107,7 +1110,8 @@ static void zoran_remove(struct pci_dev *pdev)
        btwrite(0, ZR36057_SPGPPCR);
        free_irq(zr->pci_dev->irq, zr);
        /* unmap and free memory */
-       kfree(zr->stat_com);
+       dma_free_coherent(&zr->pci_dev->dev, BUZ_NUM_STAT_COM * 4,
+                         zr->stat_com, zr->stat_com_dma);
        zoran_proc_cleanup(zr);
        iounmap(zr->zr36057_mem);
        pci_disable_device(zr->pci_dev);
diff --git a/drivers/media/pci/zoran/zoran_device.c 
b/drivers/media/pci/zoran/zoran_device.c
index 40adceebca7e..1ac7810ddd25 100644
--- a/drivers/media/pci/zoran/zoran_device.c
+++ b/drivers/media/pci/zoran/zoran_device.c
@@ -430,9 +430,9 @@ zr36057_set_vfe (struct zoran              *zr,
                 * zr->overlay_settings.width instead of video_width */
 
                mask_line_size = (BUZ_MAX_WIDTH + 31) / 32;
-               reg = virt_to_bus(zr->overlay_mask);
+               reg = zr->overlay_mask_dma;
                btwrite(reg, ZR36057_MMTR);
-               reg = virt_to_bus(zr->overlay_mask + mask_line_size);
+               reg = zr->overlay_mask_dma + mask_line_size;
                btwrite(reg, ZR36057_MMBR);
                reg =
                    mask_line_size - (zr->overlay_settings.width +
@@ -775,7 +775,7 @@ zr36057_set_jpg (struct zoran          *zr,
        //btor(ZR36057_VFESPFR_VCLKPol, ZR36057_VFESPFR);
 
        /* code base address */
-       reg = virt_to_bus(zr->stat_com);
+       reg = zr->stat_com_dma;
        btwrite(reg, ZR36057_JCBA);
 
        /* FIFO threshold (FIFO is 160. double words) */
@@ -1097,7 +1097,7 @@ zoran_feed_stat_com (struct zoran *zr)
                        if (!(zr->stat_com[i] & cpu_to_le32(1)))
                                break;
                        zr->stat_com[i] =
-                           
cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus);
+                           
cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_dma);
                } else {
                        /* fill 2 stat_com entries */
                        i = ((zr->jpg_dma_head -
@@ -1105,9 +1105,9 @@ zoran_feed_stat_com (struct zoran *zr)
                        if (!(zr->stat_com[i] & cpu_to_le32(1)))
                                break;
                        zr->stat_com[i] =
-                           
cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus);
+                           
cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_dma);
                        zr->stat_com[i + 1] =
-                           
cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus);
+                           
cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_dma);
                }
                zr->jpg_buffers.buffer[frame].state = BUZ_STATE_DMA;
                zr->jpg_dma_head++;
@@ -1272,7 +1272,7 @@ error_handler (struct zoran *zr,
                printk(KERN_INFO "stat_com frames:");
                for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
                        for (i = 0; i < zr->jpg_buffers.num_buffers; i++) {
-                               if (le32_to_cpu(zr->stat_com[j]) == 
zr->jpg_buffers.buffer[i].jpg.frag_tab_bus)
+                               if (le32_to_cpu(zr->stat_com[j]) == 
zr->jpg_buffers.buffer[i].jpg.frag_tab_dma)
                                        printk(KERN_CONT "% d->%d", j, i);
                        }
                }
@@ -1411,7 +1411,7 @@ zoran_irq (int             irq,
 
                                        /* Buffer address */
 
-                                       reg = 
zr->v4l_buffers.buffer[frame].v4l.fbuffer_bus;
+                                       reg = 
zr->v4l_buffers.buffer[frame].v4l.fbuffer_dma;
                                        btwrite(reg, ZR36057_VDTR);
                                        if (zr->v4l_settings.height > 
BUZ_MAX_HEIGHT / 2)
                                                reg += 
zr->v4l_settings.bytesperline;
diff --git a/drivers/media/pci/zoran/zoran_driver.c 
b/drivers/media/pci/zoran/zoran_driver.c
index 4b6466961b41..dad1fb02ced2 100644
--- a/drivers/media/pci/zoran/zoran_driver.c
+++ b/drivers/media/pci/zoran/zoran_driver.c
@@ -235,15 +235,20 @@ static int v4l_fbuffer_alloc(struct zoran_fh *fh)
                }
                fh->buffers.buffer[i].v4l.fbuffer = mem;
                fh->buffers.buffer[i].v4l.fbuffer_phys = virt_to_phys(mem);
-               fh->buffers.buffer[i].v4l.fbuffer_bus = virt_to_bus(mem);
+               fh->buffers.buffer[i].v4l.fbuffer_dma =
+                       dma_map_single(&zr->pci_dev->dev, mem,
+                                      fh->buffers.buffer_size,
+                                      DMA_FROM_DEVICE);
+               if (!fh->buffers.buffer[i].v4l.fbuffer_dma)
+                       return -ENXIO;
                for (off = 0; off < fh->buffers.buffer_size;
                     off += PAGE_SIZE)
                        SetPageReserved(virt_to_page(mem + off));
                dprintk(4,
                        KERN_INFO
-                       "%s: %s - V4L frame %d mem %p (bus: 0x%llx)\n",
+                       "%s: %s - V4L frame %d mem %p (bus: %pad)\n",
                        ZR_DEVNAME(zr), __func__, i, mem,
-                       (unsigned long long)virt_to_bus(mem));
+                       &fh->buffers.buffer[i].v4l.fbuffer_dma);
        }
 
        fh->buffers.allocated = 1;
@@ -308,6 +313,7 @@ static int jpg_fbuffer_alloc(struct zoran_fh *fh)
        struct zoran *zr = fh->zr;
        int i, j, off;
        u8 *mem;
+       void **virt_tab;
 
        for (i = 0; i < fh->buffers.num_buffers; i++) {
                if (fh->buffers.buffer[i].jpg.frag_tab)
@@ -319,16 +325,19 @@ static int jpg_fbuffer_alloc(struct zoran_fh *fh)
                /* Allocate fragment table for this buffer */
 
                mem = (void *)get_zeroed_page(GFP_KERNEL);
-               if (!mem) {
+               virt_tab = (void *)get_zeroed_page(GFP_KERNEL);
+               if (!mem || !virt_tab) {
                        dprintk(1,
                                KERN_ERR
                                "%s: %s - get_zeroed_page (frag_tab) failed for 
buffer %d\n",
                                ZR_DEVNAME(zr), __func__, i);
+                       kfree(mem);
+                       kfree(virt_tab);
                        jpg_fbuffer_free(fh);
                        return -ENOBUFS;
                }
                fh->buffers.buffer[i].jpg.frag_tab = (__le32 *)mem;
-               fh->buffers.buffer[i].jpg.frag_tab_bus = virt_to_bus(mem);
+               fh->buffers.buffer[i].jpg.frag_virt_tab = virt_tab;
 
                if (fh->buffers.need_contiguous) {
                        mem = kmalloc(fh->buffers.buffer_size, GFP_KERNEL);
@@ -340,8 +349,9 @@ static int jpg_fbuffer_alloc(struct zoran_fh *fh)
                                jpg_fbuffer_free(fh);
                                return -ENOBUFS;
                        }
+                       fh->buffers.buffer[i].jpg.frag_virt_tab[0] = mem;
                        fh->buffers.buffer[i].jpg.frag_tab[0] =
-                               cpu_to_le32(virt_to_bus(mem));
+                               cpu_to_le32(dma_map_single(&zr->pci_dev->dev, 
mem, fh->buffers.buffer_size, DMA_FROM_DEVICE));
                        fh->buffers.buffer[i].jpg.frag_tab[1] =
                                cpu_to_le32((fh->buffers.buffer_size >> 1) | 1);
                        for (off = 0; off < fh->buffers.buffer_size; off += 
PAGE_SIZE)
@@ -359,8 +369,9 @@ static int jpg_fbuffer_alloc(struct zoran_fh *fh)
                                        return -ENOBUFS;
                                }
 
+                               fh->buffers.buffer[i].jpg.frag_virt_tab[j] = 
mem;
                                fh->buffers.buffer[i].jpg.frag_tab[2 * j] =
-                                       cpu_to_le32(virt_to_bus(mem));
+                                       
cpu_to_le32(dma_map_single(&zr->pci_dev->dev, mem, fh->buffers.buffer_size, 
DMA_FROM_DEVICE));
                                fh->buffers.buffer[i].jpg.frag_tab[2 * j + 1] =
                                        cpu_to_le32((PAGE_SIZE >> 2) << 1);
                                SetPageReserved(virt_to_page(mem));
@@ -368,6 +379,8 @@ static int jpg_fbuffer_alloc(struct zoran_fh *fh)
 
                        fh->buffers.buffer[i].jpg.frag_tab[2 * j - 1] |= 
cpu_to_le32(1);
                }
+
+               fh->buffers.buffer[i].jpg.frag_tab_dma = 
dma_map_single(&zr->pci_dev->dev, mem, PAGE_SIZE, DMA_TO_DEVICE);
        }
 
        dprintk(4,
@@ -400,9 +413,10 @@ static void jpg_fbuffer_free(struct zoran_fh *fh)
                        frag_tab = buffer->jpg.frag_tab[0];
 
                        if (frag_tab) {
-                               mem = bus_to_virt(le32_to_cpu(frag_tab));
+                               mem = buffer->jpg.frag_virt_tab[0];
                                for (off = 0; off < fh->buffers.buffer_size; 
off += PAGE_SIZE)
                                        ClearPageReserved(virt_to_page(mem + 
off));
+                               dma_unmap_single(&zr->pci_dev->dev, frag_tab, 
PAGE_SIZE, DMA_FROM_DEVICE);
                                kfree(mem);
                                buffer->jpg.frag_tab[0] = 0;
                                buffer->jpg.frag_tab[1] = 0;
@@ -413,14 +427,19 @@ static void jpg_fbuffer_free(struct zoran_fh *fh)
 
                                if (!frag_tab)
                                        break;
-                               
ClearPageReserved(virt_to_page(bus_to_virt(le32_to_cpu(frag_tab))));
-                               free_page((unsigned 
long)bus_to_virt(le32_to_cpu(frag_tab)));
+                               
ClearPageReserved(virt_to_page(buffer->jpg.frag_virt_tab[j]));
+                               dma_unmap_single(&zr->pci_dev->dev, 
le32_to_cpu(frag_tab), PAGE_SIZE, DMA_FROM_DEVICE);
+                               free_page((unsigned 
long)buffer->jpg.frag_virt_tab[j]);
+                               buffer->jpg.frag_virt_tab[j] = NULL;
                                buffer->jpg.frag_tab[2 * j] = 0;
                                buffer->jpg.frag_tab[2 * j + 1] = 0;
                        }
                }
 
+               dma_unmap_single(&zr->pci_dev->dev, buffer->jpg.frag_tab_dma, 
PAGE_SIZE, DMA_TO_DEVICE);
                free_page((unsigned long)buffer->jpg.frag_tab);
+               free_page((unsigned long)buffer->jpg.frag_virt_tab);
+               buffer->jpg.frag_virt_tab = NULL;
                buffer->jpg.frag_tab = NULL;
        }
 
@@ -873,6 +892,7 @@ static void zoran_close_end_session(struct zoran_fh *fh)
                if (!zr->v4l_memgrab_active)
                        zr36057_overlay(zr, 0);
                zr->overlay_mask = NULL;
+               zr->overlay_mask_dma = 0;
        }
 
        if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
@@ -940,8 +960,10 @@ static int zoran_open(struct file *file)
 
        /* used to be BUZ_MAX_WIDTH/HEIGHT, but that gives overflows
         * on norm-change! */
-       fh->overlay_mask =
-           kmalloc(((768 + 31) / 32) * 576 * 4, GFP_KERNEL);
+       fh->overlay_mask = dma_alloc_wc(&zr->pci_dev->dev,
+                                       ((768 + 31) / 32) * 576 * 4,
+                                       &fh->overlay_mask_dma,
+                                       GFP_KERNEL);
        if (!fh->overlay_mask) {
                dprintk(1,
                        KERN_ERR
@@ -1016,6 +1038,7 @@ zoran_close(struct file  *file)
                zr->v4l_overlay_active = 0;
                zr36057_overlay(zr, 0);
                zr->overlay_mask = NULL;
+               zr->overlay_mask_dma = 0;
 
                /* capture off */
                wake_up_interruptible(&zr->v4l_capq);
@@ -1033,7 +1056,8 @@ zoran_close(struct file  *file)
 
        v4l2_fh_del(&fh->fh);
        v4l2_fh_exit(&fh->fh);
-       kfree(fh->overlay_mask);
+       dma_free_wc(&zr->pci_dev->dev, ((768 + 31) / 32) * 576 * 4,
+                   fh->overlay_mask, fh->overlay_mask_dma);
        kfree(fh);
 
        dprintk(4, KERN_INFO "%s: %s done\n", ZR_DEVNAME(zr), __func__);
@@ -1284,6 +1308,7 @@ static int setup_overlay(struct zoran_fh *fh, int on)
                if (!zr->v4l_memgrab_active)
                        zr36057_overlay(zr, 0);
                zr->overlay_mask = NULL;
+               zr->overlay_mask_dma = 0;
        } else {
                if (!zr->vbuf_base || !fh->overlay_settings.is_set) {
                        dprintk(1,
@@ -1302,6 +1327,7 @@ static int setup_overlay(struct zoran_fh *fh, int on)
                zr->overlay_active = fh->overlay_active = ZORAN_LOCKED;
                zr->v4l_overlay_active = 1;
                zr->overlay_mask = fh->overlay_mask;
+               zr->overlay_mask_dma = fh->overlay_mask_dma;
                zr->overlay_settings = fh->overlay_settings;
                if (!zr->v4l_memgrab_active)
                        zr36057_overlay(zr, 1);
@@ -2763,7 +2789,7 @@ zoran_mmap (struct file           *file,
                                    le32_to_cpu(fh->buffers.
                                    buffer[i].jpg.frag_tab[2 * j]);
                                /* should just be pos on i386 */
-                               page = virt_to_phys(bus_to_virt(pos))
+                               page = 
virt_to_phys(fh->buffers.buffer[i].jpg.frag_virt_tab[j])
                                                                >> PAGE_SHIFT;
                                if (remap_pfn_range(vma, start, page,
                                                        todo, PAGE_SHARED)) {
-- 
2.9.0

Reply via email to