diff options
| author | Gopikrishnaiah Anandan <agopik@codeaurora.org> | 2014-12-12 14:14:56 -0800 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:37:24 -0700 |
| commit | 4e095a46e7c9409c4890b773cf02b8b2ea3e6ce2 (patch) | |
| tree | 70c3257b75ba031c895771d5584ceb387f7fc61c /drivers/video/fbdev | |
| parent | 7e3a174db3b4db364c674646998b2e26e9fe60c8 (diff) | |
msm: mdss: Add compat ioctl support for IGC in thulium
Post processing structures have been upgraded for thulium. Changes have
to be made on the compat ioctl path to ensure that 32 bit userspace
driver clients are able to configure the PP features when kernel is in
64 bit mode. This change updates the compat ioctl path for post
processing features.
Change-Id: Id3e1d4f2055638bc553082a1f477b5ef3ef41c80
Signed-off-by: Gopikrishnaiah Anandan <agopik@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev')
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_compat_utils.c | 91 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_compat_utils.h | 11 |
2 files changed, 92 insertions, 10 deletions
diff --git a/drivers/video/fbdev/msm/mdss_compat_utils.c b/drivers/video/fbdev/msm/mdss_compat_utils.c index 48d0f11e8671..b7ce8480b486 100644 --- a/drivers/video/fbdev/msm/mdss_compat_utils.c +++ b/drivers/video/fbdev/msm/mdss_compat_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * Copyright (C) 1994 Martin Schaller * * 2001 - Documented with DocBook @@ -582,11 +582,38 @@ static int __to_user_csc_cfg_data( return 0; } +static int __from_user_igc_lut_data_v17( + struct mdp_igc_lut_data32 __user *igc_lut32, + struct mdp_igc_lut_data __user *igc_lut) +{ + struct mdp_igc_lut_data_v1_7_32 igc_cfg_payload_32; + struct mdp_igc_lut_data_v1_7 igc_cfg_payload; + + if (copy_from_user(&igc_cfg_payload_32, + compat_ptr(igc_lut32->cfg_payload), + sizeof(igc_cfg_payload_32))) { + pr_err("failed to copy payload from user for igc\n"); + return -EFAULT; + } + igc_cfg_payload.c0_c1_data = compat_ptr(igc_cfg_payload_32.c0_c1_data); + igc_cfg_payload.c2_data = compat_ptr(igc_cfg_payload_32.c2_data); + igc_cfg_payload.len = igc_cfg_payload_32.len; + igc_cfg_payload.table_fmt = igc_cfg_payload_32.table_fmt; + if (copy_to_user(igc_lut->cfg_payload, &igc_cfg_payload, + sizeof(igc_cfg_payload))) { + pr_err("failed to copy payload to user for igc\n"); + return -EFAULT; + } + return 0; +} + static int __from_user_igc_lut_data( struct mdp_igc_lut_data32 __user *igc_lut32, struct mdp_igc_lut_data __user *igc_lut) { uint32_t data; + uint32_t version = mdp_igc_vmax; + int ret = 0; if (copy_in_user(&igc_lut->block, &igc_lut32->block, @@ -596,16 +623,35 @@ static int __from_user_igc_lut_data( sizeof(uint32_t)) || copy_in_user(&igc_lut->ops, &igc_lut32->ops, + sizeof(uint32_t)) || + copy_in_user(&igc_lut->version, + &igc_lut32->version, sizeof(uint32_t))) return -EFAULT; - if (get_user(data, &igc_lut32->c0_c1_data) || - put_user(compat_ptr(data), &igc_lut->c0_c1_data) || - get_user(data, &igc_lut32->c2_data) || - put_user(compat_ptr(data), &igc_lut->c2_data)) + if (get_user(version, &igc_lut32->version)) { + pr_err("failed to copy the version for IGC\n"); return -EFAULT; + } - return 0; + switch (version) { + case mdp_igc_v1_7: + ret = __from_user_igc_lut_data_v17(igc_lut32, igc_lut); + if (ret) + pr_err("failed to copy payload for igc version %d ret %d\n", + version, ret); + break; + default: + pr_debug("version not supported fallback to legacy %d\n", + version); + if (get_user(data, &igc_lut32->c0_c1_data) || + put_user(compat_ptr(data), &igc_lut->c0_c1_data) || + get_user(data, &igc_lut32->c2_data) || + put_user(compat_ptr(data), &igc_lut->c2_data)) + return -EFAULT; + break; + } + return ret; } static int __to_user_igc_lut_data( @@ -1804,6 +1850,14 @@ static int __from_user_pp_init_data( return 0; } +static u32 __pp_compat_size_igc(void) +{ + u32 alloc_size = 0; + /* When we have mutiple versions pick largest struct size */ + alloc_size = sizeof(struct mdp_igc_lut_data_v1_7); + return alloc_size; +} + static int __pp_compat_alloc(struct msmfb_mdp_pp32 __user *pp32, struct msmfb_mdp_pp __user **pp, uint32_t op) @@ -1820,7 +1874,8 @@ static int __pp_compat_alloc(struct msmfb_mdp_pp32 __user *pp32, sizeof(uint32_t))) return -EFAULT; - if (lut_type == mdp_lut_pgc) { + switch (lut_type) { + case mdp_lut_pgc: pgc_data32 = compat_ptr((uintptr_t) &pp32->data.lut_cfg_data.data.pgc_lut_data); if (copy_from_user(&num_r_stages, @@ -1869,11 +1924,29 @@ static int __pp_compat_alloc(struct msmfb_mdp_pp32 __user *pp32, ((unsigned long) *pp + sizeof(struct msmfb_mdp_pp) + r_size + g_size); - } else { + break; + case mdp_lut_igc: + alloc_size += __pp_compat_size_igc(); *pp = compat_alloc_user_space(alloc_size); - if (NULL == *pp) + if (NULL == *pp) { + pr_err("failed to alloc from user size %d for igc\n", + alloc_size); + return -ENOMEM; + } + memset(*pp, 0, alloc_size); + (*pp)->data.lut_cfg_data.data.igc_lut_data.cfg_payload + = (void *)((unsigned long)(*pp) + + sizeof(struct msmfb_mdp_pp)); + break; + default: + *pp = compat_alloc_user_space(alloc_size); + if (NULL == *pp) { + pr_err("failed to alloc from user size %d for lut_type %d\n", + alloc_size, lut_type); return -ENOMEM; + } memset(*pp, 0, alloc_size); + break; } } else { *pp = compat_alloc_user_space(alloc_size); diff --git a/drivers/video/fbdev/msm/mdss_compat_utils.h b/drivers/video/fbdev/msm/mdss_compat_utils.h index 364746866db8..77452b7194c6 100644 --- a/drivers/video/fbdev/msm/mdss_compat_utils.h +++ b/drivers/video/fbdev/msm/mdss_compat_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -168,11 +168,20 @@ struct mdp_pa_cfg_data32 { struct mdp_pa_cfg32 pa_data; }; +struct mdp_igc_lut_data_v1_7_32 { + uint32_t table_fmt; + uint32_t len; + compat_caddr_t c0_c1_data; + compat_caddr_t c2_data; +}; + struct mdp_igc_lut_data32 { uint32_t block; + uint32_t version; uint32_t len, ops; compat_caddr_t c0_c1_data; compat_caddr_t c2_data; + compat_caddr_t cfg_payload; }; struct mdp_hist_lut_data32 { |
