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