}
static int __mdss_fb_copy_destscaler_data(struct fb_info *info,
- struct mdp_layer_commit *commit)
+ struct mdp_layer_commit *commit,
+ struct mdp_destination_scaler_data *ds_data,
+ struct mdp_scale_data_v2 *scale_data)
{
int i = 0;
int ret = 0;
- u32 data_size;
struct mdp_destination_scaler_data __user *ds_data_user;
- struct mdp_destination_scaler_data *ds_data = NULL;
void __user *scale_data_user;
- struct mdp_scale_data_v2 *scale_data = NULL;
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
struct mdss_data_type *mdata;
if (!mfd || !mfd->mdp.private1) {
pr_err("mfd is NULL or operation not permitted\n");
- ret = -EINVAL;
- goto err;
+ return -EINVAL;
}
mdata = mfd_to_mdata(mfd);
if (!mdata) {
pr_err("mdata is NULL or not initialized\n");
- ret = -EINVAL;
- goto err;
+ return -EINVAL;
}
if (commit->commit_v1.dest_scaler_cnt >
mdata->scaler_off->ndest_scalers) {
pr_err("Commit destination scaler cnt larger than HW setting, commit cnt=%d\n",
commit->commit_v1.dest_scaler_cnt);
- ret = -EINVAL;
- goto err;
+ return -EINVAL;
}
ds_data_user = (struct mdp_destination_scaler_data *)
commit->commit_v1.dest_scaler;
- data_size = commit->commit_v1.dest_scaler_cnt *
- sizeof(struct mdp_destination_scaler_data);
- ds_data = kzalloc(data_size, GFP_KERNEL);
- if (!ds_data) {
- ret = -ENOMEM;
- goto err;
- }
-
- ret = copy_from_user(ds_data, ds_data_user, data_size);
+ ret = copy_from_user(ds_data, ds_data_user,
+ commit->commit_v1.dest_scaler_cnt * sizeof(*ds_data));
if (ret) {
pr_err("dest scaler data copy from user failed\n");
- goto err;
+ return ret;
}
commit->commit_v1.dest_scaler = ds_data;
for (i = 0; i < commit->commit_v1.dest_scaler_cnt; i++) {
- scale_data = NULL;
-
- if (ds_data[i].scale) {
- scale_data_user = to_user_ptr(ds_data[i].scale);
- data_size = sizeof(struct mdp_scale_data_v2);
-
- scale_data = kzalloc(data_size, GFP_KERNEL);
- if (!scale_data) {
- ds_data[i].scale = 0;
- ret = -ENOMEM;
- goto err;
- }
-
- ds_data[i].scale = to_user_u64(scale_data);
- }
+ if (!ds_data[i].scale)
+ continue;
- if (scale_data && (ds_data[i].flags &
- (MDP_DESTSCALER_SCALE_UPDATE |
- MDP_DESTSCALER_ENHANCER_UPDATE))) {
- ret = copy_from_user(scale_data, scale_data_user,
- data_size);
+ scale_data_user = to_user_ptr(ds_data[i].scale);
+ ds_data[i].scale = to_user_u64(&scale_data[i]);
+ if (ds_data[i].flags & (MDP_DESTSCALER_SCALE_UPDATE |
+ MDP_DESTSCALER_ENHANCER_UPDATE)) {
+ ret = copy_from_user(scale_data + i, scale_data_user,
+ sizeof(*scale_data));
if (ret) {
pr_err("scale data copy from user failed\n");
- kfree(scale_data);
- goto err;
+ return ret;
}
+ } else {
+ memset(scale_data + i, 0, sizeof(*scale_data));
}
}
return ret;
-
-err:
- if (ds_data) {
- for (i--; i >= 0; i--) {
- scale_data = to_user_ptr(ds_data[i].scale);
- kfree(scale_data);
- }
- kfree(ds_data);
- }
-
- return ret;
}
static int mdss_fb_atomic_commit_ioctl(struct fb_info *info,
struct mdp_input_layer __user *input_layer_list;
struct mdp_output_layer *output_layer = NULL;
struct mdp_output_layer __user *output_layer_user;
- struct mdp_destination_scaler_data *ds_data = NULL;
struct mdp_destination_scaler_data __user *ds_data_user;
struct msm_fb_data_type *mfd;
struct mdss_overlay_private *mdp5_data = NULL;
struct mdss_data_type *mdata;
+ struct mdp_destination_scaler_data ds_data[2];
+ struct mdp_scale_data_v2 scale_data[2];
ret = copy_from_user(&commit, argp, sizeof(struct mdp_layer_commit));
if (ret) {
ret = -EPERM;
goto err;
}
- ret = __mdss_fb_copy_destscaler_data(info, &commit);
+ ret = __mdss_fb_copy_destscaler_data(info, &commit, ds_data,
+ scale_data);
if (ret) {
pr_err("copy dest scaler failed\n");
goto err;
}
- ds_data = commit.commit_v1.dest_scaler;
}
ATRACE_BEGIN("ATOMIC_COMMIT");
}
kfree(layer_list);
kfree(output_layer);
- if (ds_data) {
- for (i = 0; i < commit.commit_v1.dest_scaler_cnt; i++)
- kfree(to_user_ptr(ds_data[i].scale));
- kfree(ds_data);
- }
return ret;
}