aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/video/saa7164/saa7164-buffer.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-21 09:03:10 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-21 09:03:10 -0700
commitc720f5655df159a630fa0290a0bd67c93e92b0bf (patch)
tree940d139d0ec1ff5201efddef6cc663166a8a2df3 /drivers/media/video/saa7164/saa7164-buffer.c
parent33e6c1a0de818d3698cdab27c42915661011319d (diff)
parent84d6ae431f315e8973aac3c3fe1d550fc9240ef3 (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (222 commits) V4L/DVB (13033): pt1: Don't use a deprecated DMA_BIT_MASK macro V4L/DVB (13029): radio-si4713: remove #include <linux/version.h> V4L/DVB (13027): go7007: convert printks to v4l2_info V4L/DVB (13026): s2250-board: Implement brightness and contrast controls V4L/DVB (13025): s2250-board: Fix memory leaks V4L/DVB (13024): go7007: Implement vidioc_g_std and vidioc_querystd V4L/DVB (13023): go7007: Merge struct gofh and go declarations V4L/DVB (13022): go7007: Fix mpeg controls V4L/DVB (13021): go7007: Fix whitespace and line lengths V4L/DVB (13020): go7007: Updates to Kconfig and Makefile V4L/DVB (13019): video: initial support for ADV7180 V4L/DVB (13018): kzalloc failure ignored in au8522_probe() V4L/DVB (13017): gspca: kmalloc failure ignored in sd_start() V4L/DVB (13016): kmalloc failure ignored in lgdt3304_attach() and s921_attach() V4L/DVB (13015): kmalloc failure ignored in m920x_firmware_download() V4L/DVB (13014): Add support for Compro VideoMate E800 (DVB-T part only) V4L/DVB (13013): FM TX: si4713: Kconfig: Fixed two typos. V4L/DVB (13012): uvc: introduce missing kfree V4L/DVB (13011): Change tuner type of BeholdTV cards V4L/DVB (13009): gspca - stv06xx-hdcs: Reduce exposure range ...
Diffstat (limited to 'drivers/media/video/saa7164/saa7164-buffer.c')
-rw-r--r--drivers/media/video/saa7164/saa7164-buffer.c155
1 files changed, 155 insertions, 0 deletions
diff --git a/drivers/media/video/saa7164/saa7164-buffer.c b/drivers/media/video/saa7164/saa7164-buffer.c
new file mode 100644
index 00000000000..9ca5c83d165
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-buffer.c
@@ -0,0 +1,155 @@
+/*
+ * Driver for the NXP SAA7164 PCIe bridge
+ *
+ * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "saa7164.h"
+
+/* The PCI address space for buffer handling looks like this:
+
+ +-u32 wide-------------+
+ | +
+ +-u64 wide------------------------------------+
+ + +
+ +----------------------+
+ | CurrentBufferPtr + Pointer to current PCI buffer >-+
+ +----------------------+ |
+ | Unused + |
+ +----------------------+ |
+ | Pitch + = 188 (bytes) |
+ +----------------------+ |
+ | PCI buffer size + = pitch * number of lines (312) |
+ +----------------------+ |
+ |0| Buf0 Write Offset + |
+ +----------------------+ v
+ |1| Buf1 Write Offset + |
+ +----------------------+ |
+ |2| Buf2 Write Offset + |
+ +----------------------+ |
+ |3| Buf3 Write Offset + |
+ +----------------------+ |
+ ... More write offsets |
+ +---------------------------------------------+ |
+ +0| set of ptrs to PCI pagetables + |
+ +---------------------------------------------+ |
+ +1| set of ptrs to PCI pagetables + <--------+
+ +---------------------------------------------+
+ +2| set of ptrs to PCI pagetables +
+ +---------------------------------------------+
+ +3| set of ptrs to PCI pagetables + >--+
+ +---------------------------------------------+ |
+ ... More buffer pointers | +----------------+
+ +->| pt[0] TS data |
+ | +----------------+
+ |
+ | +----------------+
+ +->| pt[1] TS data |
+ | +----------------+
+ | etc
+ */
+
+/* Allocate a new buffer structure and associated PCI space in bytes.
+ * len must be a multiple of sizeof(u64)
+ */
+struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_tsport *port,
+ u32 len)
+{
+ struct saa7164_buffer *buf = 0;
+ struct saa7164_dev *dev = port->dev;
+ int i;
+
+ if ((len == 0) || (len >= 65536) || (len % sizeof(u64))) {
+ log_warn("%s() SAA_ERR_BAD_PARAMETER\n", __func__);
+ goto ret;
+ }
+
+ buf = kzalloc(sizeof(struct saa7164_buffer), GFP_KERNEL);
+ if (buf == NULL) {
+ log_warn("%s() SAA_ERR_NO_RESOURCES\n", __func__);
+ goto ret;
+ }
+
+ buf->port = port;
+ buf->flags = SAA7164_BUFFER_FREE;
+ /* TODO: arg len is being ignored */
+ buf->pci_size = SAA7164_PT_ENTRIES * 0x1000;
+ buf->pt_size = (SAA7164_PT_ENTRIES * sizeof(u64)) + 0x1000;
+
+ /* Allocate contiguous memory */
+ buf->cpu = pci_alloc_consistent(port->dev->pci, buf->pci_size,
+ &buf->dma);
+ if (!buf->cpu)
+ goto fail1;
+
+ buf->pt_cpu = pci_alloc_consistent(port->dev->pci, buf->pt_size,
+ &buf->pt_dma);
+ if (!buf->pt_cpu)
+ goto fail2;
+
+ /* init the buffers to a known pattern, easier during debugging */
+ memset(buf->cpu, 0xff, buf->pci_size);
+ memset(buf->pt_cpu, 0xff, buf->pt_size);
+
+ dprintk(DBGLVL_BUF, "%s() allocated buffer @ 0x%p\n", __func__, buf);
+ dprintk(DBGLVL_BUF, " pci_cpu @ 0x%p dma @ 0x%08lx len = 0x%x\n",
+ buf->cpu, (long)buf->dma, buf->pci_size);
+ dprintk(DBGLVL_BUF, " pt_cpu @ 0x%p pt_dma @ 0x%08lx len = 0x%x\n",
+ buf->pt_cpu, (long)buf->pt_dma, buf->pt_size);
+
+ /* Format the Page Table Entries to point into the data buffer */
+ for (i = 0 ; i < SAA7164_PT_ENTRIES; i++) {
+
+ *(buf->pt_cpu + i) = buf->dma + (i * 0x1000); /* TODO */
+
+ }
+
+ goto ret;
+
+fail2:
+ pci_free_consistent(port->dev->pci, buf->pci_size, buf->cpu, buf->dma);
+fail1:
+ kfree(buf);
+
+ buf = 0;
+ret:
+ return buf;
+}
+
+int saa7164_buffer_dealloc(struct saa7164_tsport *port,
+ struct saa7164_buffer *buf)
+{
+ struct saa7164_dev *dev = port->dev;
+
+ if ((buf == 0) || (port == 0))
+ return SAA_ERR_BAD_PARAMETER;
+
+ dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n", __func__, buf);
+
+ if (buf->flags != SAA7164_BUFFER_FREE)
+ log_warn(" freeing a non-free buffer\n");
+
+ pci_free_consistent(port->dev->pci, buf->pci_size, buf->cpu, buf->dma);
+ pci_free_consistent(port->dev->pci, buf->pt_size, buf->pt_cpu,
+ buf->pt_dma);
+
+ kfree(buf);
+
+ return SAA_OK;
+}
+