summaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/standalone/0002-Resizer-bug-fixes-on-top-of-1.0.2-release.patch
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:14:24 +0100
committerRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:29:45 +0100
commit29d6678fd546377459ef75cf54abeef5b969b5cf (patch)
tree8edd65790e37a00d01c3f203f773fe4b5012db18 /meta/recipes-kernel/linux/linux-omap-2.6.29/isp/standalone/0002-Resizer-bug-fixes-on-top-of-1.0.2-release.patch
parentda49de6885ee1bc424e70bc02f21f6ab920efb55 (diff)
downloadpoky-29d6678fd546377459ef75cf54abeef5b969b5cf.tar.gz
Major layout change to the packages directory
Having one monolithic packages directory makes it hard to find things and is generally overwhelming. This commit splits it into several logical sections roughly based on function, recipes.txt gives more information about the classifications used. The opportunity is also used to switch from "packages" to "recipes" as used in OpenEmbedded as the term "packages" can be confusing to people and has many different meanings. Not all recipes have been classified yet, this is just a first pass at separating things out. Some packages are moved to meta-extras as they're no longer actively used or maintained. Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'meta/recipes-kernel/linux/linux-omap-2.6.29/isp/standalone/0002-Resizer-bug-fixes-on-top-of-1.0.2-release.patch')
-rw-r--r--meta/recipes-kernel/linux/linux-omap-2.6.29/isp/standalone/0002-Resizer-bug-fixes-on-top-of-1.0.2-release.patch730
1 files changed, 730 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/standalone/0002-Resizer-bug-fixes-on-top-of-1.0.2-release.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/standalone/0002-Resizer-bug-fixes-on-top-of-1.0.2-release.patch
new file mode 100644
index 0000000000..631b05f417
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/standalone/0002-Resizer-bug-fixes-on-top-of-1.0.2-release.patch
@@ -0,0 +1,730 @@
1From 20d79137ecaa6c7dad007d9ea1d7be5550db4839 Mon Sep 17 00:00:00 2001
2From: Vaibhav Hiremath <hvaibhav@ti.com>
3Date: Fri, 13 Feb 2009 15:40:25 +0530
4Subject: [PATCH 2/2] Resizer bug fixes on top of 1.0.2 release
5
6This commit contains resizer bug fixes on top of
7 PSP1.0.2 release -
8 - 4096 aligned address constraint
9 - workaround for extra page allocation for page aligned
10 size buffers
11
12Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
13---
14 drivers/media/video/isp/omap_resizer.c | 417 ++++++++++++++++++++++++--------
15 include/linux/omap_resizer.h | 3 +-
16 2 files changed, 321 insertions(+), 99 deletions(-)
17
18diff --git a/drivers/media/video/isp/omap_resizer.c b/drivers/media/video/isp/omap_resizer.c
19index 54bc425..8059c70 100644
20--- a/drivers/media/video/isp/omap_resizer.c
21+++ b/drivers/media/video/isp/omap_resizer.c
22@@ -28,6 +28,7 @@
23 #include <linux/platform_device.h>
24 #include <linux/io.h>
25 #include <linux/uaccess.h>
26+#include <linux/pci.h>
27 #include <media/v4l2-dev.h>
28 #include <asm/cacheflush.h>
29
30@@ -76,6 +77,10 @@
31 #define MAX_COEF_COUNTER 16
32 #define COEFF_ADDRESS_OFFSET 0x04
33
34+#define RSZ_DEF_REQ_EXP 0xE /* Default read operation expand
35+ * for the Resizer driver; value
36+ * taken from Davinci.
37+ */
38 /* Global structure which contains information about number of channels
39 and protection variables */
40 struct device_params {
41@@ -85,6 +90,7 @@ struct device_params {
42 struct mutex reszwrap_mutex; /* Semaphore for array */
43
44 struct videobuf_queue_ops vbq_ops; /* videobuf queue operations */
45+ unsigned long extra_page_addr;
46 };
47
48 /* Register mapped structure which contains the every register
49@@ -126,6 +132,9 @@ struct resizer_config {
50 u32 rsz_yehn; /* yehn(luma)register mapping
51 * variable.
52 */
53+ u32 sdr_req_exp; /* Configuration for Non
54+ * real time read expand
55+ */
56 };
57
58 struct rsz_mult {
59@@ -179,6 +188,7 @@ struct channel_config {
60 * channel is busy or not
61 */
62 struct mutex chanprotection_mutex;
63+ int buf_address[VIDEO_MAX_FRAME];
64 enum config_done config_state;
65 u8 input_buf_index;
66 u8 output_buf_index;
67@@ -200,8 +210,6 @@ struct rsz_fh {
68 struct videobuf_queue vbq;
69 struct device_params *device;
70
71- dma_addr_t isp_addr_read; /* Input/Output address */
72- dma_addr_t isp_addr_write; /* Input/Output address */
73 u32 rsz_bufsize; /* channel specific buffersize
74 */
75 };
76@@ -227,6 +235,10 @@ static int rsz_set_ratio(struct rsz_mult *multipass,
77 static void rsz_config_ratio(struct rsz_mult *multipass,
78 struct channel_config *rsz_conf_chan);
79
80+static void inline rsz_set_exp(unsigned int exp)
81+{
82+ omap_writel(((exp & 0x3FF) << 10), OMAP3ISP_SBL_REG(0xF8));
83+}
84 /**
85 * rsz_hardware_setup - Sets hardware configuration registers
86 * @rsz_conf_chan: Structure containing channel configuration
87@@ -271,12 +283,15 @@ static void rsz_hardware_setup(struct channel_config *rsz_conf_chan)
88 + coeffoffset));
89 coeffoffset = coeffoffset + COEFF_ADDRESS_OFFSET;
90 }
91+ /* Configure the read expand register */
92+ rsz_set_exp(rsz_conf_chan->register_config.sdr_req_exp);
93 }
94
95 /**
96 * rsz_start - Enables Resizer Wrapper
97 * @arg: Currently not used.
98- * @device: Structure containing ISP resizer wrapper global information
99+ * @fh: File structure containing ISP resizer information specific to
100+ * channel opened.
101 *
102 * Submits a resizing task specified by the rsz_resize structure. The call can
103 * either be blocked until the task is completed or returned immediately based
104@@ -292,12 +307,18 @@ int rsz_start(int *arg, struct rsz_fh *fh)
105 struct channel_config *rsz_conf_chan = fh->config;
106 struct rsz_mult *multipass = fh->multipass;
107 struct videobuf_queue *q = &fh->vbq;
108+ struct videobuf_buffer *buf;
109 int ret;
110
111 if (rsz_conf_chan->config_state) {
112 dev_err(rsz_device, "State not configured \n");
113 goto err_einval;
114 }
115+ if (!rsz_conf_chan->register_config.rsz_sdr_inadd ||
116+ !rsz_conf_chan->register_config.rsz_sdr_outadd) {
117+ dev_err(rsz_device, "address is null\n");
118+ goto err_einval;
119+ }
120
121 rsz_conf_chan->status = CHANNEL_BUSY;
122
123@@ -325,33 +346,22 @@ mult:
124 goto mult;
125 }
126
127- if (fh->isp_addr_read) {
128- ispmmu_vunmap(fh->isp_addr_read);
129- fh->isp_addr_read = 0;
130- }
131- if (fh->isp_addr_write) {
132- ispmmu_vunmap(fh->isp_addr_write);
133- fh->isp_addr_write = 0;
134- }
135-
136 rsz_conf_chan->status = CHANNEL_FREE;
137- q->bufs[rsz_conf_chan->input_buf_index]->state = VIDEOBUF_NEEDS_INIT;
138- q->bufs[rsz_conf_chan->output_buf_index]->state = VIDEOBUF_NEEDS_INIT;
139 rsz_conf_chan->register_config.rsz_sdr_outadd = 0;
140 rsz_conf_chan->register_config.rsz_sdr_inadd = 0;
141
142- /* Unmap and free the DMA memory allocated for buffers */
143- videobuf_dma_unmap(q, videobuf_to_dma(
144- q->bufs[rsz_conf_chan->input_buf_index]));
145- videobuf_dma_unmap(q, videobuf_to_dma(
146- q->bufs[rsz_conf_chan->output_buf_index]));
147- videobuf_dma_free(videobuf_to_dma(
148- q->bufs[rsz_conf_chan->input_buf_index]));
149- videobuf_dma_free(videobuf_to_dma(
150- q->bufs[rsz_conf_chan->output_buf_index]));
151-
152 isp_unset_callback(CBK_RESZ_DONE);
153
154+ /* Empty the Videobuf queue which was filled during the qbuf */
155+ buf = q->bufs[rsz_conf_chan->input_buf_index];
156+ buf->state = VIDEOBUF_IDLE;
157+ list_del(&buf->stream);
158+ if (rsz_conf_chan->input_buf_index != rsz_conf_chan->output_buf_index) {
159+ buf = q->bufs[rsz_conf_chan->output_buf_index];
160+ buf->state = VIDEOBUF_IDLE;
161+ list_del(&buf->stream);
162+ }
163+
164 return 0;
165 err_einval:
166 return -EINVAL;
167@@ -359,6 +369,8 @@ err_einval:
168
169 /**
170 * rsz_set_multipass - Set resizer multipass
171+ * @multipass: Structure containing channel configuration
172+ for multipass support
173 * @rsz_conf_chan: Structure containing channel configuration
174 *
175 * Returns always 0
176@@ -384,6 +396,8 @@ static int rsz_set_multipass(struct rsz_mult *multipass,
177
178 /**
179 * rsz_copy_data - Copy data
180+ * @multipass: Structure containing channel configuration
181+ for multipass support
182 * @params: Structure containing the Resizer Wrapper parameters
183 *
184 * Copy data
185@@ -413,6 +427,8 @@ static void rsz_copy_data(struct rsz_mult *multipass, struct rsz_params *params)
186
187 /**
188 * rsz_set_params - Set parameters for resizer wrapper
189+ * @multipass: Structure containing channel configuration
190+ for multipass support
191 * @params: Structure containing the Resizer Wrapper parameters
192 * @rsz_conf_chan: Structure containing channel configuration
193 *
194@@ -524,6 +540,8 @@ static int rsz_set_params(struct rsz_mult *multipass, struct rsz_params *params,
195 }
196
197 rsz_config_ratio(multipass, rsz_conf_chan);
198+ /* Default value for read expand:Taken from Davinci */
199+ rsz_conf_chan->register_config.sdr_req_exp = RSZ_DEF_REQ_EXP;
200
201 rsz_conf_chan->config_state = STATE_CONFIGURED;
202
203@@ -534,6 +552,8 @@ err_einval:
204
205 /**
206 * rsz_set_ratio - Set ratio
207+ * @multipass: Structure containing channel configuration
208+ for multipass support
209 * @rsz_conf_chan: Structure containing channel configuration
210 *
211 * Returns 0 if successful, -EINVAL if invalid output size, upscaling ratio is
212@@ -548,7 +568,8 @@ static int rsz_set_ratio(struct rsz_mult *multipass,
213
214 if ((multipass->out_hsize > MAX_IMAGE_WIDTH) ||
215 (multipass->out_vsize > MAX_IMAGE_WIDTH)) {
216- dev_err(rsz_device, "Invalid output size!");
217+ dev_err(rsz_device, "Invalid output size! - %d", \
218+ multipass->out_hsize);
219 goto err_einval;
220 }
221 if (multipass->cbilin) {
222@@ -758,6 +779,8 @@ err_einval:
223
224 /**
225 * rsz_config_ratio - Configure ratio
226+ * @multipass: Structure containing channel configuration
227+ for multipass support
228 * @rsz_conf_chan: Structure containing channel configuration
229 *
230 * Configure ratio
231@@ -789,6 +812,20 @@ static void rsz_config_ratio(struct rsz_mult *multipass,
232 ((vsize << ISPRSZ_IN_SIZE_VERT_SHIFT)
233 & ISPRSZ_IN_SIZE_VERT_MASK);
234
235+ /* This is another workaround for the ISP-MMU translation fault.
236+ For the parameters whose image size comes exactly to PAGE_SIZE
237+ generates ISP-MMU translation fault. The root-cause is the equation
238+ input width = (32*sph + (ow - 1)*hrsz + 16) >> 8 + 7
239+ = (64*sph + (ow - 1)*hrsz + 32) >> 8 + 7
240+ input height = (32*spv + (oh - 1)*vrsz + 16) >> 8 + 4
241+ = (64*spv + (oh - 1)*vrsz + 32) >> 8 + 7
242+
243+ we are adjusting the input width to suit for Resizer module,
244+ application should use this configuration henceforth.
245+ */
246+ multipass->in_hsize = hsize;
247+ multipass->in_vsize = vsize;
248+
249 for (coeffcounter = 0; coeffcounter < MAX_COEF_COUNTER;
250 coeffcounter++) {
251 if (multipass->num_htap) {
252@@ -990,24 +1027,15 @@ static void rsz_calculate_crop(struct channel_config *rsz_conf_chan,
253 static void rsz_vbq_release(struct videobuf_queue *q,
254 struct videobuf_buffer *vb)
255 {
256- int i;
257 struct rsz_fh *fh = q->priv_data;
258+ struct videobuf_dmabuf *dma = NULL;
259
260- for (i = 0; i < VIDEO_MAX_FRAME; i++) {
261- struct videobuf_dmabuf *dma = NULL;
262- if (!q->bufs[i])
263- continue;
264- if (q->bufs[i]->memory != V4L2_MEMORY_MMAP)
265- continue;
266- dma = videobuf_to_dma(q->bufs[i]);
267- videobuf_dma_unmap(q, dma);
268- videobuf_dma_free(dma);
269- }
270+ dma = videobuf_to_dma(q->bufs[vb->i]);
271+ videobuf_dma_unmap(q, dma);
272+ videobuf_dma_free(dma);
273+ ispmmu_vunmap(fh->config->buf_address[vb->i]);
274+ fh->config->buf_address[vb->i] = 0;
275
276- ispmmu_vunmap(fh->isp_addr_read);
277- ispmmu_vunmap(fh->isp_addr_write);
278- fh->isp_addr_read = 0;
279- fh->isp_addr_write = 0;
280 spin_lock(&fh->vbq_lock);
281 vb->state = VIDEOBUF_NEEDS_INIT;
282 spin_unlock(&fh->vbq_lock);
283@@ -1062,7 +1090,105 @@ err_einval:
284 spin_unlock(&fh->vbq_lock);
285 return -EINVAL;
286 }
287+/*
288+ * This function is work around for the videobuf_iolock API,
289+ * for User memory allocated with ioremap (VM_IO flag) the API
290+ * get_user_pages fails.
291+ *
292+ * To fulfill this requirement, we have completely ignored VM layer of
293+ * Linux, and configuring the ISP MMU with physical address.
294+ */
295+static int omap_videobuf_dma_init_user(struct videobuf_buffer *vb,
296+ unsigned long physp, unsigned long asize)
297+{
298+ struct videobuf_dmabuf *dma;
299+ struct scatterlist *sglist;
300+ unsigned long data, first, last;
301+ int len, i = 0;
302+
303+ dma = videobuf_to_dma(vb);
304+ data = vb->baddr;
305+
306+ first = (data & PAGE_MASK) >> PAGE_SHIFT;
307+ last = ((data+asize-1) & PAGE_MASK) >> PAGE_SHIFT;
308+ dma->offset = data & ~PAGE_MASK;
309+ dma->nr_pages = last-first+1;
310+
311+ dma->direction = PCI_DMA_FROMDEVICE;
312+ /*
313+ * Allocate array of sglen + 1, to add entry of extra page
314+ * for input buffer. Driver always uses 0th buffer as input buffer.
315+ */
316+ len = dma->nr_pages + (vb->i ? 0 : 1);
317+ sglist = kcalloc(len, sizeof(*sglist), GFP_KERNEL);
318+ if (NULL == sglist)
319+ return -ENOMEM;
320+
321+ sglist[0].offset = 0;
322+ sglist[0].length = PAGE_SIZE - dma->offset;
323+ sglist[0].dma_address = (dma_addr_t)physp;
324+ physp += sglist[0].length;
325+ /*
326+ * Iterate in a loop for the number of pages
327+ */
328+ for (i = 1; i < (len - (vb->i ? 0 : 1)); i++) {
329+ sglist[i].offset = 0;
330+ sglist[i].length = PAGE_SIZE;
331+ sglist[i].dma_address = (dma_addr_t)physp;
332+ physp += PAGE_SIZE;
333+ }
334+ if (0 == vb->i) {
335+ sglist[i].offset = 0;
336+ sglist[i].length = PAGE_SIZE;
337+ sglist[i].dma_address =
338+ (dma_addr_t)device_config->extra_page_addr;
339+ }
340+ dma->sglist = sglist;
341+ dma->sglen = len;
342+ return 0;
343+
344+ }
345+/*
346+ * This function is workaround for the issue, where ISP-MMU generated
347+ * translation fault for specific params whose size is aligned to PAGE_SIZE.
348+
349+ * As a workaround we are padding one extra page for input buffer. This page
350+ * we are allocating during init time and will not be released through-out
351+ * life time of resizer driver. Please note that Resizer module only reads
352+ * from this extra page.
353+ */
354+int omap_create_sg(struct videobuf_queue *q, struct videobuf_dmabuf *dma)
355+{
356+ struct scatterlist *sglist;
357+ int sglen;
358
359+ sglen = dma->sglen;
360+ sglist = kcalloc(sglen + 1, sizeof(*sglist), GFP_KERNEL);
361+ if (NULL == sglist)
362+ return -ENOMEM;
363+ /*
364+ * Copy the sglist locally
365+ */
366+ memcpy(sglist, dma->sglist, sglen * sizeof(*sglist));
367+ /*
368+ * Release the old sglist, since we already copied it locally
369+ */
370+ videobuf_dma_unmap(q, dma);
371+ /*
372+ * Add extra entry to sglist to work with specific params, whose
373+ * buffer address alined to PAGE_SIZE.
374+ */
375+ sglist[sglen].offset = 0;
376+ sglist[sglen].length = PAGE_SIZE;
377+ sglist[sglen].dma_address = (dma_addr_t)device_config->extra_page_addr;
378+ sglen++;
379+ /*
380+ * Save the sglist for mapping to ISP-MMU space
381+ */
382+ dma->sglist = sglist;
383+ dma->sglen = sglen;
384+ return 0;
385+}
386 /**
387 * rsz_vbq_prepare - Videobuffer is prepared and mmapped.
388 * @q: Structure containing the videobuffer queue file handle, and device
389@@ -1079,19 +1205,24 @@ static int rsz_vbq_prepare(struct videobuf_queue *q,
390 {
391 struct rsz_fh *fh = q->priv_data;
392 struct channel_config *rsz_conf_chan = fh->config;
393- struct rsz_mult *multipass = fh->multipass;
394 int err = 0;
395 unsigned int isp_addr, insize, outsize;
396- struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
397-
398+ struct rsz_mult *multipass = fh->multipass;
399 spin_lock(&fh->vbq_lock);
400 if (vb->baddr) {
401+ /* Check for 32 byte alignement */
402+ if (vb->baddr != (vb->baddr & ~0x1F)) {
403+ spin_unlock(&fh->vbq_lock);
404+ dev_err(rsz_device, "Buffer address should be aligned \
405+ to 32 byte\n");
406+ return -EINVAL;
407+ }
408 vb->size = fh->rsz_bufsize;
409 vb->bsize = fh->rsz_bufsize;
410 } else {
411 spin_unlock(&fh->vbq_lock);
412 dev_err(rsz_device, "No user buffer allocated\n");
413- goto out;
414+ return -EINVAL;
415 }
416 if (vb->i) {
417 vb->width = fh->params->out_hsize;
418@@ -1103,55 +1234,128 @@ static int rsz_vbq_prepare(struct videobuf_queue *q,
419
420 vb->field = field;
421 spin_unlock(&fh->vbq_lock);
422+ /*
423+ * Calculate input and output sizes, will be used while mapping
424+ * user pages
425+ */
426+ outsize = multipass->out_pitch * multipass->out_vsize;
427+ insize = multipass->in_pitch * multipass->in_vsize;
428
429 if (vb->state == VIDEOBUF_NEEDS_INIT) {
430- err = videobuf_iolock(q, vb, NULL);
431- if (!err) {
432- isp_addr = ispmmu_vmap(dma->sglist, dma->sglen);
433- if (!isp_addr)
434- err = -EIO;
435- else {
436- if (vb->i) {
437- rsz_conf_chan->register_config.
438- rsz_sdr_outadd
439- = isp_addr;
440- fh->isp_addr_write = isp_addr;
441- rsz_conf_chan->output_buf_index = vb->i;
442- } else {
443+ struct videobuf_dmabuf *dma;
444+ struct vm_area_struct *vma;
445+ spin_lock(&fh->vbq_lock);
446+ dma = videobuf_to_dma(vb);
447+ vma = find_vma(current->mm, vb->baddr);
448+ if ((vma) && (vma->vm_flags & VM_IO) && (vma->vm_pgoff)) {
449+ /* This will catch ioremaped buffers to the kernel.
450+ * It gives two possible scenarios -
451+ * - Driver allocates buffer using either
452+ * dma_alloc_coherent or get_free_pages,
453+ * and maps to user space using
454+ * io_remap_pfn_range/remap_pfn_range
455+ * - Drivers maps memory outside from Linux using
456+ * io_remap
457+ */
458+ unsigned long physp = 0, asize;
459+ asize = vb->i ? outsize : insize;
460+ if ((vb->baddr + asize) > vma->vm_end) {
461+ spin_unlock(&fh->vbq_lock);
462+ dev_err(rsz_device, "User Buffer Allocation:" \
463+ "err=%lu[%lu]\n",\
464+ (vma->vm_end - vb->baddr), asize);
465+ return -ENOMEM;
466+ }
467+ physp = (vma->vm_pgoff << PAGE_SHIFT) +
468+ (vb->baddr - vma->vm_start);
469+ err = omap_videobuf_dma_init_user(vb, physp, asize);
470+ spin_unlock(&fh->vbq_lock);
471+ if (0 != err)
472+ return err;
473+ } else {
474+ err = videobuf_iolock(q, vb, NULL);
475+ /*
476+ * In case of user pointer mode, the get_user_pages
477+ * will fail if user has allocated less memory than
478+ * vb->size. But it is not error from resizer driver
479+ * point of view. so handled seperately
480+ */
481+ if ((err < 0) && (dma->nr_pages > 0))
482+ err = videobuf_dma_map(q, dma);
483+ if (err)
484+ goto buf_release;
485+ /*
486+ * Add one extra page for input buffer
487+ */
488+ if (0 == vb->i)
489+ err = omap_create_sg(q, dma);
490+ if (err)
491+ goto buf_release;
492+ spin_unlock(&fh->vbq_lock);
493+ }
494+ isp_addr = ispmmu_vmap(dma->sglist, dma->sglen);
495+ if (!isp_addr)
496+ err = -EIO;
497+ else {
498+ if (vb->i) {
499+ rsz_conf_chan->buf_address[vb->i] = isp_addr;
500+ rsz_conf_chan->register_config.
501+ rsz_sdr_outadd
502+ = isp_addr;
503+ rsz_conf_chan->output_buf_index = vb->i;
504+ } else {
505+ rsz_conf_chan->buf_address[vb->i] = isp_addr;
506+ rsz_conf_chan->register_config.
507+ rsz_sdr_inadd
508+ = isp_addr;
509+ rsz_conf_chan->input_buf_index = vb->i;
510+ if (outsize < insize && rsz_conf_chan->
511+ register_config.
512+ rsz_sdr_outadd == 0) {
513 rsz_conf_chan->register_config.
514- rsz_sdr_inadd
515- = isp_addr;
516- rsz_conf_chan->input_buf_index = vb->i;
517- outsize = multipass->out_pitch *
518- multipass->out_vsize;
519- insize = multipass->in_pitch *
520- multipass->in_vsize;
521- if (outsize < insize) {
522- rsz_conf_chan->register_config.
523- rsz_sdr_outadd
524- = isp_addr;
525- rsz_conf_chan->
526- output_buf_index =
527- vb->i;
528- }
529-
530- fh->isp_addr_read = isp_addr;
531+ rsz_sdr_outadd
532+ = isp_addr;
533+ rsz_conf_chan->
534+ output_buf_index =
535+ vb->i;
536 }
537 }
538 }
539
540- }
541+ } else {
542+ if(vb->i) {
543+ rsz_conf_chan->register_config.
544+ rsz_sdr_outadd =
545+ rsz_conf_chan->buf_address[vb->i];
546+ rsz_conf_chan->output_buf_index = vb->i;
547+ } else {
548+ rsz_conf_chan->register_config.
549+ rsz_sdr_inadd =
550+ rsz_conf_chan->buf_address[vb->i];
551+ rsz_conf_chan->input_buf_index = vb->i;
552+ if(outsize < insize && rsz_conf_chan->
553+ register_config.
554+ rsz_sdr_outadd == 0) {
555+ rsz_conf_chan->register_config.
556+ rsz_sdr_outadd
557+ = rsz_conf_chan->buf_address[vb->i];
558+ rsz_conf_chan->output_buf_index = vb->i;
559+ }
560+
561+ }
562
563+ }
564 if (!err) {
565 spin_lock(&fh->vbq_lock);
566 vb->state = VIDEOBUF_PREPARED;
567 spin_unlock(&fh->vbq_lock);
568- flush_cache_user_range(NULL, vb->baddr, (vb->baddr
569- + vb->bsize));
570 } else
571 rsz_vbq_release(q, vb);
572
573-out:
574+ return err;
575+buf_release:
576+ spin_unlock(&fh->vbq_lock);
577+ rsz_vbq_release(q, vb);
578 return err;
579 }
580
581@@ -1255,7 +1459,8 @@ err_enomem0:
582 **/
583 static int rsz_release(struct inode *inode, struct file *filp)
584 {
585- u32 timeout = 0;
586+ int i;
587+ unsigned int timeout = 0;
588 struct rsz_fh *fh = filp->private_data;
589 struct channel_config *rsz_conf_chan = fh->config;
590 struct rsz_params *params = fh->params;
591@@ -1266,17 +1471,17 @@ static int rsz_release(struct inode *inode, struct file *filp)
592 timeout++;
593 schedule();
594 }
595- if (mutex_lock_interruptible(&device_config->reszwrap_mutex))
596- return -EINTR;
597- device_config->opened--;
598- mutex_unlock(&device_config->reszwrap_mutex);
599- /* This will Free memory allocated to the buffers,
600- * and flushes the queue
601- */
602- videobuf_queue_cancel(q);
603- fh->params = NULL;
604- fh->config = NULL;
605+ /* Free memory allocated to the buffers */
606+ for (i = 0 ; i < VIDEO_MAX_FRAME ; i++) {
607+ struct videobuf_dmabuf *dma = NULL;
608+ if (!q->bufs[i])
609+ continue;
610+ dma = videobuf_to_dma(q->bufs[i]);
611+ videobuf_dma_unmap(q, dma);
612+ videobuf_dma_free(dma);
613+ }
614
615+ videobuf_mmap_free(q);
616 fh->rsz_bufsize = 0;
617 filp->private_data = NULL;
618
619@@ -1286,7 +1491,8 @@ static int rsz_release(struct inode *inode, struct file *filp)
620 kfree(fh);
621
622 isp_put();
623-
624+ fh->params = NULL;
625+ fh->config = NULL;
626 return 0;
627 }
628
629@@ -1353,6 +1559,12 @@ static long rsz_unlocked_ioctl(struct file *file, unsigned int cmd,
630 chanprotection_mutex))
631 return -EINTR;
632 ret = videobuf_reqbufs(&fh->vbq, (void *)&req_buf);
633+ if (ret >= 0) {
634+ if (copy_to_user((struct v4l2_requestbuffers *)arg,
635+ &req_buf, sizeof(struct
636+ v4l2_requestbuffers)))
637+ return -EFAULT;
638+ }
639 mutex_unlock(&rsz_conf_chan->chanprotection_mutex);
640 break;
641 }
642@@ -1394,11 +1606,7 @@ static long rsz_unlocked_ioctl(struct file *file, unsigned int cmd,
643 sizeof(struct rsz_params))) {
644 return -EFAULT;
645 }
646- if (mutex_lock_interruptible(&rsz_conf_chan->
647- chanprotection_mutex))
648- return -EINTR;
649- ret = rsz_set_params(fh->multipass, params, rsz_conf_chan);
650- mutex_unlock(&rsz_conf_chan->chanprotection_mutex);
651+ ret = rsz_set_params(fh->multipass, fh->params, rsz_conf_chan);
652 break;
653 }
654 case RSZ_G_PARAM:
655@@ -1433,6 +1641,12 @@ static long rsz_unlocked_ioctl(struct file *file, unsigned int cmd,
656 rsz_calculate_crop(rsz_conf_chan, (struct rsz_cropsize *)arg);
657 break;
658
659+ case RSZ_S_EXP:
660+ if (mutex_lock_interruptible(&rsz_conf_chan->chanprotection_mutex))
661+ return -EINTR;
662+ rsz_conf_chan->register_config.sdr_req_exp = *((unsigned int *)arg);
663+ mutex_unlock(&rsz_conf_chan->chanprotection_mutex);
664+ break;
665 default:
666 dev_err(rsz_device, "resizer_ioctl: Invalid Command Value");
667 return -EINVAL;
668@@ -1535,14 +1749,18 @@ static int __init omap_rsz_init(void)
669 "memory\n");
670 return -ENOMEM;
671 }
672-
673+ device->extra_page_addr = __get_free_pages(GFP_KERNEL | GFP_DMA, 0);
674+ if (!device->extra_page_addr) {
675+ dev_err(rsz_device, OMAP_REZR_NAME ":Allocation failed. ");
676+ kfree(device);
677+ return -ENOMEM;
678+ }
679 ret = alloc_chrdev_region(&dev, 0, 1, OMAP_REZR_NAME);
680 if (ret < 0) {
681 dev_err(rsz_device, OMAP_REZR_NAME ": intialization failed. "
682 "Could not allocate region "
683 "for character device\n");
684- kfree(device);
685- return -ENODEV;
686+ goto fail1;
687 }
688
689 /* Register the driver in the kernel */
690@@ -1608,6 +1826,8 @@ fail3:
691 cdev_del(&c_dev);
692 fail2:
693 unregister_chrdev_region(dev, 1);
694+fail1:
695+ free_pages((unsigned long)device->extra_page_addr, 0);
696 kfree(device);
697 return ret;
698 }
699@@ -1623,6 +1843,7 @@ void __exit omap_rsz_exit(void)
700 platform_driver_unregister(&omap_resizer_driver);
701 cdev_del(&c_dev);
702 unregister_chrdev_region(dev, 1);
703+ free_pages((unsigned long)device_config->extra_page_addr, 0);
704 kfree(device_config);
705 }
706
707diff --git a/include/linux/omap_resizer.h b/include/linux/omap_resizer.h
708index 5ac0c88..47b8dd8 100644
709--- a/include/linux/omap_resizer.h
710+++ b/include/linux/omap_resizer.h
711@@ -21,7 +21,7 @@
712
713 /* ioctls definition */
714 #define RSZ_IOC_BASE 'R'
715-#define RSZ_IOC_MAXNR 8
716+#define RSZ_IOC_MAXNR 9
717
718 /*Ioctl options which are to be passed while calling the ioctl*/
719 #define RSZ_REQBUF _IOWR(RSZ_IOC_BASE, 1,\
720@@ -33,6 +33,7 @@
721 #define RSZ_G_STATUS _IOWR(RSZ_IOC_BASE, 6, struct rsz_status)
722 #define RSZ_QUEUEBUF _IOWR(RSZ_IOC_BASE, 7, struct v4l2_buffer)
723 #define RSZ_GET_CROPSIZE _IOWR(RSZ_IOC_BASE, 8, struct rsz_cropsize)
724+#define RSZ_S_EXP _IOWR(RSZ_IOC_BASE, 9, __s32)
725
726 #define RSZ_INTYPE_YCBCR422_16BIT 0
727 #define RSZ_INTYPE_PLANAR_8BIT 1
728--
7291.6.0.3
730