xref: /openbmc/linux/drivers/media/pci/saa7164/saa7164-buffer.c (revision d0034a7a4ac7fae708146ac0059b9c47a1543f0d)
1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2b285192aSMauro Carvalho Chehab /*
3b285192aSMauro Carvalho Chehab  *  Driver for the NXP SAA7164 PCIe bridge
4b285192aSMauro Carvalho Chehab  *
563a412ecSSteven Toth  *  Copyright (c) 2010-2015 Steven Toth <stoth@kernellabs.com>
6b285192aSMauro Carvalho Chehab  */
7b285192aSMauro Carvalho Chehab 
8b285192aSMauro Carvalho Chehab #include <linux/slab.h>
9b285192aSMauro Carvalho Chehab 
10b285192aSMauro Carvalho Chehab #include "saa7164.h"
11b285192aSMauro Carvalho Chehab 
12b285192aSMauro Carvalho Chehab /* The PCI address space for buffer handling looks like this:
13b285192aSMauro Carvalho Chehab  *
14b285192aSMauro Carvalho Chehab  * +-u32 wide-------------+
15b285192aSMauro Carvalho Chehab  * |                      +
16b285192aSMauro Carvalho Chehab  * +-u64 wide------------------------------------+
17b285192aSMauro Carvalho Chehab  * +                                             +
18b285192aSMauro Carvalho Chehab  * +----------------------+
19b285192aSMauro Carvalho Chehab  * | CurrentBufferPtr     + Pointer to current PCI buffer >-+
20b285192aSMauro Carvalho Chehab  * +----------------------+                                 |
21b285192aSMauro Carvalho Chehab  * | Unused               +                                 |
22b285192aSMauro Carvalho Chehab  * +----------------------+                                 |
23b285192aSMauro Carvalho Chehab  * | Pitch                + = 188 (bytes)                   |
24b285192aSMauro Carvalho Chehab  * +----------------------+                                 |
25b285192aSMauro Carvalho Chehab  * | PCI buffer size      + = pitch * number of lines (312) |
26b285192aSMauro Carvalho Chehab  * +----------------------+                                 |
27b285192aSMauro Carvalho Chehab  * |0| Buf0 Write Offset  +                                 |
28b285192aSMauro Carvalho Chehab  * +----------------------+                                 v
29b285192aSMauro Carvalho Chehab  * |1| Buf1 Write Offset  +                                 |
30b285192aSMauro Carvalho Chehab  * +----------------------+                                 |
31b285192aSMauro Carvalho Chehab  * |2| Buf2 Write Offset  +                                 |
32b285192aSMauro Carvalho Chehab  * +----------------------+                                 |
33b285192aSMauro Carvalho Chehab  * |3| Buf3 Write Offset  +                                 |
34b285192aSMauro Carvalho Chehab  * +----------------------+                                 |
35b285192aSMauro Carvalho Chehab  * ... More write offsets                                   |
36b285192aSMauro Carvalho Chehab  * +---------------------------------------------+          |
37b285192aSMauro Carvalho Chehab  * +0| set of ptrs to PCI pagetables             +          |
38b285192aSMauro Carvalho Chehab  * +---------------------------------------------+          |
39b285192aSMauro Carvalho Chehab  * +1| set of ptrs to PCI pagetables             + <--------+
40b285192aSMauro Carvalho Chehab  * +---------------------------------------------+
41b285192aSMauro Carvalho Chehab  * +2| set of ptrs to PCI pagetables             +
42b285192aSMauro Carvalho Chehab  * +---------------------------------------------+
43b285192aSMauro Carvalho Chehab  * +3| set of ptrs to PCI pagetables             + >--+
44b285192aSMauro Carvalho Chehab  * +---------------------------------------------+    |
45b285192aSMauro Carvalho Chehab  * ... More buffer pointers                           |  +----------------+
46b285192aSMauro Carvalho Chehab  *						    +->| pt[0] TS data  |
47b285192aSMauro Carvalho Chehab  *						    |  +----------------+
48b285192aSMauro Carvalho Chehab  *						    |
49b285192aSMauro Carvalho Chehab  *						    |  +----------------+
50b285192aSMauro Carvalho Chehab  *						    +->| pt[1] TS data  |
51b285192aSMauro Carvalho Chehab  *						    |  +----------------+
52b285192aSMauro Carvalho Chehab  *						    | etc
53b285192aSMauro Carvalho Chehab  */
54b285192aSMauro Carvalho Chehab 
saa7164_buffer_display(struct saa7164_buffer * buf)55b285192aSMauro Carvalho Chehab void saa7164_buffer_display(struct saa7164_buffer *buf)
56b285192aSMauro Carvalho Chehab {
57b285192aSMauro Carvalho Chehab 	struct saa7164_dev *dev = buf->port->dev;
58b285192aSMauro Carvalho Chehab 	int i;
59b285192aSMauro Carvalho Chehab 
60b285192aSMauro Carvalho Chehab 	dprintk(DBGLVL_BUF, "%s()   buffer @ 0x%p nr=%d\n",
61b285192aSMauro Carvalho Chehab 		__func__, buf, buf->idx);
62b285192aSMauro Carvalho Chehab 	dprintk(DBGLVL_BUF, "  pci_cpu @ 0x%p    dma @ 0x%08llx len = 0x%x\n",
63b285192aSMauro Carvalho Chehab 		buf->cpu, (long long)buf->dma, buf->pci_size);
64b285192aSMauro Carvalho Chehab 	dprintk(DBGLVL_BUF, "   pt_cpu @ 0x%p pt_dma @ 0x%08llx len = 0x%x\n",
65b285192aSMauro Carvalho Chehab 		buf->pt_cpu, (long long)buf->pt_dma, buf->pt_size);
66b285192aSMauro Carvalho Chehab 
67b285192aSMauro Carvalho Chehab 	/* Format the Page Table Entries to point into the data buffer */
68b285192aSMauro Carvalho Chehab 	for (i = 0 ; i < SAA7164_PT_ENTRIES; i++) {
69b285192aSMauro Carvalho Chehab 
70b285192aSMauro Carvalho Chehab 		dprintk(DBGLVL_BUF, "    pt[%02d] = 0x%p -> 0x%llx\n",
71b285192aSMauro Carvalho Chehab 			i, buf->pt_cpu, (u64)*(buf->pt_cpu));
72b285192aSMauro Carvalho Chehab 
73b285192aSMauro Carvalho Chehab 	}
74b285192aSMauro Carvalho Chehab }
75b285192aSMauro Carvalho Chehab /* Allocate a new buffer structure and associated PCI space in bytes.
76b285192aSMauro Carvalho Chehab  * len must be a multiple of sizeof(u64)
77b285192aSMauro Carvalho Chehab  */
saa7164_buffer_alloc(struct saa7164_port * port,u32 len)78b285192aSMauro Carvalho Chehab struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_port *port,
79b285192aSMauro Carvalho Chehab 	u32 len)
80b285192aSMauro Carvalho Chehab {
81b285192aSMauro Carvalho Chehab 	struct tmHWStreamParameters *params = &port->hw_streamingparams;
82b285192aSMauro Carvalho Chehab 	struct saa7164_buffer *buf = NULL;
83b285192aSMauro Carvalho Chehab 	struct saa7164_dev *dev = port->dev;
84b285192aSMauro Carvalho Chehab 	int i;
85b285192aSMauro Carvalho Chehab 
86b285192aSMauro Carvalho Chehab 	if ((len == 0) || (len >= 65536) || (len % sizeof(u64))) {
87b285192aSMauro Carvalho Chehab 		log_warn("%s() SAA_ERR_BAD_PARAMETER\n", __func__);
88b285192aSMauro Carvalho Chehab 		goto ret;
89b285192aSMauro Carvalho Chehab 	}
90b285192aSMauro Carvalho Chehab 
912d3da59fSMarkus Elfring 	buf = kzalloc(sizeof(*buf), GFP_KERNEL);
92c38e8657SMarkus Elfring 	if (!buf)
93b285192aSMauro Carvalho Chehab 		goto ret;
94b285192aSMauro Carvalho Chehab 
95b285192aSMauro Carvalho Chehab 	buf->idx = -1;
96b285192aSMauro Carvalho Chehab 	buf->port = port;
97b285192aSMauro Carvalho Chehab 	buf->flags = SAA7164_BUFFER_FREE;
98b285192aSMauro Carvalho Chehab 	buf->pos = 0;
99b285192aSMauro Carvalho Chehab 	buf->actual_size = params->pitch * params->numberoflines;
100b285192aSMauro Carvalho Chehab 	buf->crc = 0;
101b285192aSMauro Carvalho Chehab 	/* TODO: arg len is being ignored */
102b285192aSMauro Carvalho Chehab 	buf->pci_size = SAA7164_PT_ENTRIES * 0x1000;
103b285192aSMauro Carvalho Chehab 	buf->pt_size = (SAA7164_PT_ENTRIES * sizeof(u64)) + 0x1000;
104b285192aSMauro Carvalho Chehab 
105b285192aSMauro Carvalho Chehab 	/* Allocate contiguous memory */
106*873a623fSChristophe JAILLET 	buf->cpu = dma_alloc_coherent(&port->dev->pci->dev, buf->pci_size,
107*873a623fSChristophe JAILLET 				      &buf->dma, GFP_KERNEL);
108b285192aSMauro Carvalho Chehab 	if (!buf->cpu)
109b285192aSMauro Carvalho Chehab 		goto fail1;
110b285192aSMauro Carvalho Chehab 
111*873a623fSChristophe JAILLET 	buf->pt_cpu = dma_alloc_coherent(&port->dev->pci->dev, buf->pt_size,
112*873a623fSChristophe JAILLET 					 &buf->pt_dma, GFP_KERNEL);
113b285192aSMauro Carvalho Chehab 	if (!buf->pt_cpu)
114b285192aSMauro Carvalho Chehab 		goto fail2;
115b285192aSMauro Carvalho Chehab 
116b285192aSMauro Carvalho Chehab 	/* init the buffers to a known pattern, easier during debugging */
117065e1477SHans Verkuil 	memset(buf->cpu, 0xff, buf->pci_size);
118b285192aSMauro Carvalho Chehab 	buf->crc = crc32(0, buf->cpu, buf->actual_size);
119065e1477SHans Verkuil 	memset(buf->pt_cpu, 0xff, buf->pt_size);
120b285192aSMauro Carvalho Chehab 
121b285192aSMauro Carvalho Chehab 	dprintk(DBGLVL_BUF, "%s()   allocated buffer @ 0x%p (%d pageptrs)\n",
122b285192aSMauro Carvalho Chehab 		__func__, buf, params->numpagetables);
123b285192aSMauro Carvalho Chehab 	dprintk(DBGLVL_BUF, "  pci_cpu @ 0x%p    dma @ 0x%08lx len = 0x%x\n",
124b285192aSMauro Carvalho Chehab 		buf->cpu, (long)buf->dma, buf->pci_size);
125b285192aSMauro Carvalho Chehab 	dprintk(DBGLVL_BUF, "   pt_cpu @ 0x%p pt_dma @ 0x%08lx len = 0x%x\n",
126b285192aSMauro Carvalho Chehab 		buf->pt_cpu, (long)buf->pt_dma, buf->pt_size);
127b285192aSMauro Carvalho Chehab 
128b285192aSMauro Carvalho Chehab 	/* Format the Page Table Entries to point into the data buffer */
129b285192aSMauro Carvalho Chehab 	for (i = 0 ; i < params->numpagetables; i++) {
130b285192aSMauro Carvalho Chehab 
131b285192aSMauro Carvalho Chehab 		*(buf->pt_cpu + i) = buf->dma + (i * 0x1000); /* TODO */
132b285192aSMauro Carvalho Chehab 		dprintk(DBGLVL_BUF, "    pt[%02d] = 0x%p -> 0x%llx\n",
133b285192aSMauro Carvalho Chehab 			i, buf->pt_cpu, (u64)*(buf->pt_cpu));
134b285192aSMauro Carvalho Chehab 
135b285192aSMauro Carvalho Chehab 	}
136b285192aSMauro Carvalho Chehab 
137b285192aSMauro Carvalho Chehab 	goto ret;
138b285192aSMauro Carvalho Chehab 
139b285192aSMauro Carvalho Chehab fail2:
140*873a623fSChristophe JAILLET 	dma_free_coherent(&port->dev->pci->dev, buf->pci_size, buf->cpu,
141*873a623fSChristophe JAILLET 			  buf->dma);
142b285192aSMauro Carvalho Chehab fail1:
143b285192aSMauro Carvalho Chehab 	kfree(buf);
144b285192aSMauro Carvalho Chehab 
145b285192aSMauro Carvalho Chehab 	buf = NULL;
146b285192aSMauro Carvalho Chehab ret:
147b285192aSMauro Carvalho Chehab 	return buf;
148b285192aSMauro Carvalho Chehab }
149b285192aSMauro Carvalho Chehab 
saa7164_buffer_dealloc(struct saa7164_buffer * buf)150b285192aSMauro Carvalho Chehab int saa7164_buffer_dealloc(struct saa7164_buffer *buf)
151b285192aSMauro Carvalho Chehab {
152b285192aSMauro Carvalho Chehab 	struct saa7164_dev *dev;
153b285192aSMauro Carvalho Chehab 
154b285192aSMauro Carvalho Chehab 	if (!buf || !buf->port)
155b285192aSMauro Carvalho Chehab 		return SAA_ERR_BAD_PARAMETER;
156b285192aSMauro Carvalho Chehab 	dev = buf->port->dev;
157b285192aSMauro Carvalho Chehab 
158b285192aSMauro Carvalho Chehab 	dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n",
159b285192aSMauro Carvalho Chehab 		__func__, buf);
160b285192aSMauro Carvalho Chehab 
161b285192aSMauro Carvalho Chehab 	if (buf->flags != SAA7164_BUFFER_FREE)
162b285192aSMauro Carvalho Chehab 		log_warn(" freeing a non-free buffer\n");
163b285192aSMauro Carvalho Chehab 
164*873a623fSChristophe JAILLET 	dma_free_coherent(&dev->pci->dev, buf->pci_size, buf->cpu, buf->dma);
165*873a623fSChristophe JAILLET 	dma_free_coherent(&dev->pci->dev, buf->pt_size, buf->pt_cpu,
166*873a623fSChristophe JAILLET 			  buf->pt_dma);
167b285192aSMauro Carvalho Chehab 
168b285192aSMauro Carvalho Chehab 	kfree(buf);
169b285192aSMauro Carvalho Chehab 
170b285192aSMauro Carvalho Chehab 	return SAA_OK;
171b285192aSMauro Carvalho Chehab }
172b285192aSMauro Carvalho Chehab 
saa7164_buffer_zero_offsets(struct saa7164_port * port,int i)173b285192aSMauro Carvalho Chehab int saa7164_buffer_zero_offsets(struct saa7164_port *port, int i)
174b285192aSMauro Carvalho Chehab {
175b285192aSMauro Carvalho Chehab 	struct saa7164_dev *dev = port->dev;
176b285192aSMauro Carvalho Chehab 
177b285192aSMauro Carvalho Chehab 	if ((i < 0) || (i >= port->hwcfg.buffercount))
178b285192aSMauro Carvalho Chehab 		return -EINVAL;
179b285192aSMauro Carvalho Chehab 
180b285192aSMauro Carvalho Chehab 	dprintk(DBGLVL_BUF, "%s(idx = %d)\n", __func__, i);
181b285192aSMauro Carvalho Chehab 
182b285192aSMauro Carvalho Chehab 	saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0);
183b285192aSMauro Carvalho Chehab 
184b285192aSMauro Carvalho Chehab 	return 0;
185b285192aSMauro Carvalho Chehab }
186b285192aSMauro Carvalho Chehab 
187b285192aSMauro Carvalho Chehab /* Write a buffer into the hardware */
saa7164_buffer_activate(struct saa7164_buffer * buf,int i)188b285192aSMauro Carvalho Chehab int saa7164_buffer_activate(struct saa7164_buffer *buf, int i)
189b285192aSMauro Carvalho Chehab {
190b285192aSMauro Carvalho Chehab 	struct saa7164_port *port = buf->port;
191b285192aSMauro Carvalho Chehab 	struct saa7164_dev *dev = port->dev;
192b285192aSMauro Carvalho Chehab 
193b285192aSMauro Carvalho Chehab 	if ((i < 0) || (i >= port->hwcfg.buffercount))
194b285192aSMauro Carvalho Chehab 		return -EINVAL;
195b285192aSMauro Carvalho Chehab 
196b285192aSMauro Carvalho Chehab 	dprintk(DBGLVL_BUF, "%s(idx = %d)\n", __func__, i);
197b285192aSMauro Carvalho Chehab 
198b285192aSMauro Carvalho Chehab 	buf->idx = i; /* Note of which buffer list index position we occupy */
199b285192aSMauro Carvalho Chehab 	buf->flags = SAA7164_BUFFER_BUSY;
200b285192aSMauro Carvalho Chehab 	buf->pos = 0;
201b285192aSMauro Carvalho Chehab 
202b285192aSMauro Carvalho Chehab 	/* TODO: Review this in light of 32v64 assignments */
203b285192aSMauro Carvalho Chehab 	saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0);
204b285192aSMauro Carvalho Chehab 	saa7164_writel(port->bufptr32h + ((sizeof(u32) * 2) * i), buf->pt_dma);
205b285192aSMauro Carvalho Chehab 	saa7164_writel(port->bufptr32l + ((sizeof(u32) * 2) * i), 0);
206b285192aSMauro Carvalho Chehab 
20724f711c1SMauro Carvalho Chehab 	dprintk(DBGLVL_BUF, "	buf[%d] offset 0x%llx (0x%x) buf 0x%llx/%llx (0x%x/%x) nr=%d\n",
208b285192aSMauro Carvalho Chehab 		buf->idx,
209b285192aSMauro Carvalho Chehab 		(u64)port->bufoffset + (i * sizeof(u32)),
210b285192aSMauro Carvalho Chehab 		saa7164_readl(port->bufoffset + (sizeof(u32) * i)),
211b285192aSMauro Carvalho Chehab 		(u64)port->bufptr32h + ((sizeof(u32) * 2) * i),
212b285192aSMauro Carvalho Chehab 		(u64)port->bufptr32l + ((sizeof(u32) * 2) * i),
213b285192aSMauro Carvalho Chehab 		saa7164_readl(port->bufptr32h + ((sizeof(u32) * i) * 2)),
214b285192aSMauro Carvalho Chehab 		saa7164_readl(port->bufptr32l + ((sizeof(u32) * i) * 2)),
215b285192aSMauro Carvalho Chehab 		buf->idx);
216b285192aSMauro Carvalho Chehab 
217b285192aSMauro Carvalho Chehab 	return 0;
218b285192aSMauro Carvalho Chehab }
219b285192aSMauro Carvalho Chehab 
saa7164_buffer_cfg_port(struct saa7164_port * port)220b285192aSMauro Carvalho Chehab int saa7164_buffer_cfg_port(struct saa7164_port *port)
221b285192aSMauro Carvalho Chehab {
222b285192aSMauro Carvalho Chehab 	struct tmHWStreamParameters *params = &port->hw_streamingparams;
223b285192aSMauro Carvalho Chehab 	struct saa7164_dev *dev = port->dev;
224b285192aSMauro Carvalho Chehab 	struct saa7164_buffer *buf;
225b285192aSMauro Carvalho Chehab 	struct list_head *c, *n;
226b285192aSMauro Carvalho Chehab 	int i = 0;
227b285192aSMauro Carvalho Chehab 
228b285192aSMauro Carvalho Chehab 	dprintk(DBGLVL_BUF, "%s(port=%d)\n", __func__, port->nr);
229b285192aSMauro Carvalho Chehab 
230b285192aSMauro Carvalho Chehab 	saa7164_writel(port->bufcounter, 0);
231b285192aSMauro Carvalho Chehab 	saa7164_writel(port->pitch, params->pitch);
232b285192aSMauro Carvalho Chehab 	saa7164_writel(port->bufsize, params->pitch * params->numberoflines);
233b285192aSMauro Carvalho Chehab 
234b285192aSMauro Carvalho Chehab 	dprintk(DBGLVL_BUF, " configured:\n");
235b285192aSMauro Carvalho Chehab 	dprintk(DBGLVL_BUF, "   lmmio       0x%p\n", dev->lmmio);
236b285192aSMauro Carvalho Chehab 	dprintk(DBGLVL_BUF, "   bufcounter  0x%x = 0x%x\n", port->bufcounter,
237b285192aSMauro Carvalho Chehab 		saa7164_readl(port->bufcounter));
238b285192aSMauro Carvalho Chehab 
239b285192aSMauro Carvalho Chehab 	dprintk(DBGLVL_BUF, "   pitch       0x%x = %d\n", port->pitch,
240b285192aSMauro Carvalho Chehab 		saa7164_readl(port->pitch));
241b285192aSMauro Carvalho Chehab 
242b285192aSMauro Carvalho Chehab 	dprintk(DBGLVL_BUF, "   bufsize     0x%x = %d\n", port->bufsize,
243b285192aSMauro Carvalho Chehab 		saa7164_readl(port->bufsize));
244b285192aSMauro Carvalho Chehab 
245b285192aSMauro Carvalho Chehab 	dprintk(DBGLVL_BUF, "   buffercount = %d\n", port->hwcfg.buffercount);
246b285192aSMauro Carvalho Chehab 	dprintk(DBGLVL_BUF, "   bufoffset = 0x%x\n", port->bufoffset);
247b285192aSMauro Carvalho Chehab 	dprintk(DBGLVL_BUF, "   bufptr32h = 0x%x\n", port->bufptr32h);
248b285192aSMauro Carvalho Chehab 	dprintk(DBGLVL_BUF, "   bufptr32l = 0x%x\n", port->bufptr32l);
249b285192aSMauro Carvalho Chehab 
250b285192aSMauro Carvalho Chehab 	/* Poke the buffers and offsets into PCI space */
251b285192aSMauro Carvalho Chehab 	mutex_lock(&port->dmaqueue_lock);
252b285192aSMauro Carvalho Chehab 	list_for_each_safe(c, n, &port->dmaqueue.list) {
253b285192aSMauro Carvalho Chehab 		buf = list_entry(c, struct saa7164_buffer, list);
254b285192aSMauro Carvalho Chehab 
2552ad5e2e4SDaniel W. S. Almeida 		BUG_ON(buf->flags != SAA7164_BUFFER_FREE);
256b285192aSMauro Carvalho Chehab 
257b285192aSMauro Carvalho Chehab 		/* Place the buffer in the h/w queue */
258b285192aSMauro Carvalho Chehab 		saa7164_buffer_activate(buf, i);
259b285192aSMauro Carvalho Chehab 
260b285192aSMauro Carvalho Chehab 		/* Don't exceed the device maximum # bufs */
2612ad5e2e4SDaniel W. S. Almeida 		BUG_ON(i > port->hwcfg.buffercount);
2622ad5e2e4SDaniel W. S. Almeida 		i++;
263b285192aSMauro Carvalho Chehab 
264b285192aSMauro Carvalho Chehab 	}
265b285192aSMauro Carvalho Chehab 	mutex_unlock(&port->dmaqueue_lock);
266b285192aSMauro Carvalho Chehab 
267b285192aSMauro Carvalho Chehab 	return 0;
268b285192aSMauro Carvalho Chehab }
269b285192aSMauro Carvalho Chehab 
saa7164_buffer_alloc_user(struct saa7164_dev * dev,u32 len)270b285192aSMauro Carvalho Chehab struct saa7164_user_buffer *saa7164_buffer_alloc_user(struct saa7164_dev *dev,
271b285192aSMauro Carvalho Chehab 	u32 len)
272b285192aSMauro Carvalho Chehab {
273b285192aSMauro Carvalho Chehab 	struct saa7164_user_buffer *buf;
274b285192aSMauro Carvalho Chehab 
2752d3da59fSMarkus Elfring 	buf = kzalloc(sizeof(*buf), GFP_KERNEL);
276b285192aSMauro Carvalho Chehab 	if (!buf)
277b285192aSMauro Carvalho Chehab 		return NULL;
278b285192aSMauro Carvalho Chehab 
279b285192aSMauro Carvalho Chehab 	buf->data = kzalloc(len, GFP_KERNEL);
280b285192aSMauro Carvalho Chehab 
281b285192aSMauro Carvalho Chehab 	if (!buf->data) {
282b285192aSMauro Carvalho Chehab 		kfree(buf);
283b285192aSMauro Carvalho Chehab 		return NULL;
284b285192aSMauro Carvalho Chehab 	}
285b285192aSMauro Carvalho Chehab 
286b285192aSMauro Carvalho Chehab 	buf->actual_size = len;
287b285192aSMauro Carvalho Chehab 	buf->pos = 0;
288b285192aSMauro Carvalho Chehab 	buf->crc = 0;
289b285192aSMauro Carvalho Chehab 
290b285192aSMauro Carvalho Chehab 	dprintk(DBGLVL_BUF, "%s()   allocated user buffer @ 0x%p\n",
291b285192aSMauro Carvalho Chehab 		__func__, buf);
292b285192aSMauro Carvalho Chehab 
293b285192aSMauro Carvalho Chehab 	return buf;
294b285192aSMauro Carvalho Chehab }
295b285192aSMauro Carvalho Chehab 
saa7164_buffer_dealloc_user(struct saa7164_user_buffer * buf)296b285192aSMauro Carvalho Chehab void saa7164_buffer_dealloc_user(struct saa7164_user_buffer *buf)
297b285192aSMauro Carvalho Chehab {
298b285192aSMauro Carvalho Chehab 	if (!buf)
299b285192aSMauro Carvalho Chehab 		return;
300b285192aSMauro Carvalho Chehab 
301b285192aSMauro Carvalho Chehab 	kfree(buf->data);
302b285192aSMauro Carvalho Chehab 	buf->data = NULL;
303b285192aSMauro Carvalho Chehab 
304b285192aSMauro Carvalho Chehab 	kfree(buf);
305b285192aSMauro Carvalho Chehab }
306