Merge tag 'LA.BR.1.3.6-04110-8976.0' of https://source.codeaurora.org/quic/la/kernel/msm-3.10 into HEAD

"LA.BR.1.3.6-04110-8976.0"

Change-Id: Ie9bc105eee4263ab1ec2f91556feca988522808f
This commit is contained in:
LuK1337 2017-07-08 18:34:23 +02:00
commit ea03599937
32 changed files with 541 additions and 270 deletions

View File

@ -2703,6 +2703,8 @@ int diag_dci_register_client(struct diag_dci_reg_tbl_t *reg_entry)
new_entry->num_buffers = 1;
break;
}
new_entry->buffers = NULL;
new_entry->real_time = MODE_REALTIME;
new_entry->in_service = 0;
INIT_LIST_HEAD(&new_entry->list_write_buf);
@ -2776,7 +2778,8 @@ int diag_dci_register_client(struct diag_dci_reg_tbl_t *reg_entry)
fail_alloc:
if (new_entry) {
for (i = 0; i < new_entry->num_buffers; i++) {
for (i = 0; ((i < new_entry->num_buffers) &&
new_entry->buffers); i++) {
proc_buf = &new_entry->buffers[i];
if (proc_buf) {
mutex_destroy(&proc_buf->health_mutex);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-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
@ -256,8 +256,10 @@ static ssize_t diag_dbgfs_read_table(struct file *file, char __user *ubuf,
struct list_head *temp;
struct diag_cmd_reg_t *item = NULL;
mutex_lock(&driver->cmd_reg_mutex);
if (diag_dbgfs_table_index == driver->cmd_reg_count) {
diag_dbgfs_table_index = 0;
mutex_unlock(&driver->cmd_reg_mutex);
return 0;
}
@ -266,6 +268,7 @@ static ssize_t diag_dbgfs_read_table(struct file *file, char __user *ubuf,
buf = kzalloc(sizeof(char) * buf_size, GFP_KERNEL);
if (ZERO_OR_NULL_PTR(buf)) {
pr_err("diag: %s, Error allocating memory\n", __func__);
mutex_unlock(&driver->cmd_reg_mutex);
return -ENOMEM;
}
buf_size = ksize(buf);
@ -310,6 +313,7 @@ static ssize_t diag_dbgfs_read_table(struct file *file, char __user *ubuf,
break;
}
diag_dbgfs_table_index = i;
mutex_unlock(&driver->cmd_reg_mutex);
*ppos = 0;
ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);

View File

@ -510,18 +510,19 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
goto inval;
field = report->field[uref->field_index];
if (cmd == HIDIOCGCOLLECTIONINDEX) {
if (uref->usage_index >= field->maxusage)
goto inval;
} else if (uref->usage_index >= field->report_count)
goto inval;
}
if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
(uref_multi->num_values > HID_MAX_MULTI_USAGES ||
uref->usage_index + uref_multi->num_values > field->report_count))
if (cmd == HIDIOCGCOLLECTIONINDEX) {
if (uref->usage_index >= field->maxusage)
goto inval;
} else if (uref->usage_index >= field->report_count)
goto inval;
else if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
(uref_multi->num_values > HID_MAX_MULTI_USAGES ||
uref->usage_index + uref_multi->num_values >
field->report_count))
goto inval;
switch (cmd) {
case HIDIOCGUSAGE:

View File

@ -663,9 +663,13 @@ static int msm_fd_s_fmt_vid_out(struct file *file,
static int msm_fd_reqbufs(struct file *file,
void *fh, struct v4l2_requestbuffers *req)
{
int ret;
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
return vb2_reqbufs(&ctx->vb2_q, req);
mutex_lock(&ctx->fd_device->recovery_lock);
ret = vb2_reqbufs(&ctx->vb2_q, req);
mutex_unlock(&ctx->fd_device->recovery_lock);
return ret;
}
/*
@ -677,9 +681,14 @@ static int msm_fd_reqbufs(struct file *file,
static int msm_fd_qbuf(struct file *file, void *fh,
struct v4l2_buffer *pb)
{
int ret;
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
return vb2_qbuf(&ctx->vb2_q, pb);
mutex_lock(&ctx->fd_device->recovery_lock);
ret = vb2_qbuf(&ctx->vb2_q, pb);
mutex_unlock(&ctx->fd_device->recovery_lock);
return ret;
}
/*
@ -691,9 +700,13 @@ static int msm_fd_qbuf(struct file *file, void *fh,
static int msm_fd_dqbuf(struct file *file,
void *fh, struct v4l2_buffer *pb)
{
int ret;
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
return vb2_dqbuf(&ctx->vb2_q, pb, file->f_flags & O_NONBLOCK);
mutex_lock(&ctx->fd_device->recovery_lock);
ret = vb2_dqbuf(&ctx->vb2_q, pb, file->f_flags & O_NONBLOCK);
mutex_unlock(&ctx->fd_device->recovery_lock);
return ret;
}
/*
@ -1198,6 +1211,7 @@ static int fd_probe(struct platform_device *pdev)
mutex_init(&fd->lock);
spin_lock_init(&fd->slock);
mutex_init(&fd->recovery_lock);
init_completion(&fd->hw_halt_completion);
INIT_LIST_HEAD(&fd->buf_queue);
fd->dev = &pdev->dev;

View File

@ -213,6 +213,7 @@ struct msm_fd_device {
struct mutex lock;
spinlock_t slock;
struct mutex recovery_lock;
int ref_count;
int irq_num;

View File

@ -795,6 +795,12 @@ int msm_isp_cfg_stats_stream(struct vfe_device *vfe_dev, void *arg)
if (vfe_dev->stats_data.num_active_stream == 0)
vfe_dev->hw_info->vfe_ops.stats_ops.cfg_ub(vfe_dev);
if (stream_cfg_cmd->num_streams > MSM_ISP_STATS_MAX) {
pr_err("%s invalid num_streams %d\n", __func__,
stream_cfg_cmd->num_streams);
return -EINVAL;
}
if (stream_cfg_cmd->enable) {
msm_isp_stats_update_cgc_override(vfe_dev, stream_cfg_cmd);

View File

@ -1247,7 +1247,8 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
(UINT_MAX - reg_cfg_cmd->u.rw_info.len)) ||
((reg_cfg_cmd->u.rw_info.reg_offset +
reg_cfg_cmd->u.rw_info.len) >
resource_size(vfe_dev->vfe_mem))) {
resource_size(vfe_dev->vfe_mem)) ||
(reg_cfg_cmd->u.rw_info.reg_offset & 0x3)) {
pr_err("%s:%d reg_offset %d len %d res %d\n",
__func__, __LINE__,
reg_cfg_cmd->u.rw_info.reg_offset,
@ -1348,7 +1349,8 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
reg_cfg_cmd->u.mask_info.reg_offset) ||
(resource_size(vfe_dev->vfe_mem) <
reg_cfg_cmd->u.mask_info.reg_offset +
sizeof(temp))) {
sizeof(temp)) ||
(reg_cfg_cmd->u.mask_info.reg_offset & 0x3)) {
pr_err("%s: VFE_CFG_MASK: Invalid length\n", __func__);
return -EINVAL;
}

View File

@ -425,7 +425,7 @@ static int msm_ispif_reset(struct ispif_device *ispif)
ispif->base + ISPIF_VFE_m_INTF_CMD_0(i));
msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY,
ispif->base + ISPIF_VFE_m_INTF_CMD_1(i));
pr_debug("%s: base %lx", __func__, (unsigned long)ispif->base);
pr_debug("%s: base %pK", __func__, ispif->base);
msm_camera_io_w(0, ispif->base +
ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 0));
msm_camera_io_w(0, ispif->base +

View File

@ -422,17 +422,11 @@ static int32_t msm_sensor_create_pd_settings(void *setting,
#ifdef CONFIG_COMPAT
if (is_compat_task()) {
int i = 0;
struct msm_sensor_power_setting32 *power_setting_iter =
(struct msm_sensor_power_setting32 *)compat_ptr((
(struct msm_camera_sensor_slave_info32 *)setting)->
power_setting_array.power_setting);
for (i = 0; i < size_down; i++) {
pd[i].config_val = power_setting_iter[i].config_val;
pd[i].delay = power_setting_iter[i].delay;
pd[i].seq_type = power_setting_iter[i].seq_type;
pd[i].seq_val = power_setting_iter[i].seq_val;
rc = msm_sensor_get_pw_settings_compat(
pd, pu, size_down);
if (rc < 0) {
pr_err("failed");
return -EFAULT;
}
} else
#endif

View File

@ -792,7 +792,6 @@ static int __init msm_vidc_init(void)
if (rc) {
dprintk(VIDC_ERR,
"Failed to register platform driver\n");
msm_vidc_debugfs_deinit_drv();
debugfs_remove_recursive(vidc_driver->debugfs_root);
kfree(vidc_driver);
vidc_driver = NULL;
@ -804,7 +803,6 @@ static int __init msm_vidc_init(void)
static void __exit msm_vidc_exit(void)
{
platform_driver_unregister(&msm_vidc_driver);
msm_vidc_debugfs_deinit_drv();
debugfs_remove_recursive(vidc_driver->debugfs_root);
kfree(vidc_driver);
vidc_driver = NULL;

View File

@ -1434,7 +1434,6 @@ static void cleanup_instance(struct msm_vidc_inst *inst)
msm_comm_smem_free(inst, inst->extradata_handle);
debugfs_remove_recursive(inst->debugfs_root);
mutex_lock(&inst->pending_getpropq.lock);
WARN_ON(!list_empty(&inst->pending_getpropq.list)
&& (msm_vidc_debug & VIDC_INFO));

View File

@ -12,6 +12,7 @@
*/
#define CREATE_TRACE_POINTS
#define MAX_SSR_STRING_LEN 10
#include "msm_vidc_debug.h"
#include "vidc_hfi_api.h"
@ -31,44 +32,31 @@ int msm_vidc_sys_idle_indicator = 0x0;
u32 msm_vidc_firmware_unload_delay = 15000;
int msm_vidc_thermal_mitigation_disabled = 0x0;
struct debug_buffer {
struct mutex lock;
char ptr[MAX_DBG_BUF_SIZE];
char *curr;
u32 filled_size;
};
static struct debug_buffer dbg_buf;
#define INIT_DBG_BUF(__buf) ({ \
__buf.curr = __buf.ptr;\
__buf.filled_size = 0; \
})
#define DYNAMIC_BUF_OWNER(__binfo) ({ \
atomic_read(&__binfo->ref_count) == 2 ? "video driver" : "firmware";\
})
struct core_inst_pair {
struct msm_vidc_core *core;
struct msm_vidc_inst *inst;
};
static int core_info_open(struct inode *inode, struct file *file)
{
file->private_data = inode->i_private;
return 0;
}
static u32 write_str(struct debug_buffer *buffer, const char *fmt, ...)
static u32 write_str(char *buffer,
size_t size, const char *fmt, ...)
{
va_list args;
u32 size;
char *curr = buffer->curr;
char *end = buffer->ptr + MAX_DBG_BUF_SIZE;
u32 len;
va_start(args, fmt);
size = vscnprintf(curr, end - curr, fmt, args);
len = vscnprintf(buffer, size, fmt, args);
va_end(args);
buffer->curr += size;
buffer->filled_size += size;
return size;
return len;
}
static ssize_t core_info_read(struct file *file, char __user *buf,
@ -77,6 +65,7 @@ static ssize_t core_info_read(struct file *file, char __user *buf,
struct msm_vidc_core *core = file->private_data;
struct hfi_device *hdev;
struct hal_fw_info fw_info;
char *dbuf, *cur, *end;
int i = 0, rc = 0;
ssize_t len = 0;
@ -84,36 +73,46 @@ static ssize_t core_info_read(struct file *file, char __user *buf,
dprintk(VIDC_ERR, "Invalid params, core: %pK\n", core);
return 0;
}
dbuf = kzalloc(MAX_DBG_BUF_SIZE, GFP_KERNEL);
if (!dbuf) {
dprintk(VIDC_ERR, "%s: Allocation failed!\n", __func__);
return -ENOMEM;
}
cur = dbuf;
end = cur + MAX_DBG_BUF_SIZE;
hdev = core->device;
mutex_lock(&dbg_buf.lock);
INIT_DBG_BUF(dbg_buf);
write_str(&dbg_buf, "===============================\n");
write_str(&dbg_buf, "CORE %d: 0x%pK\n", core->id, core);
write_str(&dbg_buf, "===============================\n");
write_str(&dbg_buf, "Core state: %d\n", core->state);
cur += write_str(cur, end - cur, "===============================\n");
cur += write_str(cur, end - cur, "CORE %d: %pK\n", core->id, core);
cur += write_str(cur, end - cur, "===============================\n");
cur += write_str(cur, end - cur, "Core state: %d\n", core->state);
rc = call_hfi_op(hdev, get_fw_info, hdev->hfi_device_data, &fw_info);
if (rc) {
dprintk(VIDC_WARN, "Failed to read FW info\n");
goto err_fw_info;
}
write_str(&dbg_buf, "FW version : %s\n", &fw_info.version);
write_str(&dbg_buf, "base addr: 0x%x\n", fw_info.base_addr);
write_str(&dbg_buf, "register_base: 0x%x\n", fw_info.register_base);
write_str(&dbg_buf, "register_size: %u\n", fw_info.register_size);
write_str(&dbg_buf, "irq: %u\n", fw_info.irq);
cur += write_str(cur, end - cur,
"FW version : %s\n", &fw_info.version);
cur += write_str(cur, end - cur,
"base addr: 0x%x\n", fw_info.base_addr);
cur += write_str(cur, end - cur,
"register_base: 0x%x\n", fw_info.register_base);
cur += write_str(cur, end - cur,
"register_size: %u\n", fw_info.register_size);
cur += write_str(cur, end - cur, "irq: %u\n", fw_info.irq);
err_fw_info:
for (i = SYS_MSG_START; i < SYS_MSG_END; i++) {
write_str(&dbg_buf, "completions[%d]: %s\n", i,
cur += write_str(cur, end - cur, "completions[%d]: %s\n", i,
completion_done(&core->completions[SYS_MSG_INDEX(i)]) ?
"pending" : "done");
}
len = simple_read_from_buffer(buf, count, ppos,
dbg_buf.ptr, dbg_buf.filled_size);
dbuf, cur - dbuf);
mutex_unlock(&dbg_buf.lock);
kfree(dbuf);
return len;
}
@ -130,17 +129,33 @@ static int trigger_ssr_open(struct inode *inode, struct file *file)
static ssize_t trigger_ssr_write(struct file *filp, const char __user *buf,
size_t count, loff_t *ppos) {
u32 ssr_trigger_val;
int rc;
unsigned long ssr_trigger_val = 0;
int rc = 0;
struct msm_vidc_core *core = filp->private_data;
rc = sscanf(buf, "%d", &ssr_trigger_val);
if (rc < 0) {
size_t size = MAX_SSR_STRING_LEN;
char kbuf[MAX_SSR_STRING_LEN + 1] = {0};
if (!count)
goto exit;
if (count < size)
size = count;
if (copy_from_user(kbuf, buf, size)) {
dprintk(VIDC_WARN, "%s User memory fault\n", __func__);
rc = -EFAULT;
goto exit;
}
rc = kstrtoul(kbuf, 0, &ssr_trigger_val);
if (rc) {
dprintk(VIDC_WARN, "returning error err %d\n", rc);
rc = -EINVAL;
} else {
msm_vidc_trigger_ssr(core, ssr_trigger_val);
rc = count;
}
exit:
return rc;
}
@ -153,7 +168,6 @@ struct dentry *msm_vidc_debugfs_init_drv(void)
{
struct dentry *dir = NULL;
mutex_init(&dbg_buf.lock);
dir = debugfs_create_dir("msm_vidc", NULL);
if (IS_ERR_OR_NULL(dir)) {
dir = NULL;
@ -276,12 +290,15 @@ failed_create_dir:
static int inst_info_open(struct inode *inode, struct file *file)
{
dprintk(VIDC_INFO, "Open inode ptr: %pK\n", inode->i_private);
file->private_data = inode->i_private;
return 0;
}
static int publish_unreleased_reference(struct msm_vidc_inst *inst)
static int publish_unreleased_reference(struct msm_vidc_inst *inst,
char **dbuf, char *end)
{
char *cur = *dbuf;
struct buffer_info *temp = NULL;
if (!inst) {
@ -290,127 +307,220 @@ static int publish_unreleased_reference(struct msm_vidc_inst *inst)
}
if (inst->buffer_mode_set[CAPTURE_PORT] == HAL_BUFFER_MODE_DYNAMIC) {
write_str(&dbg_buf, "Pending buffer references:\n");
cur += write_str(cur, end - cur, "Pending buffer references\n");
mutex_lock(&inst->registeredbufs.lock);
list_for_each_entry(temp, &inst->registeredbufs.list, list) {
if (temp->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
!temp->inactive && atomic_read(&temp->ref_count)) {
write_str(&dbg_buf,
"\tpending buffer: 0x%lx fd[0] = %d ref_count = %d held by: %s\n",
temp->device_addr[0],
temp->fd[0],
atomic_read(&temp->ref_count),
DYNAMIC_BUF_OWNER(temp));
cur += write_str(cur, end - cur,
"\tpending buffer: %#lx fd[0] = %d ref_count = %d held by: %s\n",
temp->device_addr[0],
temp->fd[0],
atomic_read(&temp->ref_count),
DYNAMIC_BUF_OWNER(temp));
}
}
mutex_unlock(&inst->registeredbufs.lock);
}
*dbuf = cur;
return 0;
}
static ssize_t inst_info_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
struct msm_vidc_inst *inst = file->private_data;
struct core_inst_pair *idata = file->private_data;
struct msm_vidc_core *core;
struct msm_vidc_inst *inst, *temp = NULL;
char *dbuf, *cur, *end;
int i, j;
ssize_t len = 0;
if (!inst) {
dprintk(VIDC_ERR, "Invalid params, core: %pK\n", inst);
if (!idata || !idata->core || !idata->inst) {
dprintk(VIDC_ERR, "%s: Invalid params\n", __func__);
return 0;
}
mutex_lock(&dbg_buf.lock);
INIT_DBG_BUF(dbg_buf);
write_str(&dbg_buf, "===============================\n");
write_str(&dbg_buf, "INSTANCE: 0x%pK (%s)\n", inst,
core = idata->core;
inst = idata->inst;
mutex_lock(&core->lock);
list_for_each_entry(temp, &core->instances, list) {
if (temp == inst)
break;
}
inst = (temp == inst)?
inst : NULL;
mutex_unlock(&core->lock);
if (!inst) {
dprintk(VIDC_ERR, "%s: Instance has become obsolete", __func__);
return 0;
}
dbuf = kzalloc(MAX_DBG_BUF_SIZE, GFP_KERNEL);
if (!dbuf) {
dprintk(VIDC_ERR, "%s: Allocation failed!\n", __func__);
len = -ENOMEM;
goto failed_alloc;
}
cur = dbuf;
end = cur + MAX_DBG_BUF_SIZE;
cur += write_str(cur, end - cur, "==============================\n");
cur += write_str(cur, end - cur, "INSTANCE: %pK (%s)\n", inst,
inst->session_type == MSM_VIDC_ENCODER ? "Encoder" : "Decoder");
write_str(&dbg_buf, "===============================\n");
write_str(&dbg_buf, "core: 0x%pK\n", inst->core);
write_str(&dbg_buf, "height: %d\n", inst->prop.height[CAPTURE_PORT]);
write_str(&dbg_buf, "width: %d\n", inst->prop.width[CAPTURE_PORT]);
write_str(&dbg_buf, "fps: %d\n", inst->prop.fps);
write_str(&dbg_buf, "state: %d\n", inst->state);
write_str(&dbg_buf, "secure: %d\n", !!(inst->flags & VIDC_SECURE));
write_str(&dbg_buf, "-----------Formats-------------\n");
cur += write_str(cur, end - cur, "==============================\n");
cur += write_str(cur, end - cur, "core: %pK\n", inst->core);
cur += write_str(cur, end - cur, "height: %d\n",
inst->prop.height[CAPTURE_PORT]);
cur += write_str(cur, end - cur, "width: %d\n",
inst->prop.width[CAPTURE_PORT]);
cur += write_str(cur, end - cur, "fps: %d\n", inst->prop.fps);
cur += write_str(cur, end - cur, "state: %d\n", inst->state);
cur += write_str(cur, end - cur, "secure: %d\n",
!!(inst->flags & VIDC_SECURE));
cur += write_str(cur, end - cur, "-----------Formats-------------\n");
for (i = 0; i < MAX_PORT_NUM; i++) {
write_str(&dbg_buf, "capability: %s\n", i == OUTPUT_PORT ?
cur += write_str(cur, end - cur, "capability: %s\n",
i == OUTPUT_PORT ? "Output" : "Capture");
cur += write_str(cur, end - cur, "name : %s\n",
inst->fmts[i]->name);
cur += write_str(cur, end - cur, "planes : %d\n",
inst->fmts[i]->num_planes);
cur += write_str(cur, end - cur,
"type: %s\n", inst->fmts[i]->type == OUTPUT_PORT ?
"Output" : "Capture");
write_str(&dbg_buf, "name : %s\n", inst->fmts[i]->name);
write_str(&dbg_buf, "planes : %d\n", inst->fmts[i]->num_planes);
write_str(
&dbg_buf, "type: %s\n", inst->fmts[i]->type == OUTPUT_PORT ?
"Output" : "Capture");
switch (inst->buffer_mode_set[i]) {
case HAL_BUFFER_MODE_STATIC:
write_str(&dbg_buf, "buffer mode : %s\n", "static");
cur += write_str(cur, end - cur,
"buffer mode : %s\n", "static");
break;
case HAL_BUFFER_MODE_RING:
write_str(&dbg_buf, "buffer mode : %s\n", "ring");
cur += write_str(cur, end - cur,
"buffer mode : %s\n", "ring");
break;
case HAL_BUFFER_MODE_DYNAMIC:
write_str(&dbg_buf, "buffer mode : %s\n", "dynamic");
cur += write_str(cur, end - cur,
"buffer mode : %s\n", "dynamic");
break;
default:
write_str(&dbg_buf, "buffer mode : unsupported\n");
cur += write_str(cur, end - cur,
"buffer mode : unsupported\n");
}
write_str(&dbg_buf, "count: %u\n",
cur += write_str(cur, end - cur, "count: %u\n",
inst->bufq[i].vb2_bufq.num_buffers);
for (j = 0; j < inst->fmts[i]->num_planes; j++)
write_str(&dbg_buf, "size for plane %d: %u\n", j,
cur += write_str(cur, end - cur,
"size for plane %d: %u\n", j,
inst->bufq[i].vb2_bufq.plane_sizes[j]);
if (i < MAX_PORT_NUM - 1)
write_str(&dbg_buf, "\n");
cur += write_str(cur, end - cur, "\n");
}
write_str(&dbg_buf, "-------------------------------\n");
cur += write_str(cur, end - cur, "-------------------------------\n");
for (i = SESSION_MSG_START; i < SESSION_MSG_END; i++) {
write_str(&dbg_buf, "completions[%d]: %s\n", i,
cur += write_str(cur, end - cur, "completions[%d]: %s\n", i,
completion_done(&inst->completions[SESSION_MSG_INDEX(i)]) ?
"pending" : "done");
}
write_str(&dbg_buf, "ETB Count: %d\n", inst->count.etb);
write_str(&dbg_buf, "EBD Count: %d\n", inst->count.ebd);
write_str(&dbg_buf, "FTB Count: %d\n", inst->count.ftb);
write_str(&dbg_buf, "FBD Count: %d\n", inst->count.fbd);
publish_unreleased_reference(inst);
cur += write_str(cur, end - cur, "ETB Count: %d\n", inst->count.etb);
cur += write_str(cur, end - cur, "EBD Count: %d\n", inst->count.ebd);
cur += write_str(cur, end - cur, "FTB Count: %d\n", inst->count.ftb);
cur += write_str(cur, end - cur, "FBD Count: %d\n", inst->count.fbd);
publish_unreleased_reference(inst, &cur, end);
len = simple_read_from_buffer(buf, count, ppos,
dbg_buf.ptr, dbg_buf.filled_size);
mutex_unlock(&dbg_buf.lock);
dbuf, cur - dbuf);
kfree(dbuf);
failed_alloc:
return len;
}
static int inst_info_release(struct inode *inode, struct file *file)
{
dprintk(VIDC_INFO, "Release inode ptr: %pK\n", inode->i_private);
file->private_data = NULL;
return 0;
}
static const struct file_operations inst_info_fops = {
.open = inst_info_open,
.read = inst_info_read,
.release = inst_info_release,
};
struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst,
struct dentry *parent)
{
struct dentry *dir = NULL;
struct dentry *dir = NULL, *info = NULL;
char debugfs_name[MAX_DEBUGFS_NAME];
struct core_inst_pair *idata = NULL;
if (!inst) {
dprintk(VIDC_ERR, "Invalid params, inst: %pK\n", inst);
goto failed_create_dir;
goto exit;
}
snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%pK", inst);
idata = kzalloc(sizeof(struct core_inst_pair), GFP_KERNEL);
if (!idata) {
dprintk(VIDC_ERR, "%s: Allocation failed!\n", __func__);
goto exit;
}
idata->core = inst->core;
idata->inst = inst;
dir = debugfs_create_dir(debugfs_name, parent);
if (!dir) {
dprintk(VIDC_ERR, "Failed to create debugfs for msm_vidc\n");
goto failed_create_dir;
}
if (!debugfs_create_file("info", S_IRUGO, dir, inst, &inst_info_fops)) {
info = debugfs_create_file("info", S_IRUGO, dir,
idata, &inst_info_fops);
if (!info) {
dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
goto failed_create_dir;
goto failed_create_file;
}
dir->d_inode->i_private = info->d_inode->i_private;
inst->debug.pdata[FRAME_PROCESSING].sampling = true;
failed_create_dir:
return dir;
failed_create_file:
debugfs_remove_recursive(dir);
dir = NULL;
failed_create_dir:
kfree(idata);
exit:
return dir;
}
void msm_vidc_debugfs_deinit_inst(struct msm_vidc_inst *inst)
{
struct dentry *dentry = NULL;
if (!inst || !inst->debugfs_root)
return;
dentry = inst->debugfs_root;
if (dentry->d_inode) {
dprintk(VIDC_INFO, "Destroy %pK\n", dentry->d_inode->i_private);
kfree(dentry->d_inode->i_private);
dentry->d_inode->i_private = NULL;
}
debugfs_remove_recursive(dentry);
inst->debugfs_root = NULL;
}
void msm_vidc_debugfs_update(struct msm_vidc_inst *inst,
@ -462,8 +572,3 @@ void msm_vidc_debugfs_update(struct msm_vidc_inst *inst,
}
}
void msm_vidc_debugfs_deinit_drv(void)
{
mutex_destroy(&dbg_buf.lock);
}

View File

@ -123,9 +123,9 @@ struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core,
struct dentry *parent);
struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst,
struct dentry *parent);
void msm_vidc_debugfs_deinit_inst(struct msm_vidc_inst *inst);
void msm_vidc_debugfs_update(struct msm_vidc_inst *inst,
enum msm_vidc_debugfs_event e);
void msm_vidc_debugfs_deinit_drv(void);
static inline void tic(struct msm_vidc_inst *i, enum profiling_points p,
char *b)

View File

@ -27,11 +27,14 @@
#include <linux/msm_audio_ion.h>
#include <linux/compat.h>
#include <sound/q6core.h>
#include <linux/mutex.h>
#include "audio_utils_aio.h"
#ifdef CONFIG_USE_DEV_CTRL_VOLUME
#include <linux/qdsp6v2/audio_dev_ctl.h>
#endif /*CONFIG_USE_DEV_CTRL_VOLUME*/
DEFINE_MUTEX(lock);
#ifdef CONFIG_DEBUG_FS
int audio_aio_debug_open(struct inode *inode, struct file *file)
{
file->private_data = inode->i_private;
@ -44,29 +47,37 @@ ssize_t audio_aio_debug_read(struct file *file, char __user *buf,
const int debug_bufmax = 4096;
static char buffer[4096];
int n = 0;
struct q6audio_aio *audio = file->private_data;
struct q6audio_aio *audio;
mutex_lock(&audio->lock);
n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened);
n += scnprintf(buffer + n, debug_bufmax - n,
"enabled %d\n", audio->enabled);
n += scnprintf(buffer + n, debug_bufmax - n,
"stopped %d\n", audio->stopped);
n += scnprintf(buffer + n, debug_bufmax - n,
"feedback %d\n", audio->feedback);
mutex_unlock(&audio->lock);
/* Following variables are only useful for debugging when
* when playback halts unexpectedly. Thus, no mutual exclusion
* enforced
*/
n += scnprintf(buffer + n, debug_bufmax - n,
"wflush %d\n", audio->wflush);
n += scnprintf(buffer + n, debug_bufmax - n,
"rflush %d\n", audio->rflush);
n += scnprintf(buffer + n, debug_bufmax - n,
"inqueue empty %d\n", list_empty(&audio->in_queue));
n += scnprintf(buffer + n, debug_bufmax - n,
"outqueue empty %d\n", list_empty(&audio->out_queue));
mutex_lock(&lock);
if (file->private_data != NULL) {
audio = file->private_data;
mutex_lock(&audio->lock);
n = scnprintf(buffer, debug_bufmax, "opened %d\n",
audio->opened);
n += scnprintf(buffer + n, debug_bufmax - n,
"enabled %d\n", audio->enabled);
n += scnprintf(buffer + n, debug_bufmax - n,
"stopped %d\n", audio->stopped);
n += scnprintf(buffer + n, debug_bufmax - n,
"feedback %d\n", audio->feedback);
mutex_unlock(&audio->lock);
/* Following variables are only useful for debugging when
* when playback halts unexpectedly. Thus, no mutual exclusion
* enforced
*/
n += scnprintf(buffer + n, debug_bufmax - n,
"wflush %d\n", audio->wflush);
n += scnprintf(buffer + n, debug_bufmax - n,
"rflush %d\n", audio->rflush);
n += scnprintf(buffer + n, debug_bufmax - n,
"inqueue empty %d\n",
list_empty(&audio->in_queue));
n += scnprintf(buffer + n, debug_bufmax - n,
"outqueue empty %d\n",
list_empty(&audio->out_queue));
}
mutex_unlock(&lock);
buffer[n] = 0;
return simple_read_from_buffer(buf, count, ppos, buffer, n);
}
@ -141,7 +152,8 @@ static int audio_aio_ion_lookup_vaddr(struct q6audio_aio *audio, void *addr,
list) {
if (addr >= region_elt->vaddr &&
addr < region_elt->vaddr + region_elt->len &&
addr + len <= region_elt->vaddr + region_elt->len)
addr + len <= region_elt->vaddr + region_elt->len &&
addr + len > addr)
pr_err("\t%s[%pK]:%pK, %ld --> %pK\n",
__func__, audio,
region_elt->vaddr,
@ -573,6 +585,7 @@ int audio_aio_release(struct inode *inode, struct file *file)
{
struct q6audio_aio *audio = file->private_data;
pr_debug("%s[%pK]\n", __func__, audio);
mutex_lock(&lock);
mutex_lock(&audio->lock);
mutex_lock(&audio->read_lock);
mutex_lock(&audio->write_lock);
@ -616,6 +629,8 @@ int audio_aio_release(struct inode *inode, struct file *file)
#endif
kfree(audio->codec_cfg);
kfree(audio);
file->private_data = NULL;
mutex_unlock(&lock);
return 0;
}

View File

@ -3371,7 +3371,7 @@ static void mmc_blk_cmdq_reset_all(struct mmc_host *host, int err)
if (!ret) {
WARN_ON(!test_and_clear_bit(itag,
&ctx_info->data_active_reqs));
mmc_cmdq_post_req(host, itag, err);
mmc_cmdq_post_req(host, itag, err, false);
} else {
clear_bit(CMDQ_STATE_DCMD_ACTIVE,
&ctx_info->curr_state);
@ -3591,8 +3591,8 @@ void mmc_blk_cmdq_complete_rq(struct request *rq)
else
BUG_ON(!test_and_clear_bit(cmdq_req->tag,
&ctx_info->data_active_reqs));
if (!is_dcmd)
mmc_cmdq_post_req(host, cmdq_req->tag, err);
mmc_cmdq_post_req(host, cmdq_req->tag, err, is_dcmd);
if (cmdq_req->cmdq_req_flags & DCMD) {
clear_bit(CMDQ_STATE_DCMD_ACTIVE, &ctx_info->curr_state);
blk_end_request_all(rq, err);

View File

@ -980,10 +980,10 @@ EXPORT_SYMBOL(mmc_cmdq_discard_queue);
* @tag: the request tag.
* @err: non-zero is error, success otherwise
*/
void mmc_cmdq_post_req(struct mmc_host *host, int tag, int err)
void mmc_cmdq_post_req(struct mmc_host *host, int tag, int err, bool is_dcmd)
{
if (likely(host->cmdq_ops->post_req))
host->cmdq_ops->post_req(host, tag, err);
host->cmdq_ops->post_req(host, tag, err, is_dcmd);
}
EXPORT_SYMBOL(mmc_cmdq_post_req);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-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
@ -786,6 +786,14 @@ skip_cqterri:
mrq->cmdq_req->resp_arg = cmdq_readl(cq_host, CQCRA);
}
/*
* Incase of error we will schedule a work to do the unvoting
* of pm_qos here. This is because incase of error, softirq
* handler will not schedule unvoting of pm_qos. Incase of
* no error, the softirq will schedule work for pm_qos unvoting
* after the last request is complete (irrespective of
* whether the last request is DCMD or data request)
*/
if (cq_host->ops->pm_qos_update)
cq_host->ops->pm_qos_update(mmc, NULL, false);
@ -798,24 +806,6 @@ skip_cqterri:
if (!comp_status)
goto out;
/*
* pm-qos for cmdq is removed only when there is no cmdq
* request been processed.
* Check if comp_status matches with the number of active_reqs.
* This means that all reqs got actually completed and there
* was no DCMD.
* But in case of DCMD, active_reqs mask has a bit set for DCMD
* as well, so ensure that the when comp_status bit is set
* for DCMD then there should not be any data_active_reqs in
* flight (which can happen if DCMD is not set with QBR)
*/
if (((mmc->cmdq_ctx).active_reqs == comp_status) ||
(((1 << 31) & comp_status) &&
!((mmc->cmdq_ctx).data_active_reqs))) {
if (cq_host->ops->pm_qos_update)
cq_host->ops->pm_qos_update(mmc, NULL, false);
}
/*
* The CQTCN must be cleared before notifying req completion
* to upper layers to avoid missing completion notification
@ -921,7 +911,14 @@ static int cmdq_halt(struct mmc_host *mmc, bool halt)
return 0;
}
static void cmdq_post_req(struct mmc_host *mmc, int tag, int err)
/*
* Since this function from now on will be called for DCMD commands
* as well, it needs a new parameter as input to know if it is DCMD
* or not. This is because the tag we get for DCMD is almost always
* never the DCMD_SLOT tag.
*/
static void cmdq_post_req(struct mmc_host *mmc, int tag, int err, bool is_dcmd)
{
struct cmdq_host *cq_host;
struct mmc_request *mrq;
@ -931,6 +928,31 @@ static void cmdq_post_req(struct mmc_host *mmc, int tag, int err)
return;
cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc);
/*
* pm-qos for cmdq is removed only when there is no cmdq
* request been processed. Since this call occurs in softirq context
* ireespective of whether the request is a DCMD command or data
* request, we can use the active_reqs counter to decide whether
* any more requests are being actively processed by command queue
* thread.
*
* In case of error in cq request, the qos unvoting is done by the
* CQ hard irq handler. So no need to do unvoting here.
*
* There is a very rare corner case when the active req counter is
* checked by completion context and before it schedules the work to
* unvote, the issuing context can set active req counter and do
* qos voting. In this case the performance suffers but this is a
* very rare corner case as the completion context is in softirq.
*/
if (!err && !mmc->cmdq_ctx.active_reqs && cq_host->ops->pm_qos_update)
cq_host->ops->pm_qos_update(mmc, NULL, false);
if (is_dcmd)
return;
mrq = get_req_by_tag(cq_host, tag);
data = mrq->data;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2014, 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
@ -514,8 +514,13 @@ static int rmnet_ctl_open(struct inode *inode, struct file *file)
if (!dev)
return -ENODEV;
if (test_bit(RMNET_CTRL_DEV_OPEN, &dev->status))
mutex_lock(&dev->dev_lock);
if (test_bit(RMNET_CTRL_DEV_OPEN, &dev->status)) {
mutex_unlock(&dev->dev_lock);
goto already_opened;
}
set_bit(RMNET_CTRL_DEV_OPEN, &dev->status);
mutex_unlock(&dev->dev_lock);
if (dev->mdm_wait_timeout &&
!test_bit(RMNET_CTRL_DEV_READY, &dev->cudev->status)) {
@ -527,10 +532,15 @@ static int rmnet_ctl_open(struct inode *inode, struct file *file)
if (retval == 0) {
dev_err(dev->devicep, "%s: Timeout opening %s\n",
__func__, dev->name);
return -ETIMEDOUT;
} else if (retval < 0) {
retval = -ETIMEDOUT;
} else if (retval < 0)
dev_err(dev->devicep, "%s: Error waiting for %s\n",
__func__, dev->name);
if (retval < 0) {
mutex_lock(&dev->dev_lock);
clear_bit(RMNET_CTRL_DEV_OPEN, &dev->status);
mutex_unlock(&dev->dev_lock);
return retval;
}
}
@ -538,14 +548,15 @@ static int rmnet_ctl_open(struct inode *inode, struct file *file)
if (!test_bit(RMNET_CTRL_DEV_READY, &dev->cudev->status)) {
dev_dbg(dev->devicep, "%s: Connection timedout opening %s\n",
__func__, dev->name);
mutex_lock(&dev->dev_lock);
clear_bit(RMNET_CTRL_DEV_OPEN, &dev->status);
mutex_unlock(&dev->dev_lock);
return -ETIMEDOUT;
}
/* clear stale data if device close called but channel was ready */
rmnet_usb_ctrl_free_rx_list(dev);
set_bit(RMNET_CTRL_DEV_OPEN, &dev->status);
file->private_data = dev;
already_opened:
@ -564,7 +575,9 @@ static int rmnet_ctl_release(struct inode *inode, struct file *file)
DBG("%s Called on %s device\n", __func__, dev->name);
mutex_lock(&dev->dev_lock);
clear_bit(RMNET_CTRL_DEV_OPEN, &dev->status);
mutex_unlock(&dev->dev_lock);
file->private_data = NULL;
@ -638,6 +651,7 @@ ctrl_read:
list_elem = list_first_entry(&dev->rx_list,
struct ctrl_pkt_list_elem, list);
list_del(&list_elem->list);
bytes_to_read = (uint32_t)(list_elem->cpkt.data_size);
if (bytes_to_read > count) {
spin_unlock_irqrestore(&dev->rx_lock, flags);
@ -654,11 +668,11 @@ ctrl_read:
dev_err(dev->devicep,
"%s: copy_to_user failed for %s\n",
__func__, dev->name);
spin_lock_irqsave(&dev->rx_lock, flags);
list_add(&list_elem->list, &dev->rx_list);
spin_unlock_irqrestore(&dev->rx_lock, flags);
return -EFAULT;
}
spin_lock_irqsave(&dev->rx_lock, flags);
list_del(&list_elem->list);
spin_unlock_irqrestore(&dev->rx_lock, flags);
kfree(list_elem->cpkt.data);
kfree(list_elem);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-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
@ -1698,8 +1698,15 @@ static void msm_pcie_sel_debug_testcase(struct msm_pcie_dev_t *dev,
dev->res[base_sel - 1].base,
wr_offset, wr_mask, wr_value);
msm_pcie_write_reg_field(dev->res[base_sel - 1].base,
wr_offset, wr_mask, wr_value);
base_sel_size = resource_size(dev->res[base_sel - 1].resource);
if (wr_offset > base_sel_size - 4 ||
msm_pcie_check_align(dev, wr_offset))
pr_alert("PCIe: RC%d: Invalid wr_offset: 0x%x. wr_offset should be no more than 0x%x\n",
dev->rc_idx, wr_offset, base_sel_size - 4);
else
msm_pcie_write_reg_field(dev->res[base_sel - 1].base,
wr_offset, wr_mask, wr_value);
break;
case 13: /* dump all registers of base_sel */

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-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
@ -62,6 +62,7 @@ static char *debugfs_buf;
static u32 debugfs_buf_size;
static u32 debugfs_buf_used;
static int wraparound;
static struct mutex sps_debugfs_lock;
struct dentry *dent;
struct dentry *dfile_info;
@ -79,6 +80,7 @@ static struct sps_bam *phy2bam(phys_addr_t phys_addr);
/* record debug info for debugfs */
void sps_debugfs_record(const char *msg)
{
mutex_lock(&sps_debugfs_lock);
if (debugfs_record_enabled) {
if (debugfs_buf_used + MAX_MSG_LEN >= debugfs_buf_size) {
debugfs_buf_used = 0;
@ -92,6 +94,7 @@ void sps_debugfs_record(const char *msg)
debugfs_buf_size - debugfs_buf_used,
"\n**** end line of sps log ****\n\n");
}
mutex_unlock(&sps_debugfs_lock);
}
/* read the recorded debug info to userspace */
@ -101,6 +104,7 @@ static ssize_t sps_read_info(struct file *file, char __user *ubuf,
int ret = 0;
int size;
mutex_lock(&sps_debugfs_lock);
if (debugfs_record_enabled) {
if (wraparound)
size = debugfs_buf_size - MAX_MSG_LEN;
@ -110,6 +114,7 @@ static ssize_t sps_read_info(struct file *file, char __user *ubuf,
ret = simple_read_from_buffer(ubuf, count, ppos,
debugfs_buf, size);
}
mutex_unlock(&sps_debugfs_lock);
return ret;
}
@ -155,11 +160,13 @@ static ssize_t sps_set_info(struct file *file, const char __user *buf,
new_buf_size = buf_size_kb * SZ_1K;
mutex_lock(&sps_debugfs_lock);
if (debugfs_record_enabled) {
if (debugfs_buf_size == new_buf_size) {
/* need do nothing */
pr_info("sps:debugfs: input buffer size "
"is the same as before.\n");
mutex_unlock(&sps_debugfs_lock);
return count;
} else {
/* release the current buffer */
@ -179,12 +186,14 @@ static ssize_t sps_set_info(struct file *file, const char __user *buf,
if (!debugfs_buf) {
debugfs_buf_size = 0;
pr_err("sps:fail to allocate memory for debug_fs.\n");
mutex_unlock(&sps_debugfs_lock);
return -ENOMEM;
}
debugfs_buf_used = 0;
wraparound = false;
debugfs_record_enabled = true;
mutex_unlock(&sps_debugfs_lock);
return count;
}
@ -233,6 +242,7 @@ static ssize_t sps_set_logging_option(struct file *file, const char __user *buf,
return count;
}
mutex_lock(&sps_debugfs_lock);
if (((option == 0) || (option == 2)) &&
((logging_option == 1) || (logging_option == 3))) {
debugfs_record_enabled = false;
@ -244,6 +254,7 @@ static ssize_t sps_set_logging_option(struct file *file, const char __user *buf,
}
logging_option = option;
mutex_unlock(&sps_debugfs_lock);
return count;
}
@ -571,6 +582,8 @@ static void sps_debugfs_init(void)
goto bam_addr_err;
}
mutex_init(&sps_debugfs_lock);
return;
bam_addr_err:

View File

@ -143,11 +143,6 @@ extern u8 print_limit_option;
pr_info(msg, ##args); \
} \
} while (0)
#define SPS_DEBUGFS(msg, args...) do { \
char buf[MAX_MSG_LEN]; \
snprintf(buf, MAX_MSG_LEN, msg"\n", ##args); \
sps_debugfs_record(buf); \
} while (0)
#define SPS_ERR(dev, msg, args...) do { \
if (logging_option != 1) { \
if (unlikely(print_limit_option > 2)) \
@ -155,8 +150,6 @@ extern u8 print_limit_option;
else \
pr_err(msg, ##args); \
} \
if (unlikely(debugfs_record_enabled)) \
SPS_DEBUGFS(msg, ##args); \
SPS_IPC(3, dev, msg, args); \
} while (0)
#define SPS_INFO(dev, msg, args...) do { \
@ -166,8 +159,6 @@ extern u8 print_limit_option;
else \
pr_info(msg, ##args); \
} \
if (unlikely(debugfs_record_enabled)) \
SPS_DEBUGFS(msg, ##args); \
SPS_IPC(3, dev, msg, args); \
} while (0)
#define SPS_DBG(dev, msg, args...) do { \
@ -179,8 +170,6 @@ extern u8 print_limit_option;
pr_info(msg, ##args); \
} else \
pr_debug(msg, ##args); \
if (unlikely(debugfs_record_enabled)) \
SPS_DEBUGFS(msg, ##args); \
if (dev) { \
if ((dev)->ipc_loglevel <= 0) \
SPS_IPC(0, dev, msg, args); \
@ -195,8 +184,6 @@ extern u8 print_limit_option;
pr_info(msg, ##args); \
} else \
pr_debug(msg, ##args); \
if (unlikely(debugfs_record_enabled)) \
SPS_DEBUGFS(msg, ##args); \
if (dev) { \
if ((dev)->ipc_loglevel <= 1) \
SPS_IPC(1, dev, msg, args); \
@ -211,8 +198,6 @@ extern u8 print_limit_option;
pr_info(msg, ##args); \
} else \
pr_debug(msg, ##args); \
if (unlikely(debugfs_record_enabled)) \
SPS_DEBUGFS(msg, ##args); \
if (dev) { \
if ((dev)->ipc_loglevel <= 2) \
SPS_IPC(2, dev, msg, args); \
@ -227,8 +212,6 @@ extern u8 print_limit_option;
pr_info(msg, ##args); \
} else \
pr_debug(msg, ##args); \
if (unlikely(debugfs_record_enabled)) \
SPS_DEBUGFS(msg, ##args); \
if (dev) { \
if ((dev)->ipc_loglevel <= 3) \
SPS_IPC(3, dev, msg, args); \

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2014, 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
@ -47,9 +47,9 @@ static ssize_t rsc_ops_write(struct file *fp, const char __user *user_buffer,
{
char buf[MAX_MSG_BUFFER], rsc_type_str[6] = {}, rpm_set[8] = {},
key_str[6] = {};
int i, pos, set = -1, nelems;
int i, pos = -1, set = -1, nelems = -1;
char *cmp;
uint32_t rsc_type, rsc_id, key, data;
uint32_t rsc_type = 0, rsc_id = 0, key = 0, data = 0;
struct msm_rpm_request *req;
rpm_send_msg_usage_count++;
@ -64,8 +64,12 @@ static ssize_t rsc_ops_write(struct file *fp, const char __user *user_buffer,
buf[count] = '\0';
cmp = strstrip(buf);
sscanf(cmp, "%7s %5s %u %d %n", rpm_set, rsc_type_str, &rsc_id,
&nelems, &pos);
if (sscanf(cmp, "%7s %5s %u %d %n", rpm_set, rsc_type_str,
&rsc_id, &nelems, &pos) != 4) {
pr_err("Invalid number of arguments passed\n");
goto err;
}
if (strlen(rpm_set) > 6 || strlen(rsc_type_str) > 4) {
pr_err("Invalid value of set or resource type\n");
goto err;
@ -93,7 +97,11 @@ static ssize_t rsc_ops_write(struct file *fp, const char __user *user_buffer,
for (i = 0; i < nelems; i++) {
cmp += pos;
sscanf(cmp, "%5s %n", key_str, &pos);
if (sscanf(cmp, "%5s %n", key_str, &pos) != 1) {
pr_err("Invalid number of arguments passed\n");
goto err;
}
if (strlen(key_str) > 4) {
pr_err("Key value cannot be more than 4 charecters");
goto err;
@ -105,7 +113,11 @@ static ssize_t rsc_ops_write(struct file *fp, const char __user *user_buffer,
}
cmp += pos;
sscanf(cmp, "%u %n", &data, &pos);
if (sscanf(cmp, "%u %n", &data, &pos) != 1) {
pr_err("Invalid number of arguments passed\n");
goto err;
}
if (msm_rpm_add_kvp_data(req, key,
(void *)&data, sizeof(data)))
goto err_request;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2015, 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
@ -50,6 +50,8 @@
#define GET_FIELD(a) ((strnstr(#a, ".", 80) + 1))
static DEFINE_MUTEX(msm_rpm_master_stats_mutex);
struct msm_rpm_master_stats {
uint32_t active_cores;
uint32_t numshutdowns;
@ -80,9 +82,11 @@ int msm_rpm_master_stats_file_close(struct inode *inode,
{
struct msm_rpm_master_stats_private_data *private = file->private_data;
mutex_lock(&msm_rpm_master_stats_mutex);
if (private->reg_base)
iounmap(private->reg_base);
kfree(file->private_data);
mutex_unlock(&msm_rpm_master_stats_mutex);
return 0;
}
@ -95,14 +99,10 @@ static int msm_rpm_master_copy_stats(
static int master_cnt;
int count, j = 0;
char *buf;
static DEFINE_MUTEX(msm_rpm_master_stats_mutex);
mutex_lock(&msm_rpm_master_stats_mutex);
/* Iterate possible number of masters */
if (master_cnt > prvdata->num_masters - 1) {
master_cnt = 0;
mutex_unlock(&msm_rpm_master_stats_mutex);
return 0;
}
@ -254,7 +254,6 @@ static int msm_rpm_master_copy_stats(
}
master_cnt++;
mutex_unlock(&msm_rpm_master_stats_mutex);
return RPM_MASTERS_BUF_LEN - count;
}
@ -263,25 +262,36 @@ static ssize_t msm_rpm_master_stats_file_read(struct file *file,
{
struct msm_rpm_master_stats_private_data *prvdata;
struct msm_rpm_master_stats_platform_data *pdata;
ssize_t ret;
mutex_lock(&msm_rpm_master_stats_mutex);
prvdata = file->private_data;
if (!prvdata)
return -EINVAL;
if (!prvdata) {
ret = -EINVAL;
goto exit;
}
pdata = prvdata->platform_data;
if (!pdata)
return -EINVAL;
if (!pdata) {
ret = -EINVAL;
goto exit;
}
if (!bufu || count == 0)
return -EINVAL;
if (!bufu || count == 0) {
ret = -EINVAL;
goto exit;
}
if ((*ppos <= pdata->phys_size)) {
prvdata->len = msm_rpm_master_copy_stats(prvdata);
*ppos = 0;
}
return simple_read_from_buffer(bufu, count, ppos,
ret = simple_read_from_buffer(bufu, count, ppos,
prvdata->buf, prvdata->len);
exit:
mutex_unlock(&msm_rpm_master_stats_mutex);
return ret;
}
static int msm_rpm_master_stats_file_open(struct inode *inode,
@ -289,15 +299,20 @@ static int msm_rpm_master_stats_file_open(struct inode *inode,
{
struct msm_rpm_master_stats_private_data *prvdata;
struct msm_rpm_master_stats_platform_data *pdata;
int ret = 0;
mutex_lock(&msm_rpm_master_stats_mutex);
pdata = inode->i_private;
file->private_data =
kzalloc(sizeof(struct msm_rpm_master_stats_private_data),
GFP_KERNEL);
if (!file->private_data)
return -ENOMEM;
if (!file->private_data) {
ret = -ENOMEM;
goto exit;
}
prvdata = file->private_data;
prvdata->reg_base = ioremap(pdata->phys_addr_base,
@ -308,14 +323,17 @@ static int msm_rpm_master_stats_file_open(struct inode *inode,
pr_err("%s: ERROR could not ioremap start=%pa, len=%u\n",
__func__, &pdata->phys_addr_base,
pdata->phys_size);
return -EBUSY;
ret = -EBUSY;
goto exit;
}
prvdata->len = 0;
prvdata->num_masters = pdata->num_masters;
prvdata->master_names = pdata->masters;
prvdata->platform_data = pdata;
return 0;
exit:
mutex_unlock(&msm_rpm_master_stats_mutex);
return ret;
}
static const struct file_operations msm_rpm_master_stats_fops = {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2015, 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
@ -31,6 +31,8 @@
#define GET_PDATA_OF_ATTR(attr) \
(container_of(attr, struct msm_rpmstats_kobj_attr, ka)->pd)
static DEFINE_MUTEX(rpm_stats_mutex);
enum {
ID_COUNTER,
ID_ACCUM_TIME_SCLK,
@ -218,6 +220,12 @@ static int msm_rpmstats_copy_stats(struct msm_rpmstats_private_data *pdata)
record.id = msm_rpmstats_read_register(pdata->reg_base,
pdata->read_idx, 1);
if (record.id >= ID_MAX) {
pr_err("%s: array out of bound error found.\n",
__func__);
return -EINVAL;
}
record.val = msm_rpmstats_read_register(pdata->reg_base,
pdata->read_idx, 2);
@ -240,13 +248,20 @@ static ssize_t msm_rpmstats_file_read(struct file *file, char __user *bufu,
size_t count, loff_t *ppos)
{
struct msm_rpmstats_private_data *prvdata;
ssize_t ret;
mutex_lock(&rpm_stats_mutex);
prvdata = file->private_data;
if (!prvdata)
return -EINVAL;
if (!prvdata) {
ret = -EINVAL;
goto exit;
}
if (!bufu || count == 0)
return -EINVAL;
if (!bufu || count == 0) {
ret = -EINVAL;
goto exit;
}
if (prvdata->platform_data->version == 1) {
if (!prvdata->num_records)
@ -263,22 +278,30 @@ static ssize_t msm_rpmstats_file_read(struct file *file, char __user *bufu,
*ppos = 0;
}
return simple_read_from_buffer(bufu, count, ppos,
ret = simple_read_from_buffer(bufu, count, ppos,
prvdata->buf, prvdata->len);
exit:
mutex_unlock(&rpm_stats_mutex);
return ret;
}
static int msm_rpmstats_file_open(struct inode *inode, struct file *file)
{
struct msm_rpmstats_private_data *prvdata;
struct msm_rpmstats_platform_data *pdata;
int ret = 0;
mutex_lock(&rpm_stats_mutex);
pdata = inode->i_private;
file->private_data =
kmalloc(sizeof(struct msm_rpmstats_private_data), GFP_KERNEL);
if (!file->private_data)
return -ENOMEM;
if (!file->private_data) {
ret = -ENOMEM;
goto exit;
}
prvdata = file->private_data;
prvdata->reg_base = ioremap_nocache(pdata->phys_addr_base,
@ -289,24 +312,28 @@ static int msm_rpmstats_file_open(struct inode *inode, struct file *file)
pr_err("%s: ERROR could not ioremap start=%pa, len=%u\n",
__func__, &pdata->phys_addr_base,
pdata->phys_size);
return -EBUSY;
ret = -EBUSY;
goto exit;
}
prvdata->read_idx = prvdata->num_records = prvdata->len = 0;
prvdata->platform_data = pdata;
if (pdata->version == 2)
prvdata->num_records = 2;
return 0;
exit:
mutex_unlock(&rpm_stats_mutex);
return ret;
}
static int msm_rpmstats_file_close(struct inode *inode, struct file *file)
{
struct msm_rpmstats_private_data *private = file->private_data;
mutex_lock(&rpm_stats_mutex);
if (private->reg_base)
iounmap(private->reg_base);
kfree(file->private_data);
mutex_unlock(&rpm_stats_mutex);
return 0;
}
@ -362,22 +389,26 @@ static ssize_t rpmstats_show(struct kobject *kobj,
{
struct msm_rpmstats_private_data *prvdata = NULL;
struct msm_rpmstats_platform_data *pdata = NULL;
ssize_t ret;
mutex_lock(&rpm_stats_mutex);
pdata = GET_PDATA_OF_ATTR(attr);
prvdata =
kmalloc(sizeof(*prvdata), GFP_KERNEL);
if (!prvdata)
return -ENOMEM;
if (!prvdata) {
ret = -ENOMEM;
goto kmalloc_fail;
}
prvdata->reg_base = ioremap_nocache(pdata->phys_addr_base,
pdata->phys_size);
if (!prvdata->reg_base) {
kfree(prvdata);
pr_err("%s: ERROR could not ioremap start=%pa, len=%u\n",
__func__, &pdata->phys_addr_base,
pdata->phys_size);
return -EBUSY;
ret = -EBUSY;
goto ioremap_fail;
}
prvdata->read_idx = prvdata->num_records = prvdata->len = 0;
@ -399,23 +430,22 @@ static ssize_t rpmstats_show(struct kobject *kobj,
prvdata);
}
return snprintf(buf, prvdata->len, prvdata->buf);
ret = snprintf(buf, prvdata->len, prvdata->buf);
iounmap(prvdata->reg_base);
ioremap_fail:
kfree(prvdata);
kmalloc_fail:
mutex_unlock(&rpm_stats_mutex);
return ret;
}
static int msm_rpmstats_create_sysfs(struct msm_rpmstats_platform_data *pd)
{
struct kobject *module_kobj = NULL;
struct kobject *rpmstats_kobj = NULL;
struct msm_rpmstats_kobj_attr *rpms_ka = NULL;
int ret = 0;
module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME);
if (!module_kobj) {
pr_err("%s: Cannot find module_kset\n", __func__);
return -ENODEV;
}
rpmstats_kobj = kobject_create_and_add("rpmstats", module_kobj);
rpmstats_kobj = kobject_create_and_add("system_sleep", power_kobj);
if (!rpmstats_kobj) {
pr_err("%s: Cannot create rpmstats kobject\n", __func__);
ret = -ENOMEM;

View File

@ -421,7 +421,7 @@ static ssize_t dwc3_mode_write(struct file *file,
struct dwc3 *dwc = s->private;
unsigned long flags;
u32 mode = 0;
char buf[32];
char buf[32] = {0};
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
return -EFAULT;
@ -501,7 +501,7 @@ static ssize_t dwc3_testmode_write(struct file *file,
struct dwc3 *dwc = s->private;
unsigned long flags;
u32 testmode = 0;
char buf[32];
char buf[32] = {0};
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
return -EFAULT;
@ -608,7 +608,7 @@ static ssize_t dwc3_link_state_write(struct file *file,
struct dwc3 *dwc = s->private;
unsigned long flags;
enum dwc3_link_state state = 0;
char buf[32];
char buf[32] = {0};
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
return -EFAULT;
@ -649,12 +649,10 @@ static ssize_t dwc3_store_ep_num(struct file *file, const char __user *ubuf,
{
struct seq_file *s = file->private_data;
struct dwc3 *dwc = s->private;
char kbuf[10];
char kbuf[10] = {0};
unsigned int num, dir, temp;
unsigned long flags;
memset(kbuf, 0, 10);
if (copy_from_user(kbuf, ubuf, count > 10 ? 10 : count))
return -EFAULT;

View File

@ -410,6 +410,9 @@ static ssize_t mdss_debug_base_offset_write(struct file *file,
buf[count] = 0; /* end of string */
if (off % sizeof(u32))
return -EINVAL;
sscanf(buf, "%5x %x", &off, &cnt);
if (off > dbg->max_offset)
@ -484,6 +487,9 @@ static ssize_t mdss_debug_base_reg_write(struct file *file,
if (cnt < 2)
return -EFAULT;
if (off % sizeof(u32))
return -EFAULT;
if (off >= dbg->max_offset)
return -EFAULT;
@ -529,6 +535,9 @@ static ssize_t mdss_debug_base_reg_read(struct file *file,
return -ENOMEM;
}
if (dbg->off % sizeof(u32))
return -EFAULT;
ptr = dbg->base + dbg->off;
tot = 0;

View File

@ -703,6 +703,11 @@ static ssize_t mdss_dsi_cmd_state_write(struct file *file,
int *link_state = file->private_data;
char *input;
if (!count) {
pr_err("%s: Zero bytes to be written\n", __func__);
return -EINVAL;
}
input = kmalloc(count, GFP_KERNEL);
if (!input) {
pr_err("%s: Failed to allocate memory\n", __func__);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2010-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
@ -148,7 +148,7 @@ static void hdmi_cec_msg_recv(struct work_struct *work)
msg.sender_id, msg.recvr_id,
msg.frame_size);
if (msg.frame_size < 1) {
if (msg.frame_size < 1 || msg.frame_size > MAX_CEC_FRAME_SIZE) {
DEV_ERR("%s: invalid message (frame length = %d)\n",
__func__, msg.frame_size);
return;
@ -168,7 +168,7 @@ static void hdmi_cec_msg_recv(struct work_struct *work)
msg.operand[i] = data & 0xFF;
}
for (; i < 14; i++)
for (; i < MAX_OPERAND_SIZE; i++)
msg.operand[i] = 0;
if (cbs && cbs->msg_recv_notify)

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2010-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
@ -310,8 +310,10 @@ static ssize_t hdmi_edid_sysfs_wta_res_info(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int rc, page_id;
u32 i = 0, j, page;
ssize_t ret = strnlen(buf, PAGE_SIZE);
struct hdmi_edid_ctrl *edid_ctrl = hdmi_edid_get_ctrl(dev);
struct msm_hdmi_mode_timing_info info = {0};
if (!edid_ctrl) {
DEV_ERR("%s: invalid input\n", __func__);
@ -324,7 +326,22 @@ static ssize_t hdmi_edid_sysfs_wta_res_info(struct device *dev,
return rc;
}
edid_ctrl->page_id = page_id;
if (page_id > MSM_HDMI_INIT_RES_PAGE) {
page = MSM_HDMI_INIT_RES_PAGE;
while (page < page_id) {
j = 1;
while (sizeof(info) * j < PAGE_SIZE) {
i++;
j++;
}
page++;
}
}
if (i < HDMI_VFRMT_MAX)
edid_ctrl->page_id = page_id;
else
DEV_ERR("%s: invalid page id\n", __func__);
DEV_DBG("%s: %d\n", __func__, edid_ctrl->page_id);
return ret;

View File

@ -432,7 +432,7 @@ struct mdss_pp_res_type {
struct mdp_hist_lut_data enhist_disp_cfg[MDSS_BLOCK_DISP_NUM];
struct mdp_dither_cfg_data dither_disp_cfg[MDSS_BLOCK_DISP_NUM];
struct mdp_gamut_cfg_data gamut_disp_cfg[MDSS_BLOCK_DISP_NUM];
uint16_t gamut_tbl[MDSS_BLOCK_DISP_NUM][GAMUT_TOTAL_TABLE_SIZE];
uint16_t gamut_tbl[MDSS_BLOCK_DISP_NUM][3 * GAMUT_TOTAL_TABLE_SIZE];
u32 hist_data[MDSS_BLOCK_DISP_NUM][HIST_V_SIZE];
struct pp_sts_type pp_disp_sts[MDSS_MAX_MIXER_DISP_NUM];
/* physical info */

View File

@ -118,7 +118,8 @@ struct mmc_cmdq_req;
extern int mmc_cmdq_discard_queue(struct mmc_host *host, u32 tasks);
extern int mmc_cmdq_halt(struct mmc_host *host, bool enable);
extern int mmc_cmdq_halt_on_empty_queue(struct mmc_host *host);
extern void mmc_cmdq_post_req(struct mmc_host *host, int tag, int err);
extern void mmc_cmdq_post_req(struct mmc_host *host, int tag, int err,
bool is_dcmd);
extern int mmc_cmdq_start_req(struct mmc_host *host,
struct mmc_cmdq_req *cmdq_req);
extern int mmc_cmdq_prepare_flush(struct mmc_command *cmd);

View File

@ -103,7 +103,7 @@ struct mmc_cmdq_host_ops {
int (*enable)(struct mmc_host *host);
void (*disable)(struct mmc_host *host, bool soft);
int (*request)(struct mmc_host *host, struct mmc_request *mrq);
void (*post_req)(struct mmc_host *host, int tag, int err);
void (*post_req)(struct mmc_host *host, int tag, int err, bool is_dcmd);
int (*halt)(struct mmc_host *host, bool halt);
void (*reset)(struct mmc_host *host, bool soft);
void (*dumpstate)(struct mmc_host *host);