GNU Linux-libre 4.14.266-gnu1
[releases.git] / drivers / staging / media / atomisp / pci / atomisp2 / atomisp_compat_ioctl32.c
1 /*
2  * Support for Intel Camera Imaging ISP subsystem.
3  *
4  * Copyright (c) 2013 Intel Corporation. All Rights Reserved.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License version
8  * 2 as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  * 02110-1301, USA.
19  *
20  */
21 #ifdef CONFIG_COMPAT
22 #include <linux/compat.h>
23
24 #include <linux/videodev2.h>
25
26 #include "atomisp_internal.h"
27 #include "atomisp_compat.h"
28 #include "atomisp_compat_ioctl32.h"
29
30 static int get_atomisp_histogram32(struct atomisp_histogram *kp,
31                                         struct atomisp_histogram32 __user *up)
32 {
33         compat_uptr_t tmp;
34
35         if (!access_ok(VERIFY_READ, up, sizeof(struct atomisp_histogram32)) ||
36                 get_user(kp->num_elements, &up->num_elements) ||
37                 get_user(tmp, &up->data))
38                         return -EFAULT;
39
40         kp->data = compat_ptr(tmp);
41         return 0;
42 }
43
44 static int put_atomisp_histogram32(struct atomisp_histogram *kp,
45                                         struct atomisp_histogram32 __user *up)
46 {
47         compat_uptr_t tmp = (compat_uptr_t)((uintptr_t)kp->data);
48
49         if (!access_ok(VERIFY_WRITE, up, sizeof(struct atomisp_histogram32)) ||
50                 put_user(kp->num_elements, &up->num_elements) ||
51                 put_user(tmp, &up->data))
52                         return -EFAULT;
53
54         return 0;
55 }
56
57 static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp,
58                                         struct v4l2_pix_format __user *up)
59 {
60         if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format)))
61                 return -EFAULT;
62         return 0;
63 }
64
65 static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp,
66                                         struct v4l2_pix_format __user *up)
67 {
68         if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format)))
69                 return -EFAULT;
70         return 0;
71 }
72
73 static int get_v4l2_framebuffer32(struct v4l2_framebuffer *kp,
74                                         struct v4l2_framebuffer32 __user *up)
75 {
76         compat_uptr_t tmp;
77
78         if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_framebuffer32)) ||
79                 get_user(tmp, &up->base) ||
80                 get_user(kp->capability, &up->capability) ||
81                 get_user(kp->flags, &up->flags))
82                         return -EFAULT;
83
84         kp->base = (void __force *)compat_ptr(tmp);
85         get_v4l2_pix_format((struct v4l2_pix_format *)&kp->fmt, &up->fmt);
86         return 0;
87 }
88
89 static int get_atomisp_dis_statistics32(struct atomisp_dis_statistics *kp,
90                                 struct atomisp_dis_statistics32 __user *up)
91 {
92         compat_uptr_t hor_prod_odd_real;
93         compat_uptr_t hor_prod_odd_imag;
94         compat_uptr_t hor_prod_even_real;
95         compat_uptr_t hor_prod_even_imag;
96         compat_uptr_t ver_prod_odd_real;
97         compat_uptr_t ver_prod_odd_imag;
98         compat_uptr_t ver_prod_even_real;
99         compat_uptr_t ver_prod_even_imag;
100
101         if (!access_ok(VERIFY_READ, up,
102                         sizeof(struct atomisp_dis_statistics32)) ||
103                 copy_from_user(kp, up, sizeof(struct atomisp_dvs_grid_info)) ||
104                 get_user(hor_prod_odd_real,
105                                 &up->dvs2_stat.hor_prod.odd_real) ||
106                 get_user(hor_prod_odd_imag,
107                                 &up->dvs2_stat.hor_prod.odd_imag) ||
108                 get_user(hor_prod_even_real,
109                                 &up->dvs2_stat.hor_prod.even_real) ||
110                 get_user(hor_prod_even_imag,
111                                 &up->dvs2_stat.hor_prod.even_imag) ||
112                 get_user(ver_prod_odd_real,
113                                 &up->dvs2_stat.ver_prod.odd_real) ||
114                 get_user(ver_prod_odd_imag,
115                                 &up->dvs2_stat.ver_prod.odd_imag) ||
116                 get_user(ver_prod_even_real,
117                                 &up->dvs2_stat.ver_prod.even_real) ||
118                 get_user(ver_prod_even_imag,
119                                 &up->dvs2_stat.ver_prod.even_imag) ||
120                 get_user(kp->exp_id, &up->exp_id))
121                         return -EFAULT;
122
123         kp->dvs2_stat.hor_prod.odd_real = compat_ptr(hor_prod_odd_real);
124         kp->dvs2_stat.hor_prod.odd_imag = compat_ptr(hor_prod_odd_imag);
125         kp->dvs2_stat.hor_prod.even_real = compat_ptr(hor_prod_even_real);
126         kp->dvs2_stat.hor_prod.even_imag = compat_ptr(hor_prod_even_imag);
127         kp->dvs2_stat.ver_prod.odd_real = compat_ptr(ver_prod_odd_real);
128         kp->dvs2_stat.ver_prod.odd_imag = compat_ptr(ver_prod_odd_imag);
129         kp->dvs2_stat.ver_prod.even_real = compat_ptr(ver_prod_even_real);
130         kp->dvs2_stat.ver_prod.even_imag = compat_ptr(ver_prod_even_imag);
131         return 0;
132 }
133
134 static int put_atomisp_dis_statistics32(struct atomisp_dis_statistics *kp,
135                                 struct atomisp_dis_statistics32 __user *up)
136 {
137         compat_uptr_t hor_prod_odd_real =
138                 (compat_uptr_t)((uintptr_t)kp->dvs2_stat.hor_prod.odd_real);
139         compat_uptr_t hor_prod_odd_imag =
140                 (compat_uptr_t)((uintptr_t)kp->dvs2_stat.hor_prod.odd_imag);
141         compat_uptr_t hor_prod_even_real =
142                 (compat_uptr_t)((uintptr_t)kp->dvs2_stat.hor_prod.even_real);
143         compat_uptr_t hor_prod_even_imag =
144                 (compat_uptr_t)((uintptr_t)kp->dvs2_stat.hor_prod.even_imag);
145         compat_uptr_t ver_prod_odd_real =
146                 (compat_uptr_t)((uintptr_t)kp->dvs2_stat.ver_prod.odd_real);
147         compat_uptr_t ver_prod_odd_imag =
148                 (compat_uptr_t)((uintptr_t)kp->dvs2_stat.ver_prod.odd_imag);
149         compat_uptr_t ver_prod_even_real =
150                 (compat_uptr_t)((uintptr_t)kp->dvs2_stat.ver_prod.even_real);
151         compat_uptr_t ver_prod_even_imag =
152                 (compat_uptr_t)((uintptr_t)kp->dvs2_stat.ver_prod.even_imag);
153
154         if (!access_ok(VERIFY_WRITE, up,
155                         sizeof(struct atomisp_dis_statistics32)) ||
156                 copy_to_user(up, kp, sizeof(struct atomisp_dvs_grid_info)) ||
157                 put_user(hor_prod_odd_real,
158                                 &up->dvs2_stat.hor_prod.odd_real) ||
159                 put_user(hor_prod_odd_imag,
160                                 &up->dvs2_stat.hor_prod.odd_imag) ||
161                 put_user(hor_prod_even_real,
162                                 &up->dvs2_stat.hor_prod.even_real) ||
163                 put_user(hor_prod_even_imag,
164                                 &up->dvs2_stat.hor_prod.even_imag) ||
165                 put_user(ver_prod_odd_real,
166                                 &up->dvs2_stat.ver_prod.odd_real) ||
167                 put_user(ver_prod_odd_imag,
168                                 &up->dvs2_stat.ver_prod.odd_imag) ||
169                 put_user(ver_prod_even_real,
170                                 &up->dvs2_stat.ver_prod.even_real) ||
171                 put_user(ver_prod_even_imag,
172                                 &up->dvs2_stat.ver_prod.even_imag) ||
173                 put_user(kp->exp_id, &up->exp_id))
174                         return -EFAULT;
175
176         return 0;
177 }
178
179 static int get_atomisp_dis_coefficients32(struct atomisp_dis_coefficients *kp,
180                                 struct atomisp_dis_coefficients32 __user *up)
181 {
182         compat_uptr_t hor_coefs_odd_real;
183         compat_uptr_t hor_coefs_odd_imag;
184         compat_uptr_t hor_coefs_even_real;
185         compat_uptr_t hor_coefs_even_imag;
186         compat_uptr_t ver_coefs_odd_real;
187         compat_uptr_t ver_coefs_odd_imag;
188         compat_uptr_t ver_coefs_even_real;
189         compat_uptr_t ver_coefs_even_imag;
190
191         if (!access_ok(VERIFY_READ, up,
192                         sizeof(struct atomisp_dis_coefficients32)) ||
193                 copy_from_user(kp, up, sizeof(struct atomisp_dvs_grid_info)) ||
194                 get_user(hor_coefs_odd_real, &up->hor_coefs.odd_real) ||
195                 get_user(hor_coefs_odd_imag, &up->hor_coefs.odd_imag) ||
196                 get_user(hor_coefs_even_real, &up->hor_coefs.even_real) ||
197                 get_user(hor_coefs_even_imag, &up->hor_coefs.even_imag) ||
198                 get_user(ver_coefs_odd_real, &up->ver_coefs.odd_real) ||
199                 get_user(ver_coefs_odd_imag, &up->ver_coefs.odd_imag) ||
200                 get_user(ver_coefs_even_real, &up->ver_coefs.even_real) ||
201                 get_user(ver_coefs_even_imag, &up->ver_coefs.even_imag))
202                         return -EFAULT;
203
204         kp->hor_coefs.odd_real = compat_ptr(hor_coefs_odd_real);
205         kp->hor_coefs.odd_imag = compat_ptr(hor_coefs_odd_imag);
206         kp->hor_coefs.even_real = compat_ptr(hor_coefs_even_real);
207         kp->hor_coefs.even_imag = compat_ptr(hor_coefs_even_imag);
208         kp->ver_coefs.odd_real = compat_ptr(ver_coefs_odd_real);
209         kp->ver_coefs.odd_imag = compat_ptr(ver_coefs_odd_imag);
210         kp->ver_coefs.even_real = compat_ptr(ver_coefs_even_real);
211         kp->ver_coefs.even_imag = compat_ptr(ver_coefs_even_imag);
212         return 0;
213 }
214
215 static int get_atomisp_dvs_6axis_config32(struct atomisp_dvs_6axis_config *kp,
216                                 struct atomisp_dvs_6axis_config32 __user *up)
217 {       compat_uptr_t xcoords_y;
218         compat_uptr_t ycoords_y;
219         compat_uptr_t xcoords_uv;
220         compat_uptr_t ycoords_uv;
221
222         if (!access_ok(VERIFY_READ, up,
223                         sizeof(struct atomisp_dvs_6axis_config32)) ||
224                 get_user(kp->exp_id, &up->exp_id) ||
225                 get_user(kp->width_y, &up->width_y) ||
226                 get_user(kp->height_y, &up->height_y) ||
227                 get_user(kp->width_uv, &up->width_uv) ||
228                 get_user(kp->height_uv, &up->height_uv) ||
229                 get_user(xcoords_y, &up->xcoords_y) ||
230                 get_user(ycoords_y, &up->ycoords_y) ||
231                 get_user(xcoords_uv, &up->xcoords_uv) ||
232                 get_user(ycoords_uv, &up->ycoords_uv))
233                         return -EFAULT;
234
235         kp->xcoords_y = (void __force *)compat_ptr(xcoords_y);
236         kp->ycoords_y = (void __force *)compat_ptr(ycoords_y);
237         kp->xcoords_uv = (void __force *)compat_ptr(xcoords_uv);
238         kp->ycoords_uv = (void __force *)compat_ptr(ycoords_uv);
239         return 0;
240 }
241
242 static int get_atomisp_3a_statistics32(struct atomisp_3a_statistics *kp,
243                                 struct atomisp_3a_statistics32 __user *up)
244 {
245         compat_uptr_t data;
246         compat_uptr_t rgby_data;
247
248         if (!access_ok(VERIFY_READ, up,
249                         sizeof(struct atomisp_3a_statistics32)) ||
250                 copy_from_user(kp, up, sizeof(struct atomisp_grid_info)) ||
251                 get_user(rgby_data, &up->rgby_data) ||
252                 get_user(data, &up->data) ||
253                 get_user(kp->exp_id, &up->exp_id) ||
254                 get_user(kp->isp_config_id, &up->isp_config_id))
255                         return -EFAULT;
256
257         kp->data = compat_ptr(data);
258         kp->rgby_data = compat_ptr(rgby_data);
259
260         return 0;
261 }
262
263 static int put_atomisp_3a_statistics32(struct atomisp_3a_statistics *kp,
264                                 struct atomisp_3a_statistics32 __user *up)
265 {
266         compat_uptr_t data = (compat_uptr_t)((uintptr_t)kp->data);
267         compat_uptr_t rgby_data = (compat_uptr_t)((uintptr_t)kp->rgby_data);
268
269         if (!access_ok(VERIFY_WRITE, up,
270                         sizeof(struct atomisp_3a_statistics32)) ||
271                 copy_to_user(up, kp, sizeof(struct atomisp_grid_info)) ||
272                 put_user(rgby_data, &up->rgby_data) ||
273                 put_user(data, &up->data) ||
274                 put_user(kp->exp_id, &up->exp_id) ||
275                 put_user(kp->isp_config_id, &up->isp_config_id))
276                         return -EFAULT;
277
278         return 0;
279 }
280
281
282 static int get_atomisp_metadata_stat32(struct atomisp_metadata *kp,
283                                 struct atomisp_metadata32 __user *up)
284 {
285         compat_uptr_t data;
286         compat_uptr_t effective_width;
287
288         if (!access_ok(VERIFY_READ, up,
289                         sizeof(struct atomisp_metadata32)) ||
290                 get_user(data, &up->data) ||
291                 get_user(kp->width, &up->width) ||
292                 get_user(kp->height, &up->height) ||
293                 get_user(kp->stride, &up->stride) ||
294                 get_user(kp->exp_id, &up->exp_id) ||
295                 get_user(effective_width, &up->effective_width))
296                         return -EFAULT;
297
298         kp->data = compat_ptr(data);
299         kp->effective_width = (void __force *)compat_ptr(effective_width);
300         return 0;
301 }
302
303
304 static int put_atomisp_metadata_stat32(struct atomisp_metadata *kp,
305                                 struct atomisp_metadata32 __user *up)
306 {
307         compat_uptr_t data = (compat_uptr_t)((uintptr_t)kp->data);
308         compat_uptr_t effective_width =
309                 (compat_uptr_t)((uintptr_t)kp->effective_width);
310         if (!access_ok(VERIFY_WRITE, up,
311                         sizeof(struct atomisp_metadata32)) ||
312                 put_user(data, &up->data) ||
313                 put_user(kp->width, &up->width) ||
314                 put_user(kp->height, &up->height) ||
315                 put_user(kp->stride, &up->stride) ||
316                 put_user(kp->exp_id, &up->exp_id) ||
317                 put_user(effective_width, &up->effective_width))
318                         return -EFAULT;
319
320         return 0;
321 }
322
323 static int put_atomisp_metadata_by_type_stat32(
324                                 struct atomisp_metadata_with_type *kp,
325                                 struct atomisp_metadata_with_type32 __user *up)
326 {
327         compat_uptr_t data = (compat_uptr_t)((uintptr_t)kp->data);
328         compat_uptr_t effective_width =
329                 (compat_uptr_t)((uintptr_t)kp->effective_width);
330         if (!access_ok(VERIFY_WRITE, up,
331                         sizeof(struct atomisp_metadata_with_type32)) ||
332                 put_user(data, &up->data) ||
333                 put_user(kp->width, &up->width) ||
334                 put_user(kp->height, &up->height) ||
335                 put_user(kp->stride, &up->stride) ||
336                 put_user(kp->exp_id, &up->exp_id) ||
337                 put_user(effective_width, &up->effective_width) ||
338                 put_user(kp->type, &up->type))
339                         return -EFAULT;
340
341         return 0;
342 }
343
344 static int get_atomisp_metadata_by_type_stat32(
345                                 struct atomisp_metadata_with_type *kp,
346                                 struct atomisp_metadata_with_type32 __user *up)
347 {
348         compat_uptr_t data;
349         compat_uptr_t effective_width;
350
351         if (!access_ok(VERIFY_READ, up,
352                         sizeof(struct atomisp_metadata_with_type32)) ||
353                 get_user(data, &up->data) ||
354                 get_user(kp->width, &up->width) ||
355                 get_user(kp->height, &up->height) ||
356                 get_user(kp->stride, &up->stride) ||
357                 get_user(kp->exp_id, &up->exp_id) ||
358                 get_user(effective_width, &up->effective_width) ||
359                 get_user(kp->type, &up->type))
360                         return -EFAULT;
361
362         kp->data = compat_ptr(data);
363         kp->effective_width = (void __force *)compat_ptr(effective_width);
364         return 0;
365 }
366
367 static int get_atomisp_morph_table32(struct atomisp_morph_table *kp,
368                                 struct atomisp_morph_table32 __user *up)
369 {
370         unsigned int n = ATOMISP_MORPH_TABLE_NUM_PLANES;
371
372         if (!access_ok(VERIFY_READ, up,
373                         sizeof(struct atomisp_morph_table32)) ||
374                 get_user(kp->enabled, &up->enabled) ||
375                 get_user(kp->width, &up->width) ||
376                 get_user(kp->height, &up->height))
377                         return -EFAULT;
378
379         while (n-- > 0) {
380                 uintptr_t *coord_kp = (uintptr_t *)&kp->coordinates_x[n];
381
382                 if (get_user((*coord_kp), &up->coordinates_x[n]))
383                         return -EFAULT;
384
385                 coord_kp = (uintptr_t *)&kp->coordinates_y[n];
386                 if (get_user((*coord_kp), &up->coordinates_y[n]))
387                         return -EFAULT;
388         }
389         return 0;
390 }
391
392 static int put_atomisp_morph_table32(struct atomisp_morph_table *kp,
393                                 struct atomisp_morph_table32 __user *up)
394 {
395         unsigned int n = ATOMISP_MORPH_TABLE_NUM_PLANES;
396
397         if (!access_ok(VERIFY_WRITE, up,
398                         sizeof(struct atomisp_morph_table32)) ||
399                 put_user(kp->enabled, &up->enabled) ||
400                 put_user(kp->width, &up->width) ||
401                 put_user(kp->height, &up->height))
402                         return -EFAULT;
403
404         while (n-- > 0) {
405                 uintptr_t *coord_kp = (uintptr_t *)&kp->coordinates_x[n];
406
407                 if (put_user((*coord_kp), &up->coordinates_x[n]))
408                         return -EFAULT;
409
410                 coord_kp = (uintptr_t *)&kp->coordinates_y[n];
411                 if (put_user((*coord_kp), &up->coordinates_y[n]))
412                         return -EFAULT;
413         }
414         return 0;
415 }
416
417 static int get_atomisp_overlay32(struct atomisp_overlay *kp,
418                                         struct atomisp_overlay32 __user *up)
419 {
420         compat_uptr_t frame;
421         if (!access_ok(VERIFY_READ, up, sizeof(struct atomisp_overlay32)) ||
422                 get_user(frame, &up->frame) ||
423                 get_user(kp->bg_y, &up->bg_y) ||
424                 get_user(kp->bg_u, &up->bg_u) ||
425                 get_user(kp->bg_v, &up->bg_v) ||
426                 get_user(kp->blend_input_perc_y, &up->blend_input_perc_y) ||
427                 get_user(kp->blend_input_perc_u, &up->blend_input_perc_u) ||
428                 get_user(kp->blend_input_perc_v, &up->blend_input_perc_v) ||
429                 get_user(kp->blend_overlay_perc_y,
430                                 &up->blend_overlay_perc_y) ||
431                 get_user(kp->blend_overlay_perc_u,
432                                 &up->blend_overlay_perc_u) ||
433                 get_user(kp->blend_overlay_perc_v,
434                                 &up->blend_overlay_perc_v) ||
435                 get_user(kp->blend_overlay_perc_u,
436                                 &up->blend_overlay_perc_u) ||
437                 get_user(kp->overlay_start_x, &up->overlay_start_y))
438                         return -EFAULT;
439
440         kp->frame = (void __force *)compat_ptr(frame);
441         return 0;
442 }
443
444 static int put_atomisp_overlay32(struct atomisp_overlay *kp,
445                                         struct atomisp_overlay32 __user *up)
446 {
447         compat_uptr_t frame = (compat_uptr_t)((uintptr_t)kp->frame);
448
449         if (!access_ok(VERIFY_WRITE, up, sizeof(struct atomisp_overlay32)) ||
450                 put_user(frame, &up->frame) ||
451                 put_user(kp->bg_y, &up->bg_y) ||
452                 put_user(kp->bg_u, &up->bg_u) ||
453                 put_user(kp->bg_v, &up->bg_v) ||
454                 put_user(kp->blend_input_perc_y, &up->blend_input_perc_y) ||
455                 put_user(kp->blend_input_perc_u, &up->blend_input_perc_u) ||
456                 put_user(kp->blend_input_perc_v, &up->blend_input_perc_v) ||
457                 put_user(kp->blend_overlay_perc_y,
458                                 &up->blend_overlay_perc_y) ||
459                 put_user(kp->blend_overlay_perc_u,
460                                 &up->blend_overlay_perc_u) ||
461                 put_user(kp->blend_overlay_perc_v,
462                                 &up->blend_overlay_perc_v) ||
463                 put_user(kp->blend_overlay_perc_u,
464                                 &up->blend_overlay_perc_u) ||
465                 put_user(kp->overlay_start_x, &up->overlay_start_y))
466                         return -EFAULT;
467
468         return 0;
469 }
470
471 static int get_atomisp_calibration_group32(
472                                 struct atomisp_calibration_group *kp,
473                                 struct atomisp_calibration_group32 __user *up)
474 {
475         compat_uptr_t calb_grp_values;
476
477         if (!access_ok(VERIFY_READ, up,
478                         sizeof(struct atomisp_calibration_group32)) ||
479                 get_user(kp->size, &up->size) ||
480                 get_user(kp->type, &up->type) ||
481                 get_user(calb_grp_values, &up->calb_grp_values))
482                         return -EFAULT;
483
484         kp->calb_grp_values = (void __force *)compat_ptr(calb_grp_values);
485         return 0;
486 }
487
488 static int put_atomisp_calibration_group32(
489                                 struct atomisp_calibration_group *kp,
490                                 struct atomisp_calibration_group32 __user *up)
491 {
492         compat_uptr_t calb_grp_values =
493                         (compat_uptr_t)((uintptr_t)kp->calb_grp_values);
494
495         if (!access_ok(VERIFY_WRITE, up,
496                         sizeof(struct atomisp_calibration_group32)) ||
497                 put_user(kp->size, &up->size) ||
498                 put_user(kp->type, &up->type) ||
499                 put_user(calb_grp_values, &up->calb_grp_values))
500                         return -EFAULT;
501
502         return 0;
503 }
504
505 static int get_atomisp_acc_fw_load32(struct atomisp_acc_fw_load *kp,
506                                 struct atomisp_acc_fw_load32 __user *up)
507 {
508         compat_uptr_t data;
509
510         if (!access_ok(VERIFY_READ, up,
511                         sizeof(struct atomisp_acc_fw_load32)) ||
512                 get_user(kp->size, &up->size) ||
513                 get_user(kp->fw_handle, &up->fw_handle) ||
514                 get_user(data, &up->data))
515                         return -EFAULT;
516
517         kp->data = compat_ptr(data);
518         return 0;
519 }
520
521 static int put_atomisp_acc_fw_load32(struct atomisp_acc_fw_load *kp,
522                                 struct atomisp_acc_fw_load32 __user *up)
523 {
524         compat_uptr_t data = (compat_uptr_t)((uintptr_t)kp->data);
525
526         if (!access_ok(VERIFY_WRITE, up,
527                         sizeof(struct atomisp_acc_fw_load32)) ||
528                 put_user(kp->size, &up->size) ||
529                 put_user(kp->fw_handle, &up->fw_handle) ||
530                 put_user(data, &up->data))
531                         return -EFAULT;
532
533         return 0;
534 }
535
536 static int get_atomisp_acc_fw_arg32(struct atomisp_acc_fw_arg *kp,
537                                         struct atomisp_acc_fw_arg32 __user *up)
538 {
539         compat_uptr_t value;
540
541         if (!access_ok(VERIFY_READ, up, sizeof(struct atomisp_acc_fw_arg32)) ||
542                 get_user(kp->fw_handle, &up->fw_handle) ||
543                 get_user(kp->index, &up->index) ||
544                 get_user(value, &up->value) ||
545                 get_user(kp->size, &up->size))
546                         return -EFAULT;
547
548         kp->value = compat_ptr(value);
549         return 0;
550 }
551
552 static int put_atomisp_acc_fw_arg32(struct atomisp_acc_fw_arg *kp,
553                                         struct atomisp_acc_fw_arg32 __user *up)
554 {
555         compat_uptr_t value = (compat_uptr_t)((uintptr_t)kp->value);
556
557         if (!access_ok(VERIFY_WRITE, up, sizeof(struct atomisp_acc_fw_arg32)) ||
558                 put_user(kp->fw_handle, &up->fw_handle) ||
559                 put_user(kp->index, &up->index) ||
560                 put_user(value, &up->value) ||
561                 put_user(kp->size, &up->size))
562                         return -EFAULT;
563
564         return 0;
565 }
566
567 static int get_v4l2_private_int_data32(struct v4l2_private_int_data *kp,
568                                         struct v4l2_private_int_data32 __user *up)
569 {
570         compat_uptr_t data;
571
572         if (!access_ok(VERIFY_READ, up,
573                         sizeof(struct v4l2_private_int_data32)) ||
574                 get_user(kp->size, &up->size) ||
575                 get_user(data, &up->data) ||
576                 get_user(kp->reserved[0], &up->reserved[0]) ||
577                 get_user(kp->reserved[1], &up->reserved[1]))
578                         return -EFAULT;
579
580         kp->data = compat_ptr(data);
581         return 0;
582 }
583
584 static int put_v4l2_private_int_data32(struct v4l2_private_int_data *kp,
585                                 struct v4l2_private_int_data32 __user *up)
586 {
587         compat_uptr_t data = (compat_uptr_t)((uintptr_t)kp->data);
588
589         if (!access_ok(VERIFY_WRITE, up,
590                         sizeof(struct v4l2_private_int_data32)) ||
591                 put_user(kp->size, &up->size) ||
592                 put_user(data, &up->data) ||
593                 put_user(kp->reserved[0], &up->reserved[0]) ||
594                 put_user(kp->reserved[1], &up->reserved[1]))
595                         return -EFAULT;
596
597         return 0;
598 }
599
600 static int get_atomisp_shading_table32(struct atomisp_shading_table *kp,
601                                 struct atomisp_shading_table32 __user *up)
602 {
603         unsigned int n = ATOMISP_NUM_SC_COLORS;
604
605         if (!access_ok(VERIFY_READ, up,
606                         sizeof(struct atomisp_shading_table32)) ||
607                 get_user(kp->enable, &up->enable) ||
608                 get_user(kp->sensor_width, &up->sensor_width) ||
609                 get_user(kp->sensor_height, &up->sensor_height) ||
610                 get_user(kp->width, &up->width) ||
611                 get_user(kp->height, &up->height) ||
612                 get_user(kp->fraction_bits, &up->fraction_bits))
613                         return -EFAULT;
614
615         while (n-- > 0) {
616                 uintptr_t *data_p = (uintptr_t *)&kp->data[n];
617
618                 if (get_user((*data_p), &up->data[n]))
619                         return -EFAULT;
620         }
621         return 0;
622 }
623
624 static int get_atomisp_acc_map32(struct atomisp_acc_map *kp,
625                                         struct atomisp_acc_map32 __user *up)
626 {
627         compat_uptr_t user_ptr;
628
629         if (!access_ok(VERIFY_READ, up, sizeof(struct atomisp_acc_map32)) ||
630                 get_user(kp->flags, &up->flags) ||
631                 get_user(kp->length, &up->length) ||
632                 get_user(user_ptr, &up->user_ptr) ||
633                 get_user(kp->css_ptr, &up->css_ptr) ||
634                 get_user(kp->reserved[0], &up->reserved[0]) ||
635                 get_user(kp->reserved[1], &up->reserved[1]) ||
636                 get_user(kp->reserved[2], &up->reserved[2]) ||
637                 get_user(kp->reserved[3], &up->reserved[3]))
638                         return -EFAULT;
639
640         kp->user_ptr = compat_ptr(user_ptr);
641         return 0;
642 }
643
644 static int put_atomisp_acc_map32(struct atomisp_acc_map *kp,
645                                         struct atomisp_acc_map32 __user *up)
646 {
647         compat_uptr_t user_ptr = (compat_uptr_t)((uintptr_t)kp->user_ptr);
648
649         if (!access_ok(VERIFY_WRITE, up, sizeof(struct atomisp_acc_map32)) ||
650                 put_user(kp->flags, &up->flags) ||
651                 put_user(kp->length, &up->length) ||
652                 put_user(user_ptr, &up->user_ptr) ||
653                 put_user(kp->css_ptr, &up->css_ptr) ||
654                 put_user(kp->reserved[0], &up->reserved[0]) ||
655                 put_user(kp->reserved[1], &up->reserved[1]) ||
656                 put_user(kp->reserved[2], &up->reserved[2]) ||
657                 put_user(kp->reserved[3], &up->reserved[3]))
658                         return -EFAULT;
659
660         return 0;
661 }
662
663 static int get_atomisp_acc_s_mapped_arg32(struct atomisp_acc_s_mapped_arg *kp,
664                                 struct atomisp_acc_s_mapped_arg32 __user *up)
665 {
666         if (!access_ok(VERIFY_READ, up,
667                         sizeof(struct atomisp_acc_s_mapped_arg32)) ||
668                 get_user(kp->fw_handle, &up->fw_handle) ||
669                 get_user(kp->memory, &up->memory) ||
670                 get_user(kp->length, &up->length) ||
671                 get_user(kp->css_ptr, &up->css_ptr))
672                         return -EFAULT;
673
674         return 0;
675 }
676
677 static int put_atomisp_acc_s_mapped_arg32(struct atomisp_acc_s_mapped_arg *kp,
678                                 struct atomisp_acc_s_mapped_arg32 __user *up)
679 {
680         if (!access_ok(VERIFY_WRITE, up,
681                         sizeof(struct atomisp_acc_s_mapped_arg32)) ||
682                 put_user(kp->fw_handle, &up->fw_handle) ||
683                 put_user(kp->memory, &up->memory) ||
684                 put_user(kp->length, &up->length) ||
685                 put_user(kp->css_ptr, &up->css_ptr))
686                         return -EFAULT;
687
688         return 0;
689 }
690
691 static int get_atomisp_parameters32(struct atomisp_parameters *kp,
692                                         struct atomisp_parameters32 __user *up)
693 {
694         int n = offsetof(struct atomisp_parameters32, output_frame) /
695                                 sizeof(compat_uptr_t);
696         unsigned int size, offset = 0;
697         void  __user *user_ptr;
698 #ifdef ISP2401
699         unsigned int stp, mtp, dcp, dscp = 0;
700
701 #endif
702         if (!access_ok(VERIFY_READ, up, sizeof(struct atomisp_parameters32)))
703                         return -EFAULT;
704
705         while (n >= 0) {
706                 compat_uptr_t __user *src = ((compat_uptr_t __user *)up) + n;
707                 uintptr_t *dst = ((uintptr_t *)kp) + n;
708
709                 if (get_user((*dst), src))
710                         return -EFAULT;
711                 n--;
712         }
713         if (get_user(kp->isp_config_id, &up->isp_config_id) ||
714 #ifndef ISP2401
715             get_user(kp->per_frame_setting, &up->per_frame_setting))
716 #else
717             get_user(kp->per_frame_setting, &up->per_frame_setting) ||
718             get_user(stp, &up->shading_table) ||
719             get_user(mtp, &up->morph_table) ||
720             get_user(dcp, &up->dvs2_coefs) ||
721             get_user(dscp, &up->dvs_6axis_config))
722 #endif
723                 return -EFAULT;
724
725         {
726                 union {
727                         struct atomisp_shading_table shading_table;
728                         struct atomisp_morph_table   morph_table;
729                         struct atomisp_dis_coefficients dvs2_coefs;
730                         struct atomisp_dvs_6axis_config dvs_6axis_config;
731                 } karg;
732
733                 size = sizeof(struct atomisp_shading_table) +
734                                 sizeof(struct atomisp_morph_table) +
735                                 sizeof(struct atomisp_dis_coefficients) +
736                                 sizeof(struct atomisp_dvs_6axis_config);
737                 user_ptr = compat_alloc_user_space(size);
738
739                 /* handle shading table */
740 #ifndef ISP2401
741                 if (up->shading_table != 0) {
742 #else
743                 if (stp != 0) {
744 #endif
745                         if (get_atomisp_shading_table32(&karg.shading_table,
746                                 (struct atomisp_shading_table32 __user *)
747 #ifndef ISP2401
748                                                 (uintptr_t)up->shading_table))
749 #else
750                                                 (uintptr_t)stp))
751 #endif
752                                 return -EFAULT;
753
754                         kp->shading_table = (void __force *)user_ptr + offset;
755                         offset = sizeof(struct atomisp_shading_table);
756                         if (!kp->shading_table)
757                                 return -EFAULT;
758
759                         if (copy_to_user((void __user *)kp->shading_table,
760                                          &karg.shading_table,
761                                          sizeof(struct atomisp_shading_table)))
762                                 return -EFAULT;
763                 }
764
765                 /* handle morph table */
766 #ifndef ISP2401
767                 if (up->morph_table != 0) {
768 #else
769                 if (mtp != 0) {
770 #endif
771                         if (get_atomisp_morph_table32(&karg.morph_table,
772                                         (struct atomisp_morph_table32 __user *)
773 #ifndef ISP2401
774                                                 (uintptr_t)up->morph_table))
775 #else
776                                                 (uintptr_t)mtp))
777 #endif
778                                 return -EFAULT;
779
780                         kp->morph_table = (void __force *)user_ptr + offset;
781                         offset += sizeof(struct atomisp_morph_table);
782                         if (!kp->morph_table)
783                                 return -EFAULT;
784
785                         if (copy_to_user((void __user *)kp->morph_table,
786                                          &karg.morph_table,
787                                          sizeof(struct atomisp_morph_table)))
788                                 return -EFAULT;
789                 }
790
791                 /* handle dvs2 coefficients */
792 #ifndef ISP2401
793                 if (up->dvs2_coefs != 0) {
794 #else
795                 if (dcp != 0) {
796 #endif
797                         if (get_atomisp_dis_coefficients32(&karg.dvs2_coefs,
798                                 (struct atomisp_dis_coefficients32 __user *)
799 #ifndef ISP2401
800                                                 (uintptr_t)up->dvs2_coefs))
801 #else
802                                                 (uintptr_t)dcp))
803 #endif
804                                 return -EFAULT;
805
806                         kp->dvs2_coefs = (void __force *)user_ptr + offset;
807                         offset += sizeof(struct atomisp_dis_coefficients);
808                         if (!kp->dvs2_coefs)
809                                 return -EFAULT;
810
811                         if (copy_to_user((void __user *)kp->dvs2_coefs,
812                                          &karg.dvs2_coefs,
813                                          sizeof(struct atomisp_dis_coefficients)))
814                                 return -EFAULT;
815                 }
816                 /* handle dvs 6axis configuration */
817 #ifndef ISP2401
818                 if (up->dvs_6axis_config != 0) {
819 #else
820                 if (dscp != 0) {
821 #endif
822                         if (get_atomisp_dvs_6axis_config32(&karg.dvs_6axis_config,
823                                 (struct atomisp_dvs_6axis_config32 __user *)
824 #ifndef ISP2401
825                                                 (uintptr_t)up->dvs_6axis_config))
826 #else
827                                                 (uintptr_t)dscp))
828 #endif
829                                 return -EFAULT;
830
831                         kp->dvs_6axis_config = (void __force *)user_ptr + offset;
832                         offset += sizeof(struct atomisp_dvs_6axis_config);
833                         if (!kp->dvs_6axis_config)
834                                 return -EFAULT;
835
836                         if (copy_to_user((void __user *)kp->dvs_6axis_config,
837                                          &karg.dvs_6axis_config,
838                                          sizeof(struct atomisp_dvs_6axis_config)))
839                                 return -EFAULT;
840                 }
841         }
842         return 0;
843 }
844
845 static int get_atomisp_acc_fw_load_to_pipe32(
846                         struct atomisp_acc_fw_load_to_pipe *kp,
847                         struct atomisp_acc_fw_load_to_pipe32 __user *up)
848 {
849         compat_uptr_t data;
850         if (!access_ok(VERIFY_READ, up,
851                         sizeof(struct atomisp_acc_fw_load_to_pipe32)) ||
852                 get_user(kp->flags, &up->flags) ||
853                 get_user(kp->fw_handle, &up->fw_handle) ||
854                 get_user(kp->size, &up->size) ||
855                 get_user(kp->type, &up->type) ||
856                 get_user(kp->reserved[0], &up->reserved[0]) ||
857                 get_user(kp->reserved[1], &up->reserved[1]) ||
858                 get_user(kp->reserved[2], &up->reserved[2]) ||
859                 get_user(data, &up->data))
860                         return -EFAULT;
861
862         kp->data = compat_ptr(data);
863         return 0;
864 }
865
866 static int put_atomisp_acc_fw_load_to_pipe32(
867                         struct atomisp_acc_fw_load_to_pipe *kp,
868                         struct atomisp_acc_fw_load_to_pipe32 __user *up)
869 {
870         compat_uptr_t data = (compat_uptr_t)((uintptr_t)kp->data);
871         if (!access_ok(VERIFY_WRITE, up,
872                         sizeof(struct atomisp_acc_fw_load_to_pipe32)) ||
873                 put_user(kp->flags, &up->flags) ||
874                 put_user(kp->fw_handle, &up->fw_handle) ||
875                 put_user(kp->size, &up->size) ||
876                 put_user(kp->type, &up->type) ||
877                 put_user(kp->reserved[0], &up->reserved[0]) ||
878                 put_user(kp->reserved[1], &up->reserved[1]) ||
879                 put_user(kp->reserved[2], &up->reserved[2]) ||
880                 put_user(data, &up->data))
881                         return -EFAULT;
882
883         return 0;
884 }
885
886 static int get_atomisp_sensor_ae_bracketing_lut(
887                         struct atomisp_sensor_ae_bracketing_lut *kp,
888                         struct atomisp_sensor_ae_bracketing_lut32 __user *up)
889 {
890         compat_uptr_t lut;
891         if (!access_ok(VERIFY_READ, up,
892                         sizeof(struct atomisp_sensor_ae_bracketing_lut32)) ||
893                 get_user(kp->lut_size, &up->lut_size) ||
894                 get_user(lut, &up->lut))
895                         return -EFAULT;
896
897         kp->lut = (void __force *)compat_ptr(lut);
898         return 0;
899 }
900
901 static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
902 {
903         long ret = -ENOIOCTLCMD;
904
905         if (file->f_op->unlocked_ioctl)
906                 ret = file->f_op->unlocked_ioctl(file, cmd, arg);
907
908         return ret;
909 }
910
911 long atomisp_do_compat_ioctl(struct file *file,
912                             unsigned int cmd, unsigned long arg)
913 {
914         union {
915                 struct atomisp_histogram his;
916                 struct atomisp_dis_statistics dis_s;
917                 struct atomisp_dis_coefficients dis_c;
918                 struct atomisp_dvs_6axis_config dvs_c;
919                 struct atomisp_3a_statistics s3a_s;
920                 struct atomisp_morph_table mor_t;
921                 struct v4l2_framebuffer v4l2_buf;
922                 struct atomisp_overlay overlay;
923                 struct atomisp_calibration_group cal_grp;
924                 struct atomisp_acc_fw_load acc_fw_load;
925                 struct atomisp_acc_fw_arg acc_fw_arg;
926                 struct v4l2_private_int_data v4l2_pri_data;
927                 struct atomisp_shading_table shd_tbl;
928                 struct atomisp_acc_map acc_map;
929                 struct atomisp_acc_s_mapped_arg acc_map_arg;
930                 struct atomisp_parameters param;
931                 struct atomisp_acc_fw_load_to_pipe acc_fw_to_pipe;
932                 struct atomisp_metadata md;
933                 struct atomisp_metadata_with_type md_with_type;
934                 struct atomisp_sensor_ae_bracketing_lut lut;
935         } karg;
936         mm_segment_t old_fs;
937         void __user *up = compat_ptr(arg);
938         long err = -ENOIOCTLCMD;
939
940         /* First, convert the command. */
941         switch (cmd) {
942         case ATOMISP_IOC_G_HISTOGRAM32:
943                 cmd = ATOMISP_IOC_G_HISTOGRAM;
944                 break;
945         case ATOMISP_IOC_S_HISTOGRAM32:
946                 cmd = ATOMISP_IOC_S_HISTOGRAM;
947                 break;
948         case ATOMISP_IOC_G_DIS_STAT32:
949                 cmd = ATOMISP_IOC_G_DIS_STAT;
950                 break;
951         case ATOMISP_IOC_S_DIS_COEFS32:
952                 cmd = ATOMISP_IOC_S_DIS_COEFS;
953                 break;
954         case ATOMISP_IOC_S_DIS_VECTOR32:
955                 cmd = ATOMISP_IOC_S_DIS_VECTOR;
956                 break;
957         case ATOMISP_IOC_G_3A_STAT32:
958                 cmd = ATOMISP_IOC_G_3A_STAT;
959                 break;
960         case ATOMISP_IOC_G_ISP_GDC_TAB32:
961                 cmd = ATOMISP_IOC_G_ISP_GDC_TAB;
962                 break;
963         case ATOMISP_IOC_S_ISP_GDC_TAB32:
964                 cmd = ATOMISP_IOC_S_ISP_GDC_TAB;
965                 break;
966         case ATOMISP_IOC_S_ISP_FPN_TABLE32:
967                 cmd = ATOMISP_IOC_S_ISP_FPN_TABLE;
968                 break;
969         case ATOMISP_IOC_G_ISP_OVERLAY32:
970                 cmd = ATOMISP_IOC_G_ISP_OVERLAY;
971                 break;
972         case ATOMISP_IOC_S_ISP_OVERLAY32:
973                 cmd = ATOMISP_IOC_S_ISP_OVERLAY;
974                 break;
975         case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP32:
976                 cmd = ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP;
977                 break;
978         case ATOMISP_IOC_ACC_LOAD32:
979                 cmd = ATOMISP_IOC_ACC_LOAD;
980                 break;
981         case ATOMISP_IOC_ACC_S_ARG32:
982                 cmd = ATOMISP_IOC_ACC_S_ARG;
983                 break;
984         case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA32:
985                 cmd = ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA;
986                 break;
987         case ATOMISP_IOC_S_ISP_SHD_TAB32:
988                 cmd = ATOMISP_IOC_S_ISP_SHD_TAB;
989                 break;
990         case ATOMISP_IOC_ACC_DESTAB32:
991                 cmd = ATOMISP_IOC_ACC_DESTAB;
992                 break;
993         case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA32:
994                 cmd = ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA;
995                 break;
996         case ATOMISP_IOC_ACC_MAP32:
997                 cmd = ATOMISP_IOC_ACC_MAP;
998                 break;
999         case ATOMISP_IOC_ACC_UNMAP32:
1000                 cmd = ATOMISP_IOC_ACC_UNMAP;
1001                 break;
1002         case ATOMISP_IOC_ACC_S_MAPPED_ARG32:
1003                 cmd = ATOMISP_IOC_ACC_S_MAPPED_ARG;
1004                 break;
1005         case ATOMISP_IOC_S_PARAMETERS32:
1006                 cmd = ATOMISP_IOC_S_PARAMETERS;
1007                 break;
1008         case ATOMISP_IOC_ACC_LOAD_TO_PIPE32:
1009                 cmd = ATOMISP_IOC_ACC_LOAD_TO_PIPE;
1010                 break;
1011         case ATOMISP_IOC_G_METADATA32:
1012                 cmd = ATOMISP_IOC_G_METADATA;
1013                 break;
1014         case ATOMISP_IOC_G_METADATA_BY_TYPE32:
1015                 cmd = ATOMISP_IOC_G_METADATA_BY_TYPE;
1016                 break;
1017         case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_LUT32:
1018                 cmd = ATOMISP_IOC_S_SENSOR_AE_BRACKETING_LUT;
1019                 break;
1020         }
1021
1022         switch (cmd) {
1023         case ATOMISP_IOC_G_HISTOGRAM:
1024         case ATOMISP_IOC_S_HISTOGRAM:
1025                 err = get_atomisp_histogram32(&karg.his, up);
1026                 break;
1027         case ATOMISP_IOC_G_DIS_STAT:
1028                 err = get_atomisp_dis_statistics32(&karg.dis_s, up);
1029                 break;
1030         case ATOMISP_IOC_S_DIS_COEFS:
1031                 err = get_atomisp_dis_coefficients32(&karg.dis_c, up);
1032                 break;
1033         case ATOMISP_IOC_S_DIS_VECTOR:
1034                 err = get_atomisp_dvs_6axis_config32(&karg.dvs_c, up);
1035                 break;
1036         case ATOMISP_IOC_G_3A_STAT:
1037                 err = get_atomisp_3a_statistics32(&karg.s3a_s, up);
1038                 break;
1039         case ATOMISP_IOC_G_ISP_GDC_TAB:
1040         case ATOMISP_IOC_S_ISP_GDC_TAB:
1041                 err = get_atomisp_morph_table32(&karg.mor_t, up);
1042                 break;
1043         case ATOMISP_IOC_S_ISP_FPN_TABLE:
1044                 err = get_v4l2_framebuffer32(&karg.v4l2_buf, up);
1045                 break;
1046         case ATOMISP_IOC_G_ISP_OVERLAY:
1047         case ATOMISP_IOC_S_ISP_OVERLAY:
1048                 err = get_atomisp_overlay32(&karg.overlay, up);
1049                 break;
1050         case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP:
1051                 err = get_atomisp_calibration_group32(&karg.cal_grp, up);
1052                 break;
1053         case ATOMISP_IOC_ACC_LOAD:
1054                 err = get_atomisp_acc_fw_load32(&karg.acc_fw_load, up);
1055                 break;
1056         case ATOMISP_IOC_ACC_S_ARG:
1057         case ATOMISP_IOC_ACC_DESTAB:
1058                 err = get_atomisp_acc_fw_arg32(&karg.acc_fw_arg, up);
1059                 break;
1060         case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA:
1061         case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA:
1062                 err = get_v4l2_private_int_data32(&karg.v4l2_pri_data, up);
1063                 break;
1064         case ATOMISP_IOC_S_ISP_SHD_TAB:
1065                 err = get_atomisp_shading_table32(&karg.shd_tbl, up);
1066                 break;
1067         case ATOMISP_IOC_ACC_MAP:
1068         case ATOMISP_IOC_ACC_UNMAP:
1069                 err = get_atomisp_acc_map32(&karg.acc_map, up);
1070                 break;
1071         case ATOMISP_IOC_ACC_S_MAPPED_ARG:
1072                 err = get_atomisp_acc_s_mapped_arg32(&karg.acc_map_arg, up);
1073                 break;
1074         case ATOMISP_IOC_S_PARAMETERS:
1075                 err = get_atomisp_parameters32(&karg.param, up);
1076                 break;
1077         case ATOMISP_IOC_ACC_LOAD_TO_PIPE:
1078                 err = get_atomisp_acc_fw_load_to_pipe32(&karg.acc_fw_to_pipe,
1079                                                         up);
1080                 break;
1081         case ATOMISP_IOC_G_METADATA:
1082                 err = get_atomisp_metadata_stat32(&karg.md, up);
1083                 break;
1084         case ATOMISP_IOC_G_METADATA_BY_TYPE:
1085                 err = get_atomisp_metadata_by_type_stat32(&karg.md_with_type,
1086                                                         up);
1087                 break;
1088         case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_LUT:
1089                 err = get_atomisp_sensor_ae_bracketing_lut(&karg.lut, up);
1090                 break;
1091         }
1092         if (err)
1093                 return err;
1094
1095         old_fs = get_fs();
1096         set_fs(KERNEL_DS);
1097         err = native_ioctl(file, cmd, (unsigned long)&karg);
1098         set_fs(old_fs);
1099         if (err)
1100                 return err;
1101
1102         switch (cmd) {
1103         case ATOMISP_IOC_G_HISTOGRAM:
1104                 err = put_atomisp_histogram32(&karg.his, up);
1105                 break;
1106         case ATOMISP_IOC_G_DIS_STAT:
1107                 err = put_atomisp_dis_statistics32(&karg.dis_s, up);
1108                 break;
1109         case ATOMISP_IOC_G_3A_STAT:
1110                 err = put_atomisp_3a_statistics32(&karg.s3a_s, up);
1111                 break;
1112         case ATOMISP_IOC_G_ISP_GDC_TAB:
1113                 err = put_atomisp_morph_table32(&karg.mor_t, up);
1114                 break;
1115         case ATOMISP_IOC_G_ISP_OVERLAY:
1116                 err = put_atomisp_overlay32(&karg.overlay, up);
1117                 break;
1118         case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP:
1119                 err = put_atomisp_calibration_group32(&karg.cal_grp, up);
1120                 break;
1121         case ATOMISP_IOC_ACC_LOAD:
1122                 err = put_atomisp_acc_fw_load32(&karg.acc_fw_load, up);
1123                 break;
1124         case ATOMISP_IOC_ACC_S_ARG:
1125         case ATOMISP_IOC_ACC_DESTAB:
1126                 err = put_atomisp_acc_fw_arg32(&karg.acc_fw_arg, up);
1127                 break;
1128         case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA:
1129         case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA:
1130                 err = put_v4l2_private_int_data32(&karg.v4l2_pri_data, up);
1131                 break;
1132         case ATOMISP_IOC_ACC_MAP:
1133         case ATOMISP_IOC_ACC_UNMAP:
1134                 err = put_atomisp_acc_map32(&karg.acc_map, up);
1135                 break;
1136         case ATOMISP_IOC_ACC_S_MAPPED_ARG:
1137                 err = put_atomisp_acc_s_mapped_arg32(&karg.acc_map_arg, up);
1138                 break;
1139         case ATOMISP_IOC_ACC_LOAD_TO_PIPE:
1140                 err = put_atomisp_acc_fw_load_to_pipe32(&karg.acc_fw_to_pipe,
1141                                                         up);
1142                 break;
1143         case ATOMISP_IOC_G_METADATA:
1144                 err = put_atomisp_metadata_stat32(&karg.md, up);
1145                 break;
1146         case ATOMISP_IOC_G_METADATA_BY_TYPE:
1147                 err = put_atomisp_metadata_by_type_stat32(&karg.md_with_type,
1148                                                         up);
1149                 break;
1150         }
1151
1152         return err;
1153 }
1154
1155 long atomisp_compat_ioctl32(struct file *file,
1156                             unsigned int cmd, unsigned long arg)
1157 {
1158
1159         struct video_device *vdev = video_devdata(file);
1160         struct atomisp_device *isp = video_get_drvdata(vdev);
1161         long ret = -ENOIOCTLCMD;
1162
1163         if (!file->f_op->unlocked_ioctl)
1164                 return ret;
1165
1166         switch (cmd) {
1167         case ATOMISP_IOC_G_XNR:
1168         case ATOMISP_IOC_S_XNR:
1169         case ATOMISP_IOC_G_NR:
1170         case ATOMISP_IOC_S_NR:
1171         case ATOMISP_IOC_G_TNR:
1172         case ATOMISP_IOC_S_TNR:
1173         case ATOMISP_IOC_G_BLACK_LEVEL_COMP:
1174         case ATOMISP_IOC_S_BLACK_LEVEL_COMP:
1175         case ATOMISP_IOC_G_EE:
1176         case ATOMISP_IOC_S_EE:
1177         case ATOMISP_IOC_S_DIS_VECTOR:
1178         case ATOMISP_IOC_G_ISP_PARM:
1179         case ATOMISP_IOC_S_ISP_PARM:
1180         case ATOMISP_IOC_G_ISP_GAMMA:
1181         case ATOMISP_IOC_S_ISP_GAMMA:
1182         case ATOMISP_IOC_ISP_MAKERNOTE:
1183         case ATOMISP_IOC_G_ISP_MACC:
1184         case ATOMISP_IOC_S_ISP_MACC:
1185         case ATOMISP_IOC_G_ISP_BAD_PIXEL_DETECTION:
1186         case ATOMISP_IOC_S_ISP_BAD_PIXEL_DETECTION:
1187         case ATOMISP_IOC_G_ISP_FALSE_COLOR_CORRECTION:
1188         case ATOMISP_IOC_S_ISP_FALSE_COLOR_CORRECTION:
1189         case ATOMISP_IOC_G_ISP_CTC:
1190         case ATOMISP_IOC_S_ISP_CTC:
1191         case ATOMISP_IOC_G_ISP_WHITE_BALANCE:
1192         case ATOMISP_IOC_S_ISP_WHITE_BALANCE:
1193         case ATOMISP_IOC_CAMERA_BRIDGE:
1194         case ATOMISP_IOC_G_SENSOR_MODE_DATA:
1195         case ATOMISP_IOC_S_EXPOSURE:
1196         case ATOMISP_IOC_G_3A_CONFIG:
1197         case ATOMISP_IOC_S_3A_CONFIG:
1198         case ATOMISP_IOC_ACC_UNLOAD:
1199         case ATOMISP_IOC_ACC_START:
1200         case ATOMISP_IOC_ACC_WAIT:
1201         case ATOMISP_IOC_ACC_ABORT:
1202         case ATOMISP_IOC_G_ISP_GAMMA_CORRECTION:
1203         case ATOMISP_IOC_S_ISP_GAMMA_CORRECTION:
1204         case ATOMISP_IOC_S_CONT_CAPTURE_CONFIG:
1205         case ATOMISP_IOC_G_DVS2_BQ_RESOLUTIONS:
1206         case ATOMISP_IOC_EXT_ISP_CTRL:
1207         case ATOMISP_IOC_EXP_ID_UNLOCK:
1208         case ATOMISP_IOC_EXP_ID_CAPTURE:
1209         case ATOMISP_IOC_S_ENABLE_DZ_CAPT_PIPE:
1210         case ATOMISP_IOC_G_FORMATS_CONFIG:
1211         case ATOMISP_IOC_S_FORMATS_CONFIG:
1212         case ATOMISP_IOC_S_EXPOSURE_WINDOW:
1213         case ATOMISP_IOC_S_ACC_STATE:
1214         case ATOMISP_IOC_G_ACC_STATE:
1215         case ATOMISP_IOC_INJECT_A_FAKE_EVENT:
1216         case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_INFO:
1217         case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_MODE:
1218         case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_MODE:
1219         case ATOMISP_IOC_G_INVALID_FRAME_NUM:
1220         case ATOMISP_IOC_S_ARRAY_RESOLUTION:
1221 #ifdef ISP2401
1222         case ATOMISP_IOC_S_SENSOR_RUNMODE:
1223         case ATOMISP_IOC_G_UPDATE_EXPOSURE:
1224 #endif
1225                 ret = native_ioctl(file, cmd, arg);
1226                 break;
1227
1228         case ATOMISP_IOC_G_HISTOGRAM32:
1229         case ATOMISP_IOC_S_HISTOGRAM32:
1230         case ATOMISP_IOC_G_DIS_STAT32:
1231         case ATOMISP_IOC_S_DIS_COEFS32:
1232         case ATOMISP_IOC_S_DIS_VECTOR32:
1233         case ATOMISP_IOC_G_3A_STAT32:
1234         case ATOMISP_IOC_G_ISP_GDC_TAB32:
1235         case ATOMISP_IOC_S_ISP_GDC_TAB32:
1236         case ATOMISP_IOC_S_ISP_FPN_TABLE32:
1237         case ATOMISP_IOC_G_ISP_OVERLAY32:
1238         case ATOMISP_IOC_S_ISP_OVERLAY32:
1239         case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP32:
1240         case ATOMISP_IOC_ACC_LOAD32:
1241         case ATOMISP_IOC_ACC_S_ARG32:
1242         case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA32:
1243         case ATOMISP_IOC_S_ISP_SHD_TAB32:
1244         case ATOMISP_IOC_ACC_DESTAB32:
1245         case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA32:
1246         case ATOMISP_IOC_ACC_MAP32:
1247         case ATOMISP_IOC_ACC_UNMAP32:
1248         case ATOMISP_IOC_ACC_S_MAPPED_ARG32:
1249         case ATOMISP_IOC_S_PARAMETERS32:
1250         case ATOMISP_IOC_ACC_LOAD_TO_PIPE32:
1251         case ATOMISP_IOC_G_METADATA32:
1252         case ATOMISP_IOC_G_METADATA_BY_TYPE32:
1253         case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_LUT32:
1254                 ret = atomisp_do_compat_ioctl(file, cmd, arg);
1255                 break;
1256
1257         default:
1258                 dev_warn(isp->dev,
1259                         "%s: unknown ioctl '%c', dir=%d, #%d (0x%08x)\n",
1260                         __func__, _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd),
1261                         cmd);
1262                 break;
1263         }
1264         return ret;
1265 }
1266 #endif /* CONFIG_COMPAT */