linux/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c
<<
>>
Prefs
   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
  48static 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
  62static 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
  76static 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
  92static 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
 144static 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
 196static 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
 239static 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
 266static 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
 285static 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
 304static 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
 324static 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
 345static int
 346put_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
 368static int
 369get_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
 390static int
 391get_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
 414static 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
 437static 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
 467static 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
 497static int
 498get_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
 513static int
 514put_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
 530static 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
 545static 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
 560static 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
 576static 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
 592static 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
 608static 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
 624static 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
 648static 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
 668static 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
 688static int
 689get_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
 702static int
 703put_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
 716static 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
 778static int
 779get_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
 799static int
 800put_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
 820static int
 821get_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
 835static 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
 845static 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
1094long 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