mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-12-12 17:34:30 -05:00
144 lines
4.5 KiB
Diff
144 lines
4.5 KiB
Diff
From 67dfd3a65336e0b3f55ee83d6312321dc5f2a6f9 Mon Sep 17 00:00:00 2001
|
|
From: Padmanabhan Komanduru <pkomandu@codeaurora.org>
|
|
Date: Wed, 25 Jan 2017 16:38:48 +0530
|
|
Subject: msm: mdss: handle synchronization issues during DSI debugfs
|
|
read/write
|
|
|
|
Handle race condition during read/write operations to DSI debugfs nodes
|
|
related to DSI panel ON/OFF commands.
|
|
|
|
Change-Id: I29c4ad74bf21d4cb5362565e902a682fe7263147
|
|
Signed-off-by: Padmanabhan Komanduru <pkomandu@codeaurora.org>
|
|
---
|
|
drivers/video/msm/mdss/mdss_dsi.c | 21 +++++++++++++++++++--
|
|
1 file changed, 19 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c
|
|
index 885d132..e6d9edc 100644
|
|
--- a/drivers/video/msm/mdss/mdss_dsi.c
|
|
+++ b/drivers/video/msm/mdss/mdss_dsi.c
|
|
@@ -1,4 +1,4 @@
|
|
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
|
|
+/* Copyright (c) 2012-2017, 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
|
|
@@ -625,6 +625,7 @@ struct buf_data {
|
|
char *string_buf; /* cmd buf as string, 3 bytes per number */
|
|
int sblen; /* string buffer length */
|
|
int sync_flag;
|
|
+ struct mutex dbg_mutex; /* mutex to synchronize read/write/flush */
|
|
};
|
|
|
|
struct mdss_dsi_debugfs_info {
|
|
@@ -714,6 +715,7 @@ static ssize_t mdss_dsi_cmd_read(struct file *file, char __user *buf,
|
|
char *bp;
|
|
ssize_t ret = 0;
|
|
|
|
+ mutex_lock(&pcmds->dbg_mutex);
|
|
if (*ppos == 0) {
|
|
kfree(pcmds->string_buf);
|
|
pcmds->string_buf = NULL;
|
|
@@ -732,6 +734,7 @@ static ssize_t mdss_dsi_cmd_read(struct file *file, char __user *buf,
|
|
buffer = kmalloc(bsize, GFP_KERNEL);
|
|
if (!buffer) {
|
|
pr_err("%s: Failed to allocate memory\n", __func__);
|
|
+ mutex_unlock(&pcmds->dbg_mutex);
|
|
return -ENOMEM;
|
|
}
|
|
|
|
@@ -767,10 +770,12 @@ static ssize_t mdss_dsi_cmd_read(struct file *file, char __user *buf,
|
|
kfree(pcmds->string_buf);
|
|
pcmds->string_buf = NULL;
|
|
pcmds->sblen = 0;
|
|
+ mutex_unlock(&pcmds->dbg_mutex);
|
|
return 0; /* the end */
|
|
}
|
|
ret = simple_read_from_buffer(buf, count, ppos, pcmds->string_buf,
|
|
pcmds->sblen);
|
|
+ mutex_unlock(&pcmds->dbg_mutex);
|
|
return ret;
|
|
}
|
|
|
|
@@ -782,6 +787,7 @@ static ssize_t mdss_dsi_cmd_write(struct file *file, const char __user *p,
|
|
int blen = 0;
|
|
char *string_buf;
|
|
|
|
+ mutex_lock(&pcmds->dbg_mutex);
|
|
if (*ppos == 0) {
|
|
kfree(pcmds->string_buf);
|
|
pcmds->string_buf = NULL;
|
|
@@ -793,6 +799,7 @@ static ssize_t mdss_dsi_cmd_write(struct file *file, const char __user *p,
|
|
string_buf = krealloc(pcmds->string_buf, blen + 1, GFP_KERNEL);
|
|
if (!string_buf) {
|
|
pr_err("%s: Failed to allocate memory\n", __func__);
|
|
+ mutex_unlock(&pcmds->dbg_mutex);
|
|
return -ENOMEM;
|
|
}
|
|
|
|
@@ -802,6 +809,7 @@ static ssize_t mdss_dsi_cmd_write(struct file *file, const char __user *p,
|
|
string_buf[blen] = '\0';
|
|
pcmds->string_buf = string_buf;
|
|
pcmds->sblen = blen;
|
|
+ mutex_unlock(&pcmds->dbg_mutex);
|
|
return ret;
|
|
}
|
|
|
|
@@ -812,8 +820,12 @@ static int mdss_dsi_cmd_flush(struct file *file, fl_owner_t id)
|
|
char *buf, *bufp, *bp;
|
|
struct dsi_ctrl_hdr *dchdr;
|
|
|
|
- if (!pcmds->string_buf)
|
|
+ mutex_lock(&pcmds->dbg_mutex);
|
|
+
|
|
+ if (!pcmds->string_buf) {
|
|
+ mutex_unlock(&pcmds->dbg_mutex);
|
|
return 0;
|
|
+ }
|
|
|
|
/*
|
|
* Allocate memory for command buffer
|
|
@@ -826,6 +838,7 @@ static int mdss_dsi_cmd_flush(struct file *file, fl_owner_t id)
|
|
kfree(pcmds->string_buf);
|
|
pcmds->string_buf = NULL;
|
|
pcmds->sblen = 0;
|
|
+ mutex_unlock(&pcmds->dbg_mutex);
|
|
return -ENOMEM;
|
|
}
|
|
|
|
@@ -850,6 +863,7 @@ static int mdss_dsi_cmd_flush(struct file *file, fl_owner_t id)
|
|
pr_err("%s: dtsi cmd=%x error, len=%d\n",
|
|
__func__, dchdr->dtype, dchdr->dlen);
|
|
kfree(buf);
|
|
+ mutex_unlock(&pcmds->dbg_mutex);
|
|
return -EINVAL;
|
|
}
|
|
bp += sizeof(*dchdr);
|
|
@@ -861,6 +875,7 @@ static int mdss_dsi_cmd_flush(struct file *file, fl_owner_t id)
|
|
pr_err("%s: dcs_cmd=%x len=%d error!\n", __func__,
|
|
bp[0], len);
|
|
kfree(buf);
|
|
+ mutex_unlock(&pcmds->dbg_mutex);
|
|
return -EINVAL;
|
|
}
|
|
|
|
@@ -873,6 +888,7 @@ static int mdss_dsi_cmd_flush(struct file *file, fl_owner_t id)
|
|
pcmds->buf = buf;
|
|
pcmds->blen = blen;
|
|
}
|
|
+ mutex_unlock(&pcmds->dbg_mutex);
|
|
return 0;
|
|
}
|
|
|
|
@@ -887,6 +903,7 @@ struct dentry *dsi_debugfs_create_dcs_cmd(const char *name, umode_t mode,
|
|
struct dentry *parent, struct buf_data *cmd,
|
|
struct dsi_panel_cmds ctrl_cmds)
|
|
{
|
|
+ mutex_init(&cmd->dbg_mutex);
|
|
cmd->buf = ctrl_cmds.buf;
|
|
cmd->blen = ctrl_cmds.blen;
|
|
cmd->string_buf = NULL;
|
|
--
|
|
cgit v1.1
|
|
|