Merge "diag: dci: Add DCI support for APSS logs and events and cmd/rsp"
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index b4574aa..3f40def 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -48,6 +48,7 @@
#include <asm/system.h>
#include <mach/socinfo.h>
+#include <mach/msm_rtb.h>
union gic_base {
void __iomem *common_base;
@@ -310,7 +311,7 @@
if (gic->need_access_lock)
raw_spin_lock(&irq_controller_lock);
- writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
+ writel_relaxed_no_log(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
if (gic->need_access_lock)
raw_spin_unlock(&irq_controller_lock);
}
@@ -388,8 +389,8 @@
bit = 1 << (cpu_logical_map(cpu) + shift);
raw_spin_lock(&irq_controller_lock);
- val = readl_relaxed(reg) & ~mask;
- writel_relaxed(val | bit, reg);
+ val = readl_relaxed_no_log(reg) & ~mask;
+ writel_relaxed_no_log(val | bit, reg);
raw_spin_unlock(&irq_controller_lock);
return IRQ_SET_MASK_OK;
@@ -434,7 +435,7 @@
do {
if (gic->need_access_lock)
raw_spin_lock(&irq_controller_lock);
- irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK);
+ irqstat = readl_relaxed_no_log(cpu_base + GIC_CPU_INTACK);
if (gic->need_access_lock)
raw_spin_unlock(&irq_controller_lock);
irqnr = irqstat & ~0x1c00;
@@ -442,16 +443,18 @@
if (likely(irqnr > 15 && irqnr < 1021)) {
irqnr = irq_find_mapping(gic->domain, irqnr);
handle_IRQ(irqnr, regs);
+ uncached_logk(LOGK_IRQ, (void *)(uintptr_t)irqnr);
continue;
}
if (irqnr < 16) {
if (gic->need_access_lock)
raw_spin_lock(&irq_controller_lock);
- writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
+ writel_relaxed_no_log(irqstat, cpu_base + GIC_CPU_EOI);
if (gic->need_access_lock)
raw_spin_unlock(&irq_controller_lock);
#ifdef CONFIG_SMP
handle_IPI(irqnr, regs);
+ uncached_logk(LOGK_IRQ, (void *)(uintptr_t)irqnr);
#endif
continue;
}
@@ -713,19 +716,22 @@
if (!dist_base || !cpu_base)
return;
- saved_cpu_ctrl = readl_relaxed(cpu_base + GIC_CPU_CTRL);
+ saved_cpu_ctrl = readl_relaxed_no_log(cpu_base + GIC_CPU_CTRL);
for (i = 0; i < DIV_ROUND_UP(32, 4); i++)
- gic_data[gic_nr].saved_dist_pri[i] = readl_relaxed(dist_base +
+ gic_data[gic_nr].saved_dist_pri[i] = readl_relaxed_no_log(
+ dist_base +
GIC_DIST_PRI + i * 4);
ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_enable);
for (i = 0; i < DIV_ROUND_UP(32, 32); i++)
- ptr[i] = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4);
+ ptr[i] = readl_relaxed_no_log(dist_base +
+ GIC_DIST_ENABLE_SET + i * 4);
ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_conf);
for (i = 0; i < DIV_ROUND_UP(32, 16); i++)
- ptr[i] = readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4);
+ ptr[i] = readl_relaxed_no_log(dist_base +
+ GIC_DIST_CONFIG + i * 4);
}
@@ -747,18 +753,20 @@
ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_enable);
for (i = 0; i < DIV_ROUND_UP(32, 32); i++)
- writel_relaxed(ptr[i], dist_base + GIC_DIST_ENABLE_SET + i * 4);
+ writel_relaxed_no_log(ptr[i], dist_base +
+ GIC_DIST_ENABLE_SET + i * 4);
ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_conf);
for (i = 0; i < DIV_ROUND_UP(32, 16); i++)
- writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4);
+ writel_relaxed_no_log(ptr[i], dist_base +
+ GIC_DIST_CONFIG + i * 4);
for (i = 0; i < DIV_ROUND_UP(32, 4); i++)
- writel_relaxed(gic_data[gic_nr].saved_dist_pri[i],
+ writel_relaxed_no_log(gic_data[gic_nr].saved_dist_pri[i],
dist_base + GIC_DIST_PRI + i * 4);
- writel_relaxed(0xf0, cpu_base + GIC_CPU_PRIMASK);
- writel_relaxed(saved_cpu_ctrl, cpu_base + GIC_CPU_CTRL);
+ writel_relaxed_no_log(0xf0, cpu_base + GIC_CPU_PRIMASK);
+ writel_relaxed_no_log(saved_cpu_ctrl, cpu_base + GIC_CPU_CTRL);
}
static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v)
@@ -993,7 +1001,7 @@
if (gic->need_access_lock)
raw_spin_lock_irqsave(&irq_controller_lock, flags);
/* this always happens on GIC0 */
- writel_relaxed(sgir, gic_data_dist_base(gic) + GIC_DIST_SOFTINT);
+ writel_relaxed_no_log(sgir, gic_data_dist_base(gic) + GIC_DIST_SOFTINT);
if (gic->need_access_lock)
raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
mb();
diff --git a/arch/arm/mach-msm/include/mach/msm_rtb.h b/arch/arm/mach-msm/include/mach/msm_rtb.h
index b33e8b6..c419a3d 100644
--- a/arch/arm/mach-msm/include/mach/msm_rtb.h
+++ b/arch/arm/mach-msm/include/mach/msm_rtb.h
@@ -27,6 +27,7 @@
LOGK_TIMESTAMP = 6,
LOGK_L2CPREAD = 7,
LOGK_L2CPWRITE = 8,
+ LOGK_IRQ = 9,
};
#define LOGTYPE_NOPC 0x80
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 12fa799..d163317 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2002,2007-2014, 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
@@ -461,6 +461,7 @@
struct kgsl_perfcounter_read_group __user *reads, unsigned int count)
{
struct adreno_perfcounters *counters = adreno_dev->gpudev->perfcounters;
+ struct kgsl_device *device = &adreno_dev->dev;
struct adreno_perfcount_group *group;
struct kgsl_perfcounter_read_group *list = NULL;
unsigned int i, j;
@@ -488,6 +489,13 @@
goto done;
}
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
+ ret = kgsl_active_count_get(device);
+ if (ret) {
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+ goto done;
+ }
+
/* list iterator */
for (j = 0; j < count; j++) {
@@ -496,7 +504,7 @@
/* Verify that the group ID is within range */
if (list[j].groupid >= counters->group_count) {
ret = -EINVAL;
- goto done;
+ break;
}
group = &(counters->groups[list[j].groupid]);
@@ -512,11 +520,13 @@
}
}
+ kgsl_active_count_put(device);
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+
/* write the data */
- if (copy_to_user(reads, list,
- sizeof(struct kgsl_perfcounter_read_group) *
- count) != 0)
- ret = -EFAULT;
+ if (ret == 0)
+ ret = copy_to_user(reads, list,
+ sizeof(struct kgsl_perfcounter_read_group) * count);
done:
kfree(list);
@@ -592,8 +602,11 @@
unsigned int *max_counters)
{
struct adreno_perfcounters *counters = adreno_dev->gpudev->perfcounters;
+ struct kgsl_device *device = &adreno_dev->dev;
struct adreno_perfcount_group *group;
- unsigned int i;
+ unsigned int i, t;
+ int ret;
+ unsigned int *buf;
*max_counters = 0;
@@ -603,6 +616,8 @@
if (groupid >= counters->group_count)
return -EINVAL;
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
+
group = &(counters->groups[groupid]);
*max_counters = group->reg_count;
@@ -610,20 +625,28 @@
* if NULL countable or *count of zero, return max reg_count in
* *max_counters and return success
*/
- if (countables == NULL || count == 0)
+ if (countables == NULL || count == 0) {
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
return 0;
-
- /*
- * Go through all available counters. Write upto *count * countable
- * values.
- */
- for (i = 0; i < group->reg_count && i < count; i++) {
- if (copy_to_user(&countables[i], &(group->regs[i].countable),
- sizeof(unsigned int)) != 0)
- return -EFAULT;
}
- return 0;
+ t = min_t(int, group->reg_count, count);
+
+ buf = kmalloc(t * sizeof(unsigned int), GFP_KERNEL);
+ if (buf == NULL) {
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < t; i++)
+ buf[i] = group->regs[i].countable;
+
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+
+ ret = copy_to_user(countables, buf, sizeof(unsigned int) * t);
+ kfree(buf);
+
+ return ret;
}
static inline void refcount_group(struct adreno_perfcount_group *group,
@@ -2832,6 +2855,8 @@
break;
}
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
+
if (enable) {
device->pwrctrl.ctrl_flags = 0;
adreno_dev->fast_hang_detect = 1;
@@ -2851,6 +2876,7 @@
kgsl_pwrscale_disable(device);
}
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
status = 0;
}
break;
@@ -2869,10 +2895,13 @@
context = kgsl_context_get_owner(dev_priv,
constraint.context_id);
+
if (context == NULL)
break;
+
status = adreno_set_constraint(device, context,
&constraint);
+
kgsl_context_put(context);
}
break;
@@ -3354,24 +3383,28 @@
}
case IOCTL_KGSL_PERFCOUNTER_GET: {
struct kgsl_perfcounter_get *get = data;
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
/*
* adreno_perfcounter_get() is called by kernel clients
* during start(), so it is not safe to take an
* active count inside this function.
*/
result = kgsl_active_count_get(device);
- if (result)
- break;
- result = adreno_perfcounter_get(adreno_dev, get->groupid,
- get->countable, &get->offset, &get->offset_hi,
- PERFCOUNTER_FLAG_NONE);
- kgsl_active_count_put(device);
+ if (result == 0) {
+ result = adreno_perfcounter_get(adreno_dev,
+ get->groupid, get->countable, &get->offset,
+ &get->offset_hi, PERFCOUNTER_FLAG_NONE);
+ kgsl_active_count_put(device);
+ }
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
break;
}
case IOCTL_KGSL_PERFCOUNTER_PUT: {
struct kgsl_perfcounter_put *put = data;
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
result = adreno_perfcounter_put(adreno_dev, put->groupid,
put->countable, PERFCOUNTER_FLAG_NONE);
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
break;
}
case IOCTL_KGSL_PERFCOUNTER_QUERY: {
@@ -3383,12 +3416,8 @@
}
case IOCTL_KGSL_PERFCOUNTER_READ: {
struct kgsl_perfcounter_read *read = data;
- result = kgsl_active_count_get(device);
- if (result)
- break;
result = adreno_perfcounter_read_group(adreno_dev,
read->reads, read->count);
- kgsl_active_count_put(device);
break;
}
default:
diff --git a/drivers/gpu/msm/adreno_profile.c b/drivers/gpu/msm/adreno_profile.c
index 45075a5..7785f3b 100644
--- a/drivers/gpu/msm/adreno_profile.c
+++ b/drivers/gpu/msm/adreno_profile.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -680,6 +680,15 @@
if (adreno_is_a2xx(adreno_dev))
return -ENOSPC;
+ buf = kmalloc(len + 1, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ if (copy_from_user(buf, user_buf, len)) {
+ size = -EFAULT;
+ goto error_free;
+ }
+
kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
if (adreno_profile_enabled(profile)) {
@@ -688,8 +697,10 @@
}
ret = kgsl_active_count_get(device);
- if (ret)
- return -EINVAL;
+ if (ret) {
+ size = ret;
+ goto error_unlock;
+ }
/*
* When adding/removing assignments, ensure that the GPU is done with
@@ -697,19 +708,13 @@
* GPU and avoid racey conditions.
*/
if (adreno_idle(device)) {
- size = -EINVAL;
+ size = -ETIMEDOUT;
goto error_put;
}
/* clear all shared buffer results */
adreno_profile_process_results(device);
- buf = kmalloc(len + 1, GFP_KERNEL);
- if (!buf) {
- size = -EINVAL;
- goto error_put;
- }
-
pbuf = buf;
/* clear the log buffer */
@@ -718,10 +723,6 @@
profile->log_tail = profile->log_buffer;
}
- if (copy_from_user(buf, user_buf, len)) {
- size = -EFAULT;
- goto error_free;
- }
/* for sanity and parsing, ensure it is null terminated */
buf[len] = '\0';
@@ -741,12 +742,12 @@
size = len;
-error_free:
- kfree(buf);
error_put:
kgsl_active_count_put(device);
error_unlock:
kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+error_free:
+ kfree(buf);
return size;
}
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 462e7a5..5a33d9d 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -1478,7 +1478,6 @@
kgsl_readtimestamp(device, context,
KGSL_TIMESTAMP_RETIRED),
result);
-
return result;
}
@@ -1487,9 +1486,14 @@
void *data)
{
struct kgsl_device_waittimestamp *param = data;
+ struct kgsl_device *device = dev_priv->device;
+ long result = -EINVAL;
- return _device_waittimestamp(dev_priv, NULL,
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
+ result = _device_waittimestamp(dev_priv, NULL,
param->timestamp, param->timeout);
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+ return result;
}
static long kgsl_ioctl_device_waittimestamp_ctxtid(struct kgsl_device_private
@@ -1498,8 +1502,10 @@
{
struct kgsl_device_waittimestamp_ctxtid *param = data;
struct kgsl_context *context;
+ struct kgsl_device *device = dev_priv->device;
long result = -EINVAL;
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
context = kgsl_context_get_owner(dev_priv, param->context_id);
if (context)
@@ -1507,6 +1513,7 @@
param->timestamp, param->timeout);
kgsl_context_put(context);
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
return result;
}
@@ -2296,9 +2303,14 @@
void *data)
{
struct kgsl_cmdstream_readtimestamp *param = data;
+ struct kgsl_device *device = dev_priv->device;
+ long result = -EINVAL;
- return _cmdstream_readtimestamp(dev_priv, NULL,
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
+ result = _cmdstream_readtimestamp(dev_priv, NULL,
param->type, ¶m->timestamp);
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+ return result;
}
static long kgsl_ioctl_cmdstream_readtimestamp_ctxtid(struct kgsl_device_private
@@ -2306,9 +2318,11 @@
void *data)
{
struct kgsl_cmdstream_readtimestamp_ctxtid *param = data;
+ struct kgsl_device *device = dev_priv->device;
struct kgsl_context *context;
long result = -EINVAL;
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
context = kgsl_context_get_owner(dev_priv, param->context_id);
if (context)
@@ -2316,6 +2330,7 @@
param->type, ¶m->timestamp);
kgsl_context_put(context);
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
return result;
}
@@ -2367,9 +2382,14 @@
void *data)
{
struct kgsl_cmdstream_freememontimestamp *param = data;
+ struct kgsl_device *device = dev_priv->device;
+ long result = -EINVAL;
- return _cmdstream_freememontimestamp(dev_priv, param->gpuaddr,
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
+ result = _cmdstream_freememontimestamp(dev_priv, param->gpuaddr,
NULL, param->timestamp, param->type);
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+ return result;
}
static long kgsl_ioctl_cmdstream_freememontimestamp_ctxtid(
@@ -2379,13 +2399,16 @@
{
struct kgsl_cmdstream_freememontimestamp_ctxtid *param = data;
struct kgsl_context *context;
+ struct kgsl_device *device = dev_priv->device;
long result = -EINVAL;
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
context = kgsl_context_get_owner(dev_priv, param->context_id);
if (context)
result = _cmdstream_freememontimestamp(dev_priv, param->gpuaddr,
context, param->timestamp, param->type);
kgsl_context_put(context);
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
return result;
}
@@ -2397,6 +2420,7 @@
struct kgsl_context *context = NULL;
struct kgsl_device *device = dev_priv->device;
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
context = device->ftbl->drawctxt_create(dev_priv, ¶m->flags);
if (IS_ERR(context)) {
result = PTR_ERR(context);
@@ -2405,6 +2429,7 @@
trace_kgsl_context_create(dev_priv->device, context, param->flags);
param->drawctxt_id = context->id;
done:
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
return result;
}
@@ -2412,14 +2437,17 @@
unsigned int cmd, void *data)
{
struct kgsl_drawctxt_destroy *param = data;
+ struct kgsl_device *device = dev_priv->device;
struct kgsl_context *context;
long result;
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
context = kgsl_context_get_owner(dev_priv, param->drawctxt_id);
result = kgsl_context_detach(context);
kgsl_context_put(context);
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
return result;
}
@@ -3488,78 +3516,65 @@
typedef long (*kgsl_ioctl_func_t)(struct kgsl_device_private *,
unsigned int, void *);
-#define KGSL_IOCTL_FUNC(_cmd, _func, _flags) \
+#define KGSL_IOCTL_FUNC(_cmd, _func) \
[_IOC_NR((_cmd))] = \
- { .cmd = (_cmd), .func = (_func), .flags = (_flags) }
+ { .cmd = (_cmd), .func = (_func) }
-#define KGSL_IOCTL_LOCK BIT(0)
static const struct {
unsigned int cmd;
kgsl_ioctl_func_t func;
- unsigned int flags;
} kgsl_ioctl_funcs[] = {
KGSL_IOCTL_FUNC(IOCTL_KGSL_DEVICE_GETPROPERTY,
- kgsl_ioctl_device_getproperty,
- KGSL_IOCTL_LOCK),
+ kgsl_ioctl_device_getproperty),
KGSL_IOCTL_FUNC(IOCTL_KGSL_DEVICE_WAITTIMESTAMP,
- kgsl_ioctl_device_waittimestamp,
- KGSL_IOCTL_LOCK),
+ kgsl_ioctl_device_waittimestamp),
KGSL_IOCTL_FUNC(IOCTL_KGSL_DEVICE_WAITTIMESTAMP_CTXTID,
- kgsl_ioctl_device_waittimestamp_ctxtid,
- KGSL_IOCTL_LOCK),
+ kgsl_ioctl_device_waittimestamp_ctxtid),
KGSL_IOCTL_FUNC(IOCTL_KGSL_RINGBUFFER_ISSUEIBCMDS,
- kgsl_ioctl_rb_issueibcmds, 0),
+ kgsl_ioctl_rb_issueibcmds),
KGSL_IOCTL_FUNC(IOCTL_KGSL_SUBMIT_COMMANDS,
- kgsl_ioctl_submit_commands, 0),
+ kgsl_ioctl_submit_commands),
KGSL_IOCTL_FUNC(IOCTL_KGSL_CMDSTREAM_READTIMESTAMP,
- kgsl_ioctl_cmdstream_readtimestamp,
- KGSL_IOCTL_LOCK),
+ kgsl_ioctl_cmdstream_readtimestamp),
KGSL_IOCTL_FUNC(IOCTL_KGSL_CMDSTREAM_READTIMESTAMP_CTXTID,
- kgsl_ioctl_cmdstream_readtimestamp_ctxtid,
- KGSL_IOCTL_LOCK),
+ kgsl_ioctl_cmdstream_readtimestamp_ctxtid),
KGSL_IOCTL_FUNC(IOCTL_KGSL_CMDSTREAM_FREEMEMONTIMESTAMP,
- kgsl_ioctl_cmdstream_freememontimestamp,
- KGSL_IOCTL_LOCK),
+ kgsl_ioctl_cmdstream_freememontimestamp),
KGSL_IOCTL_FUNC(IOCTL_KGSL_CMDSTREAM_FREEMEMONTIMESTAMP_CTXTID,
- kgsl_ioctl_cmdstream_freememontimestamp_ctxtid,
- KGSL_IOCTL_LOCK),
+ kgsl_ioctl_cmdstream_freememontimestamp_ctxtid),
KGSL_IOCTL_FUNC(IOCTL_KGSL_DRAWCTXT_CREATE,
- kgsl_ioctl_drawctxt_create,
- KGSL_IOCTL_LOCK),
+ kgsl_ioctl_drawctxt_create),
KGSL_IOCTL_FUNC(IOCTL_KGSL_DRAWCTXT_DESTROY,
- kgsl_ioctl_drawctxt_destroy,
- KGSL_IOCTL_LOCK),
+ kgsl_ioctl_drawctxt_destroy),
KGSL_IOCTL_FUNC(IOCTL_KGSL_MAP_USER_MEM,
- kgsl_ioctl_map_user_mem, 0),
+ kgsl_ioctl_map_user_mem),
KGSL_IOCTL_FUNC(IOCTL_KGSL_SHAREDMEM_FROM_PMEM,
- kgsl_ioctl_map_user_mem, 0),
+ kgsl_ioctl_map_user_mem),
KGSL_IOCTL_FUNC(IOCTL_KGSL_SHAREDMEM_FREE,
- kgsl_ioctl_sharedmem_free, 0),
+ kgsl_ioctl_sharedmem_free),
KGSL_IOCTL_FUNC(IOCTL_KGSL_SHAREDMEM_FLUSH_CACHE,
- kgsl_ioctl_sharedmem_flush_cache, 0),
+ kgsl_ioctl_sharedmem_flush_cache),
KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUMEM_ALLOC,
- kgsl_ioctl_gpumem_alloc, 0),
+ kgsl_ioctl_gpumem_alloc),
KGSL_IOCTL_FUNC(IOCTL_KGSL_CFF_SYNCMEM,
- kgsl_ioctl_cff_syncmem, 0),
+ kgsl_ioctl_cff_syncmem),
KGSL_IOCTL_FUNC(IOCTL_KGSL_CFF_USER_EVENT,
- kgsl_ioctl_cff_user_event, 0),
+ kgsl_ioctl_cff_user_event),
KGSL_IOCTL_FUNC(IOCTL_KGSL_TIMESTAMP_EVENT,
- kgsl_ioctl_timestamp_event,
- KGSL_IOCTL_LOCK),
+ kgsl_ioctl_timestamp_event),
KGSL_IOCTL_FUNC(IOCTL_KGSL_SETPROPERTY,
- kgsl_ioctl_device_setproperty,
- KGSL_IOCTL_LOCK),
+ kgsl_ioctl_device_setproperty),
KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUMEM_ALLOC_ID,
- kgsl_ioctl_gpumem_alloc_id, 0),
+ kgsl_ioctl_gpumem_alloc_id),
KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUMEM_FREE_ID,
- kgsl_ioctl_gpumem_free_id, 0),
+ kgsl_ioctl_gpumem_free_id),
KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUMEM_GET_INFO,
- kgsl_ioctl_gpumem_get_info, 0),
+ kgsl_ioctl_gpumem_get_info),
KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUMEM_SYNC_CACHE,
- kgsl_ioctl_gpumem_sync_cache, 0),
+ kgsl_ioctl_gpumem_sync_cache),
KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUMEM_SYNC_CACHE_BULK,
- kgsl_ioctl_gpumem_sync_cache_bulk, 0),
+ kgsl_ioctl_gpumem_sync_cache_bulk),
};
static long kgsl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
@@ -3567,7 +3582,7 @@
struct kgsl_device_private *dev_priv = filep->private_data;
unsigned int nr;
kgsl_ioctl_func_t func;
- int lock, ret;
+ int ret;
char ustack[64];
void *uptr = NULL;
@@ -3624,7 +3639,6 @@
}
func = kgsl_ioctl_funcs[nr].func;
- lock = kgsl_ioctl_funcs[nr].flags & KGSL_IOCTL_LOCK;
} else {
func = dev_priv->device->ftbl->ioctl;
if (!func) {
@@ -3633,19 +3647,10 @@
ret = -ENOIOCTLCMD;
goto done;
}
- lock = 1;
}
- if (lock)
- kgsl_mutex_lock(&dev_priv->device->mutex,
- &dev_priv->device->mutex_owner);
-
ret = func(dev_priv, cmd, uptr);
- if (lock)
- kgsl_mutex_unlock(&dev_priv->device->mutex,
- &dev_priv->device->mutex_owner);
-
/*
* Still copy back on failure, but assume function took
* all necessary precautions sanitizing the return values.
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
old mode 100644
new mode 100755
index 65e607b..4591165
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2002,2007-2014, 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
@@ -85,8 +85,17 @@
return status;
}
-static void _kgsl_destroy_pagetable(struct kgsl_pagetable *pagetable)
+static void kgsl_destroy_pagetable(struct kref *kref)
{
+ struct kgsl_pagetable *pagetable = container_of(kref,
+ struct kgsl_pagetable, refcount);
+
+ unsigned long flags;
+
+ spin_lock_irqsave(&kgsl_driver.ptlock, flags);
+ list_del(&pagetable->list);
+ spin_unlock_irqrestore(&kgsl_driver.ptlock, flags);
+
pagetable_remove_sysfs_objects(pagetable);
kgsl_cleanup_pt(pagetable);
@@ -101,29 +110,6 @@
kfree(pagetable);
}
-static void kgsl_destroy_pagetable(struct kref *kref)
-{
- struct kgsl_pagetable *pagetable = container_of(kref,
- struct kgsl_pagetable, refcount);
- unsigned long flags;
-
- spin_lock_irqsave(&kgsl_driver.ptlock, flags);
- list_del(&pagetable->list);
- spin_unlock_irqrestore(&kgsl_driver.ptlock, flags);
-
- _kgsl_destroy_pagetable(pagetable);
-}
-
-static void kgsl_destroy_pagetable_locked(struct kref *kref)
-{
- struct kgsl_pagetable *pagetable = container_of(kref,
- struct kgsl_pagetable, refcount);
-
- list_del(&pagetable->list);
-
- _kgsl_destroy_pagetable(pagetable);
-}
-
static inline void kgsl_put_pagetable(struct kgsl_pagetable *pagetable)
{
if (pagetable)
@@ -138,12 +124,9 @@
spin_lock_irqsave(&kgsl_driver.ptlock, flags);
list_for_each_entry(pt, &kgsl_driver.pagetable_list, list) {
- if (kref_get_unless_zero(&pt->refcount)) {
- if (pt->name == name) {
- ret = pt;
- break;
- }
- kref_put(&pt->refcount, kgsl_destroy_pagetable_locked);
+ if (name == pt->name && kref_get_unless_zero(&pt->refcount)) {
+ ret = pt;
+ break;
}
}
@@ -340,14 +323,9 @@
return KGSL_MMU_GLOBAL_PT;
spin_lock(&kgsl_driver.ptlock);
list_for_each_entry(pt, &kgsl_driver.pagetable_list, list) {
- if (kref_get_unless_zero(&pt->refcount)) {
- if (mmu->mmu_ops->mmu_pt_equal(mmu, pt, pt_base)) {
- ptid = (int) pt->name;
- kref_put(&pt->refcount,
- kgsl_destroy_pagetable_locked);
- break;
- }
- kref_put(&pt->refcount, kgsl_destroy_pagetable_locked);
+ if (mmu->mmu_ops->mmu_pt_equal(mmu, pt, pt_base)) {
+ ptid = (int) pt->name;
+ break;
}
}
spin_unlock(&kgsl_driver.ptlock);
@@ -367,23 +345,16 @@
return 0;
spin_lock(&kgsl_driver.ptlock);
list_for_each_entry(pt, &kgsl_driver.pagetable_list, list) {
- if (kref_get_unless_zero(&pt->refcount)) {
- if (mmu->mmu_ops->mmu_pt_equal(mmu, pt, pt_base)) {
- if ((addr & ~(PAGE_SIZE-1)) == pt->fault_addr) {
- ret = 1;
- kref_put(&pt->refcount,
- kgsl_destroy_pagetable_locked);
- break;
- } else {
- pt->fault_addr =
- (addr & ~(PAGE_SIZE-1));
- ret = 0;
- kref_put(&pt->refcount,
- kgsl_destroy_pagetable_locked);
- break;
- }
+ if (mmu->mmu_ops->mmu_pt_equal(mmu, pt, pt_base)) {
+ if ((addr & ~(PAGE_SIZE-1)) == pt->fault_addr) {
+ ret = 1;
+ break;
+ } else {
+ pt->fault_addr =
+ (addr & ~(PAGE_SIZE-1));
+ ret = 0;
+ break;
}
- kref_put(&pt->refcount, kgsl_destroy_pagetable_locked);
}
}
spin_unlock(&kgsl_driver.ptlock);
diff --git a/drivers/gpu/msm/kgsl_sync.c b/drivers/gpu/msm/kgsl_sync.c
index 0e694a7..cef052d 100644
--- a/drivers/gpu/msm/kgsl_sync.c
+++ b/drivers/gpu/msm/kgsl_sync.c
@@ -120,6 +120,8 @@
int ret = -EINVAL;
char fence_name[sizeof(fence->name)] = {};
+ priv.fence_fd = -1;
+
if (len != sizeof(priv))
return -EINVAL;
@@ -127,10 +129,12 @@
if (event == NULL)
return -ENOMEM;
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
+
context = kgsl_context_get_owner(owner, context_id);
if (context == NULL)
- goto fail_pt;
+ goto unlock;
event->context = context;
event->timestamp = timestamp;
@@ -139,7 +143,7 @@
if (pt == NULL) {
KGSL_DRV_ERR(device, "kgsl_sync_pt_create failed\n");
ret = -ENOMEM;
- goto fail_pt;
+ goto unlock;
}
snprintf(fence_name, sizeof(fence_name),
"%s-pid-%d-ctx-%d-ts-%d",
@@ -153,42 +157,53 @@
kgsl_sync_pt_destroy(pt);
KGSL_DRV_ERR(device, "sync_fence_create failed\n");
ret = -ENOMEM;
- goto fail_fence;
+ goto unlock;
}
priv.fence_fd = get_unused_fd_flags(0);
if (priv.fence_fd < 0) {
- KGSL_DRV_ERR(device, "invalid fence fd\n");
- ret = -EINVAL;
- goto fail_fd;
+ KGSL_DRV_ERR(device, "Unable to get a file descriptor: %d\n",
+ priv.fence_fd);
+ ret = priv.fence_fd;
+ goto unlock;
}
sync_fence_install(fence, priv.fence_fd);
+ /* Unlock the mutex before copying to user */
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+
if (copy_to_user(data, &priv, sizeof(priv))) {
ret = -EFAULT;
- goto fail_copy_fd;
+ goto out;
}
/*
* Hold the context ref-count for the event - it will get released in
* the callback
*/
+
+ kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
+
ret = kgsl_add_event(device, context_id, timestamp,
kgsl_fence_event_cb, event, owner);
+
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+
if (ret)
- goto fail_event;
+ goto out;
return 0;
-fail_event:
-fail_copy_fd:
- /* clean up sync_fence_install */
- put_unused_fd(priv.fence_fd);
-fail_fd:
- /* clean up sync_fence_create */
- sync_fence_put(fence);
-fail_fence:
-fail_pt:
+unlock:
+ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+
+out:
+ if (priv.fence_fd >= 0)
+ put_unused_fd(priv.fence_fd);
+
+ if (fence)
+ sync_fence_put(fence);
+
kgsl_context_put(context);
kfree(event);
return ret;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
index 69c5190..e8702e4 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -355,6 +355,7 @@
struct msm_vfe_src_info src_info[VFE_SRC_MAX];
uint16_t stream_handle_cnt;
unsigned long event_mask;
+ uint32_t burst_len;
};
struct msm_vfe_stats_hardware_info {
@@ -397,6 +398,7 @@
uint16_t stream_handle_cnt;
atomic_t stats_update;
uint32_t stats_mask;
+ uint32_t stats_burst_len;
};
struct msm_vfe_tasklet_queue_cmd {
@@ -480,8 +482,7 @@
struct list_head tasklet_q;
struct tasklet_struct vfe_tasklet;
struct msm_vfe_tasklet_queue_cmd
- tasklet_queue_cmd[MSM_VFE_TASKLETQ_SIZE];
-
+ tasklet_queue_cmd[MSM_VFE_TASKLETQ_SIZE];
uint32_t soc_hw_version;
uint32_t vfe_hw_version;
struct msm_vfe_hardware_info *hw_info;
@@ -498,6 +499,7 @@
void __iomem *p_avtimer_lsw;
uint8_t ignore_error;
struct msm_isp_statistics *stats;
+ uint32_t vfe_ub_size;
};
#endif
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
index e817680..353b55f 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
@@ -36,10 +36,10 @@
#define VFE40_8x26_VERSION 0x20000013
#define VFE40_8x26V2_VERSION 0x20010014
-#define VFE40_BURST_LEN 1
-#define VFE40_STATS_BURST_LEN 1
-#define VFE40_UB_SIZE 1536
-#define VFE40_EQUAL_SLICE_UB 228
+
+/* STATS_SIZE (BE + BG + BF+ RS + CS + IHIST + BHIST ) = 392 */
+#define VFE40_STATS_SIZE 392
+
#define VFE40_WM_BASE(idx) (0x6C + 0x24 * idx)
#define VFE40_RDI_BASE(idx) (0x2E8 + 0x4 * idx)
#define VFE40_XBAR_BASE(idx) (0x58 + 0x4 * (idx / 2))
@@ -971,6 +971,11 @@
uint8_t plane_idx)
{
uint32_t val;
+
+ struct msm_vfe_axi_shared_data *axi_data =
+ &vfe_dev->axi_data;
+ uint32_t burst_len = axi_data->burst_len;
+
uint32_t wm_base = VFE40_WM_BASE(stream_info->wm[plane_idx]);
if (!stream_info->frame_based) {
@@ -992,7 +997,7 @@
plane_idx].output_stride) << 16 |
(stream_info->plane_cfg[
plane_idx].output_height - 1) << 4 |
- VFE40_BURST_LEN;
+ burst_len;
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x18);
} else {
msm_camera_io_w(0x2, vfe_dev->vfe_base + wm_base);
@@ -1002,7 +1007,7 @@
plane_idx].output_width) << 16 |
(stream_info->plane_cfg[
plane_idx].output_height - 1) << 4 |
- VFE40_BURST_LEN;
+ burst_len;
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x18);
}
@@ -1117,6 +1122,7 @@
uint8_t num_used_wms = 0;
uint32_t prop_size = 0;
uint32_t wm_ub_size;
+ uint32_t axi_wm_ub;
for (i = 0; i < axi_data->hw_info->num_wm; i++) {
if (axi_data->free_wm[i] > 0) {
@@ -1124,7 +1130,9 @@
total_image_size += axi_data->wm_image_size[i];
}
}
- prop_size = MSM_ISP40_TOTAL_WM_UB -
+ axi_wm_ub = vfe_dev->vfe_ub_size - VFE40_STATS_SIZE;
+
+ prop_size = axi_wm_ub -
axi_data->hw_info->min_wm_ub * num_used_wms;
for (i = 0; i < axi_data->hw_info->num_wm; i++) {
if (axi_data->free_wm[i]) {
@@ -1149,10 +1157,14 @@
int i;
uint32_t ub_offset = 0;
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+ uint32_t axi_equal_slice_ub =
+ (vfe_dev->vfe_ub_size - VFE40_STATS_SIZE)/
+ (axi_data->hw_info->num_wm - 1);
+
for (i = 0; i < axi_data->hw_info->num_wm; i++) {
- msm_camera_io_w(ub_offset << 16 | (VFE40_EQUAL_SLICE_UB - 1),
+ msm_camera_io_w(ub_offset << 16 | (axi_equal_slice_ub - 1),
vfe_dev->vfe_base + VFE40_WM_BASE(i) + 0x10);
- ub_offset += VFE40_EQUAL_SLICE_UB;
+ ub_offset += axi_equal_slice_ub;
}
}
@@ -1334,7 +1346,11 @@
static void msm_vfe40_stats_cfg_ub(struct vfe_device *vfe_dev)
{
int i;
- uint32_t ub_offset = VFE40_UB_SIZE;
+ struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
+ uint32_t ub_offset = vfe_dev->vfe_ub_size;
+ uint32_t stats_burst_len = stats_data->stats_burst_len;
+
+
uint32_t ub_size[VFE40_NUM_STATS_TYPE] = {
64, /*MSM_ISP_STATS_BE*/
128, /*MSM_ISP_STATS_BG*/
@@ -1348,7 +1364,7 @@
for (i = 0; i < VFE40_NUM_STATS_TYPE; i++) {
ub_offset -= ub_size[i];
- msm_camera_io_w(VFE40_STATS_BURST_LEN << 30 |
+ msm_camera_io_w(stats_burst_len << 30 |
ub_offset << 16 | (ub_size[i] - 1),
vfe_dev->vfe_base + VFE40_STATS_BASE(i) + 0xC);
}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index 4c3a3d5..d11ea68 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -524,7 +524,9 @@
stream_info->format_factor / ISP_Q2;
} else {
int rdi = SRC_TO_INTF(stream_info->stream_src);
- stream_info->bandwidth = axi_data->src_info[rdi].pixel_clock;
+ if (rdi < VFE_SRC_MAX)
+ stream_info->bandwidth =
+ axi_data->src_info[rdi].pixel_clock;
}
}
@@ -534,6 +536,7 @@
uint32_t io_format = 0;
struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd = arg;
struct msm_vfe_axi_stream *stream_info;
+ struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
rc = msm_isp_axi_create_stream(
&vfe_dev->axi_data, stream_cfg_cmd);
@@ -581,6 +584,8 @@
msm_isp_calculate_framedrop(&vfe_dev->axi_data, stream_cfg_cmd);
stream_info->vt_enable = stream_cfg_cmd->vt_enable;
+ axi_data->burst_len = stream_cfg_cmd->burst_len;
+
if (stream_info->vt_enable) {
vfe_dev->vt_enable = stream_info->vt_enable;
#ifdef CONFIG_MSM_AVTIMER
@@ -853,8 +858,11 @@
struct msm_isp_event_data buf_event;
struct timeval *time_stamp;
uint32_t stream_idx = HANDLE_TO_IDX(stream_info->stream_handle);
- uint32_t frame_id = vfe_dev->axi_data.
- src_info[SRC_TO_INTF(stream_info->stream_src)].frame_id;
+ uint32_t src_intf = SRC_TO_INTF(stream_info->stream_src);
+ uint32_t frame_id = 0;
+ if (src_intf < VFE_SRC_MAX) {
+ frame_id = vfe_dev->axi_data.src_info[src_intf].frame_id;
+ }
if (buf && ts) {
if (vfe_dev->vt_enable) {
@@ -1196,7 +1204,7 @@
enum msm_isp_camif_update_state camif_update)
{
int i, rc = 0;
- uint8_t src_state, wait_for_complete = 0;
+ uint8_t src_state = 0, wait_for_complete = 0;
uint32_t wm_reload_mask = 0x0;
struct msm_vfe_axi_stream *stream_info;
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
@@ -1212,8 +1220,9 @@
}
stream_info = &axi_data->stream_info[
HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
- src_state = axi_data->src_info[
- SRC_TO_INTF(stream_info->stream_src)].active;
+ if (SRC_TO_INTF(stream_info->stream_src) < VFE_SRC_MAX)
+ src_state = axi_data->src_info[
+ SRC_TO_INTF(stream_info->stream_src)].active;
msm_isp_calculate_bandwidth(axi_data, stream_info);
msm_isp_reset_framedrop(vfe_dev, stream_info);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
index 6bd7585..d4c86a5 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
@@ -490,6 +490,9 @@
{
int rc = 0;
struct msm_vfe_stats_stream_cfg_cmd *stream_cfg_cmd = arg;
+ struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
+ stats_data->stats_burst_len = stream_cfg_cmd->stats_burst_len;
+
if (vfe_dev->stats_data.num_active_stream == 0)
vfe_dev->hw_info->vfe_ops.stats_ops.cfg_ub(vfe_dev);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index ebdca89..a81c7bb 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -701,6 +701,10 @@
}
break;
}
+ case SET_WM_UB_SIZE: {
+ vfe_dev->vfe_ub_size = *cfg_data;
+ break;
+ }
}
return 0;
}
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c
index 407b81f..2f943a4 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c
@@ -347,8 +347,12 @@
JPEG_DBG("%s:%d]", __func__, __LINE__);
}
#endif
+ if (pgmn_dev->jpeg_bus_client) {
+ msm_bus_scale_client_update_request(
+ pgmn_dev->jpeg_bus_client, 0);
+ msm_bus_scale_unregister_client(pgmn_dev->jpeg_bus_client);
+ }
- msm_bus_scale_unregister_client(pgmn_dev->jpeg_bus_client);
msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_8x_clk_info,
pgmn_dev->jpeg_clk, ARRAY_SIZE(jpeg_8x_clk_info), 0);
JPEG_DBG("%s:%d] clock disbale done", __func__, __LINE__);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
old mode 100644
new mode 100755
index 071f698..9f0dac4
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -3467,13 +3467,13 @@
capability->height.min);
rc = -ENOTSUPP;
}
-
- if (!rc) {
- rc = call_hfi_op(hdev, capability_check,
- inst->fmts[OUTPUT_PORT]->fourcc,
- inst->prop.width[CAPTURE_PORT],
- &capability->width.max,
- &capability->height.max);
+ if (!rc && (inst->prop.width[CAPTURE_PORT] >
+ capability->width.max)) {
+ dprintk(VIDC_ERR,
+ "Unsupported width = %u supported max width = %u",
+ inst->prop.width[CAPTURE_PORT],
+ capability->width.max);
+ rc = -ENOTSUPP;
}
if (!rc && (inst->prop.height[CAPTURE_PORT]
* inst->prop.width[CAPTURE_PORT] >
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
old mode 100644
new mode 100755
index 475683c..0ac6fc4
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
@@ -20,7 +20,6 @@
int msm_fw_debug = 0x18;
int msm_fw_debug_mode = 0x1;
int msm_fw_low_power_mode = 0x1;
-int msm_vp8_low_tier = 0x1;
int msm_vidc_hw_rsp_timeout = 1000;
struct debug_buffer {
@@ -184,11 +183,6 @@
dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
goto failed_create_dir;
}
- if (!debugfs_create_u32("vp8_low_tier", S_IRUGO | S_IWUSR,
- parent, &msm_vp8_low_tier)) {
- dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
- goto failed_create_dir;
- }
if (!debugfs_create_u32("debug_output", S_IRUGO | S_IWUSR,
parent, &msm_vidc_debug_out)) {
dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
diff --git a/drivers/media/platform/msm/vidc/q6_hfi.c b/drivers/media/platform/msm/vidc/q6_hfi.c
old mode 100644
new mode 100755
index bbba29a..486d740
--- a/drivers/media/platform/msm/vidc/q6_hfi.c
+++ b/drivers/media/platform/msm/vidc/q6_hfi.c
@@ -1318,24 +1318,6 @@
return rc;
}
-int q6_hfi_capability_check(u32 fourcc, u32 width,
- u32 *max_width, u32 *max_height)
-{
- int rc = 0;
- if (!max_width || !max_height) {
- dprintk(VIDC_ERR, "%s - invalid parameter\n", __func__);
- return -EINVAL;
- }
-
- if (width > *max_width) {
- dprintk(VIDC_ERR,
- "Unsupported width = %u supported max width = %u\n",
- width, *max_width);
- rc = -ENOTSUPP;
- }
- return rc;
-}
-
static void q6_hfi_unload_fw(void *hfi_device_data)
{
struct q6_hfi_device *device = hfi_device_data;
@@ -1390,7 +1372,6 @@
hdev->unset_ocmem = q6_hfi_unset_ocmem;
hdev->iommu_get_domain_partition = q6_hfi_iommu_get_domain_partition;
hdev->load_fw = q6_hfi_load_fw;
- hdev->capability_check = q6_hfi_capability_check;
hdev->unload_fw = q6_hfi_unload_fw;
hdev->get_stride_scanline = q6_hfi_get_stride_scanline;
}
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
old mode 100644
new mode 100755
index 30ee45d..448fe3b
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -3747,29 +3747,6 @@
return rc;
}
-int venus_hfi_capability_check(u32 fourcc, u32 width,
- u32 *max_width, u32 *max_height)
-{
- int rc = 0;
- if (!max_width || !max_height) {
- dprintk(VIDC_ERR, "%s - invalid parameter\n", __func__);
- return -EINVAL;
- }
-
- if (msm_vp8_low_tier && fourcc == V4L2_PIX_FMT_VP8) {
- *max_width = DEFAULT_WIDTH;
- *max_height = DEFAULT_HEIGHT;
- }
-
- if (width > *max_width) {
- dprintk(VIDC_ERR,
- "Unsupported width = %u supported max width = %u\n",
- width, *max_width);
- rc = -ENOTSUPP;
- }
- return rc;
-}
-
static void *venus_hfi_add_device(u32 device_id,
struct msm_vidc_platform_resources *res,
hfi_cmd_response_callback callback)
@@ -3932,7 +3909,6 @@
hdev->get_info = venus_hfi_get_info;
hdev->get_stride_scanline = venus_hfi_get_stride_scanline;
hdev->get_core_capabilities = venus_hfi_get_core_capabilities;
- hdev->capability_check = venus_hfi_capability_check;
hdev->power_enable = venus_hfi_power_enable;
}
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
old mode 100644
new mode 100755
index 62507a1..38c5bdb
--- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
@@ -1168,8 +1168,6 @@
int (*get_info) (void *dev, enum dev_info info);
int (*get_stride_scanline)(int color_fmt, int width,
int height, int *stride, int *scanlines);
- int (*capability_check)(u32 fourcc, u32 width,
- u32 *max_width, u32 *max_height);
int (*session_clean)(void *sess);
int (*get_core_capabilities)(void);
int (*power_enable)(void *dev);
diff --git a/drivers/platform/msm/pft.c b/drivers/platform/msm/pft.c
index 20e7249..14a6092 100644
--- a/drivers/platform/msm/pft.c
+++ b/drivers/platform/msm/pft.c
@@ -267,10 +267,11 @@
int ret = -ENOENT;
struct pft_file_info *tmp = NULL;
struct list_head *pos = NULL;
+ struct list_head *next = NULL;
bool found = false;
mutex_lock(&pft_dev->lock);
- list_for_each(pos, &pft_dev->open_file_list) {
+ list_for_each_safe(pos, next, &pft_dev->open_file_list) {
tmp = list_entry(pos, struct pft_file_info, list);
if (filp == tmp->file) {
found = true;
@@ -394,6 +395,9 @@
{
struct inode_security_struct *isec = inode->i_security;
+ if (isec == NULL)
+ return false;
+
return ((isec->tag & PFT_TAG_MAGIC_MASK) == PFT_TAG_MAGIC) ?
true : false;
}
@@ -568,27 +572,6 @@
}
/**
- * pft_is_encrypted_inode() - is the file encrypted.
- * @inode: inode of file to check.
- *
- * Return: true if the file is encrypted, false otherwise.
- */
-static bool pft_is_encrypted_inode(struct inode *inode)
-{
- u32 tag;
-
- if (!pft_is_ready())
- return false;
-
- if (!pft_is_xattr_supported(inode))
- return false;
-
- tag = pft_get_inode_tag(inode);
-
- return pft_is_file_encrypted(tag);
-}
-
-/**
* pft_is_inplace_inode() - is this the inode of file for
* in-place encryption.
* @inode: inode of file to check.
@@ -881,92 +864,6 @@
EXPORT_SYMBOL(pft_inode_mknod);
/**
- * pft_inode_symlink() - symlink file hook (callback)
- * @dir: directory inode pointer
- * @dentry: file dentry pointer
- * @name: Old file name
- *
- * Allow only enterprise app to create symlink to enterprise
- * file.
- * Call path:
- * vfs_symlink()->security_inode_symlink()->selinux_inode_symlink()
- *
- * Return: 0 on allowed operation, negative value otherwise.
- */
-int pft_inode_symlink(struct inode *dir, struct dentry *dentry,
- const char *name)
-{
- struct inode *inode;
-
- if (!dir) {
- pr_err("dir is NULL.\n");
- return 0;
- }
- if (!dentry) {
- pr_err("dentry is NULL.\n");
- return 0;
- }
- if (!name) {
- pr_err("name is NULL.\n");
- return 0;
- }
-
- pr_debug("symlink for file [%s] dir [%s] dentry [%s] started! ....\n",
- name, inode_to_filename(dir), dentry->d_iname);
- inode = dentry->d_inode;
-
- if (!dentry->d_inode) {
- pr_debug("d_inode is NULL.\n");
- return 0;
- }
-
- if (!pft_is_ready())
- return 0;
-
- /* do nothing for non-encrypted files */
- if (!pft_is_encrypted_inode(inode))
- return 0;
-
- /*
- * Only PFM allowed to access in-place-encryption-file
- * during in-place-encryption process
- */
- if (pft_is_inplace_inode(inode)) {
- pr_err("symlink for in-place-encryption file %s by pid %d is blocked.\n",
- inode_to_filename(inode), current_pid());
- return -EACCES;
- }
-
- switch (pft_dev->state) {
- case PFT_STATE_DEACTIVATED:
- case PFT_STATE_KEY_REMOVED:
- case PFT_STATE_DEACTIVATING:
- case PFT_STATE_REMOVING_KEY:
- /* Block any access for encrypted files when key not loaded */
- pr_debug("key not loaded. uid (%u) can not access file %s\n",
- current_uid(), inode_to_filename(inode));
- return -EACCES;
- case PFT_STATE_KEY_LOADED:
- /* Only registered apps may access encrypted files. */
- if (!pft_is_current_process_registered()) {
- pr_err("unregistered app uid %u pid %u is trying to access encrypted file %s\n",
- current_uid(), current_pid(), name);
- return -EACCES;
- }
- break;
- default:
- BUG(); /* State is set by "set state" command */
- break;
- }
-
- pr_debug("symlink for file %s ok.\n", name);
-
- return 0;
-
-}
-EXPORT_SYMBOL(pft_inode_symlink);
-
-/**
* pft_inode_rename() - file rename hook.
* @inode: directory inode
* @dentry: file dentry
@@ -1025,6 +922,8 @@
*/
int pft_file_open(struct file *filp, const struct cred *cred)
{
+ int ret;
+
if (!filp || !filp->f_path.dentry)
return 0;
@@ -1063,7 +962,12 @@
return -EACCES;
}
- pft_add_file(filp);
+ ret = pft_add_file(filp);
+ if (ret) {
+ pr_err("failed to add file %s to the list.\n",
+ file_to_filename(filp));
+ return -EFAULT;
+ }
break;
default:
BUG(); /* State is set by "set state" command */
@@ -1230,7 +1134,7 @@
if (pft_is_inplace_inode(inode)) {
pr_err("block delete in-place-encryption file %s by uid [%d] pid [%d], while encryption in progress.\n",
inode_to_filename(inode), current_uid(), current_pid());
- return -EACCES;
+ return -EBUSY;
}
if (!pft_is_current_process_registered()) {
@@ -1562,7 +1466,7 @@
*/
static int pft_handle_command(void *buf, int buf_size)
{
- size_t ret = 0;
+ int ret = 0;
struct pft_command *command = NULL;
/* opcode field is the minimum length of command */
@@ -1620,7 +1524,7 @@
static int pft_device_release(struct inode *inode, struct file *file)
{
mutex_lock(&pft_dev->lock);
- if (0 < pft_dev->open_count)
+ if (pft_dev->open_count > 0)
pft_dev->open_count--;
pft_dev->pfm_pid = UINT_MAX;
mutex_unlock(&pft_dev->lock);
@@ -1769,15 +1673,32 @@
}
+static void __exit pft_free_open_files_list(void)
+{
+ struct pft_file_info *tmp = NULL;
+ struct list_head *pos = NULL;
+ struct list_head *next = NULL;
+
+ mutex_lock(&pft_dev->lock);
+ list_for_each_safe(pos, next, &pft_dev->open_file_list) {
+ tmp = list_entry(pos, struct pft_file_info, list);
+ list_del(&tmp->list);
+ kfree(tmp);
+ }
+ mutex_unlock(&pft_dev->lock);
+}
+
static void __exit pft_exit(void)
{
if (pft_dev == NULL)
return;
pft_unregister_chrdev();
+ pft_free_open_files_list();
kfree(pft_dev->uid_table);
kfree(pft_dev);
+ pft_dev = NULL;
}
static int __init pft_init(void)
@@ -1790,13 +1711,14 @@
pr_err("No memory for device structr\n");
return -ENOMEM;
}
+ pft_dev = dev;
dev->state = PFT_STATE_DEACTIVATED;
+ dev->pfm_pid = UINT_MAX;
+
INIT_LIST_HEAD(&dev->open_file_list);
mutex_init(&dev->lock);
- pft_dev = dev;
-
ret = pft_register_chardev();
if (ret) {
pr_err("create character device failed.\n");
@@ -1810,6 +1732,7 @@
fail:
pr_err("Failed to init driver.\n");
kfree(dev);
+ pft_dev = NULL;
return -ENODEV;
}
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index e3284d5..81640a0 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -33,7 +33,9 @@
/* PMIC Arbiter configuration registers */
#define PMIC_ARB_VERSION 0x0000
#define PMIC_ARB_INT_EN 0x0004
-
+#define PMIC_ARB_PROTOCOL_IRQ_STATUS (0x700 + 0x820)
+#define PMIC_ARB_GENI_CTRL 0x0024
+#define PMIC_ARB_GENI_STATUS 0x0028
/* PMIC Arbiter channel registers */
#define PMIC_ARB_CMD(N) (0x0800 + (0x80 * (N)))
#define PMIC_ARB_CONFIG(N) (0x0804 + (0x80 * (N)))
@@ -125,6 +127,7 @@
u8 max_apid;
u16 periph_id_map[PMIC_ARB_MAX_PERIPHS];
u32 mapping_table[SPMI_MAPPING_TABLE_LEN];
+ u32 prev_prtcl_irq_stat;
};
static struct spmi_pmic_arb_dev *the_pmic_arb;
@@ -143,6 +146,37 @@
writel_relaxed(val, dev->base + offset);
}
+static void pmic_arb_save_stat_before_txn(struct spmi_pmic_arb_dev *dev)
+{
+ dev->prev_prtcl_irq_stat =
+ readl_relaxed(dev->cnfg + PMIC_ARB_PROTOCOL_IRQ_STATUS);
+}
+
+static int pmic_arb_diagnosis(struct spmi_pmic_arb_dev *dev, u32 status)
+{
+ if (status & PMIC_ARB_STATUS_DENIED) {
+ dev_err(dev->dev,
+ "wait_for_done: transaction denied by SPMI master (0x%x)\n",
+ status);
+ return -EPERM;
+ }
+
+ if (status & PMIC_ARB_STATUS_FAILURE) {
+ dev_err(dev->dev,
+ "wait_for_done: transaction failed (0x%x)\n", status);
+ return -EIO;
+ }
+
+ if (status & PMIC_ARB_STATUS_DROPPED) {
+ dev_err(dev->dev,
+ "wait_for_done: transaction dropped pmic-arb busy (0x%x)\n",
+ status);
+ return -EAGAIN;
+ }
+
+ return 0;
+}
+
static int pmic_arb_wait_for_done(struct spmi_pmic_arb_dev *dev)
{
u32 status = 0;
@@ -152,34 +186,13 @@
while (timeout--) {
status = pmic_arb_read(dev, offset);
- if (status & PMIC_ARB_STATUS_DONE) {
- if (status & PMIC_ARB_STATUS_DENIED) {
- dev_err(dev->dev,
- "%s: transaction denied (0x%x)\n",
- __func__, status);
- return -EPERM;
- }
+ if (status & PMIC_ARB_STATUS_DONE)
+ return pmic_arb_diagnosis(dev, status);
- if (status & PMIC_ARB_STATUS_FAILURE) {
- dev_err(dev->dev,
- "%s: transaction failed (0x%x)\n",
- __func__, status);
- return -EIO;
- }
-
- if (status & PMIC_ARB_STATUS_DROPPED) {
- dev_err(dev->dev,
- "%s: transaction dropped (0x%x)\n",
- __func__, status);
- return -EIO;
- }
-
- return 0;
- }
udelay(1);
}
- dev_err(dev->dev, "%s: timeout, status 0x%x\n", __func__, status);
+ dev_err(dev->dev, "wait_for_done:: timeout, status 0x%x\n", status);
return -ETIMEDOUT;
}
@@ -209,6 +222,29 @@
pmic_arb_write(dev, reg, data);
}
+static void pmic_arb_dbg_err_dump(struct spmi_pmic_arb_dev *pmic_arb, int ret,
+ const char *msg, u8 opc, u8 sid, u16 addr, u8 bc, u8 *buf)
+{
+ u32 irq_stat = readl_relaxed(pmic_arb->cnfg
+ + PMIC_ARB_PROTOCOL_IRQ_STATUS);
+ u32 geni_stat = readl_relaxed(pmic_arb->cnfg + PMIC_ARB_GENI_STATUS);
+ u32 geni_ctrl = readl_relaxed(pmic_arb->cnfg + PMIC_ARB_GENI_CTRL);
+
+ bc += 1; /* actual byte count */
+
+ if (buf)
+ dev_err(pmic_arb->dev,
+ "error:%d on data %s opcode:0x%x sid:%d addr:0x%x bc:%d buf:%*phC\n",
+ ret, msg, opc, sid, addr, bc, bc, buf);
+ else
+ dev_err(pmic_arb->dev,
+ "error:%d on non-data-cmd opcode:0x%x sid:%d\n",
+ ret, opc, sid);
+ dev_err(pmic_arb->dev,
+ "PROTOCOL_IRQ_STATUS before:0x%x after:0x%x GENI_STATUS:0x%x GENI_CTRL:0x%x\n",
+ irq_stat, pmic_arb->prev_prtcl_irq_stat, geni_stat, geni_ctrl);
+}
+
/* Non-data command */
static int pmic_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid)
{
@@ -228,10 +264,13 @@
cmd = (opc << 27) | ((sid & 0xf) << 20);
spin_lock_irqsave(&pmic_arb->lock, flags);
+ pmic_arb_save_stat_before_txn(pmic_arb);
pmic_arb_write(pmic_arb, PMIC_ARB_CMD(pmic_arb->channel), cmd);
rc = pmic_arb_wait_for_done(pmic_arb);
spin_unlock_irqrestore(&pmic_arb->lock, flags);
+ if (rc)
+ pmic_arb_dbg_err_dump(pmic_arb, rc, "cmd", opc, sid, 0, 0, 0);
return rc;
}
@@ -249,7 +288,8 @@
, PMIC_ARB_MAX_TRANS_BYTES, bc+1);
return -EINVAL;
}
- pr_debug("op:0x%x sid:%d bc:%d addr:0x%x\n", opc, sid, bc, addr);
+ dev_dbg(pmic_arb->dev, "client-rd op:0x%x sid:%d addr:0x%x bc:%d\n",
+ opc, sid, addr, bc + 1);
/* Check the opcode */
if (opc >= 0x60 && opc <= 0x7F)
@@ -264,6 +304,7 @@
cmd = (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7);
spin_lock_irqsave(&pmic_arb->lock, flags);
+ pmic_arb_save_stat_before_txn(pmic_arb);
pmic_arb_write(pmic_arb, PMIC_ARB_CMD(pmic_arb->channel), cmd);
rc = pmic_arb_wait_for_done(pmic_arb);
if (rc)
@@ -279,6 +320,9 @@
done:
spin_unlock_irqrestore(&pmic_arb->lock, flags);
+ if (rc)
+ pmic_arb_dbg_err_dump(pmic_arb, rc, "read", opc, sid, addr, bc,
+ buf);
return rc;
}
@@ -296,7 +340,8 @@
, PMIC_ARB_MAX_TRANS_BYTES, bc+1);
return -EINVAL;
}
- pr_debug("op:0x%x sid:%d bc:%d addr:0x%x\n", opc, sid, bc, addr);
+ dev_dbg(pmic_arb->dev, "client-wr op:0x%x sid:%d addr:0x%x bc:%d\n",
+ opc, sid, addr, bc + 1);
/* Check the opcode */
if (opc >= 0x40 && opc <= 0x5F)
@@ -314,6 +359,7 @@
/* Write data to FIFOs */
spin_lock_irqsave(&pmic_arb->lock, flags);
+ pmic_arb_save_stat_before_txn(pmic_arb);
pa_write_data(pmic_arb, buf, PMIC_ARB_WDATA0(pmic_arb->channel)
, min_t(u8, bc, 3));
if (bc > 3)
@@ -325,6 +371,10 @@
rc = pmic_arb_wait_for_done(pmic_arb);
spin_unlock_irqrestore(&pmic_arb->lock, flags);
+ if (rc)
+ pmic_arb_dbg_err_dump(pmic_arb, rc, "write", opc, sid, addr, bc,
+ buf);
+
return rc;
}
@@ -501,7 +551,9 @@
int i;
if (!is_apid_valid(pmic_arb, apid)) {
- dev_err(pmic_arb->dev, "unknown peripheral id 0x%x\n", ppid);
+ dev_err(pmic_arb->dev,
+ "periph_interrupt(apid:0x%x sid:0x%x pid:0x%x) unknown peripheral\n",
+ apid, sid, pid);
/* return IRQ_NONE; */
}
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index b7bf74e..159121f 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -2847,9 +2847,15 @@
binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES);
}
+static int binder_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ return VM_FAULT_SIGBUS;
+}
+
static struct vm_operations_struct binder_vm_ops = {
.open = binder_vma_open,
.close = binder_vma_close,
+ .fault = binder_vm_fault,
};
static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
diff --git a/drivers/video/msm/mdss/mdss.h b/drivers/video/msm/mdss/mdss.h
index afa0bc1..b1c0343 100644
--- a/drivers/video/msm/mdss/mdss.h
+++ b/drivers/video/msm/mdss/mdss.h
@@ -198,6 +198,7 @@
int handoff_pending;
struct mdss_prefill_data prefill_data;
bool ulps;
+ int iommu_ref_cnt;
};
extern struct mdss_data_type *mdss_res;
@@ -220,7 +221,8 @@
void mdss_enable_irq(struct mdss_hw *hw);
void mdss_disable_irq(struct mdss_hw *hw);
void mdss_disable_irq_nosync(struct mdss_hw *hw);
-int mdss_bus_bandwidth_ctrl(int enable);
+void mdss_bus_bandwidth_ctrl(int enable);
+int mdss_iommu_ctrl(int enable);
static inline struct ion_client *mdss_get_ionclient(void)
{
diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c
index 457deb7..56701d4 100644
--- a/drivers/video/msm/mdss/mdss_dsi_host.c
+++ b/drivers/video/msm/mdss/mdss_dsi_host.c
@@ -1031,7 +1031,7 @@
if (is_mdss_iommu_attached()) {
- int ret = msm_iommu_map_contig_buffer(tp->dmap,
+ ret = msm_iommu_map_contig_buffer(tp->dmap,
mdss_get_iommu_domain(domain), 0,
size, SZ_4K, 0, &(addr));
if (IS_ERR_VALUE(ret)) {
@@ -1240,7 +1240,7 @@
{
struct dcs_cmd_req *req;
int ret = -EINVAL;
-
+ int rc = 0;
mutex_lock(&ctrl->cmd_mutex);
req = mdss_dsi_cmdlist_get(ctrl);
@@ -1263,20 +1263,21 @@
* also, axi bus bandwidth need since dsi controller will
* fetch dcs commands from axi bus
*/
- ret = mdss_bus_bandwidth_ctrl(1);
- if (ret) {
- pr_err("bus bandwidth request failed ret=%d\n", ret);
- goto need_lock;
- }
-
+ mdss_bus_bandwidth_ctrl(1);
pr_debug("%s: from_mdp=%d pid=%d\n", __func__, from_mdp, current->pid);
mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 1);
+ rc = mdss_iommu_ctrl(1);
+ if (IS_ERR_VALUE(rc)) {
+ pr_err("IOMMU attach failed\n");
+ mutex_unlock(&ctrl->cmd_mutex);
+ return rc;
+ }
if (req->flags & CMD_REQ_RX)
ret = mdss_dsi_cmdlist_rx(ctrl, req);
else
ret = mdss_dsi_cmdlist_tx(ctrl, req);
-
+ mdss_iommu_ctrl(0);
mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 0);
mdss_bus_bandwidth_ctrl(0);
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index bf151f4..097d568 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -620,6 +620,37 @@
return clk_rate;
}
+int mdss_iommu_ctrl(int enable)
+{
+ struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+ int rc = 0;
+
+ mutex_lock(&mdp_iommu_lock);
+ pr_debug("%pS: enable %d mdata->iommu_ref_cnt %d\n",
+ __builtin_return_address(0), enable, mdata->iommu_ref_cnt);
+
+ if (enable) {
+
+ if (mdata->iommu_ref_cnt == 0)
+ rc = mdss_iommu_attach(mdata);
+ mdata->iommu_ref_cnt++;
+ } else {
+ if (mdata->iommu_ref_cnt) {
+ mdata->iommu_ref_cnt--;
+ if (mdata->iommu_ref_cnt == 0)
+ rc = mdss_iommu_dettach(mdata);
+ } else {
+ pr_err("unbalanced iommu ref\n");
+ }
+ }
+ mutex_unlock(&mdp_iommu_lock);
+
+ if (IS_ERR_VALUE(rc))
+ return rc;
+ else
+ return mdata->iommu_ref_cnt;
+}
+
/**
* mdss_bus_bandwidth_ctrl() -- place bus bandwidth request
* @enable: value of enable or disable
@@ -629,27 +660,16 @@
* Bus bandwidth is required by mdp.For dsi, it only requires to send
* dcs coammnd. It returns error if bandwidth request fails.
*/
-int mdss_bus_bandwidth_ctrl(int enable)
+void mdss_bus_bandwidth_ctrl(int enable)
{
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
static int bus_bw_cnt;
int changed = 0;
- int rc = 0;
mutex_lock(&bus_bw_lock);
if (enable) {
- if (bus_bw_cnt == 0) {
+ if (bus_bw_cnt == 0)
changed++;
- if (!mdata->handoff_pending) {
- rc = mdss_iommu_attach(mdata);
- if (rc) {
- pr_err("iommu attach failed rc=%d\n",
- rc);
- goto end;
- }
- }
- }
-
bus_bw_cnt++;
} else {
if (bus_bw_cnt) {
@@ -668,7 +688,6 @@
if (!enable) {
msm_bus_scale_client_update_request(
mdata->bus_hdl, 0);
- mdss_iommu_dettach(mdata);
pm_runtime_put(&mdata->pdev->dev);
} else {
pm_runtime_get_sync(&mdata->pdev->dev);
@@ -677,9 +696,7 @@
}
}
-end:
mutex_unlock(&bus_bw_lock);
- return rc;
}
EXPORT_SYMBOL(mdss_bus_bandwidth_ctrl);
@@ -687,7 +704,7 @@
{
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
static int mdp_clk_cnt;
- int changed = 0, rc;
+ int changed = 0;
mutex_lock(&mdp_clk_lock);
if (enable) {
@@ -720,9 +737,7 @@
if (mdata->vsync_ena)
mdss_mdp_clk_update(MDSS_CLK_MDP_VSYNC, enable);
- rc = mdss_bus_bandwidth_ctrl(enable);
- if (rc)
- pr_err("bus bandwidth control failed rc=%d", rc);
+ mdss_bus_bandwidth_ctrl(enable);
if (!enable)
pm_runtime_put(&mdata->pdev->dev);
@@ -809,7 +824,6 @@
struct mdss_iommu_map_type *iomap;
int i, rc = 0;
- mutex_lock(&mdp_iommu_lock);
MDSS_XLOG(mdata->iommu_attached);
if (mdata->iommu_attached) {
@@ -840,8 +854,6 @@
mdata->iommu_attached = true;
end:
- mutex_unlock(&mdp_iommu_lock);
-
return rc;
}
@@ -851,12 +863,10 @@
struct mdss_iommu_map_type *iomap;
int i;
- mutex_lock(&mdp_iommu_lock);
MDSS_XLOG(mdata->iommu_attached);
if (!mdata->iommu_attached) {
pr_debug("mdp iommu already dettached\n");
- mutex_unlock(&mdp_iommu_lock);
return 0;
}
@@ -873,7 +883,6 @@
}
mdata->iommu_attached = false;
- mutex_unlock(&mdp_iommu_lock);
return 0;
}
@@ -2560,7 +2569,6 @@
mdata->fs_ena = true;
} else {
pr_debug("Disable MDP FS\n");
- mdss_iommu_dettach(mdata);
if (mdata->fs_ena) {
regulator_disable(mdata->fs);
if (!mdata->ulps) {
@@ -2591,20 +2599,20 @@
pr_debug("called on=%d\n", on);
if (on) {
pm_runtime_get_sync(dev);
- rc = mdss_iommu_attach(mdata);
- if (rc) {
+ rc = mdss_iommu_ctrl(1);
+ if (IS_ERR_VALUE(rc)) {
pr_err("mdss iommu attach failed rc=%d\n", rc);
- goto end;
+ return rc;
}
mdss_hw_init(mdata);
mdata->ulps = false;
+ mdss_iommu_ctrl(0);
} else {
mdata->ulps = true;
pm_runtime_put_sync(dev);
}
-end:
- return rc;
+ return 0;
}
static inline int mdss_mdp_suspend_sub(struct mdss_data_type *mdata)
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
index 991eb06..350ea1b 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
@@ -189,6 +189,7 @@
{
unsigned long flags;
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+ int rc;
if (!ctx->panel_on)
return;
@@ -201,6 +202,10 @@
if (cancel_delayed_work_sync(&ctx->ulps_work))
pr_debug("deleted pending ulps work\n");
+ rc = mdss_iommu_ctrl(1);
+ if (IS_ERR_VALUE(rc))
+ pr_err("IOMMU attach failed\n");
+
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
if (ctx->ulps) {
@@ -243,6 +248,7 @@
mdss_mdp_hist_intr_setup(&mdata->hist_intr, MDSS_IRQ_SUSPEND);
mdss_mdp_ctl_intf_event
(ctx->ctl, MDSS_EVENT_PANEL_CLK_CTRL, (void *)0);
+ mdss_iommu_ctrl(0);
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
if (ctx->panel_on)
schedule_delayed_work(&ctx->ulps_work, ULPS_ENTER_TIME);
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
index eff708c..e5bba31 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
@@ -333,6 +333,8 @@
frame_rate = 24;
msleep((1000/frame_rate) + 1);
}
+
+ mdss_iommu_ctrl(0);
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
ctx->timegen_en = false;
@@ -717,6 +719,12 @@
pr_debug("enabling timing gen for intf=%d\n", ctl->intf_num);
+ rc = mdss_iommu_ctrl(1);
+ if (IS_ERR_VALUE(rc)) {
+ pr_err("IOMMU attach failed\n");
+ return rc;
+ }
+
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
mdss_mdp_irq_enable(MDSS_MDP_IRQ_INTF_UNDER_RUN, ctl->intf_num);
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
index 02e7b75..7bf03eb 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
@@ -442,6 +442,7 @@
rc = 0;
}
+ mdss_iommu_ctrl(0);
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false); /* clock off */
ctx->comp_cnt--;
@@ -501,6 +502,11 @@
INIT_COMPLETION(ctx->wb_comp);
mdss_mdp_irq_enable(ctx->intr_type, ctx->intf_num);
+ ret = mdss_iommu_ctrl(1);
+ if (IS_ERR_VALUE(ret)) {
+ pr_err("IOMMU attach failed\n");
+ return ret;
+ }
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_START, 1);
wmb();
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index fdfa2b0..2141659 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -707,9 +707,11 @@
if ((num_planes <= 0) || (num_planes > MAX_PLANES))
return -EINVAL;
- rc = mdss_bus_bandwidth_ctrl(1);
- if (rc)
+ rc = mdss_iommu_ctrl(1);
+ if (IS_ERR_VALUE(rc)) {
+ pr_err("Iommu attach failed");
goto end;
+ }
memset(data, 0, sizeof(*data));
for (i = 0; i < num_planes; i++) {
@@ -724,31 +726,29 @@
break;
}
}
- mdss_bus_bandwidth_ctrl(0);
+ mdss_iommu_ctrl(0);
data->num_planes = i;
-
end:
return rc;
}
int mdss_mdp_overlay_free_buf(struct mdss_mdp_data *data)
{
- int i;
- int rc;
+ int i, rc;
- rc = mdss_bus_bandwidth_ctrl(1);
- if (rc)
- goto end;
+ rc = mdss_iommu_ctrl(1);
+ if (IS_ERR_VALUE(rc)) {
+ pr_err("Iommu attach failed");
+ return rc;
+ }
for (i = 0; i < data->num_planes && data->p[i].len; i++)
mdss_mdp_put_img(&data->p[i]);
- mdss_bus_bandwidth_ctrl(0);
+ mdss_iommu_ctrl(0);
data->num_planes = 0;
-
-end:
- return rc;
+ return 0;
}
/**
@@ -919,13 +919,6 @@
if (!mdp5_data->mdata->batfet)
mdss_mdp_batfet_ctrl(mdp5_data->mdata, true);
- if (!mfd->panel_info->cont_splash_enabled) {
- rc = mdss_iommu_attach(mdp5_data->mdata);
- if (rc) {
- pr_err("mdss iommu attach failed rc=%d\n", rc);
- goto end;
- }
- }
mdss_mdp_release_splash_pipe(mfd);
return 0;
}
@@ -948,13 +941,14 @@
*/
if (!is_mdss_iommu_attached()) {
if (!mfd->panel_info->cont_splash_enabled) {
- rc = mdss_iommu_attach(mdss_res);
- if (rc) {
- pr_err("mdss iommu attach failed rc=%d\n", rc);
+ rc = mdss_iommu_ctrl(1);
+ if (IS_ERR_VALUE(rc)) {
+ pr_err("iommu attach failed rc=%d\n", rc);
goto pm_error;
}
+ mdss_hw_init(mdss_res);
+ mdss_iommu_ctrl(0);
}
- mdss_hw_init(mdss_res);
}
rc = mdss_mdp_ctl_start(ctl, false);
@@ -1385,14 +1379,6 @@
flags = (pipe->flags & MDP_SECURE_OVERLAY_SESSION);
flags |= (pipe->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION);
- if (!mfd->panel_info->cont_splash_enabled) {
- ret = mdss_iommu_attach(mdata);
- if (ret) {
- pr_err("mdss iommu attach failed ret=%d\n", ret);
- goto end;
- }
- }
-
src_data = &pipe->back_buf;
if (src_data->num_planes) {
pr_warn("dropped buffer pnum=%d play=%d addr=0x%x\n",
@@ -1405,7 +1391,6 @@
pr_err("src_data pmem error\n");
}
-end:
mdss_mdp_pipe_unmap(pipe);
return ret;
@@ -1612,6 +1597,13 @@
}
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+
+ ret = mdss_iommu_ctrl(1);
+ if (IS_ERR_VALUE(ret)) {
+ pr_err("IOMMU attach failed\n");
+ goto pan_display_error;
+ }
+
bpp = fbi->var.bits_per_pixel / 8;
offset = fbi->var.xoffset * bpp +
fbi->var.yoffset * fbi->fix.line_length;
@@ -1678,10 +1670,12 @@
(fbi->var.activate & FB_ACTIVATE_FORCE))
mfd->mdp.kickoff_fnc(mfd, NULL);
+ mdss_iommu_ctrl(0);
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
return;
pan_display_error:
+ mdss_iommu_ctrl(0);
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
mutex_unlock(&mdp5_data->ov_lock);
}
diff --git a/drivers/video/msm/mdss/mdss_mdp_rotator.c b/drivers/video/msm/mdss/mdss_mdp_rotator.c
index 6953469..ff8c6b8 100755
--- a/drivers/video/msm/mdss/mdss_mdp_rotator.c
+++ b/drivers/video/msm/mdss/mdss_mdp_rotator.c
@@ -692,7 +692,6 @@
struct msmfb_overlay_data *req)
{
struct mdss_mdp_rotator_session *rot;
- struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
int ret;
u32 flgs;
@@ -712,9 +711,6 @@
goto dst_buf_fail;
}
- if (!mfd->panel_info->cont_splash_enabled)
- mdss_iommu_attach(mdp5_data->mdata);
-
mdss_mdp_overlay_free_buf(&rot->src_buf);
ret = mdss_mdp_overlay_get_buf(mfd, &rot->src_buf, &req->data, 1, flgs);
if (ret) {
diff --git a/drivers/video/msm/mdss/mdss_mdp_splash_logo.c b/drivers/video/msm/mdss/mdss_mdp_splash_logo.c
index 838f58f..829806d 100644
--- a/drivers/video/msm/mdss/mdss_mdp_splash_logo.c
+++ b/drivers/video/msm/mdss/mdss_mdp_splash_logo.c
@@ -109,7 +109,7 @@
{
struct iommu_domain *domain;
struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
- int rc;
+ int rc, ret;
/*
* iommu dynamic attach for following conditions.
@@ -139,9 +139,9 @@
if (rc) {
pr_debug("iommu memory mapping failed rc=%d\n", rc);
} else {
- rc = mdss_iommu_attach(mdss_res);
- if (rc) {
- pr_debug("mdss iommu attach failed\n");
+ ret = mdss_iommu_ctrl(1);
+ if (IS_ERR_VALUE(ret)) {
+ pr_err("mdss iommu attach failed\n");
iommu_unmap(domain, mdp5_data->splash_mem_addr,
mdp5_data->splash_mem_size);
} else {
@@ -167,6 +167,8 @@
iommu_unmap(domain, mdp5_data->splash_mem_addr,
mdp5_data->splash_mem_size);
+ mdss_iommu_ctrl(0);
+
mfd->splash_info.iommu_dynamic_attached = false;
}
}
@@ -246,12 +248,6 @@
}
mdss_mdp_footswitch_ctrl_splash(0);
- if (!is_mdss_iommu_attached()) {
- rc = mdss_iommu_attach(mdss_res);
- if (rc)
- pr_err("iommu attach failed rc=%d\n", rc);
- }
-
end:
return rc;
}
diff --git a/drivers/video/msm/mdss/mdss_mdp_wb.c b/drivers/video/msm/mdss/mdss_mdp_wb.c
index 0e59a26..6086e28 100644
--- a/drivers/video/msm/mdss/mdss_mdp_wb.c
+++ b/drivers/video/msm/mdss/mdss_mdp_wb.c
@@ -427,11 +427,20 @@
buf = &node->buf_data.p[0];
if (wb->is_secure)
buf->flags |= MDP_SECURE_OVERLAY_SESSION;
+
+ ret = mdss_iommu_ctrl(1);
+ if (IS_ERR_VALUE(ret)) {
+ pr_err("IOMMU attach failed\n");
+ goto register_fail;
+ }
ret = mdss_mdp_get_img(data, buf);
if (IS_ERR_VALUE(ret)) {
pr_err("error getting buffer info\n");
+ mdss_iommu_ctrl(0);
goto register_fail;
}
+ mdss_iommu_ctrl(0);
+
memcpy(&node->buf_info, data, sizeof(*data));
ret = mdss_mdp_wb_register_node(wb, node);
@@ -471,7 +480,6 @@
{
struct mdss_mdp_wb *wb = mfd_to_wb(mfd);
struct mdss_mdp_wb_data *node = NULL;
- struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
int ret = 0;
if (!wb) {
@@ -481,14 +489,6 @@
pr_debug("fb%d queue\n", wb->fb_ndx);
- if (!mfd->panel_info->cont_splash_enabled) {
- ret = mdss_iommu_attach(mdp5_data->mdata);
- if (ret) {
- pr_err("mdss iommu attach failed rc=%d", ret);
- return ret;
- }
- }
-
mutex_lock(&wb->lock);
if (local)
node = get_local_node(wb, data);
@@ -741,7 +741,13 @@
}
break;
case MSMFB_WRITEBACK_TERMINATE:
+ ret = mdss_iommu_ctrl(1);
+ if (IS_ERR_VALUE(ret)) {
+ pr_err("IOMMU attach failed\n");
+ return ret;
+ }
ret = mdss_mdp_wb_terminate(mfd);
+ mdss_iommu_ctrl(0);
break;
case MSMFB_WRITEBACK_SET_MIRRORING_HINT:
if (!copy_from_user(&hint, arg, sizeof(hint))) {
@@ -854,19 +860,25 @@
EXPORT_SYMBOL(msm_fb_writeback_set_secure);
/**
- * msm_fb_writeback_iommu_ref() - Power ON/OFF mdp clock
- * @enable - true/false to Power ON/OFF mdp clock
+ * msm_fb_writeback_iommu_ref() - Add/Remove vote on MDSS IOMMU being attached.
+ * @enable - true adds vote on MDSS IOMMU, false removes the vote.
*
- * Call to enable mdp clock at start of mdp_mmap/mdp_munmap API and
- * to disable mdp clock at end of these API's to ensure iommu is in
- * proper state while driver map/un-map any buffers.
+ * Call to vote on MDSS IOMMU being enabled. To ensure buffers are properly
+ * mapped to IOMMU context bank.
*/
int msm_fb_writeback_iommu_ref(struct fb_info *info, int enable)
{
- if (enable)
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
- else
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+ int ret;
+
+ if (enable) {
+ ret = mdss_iommu_ctrl(1);
+ if (IS_ERR_VALUE(ret)) {
+ pr_err("IOMMU attach failed\n");
+ return ret;
+ }
+ } else {
+ mdss_iommu_ctrl(0);
+ }
return 0;
}
diff --git a/include/linux/spmi.h b/include/linux/spmi.h
index e8e932e..b581de8 100644
--- a/include/linux/spmi.h
+++ b/include/linux/spmi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014 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
@@ -382,6 +382,7 @@
* -EPERM if the SPMI transaction is denied due to permission issues.
* -EIO if the SPMI transaction fails (parity errors, etc).
* -ETIMEDOUT if the SPMI transaction times out.
+ * -EAGAIN if the SPMI transaction is temporarily unavailable
*/
extern int spmi_command_reset(struct spmi_controller *ctrl, u8 sid);
@@ -397,6 +398,7 @@
* -EPERM if the SPMI transaction is denied due to permission issues.
* -EIO if the SPMI transaction fails (parity errors, etc).
* -ETIMEDOUT if the SPMI transaction times out.
+ * -EAGAIN if the SPMI transaction is temporarily unavailable
*/
extern int spmi_command_sleep(struct spmi_controller *ctrl, u8 sid);
@@ -413,6 +415,7 @@
* -EPERM if the SPMI transaction is denied due to permission issues.
* -EIO if the SPMI transaction fails (parity errors, etc).
* -ETIMEDOUT if the SPMI transaction times out.
+ * -EAGAIN if the SPMI transaction is temporarily unavailable
*/
extern int spmi_command_wakeup(struct spmi_controller *ctrl, u8 sid);
@@ -428,6 +431,7 @@
* -EPERM if the SPMI transaction is denied due to permission issues.
* -EIO if the SPMI transaction fails (parity errors, etc).
* -ETIMEDOUT if the SPMI transaction times out.
+ * -EAGAIN if the SPMI transaction is temporarily unavailable
*/
extern int spmi_command_shutdown(struct spmi_controller *ctrl, u8 sid);
diff --git a/include/media/msmb_isp.h b/include/media/msmb_isp.h
index 30e7d06..e627977 100644
--- a/include/media/msmb_isp.h
+++ b/include/media/msmb_isp.h
@@ -154,6 +154,7 @@
uint8_t buf_divert; /* if TRUE no vb2 buf done. */
/*Return values*/
uint32_t axi_stream_handle;
+ uint32_t burst_len;
};
struct msm_vfe_axi_stream_release_cmd {
@@ -225,6 +226,7 @@
uint8_t num_streams;
uint32_t stream_handle[MSM_ISP_STATS_MAX];
uint8_t enable;
+ uint32_t stats_burst_len;
};
enum msm_vfe_reg_cfg_type {
@@ -242,6 +244,7 @@
GET_MAX_CLK_RATE,
VFE_HW_UPDATE_LOCK,
VFE_HW_UPDATE_UNLOCK,
+ SET_WM_UB_SIZE,
};
struct msm_vfe_cfg_cmd2 {
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 5bc3663..4ff640a 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1964,7 +1964,7 @@
hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
NL80211_CMD_NEW_KEY);
if (!hdr)
- return -ENOBUFS;
+ goto nla_put_failure;
cookie.msg = msg;
cookie.idx = key_idx;
@@ -4245,6 +4245,10 @@
err = -EINVAL;
goto out_free;
}
+
+ if (!wiphy->bands[band])
+ continue;
+
err = ieee80211_get_ratemask(wiphy->bands[band],
nla_data(attr),
nla_len(attr),
diff --git a/sound/soc/codecs/wcd9306.c b/sound/soc/codecs/wcd9306.c
index 38d7901..314c4f9 100644
--- a/sound/soc/codecs/wcd9306.c
+++ b/sound/soc/codecs/wcd9306.c
@@ -4139,6 +4139,12 @@
core = dev_get_drvdata(codec->dev->parent);
+ if(core == NULL) {
+ dev_err(codec->dev, "%s: core is null\n",
+ __func__);
+ return -EINVAL;
+ }
+
dev_dbg(codec->dev, "%s: event called! codec name %s\n",
__func__, w->codec->name);
dev_dbg(codec->dev, "%s: num_dai %d stream name %s event %d\n",
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 4c5d327..5602dd1 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -2555,9 +2555,10 @@
WCD9XXX_CLSH_STATE_LO,
WCD9XXX_CLSH_REQ_ENABLE,
WCD9XXX_CLSH_EVENT_POST_PA);
- pr_debug("%s: sleeping 3 ms after %s PA turn on\n",
+ pr_debug("%s: sleeping 5 ms after %s PA turn on\n",
__func__, w->name);
- usleep_range(3000, 3000);
+ /* Wait for CnP time after PA enable */
+ usleep_range(5000, 5100);
break;
case SND_SOC_DAPM_POST_PMD:
wcd9xxx_clsh_fsm(codec, &taiko->clsh_d,
@@ -2565,6 +2566,10 @@
WCD9XXX_CLSH_REQ_DISABLE,
WCD9XXX_CLSH_EVENT_POST_PA);
snd_soc_update_bits(codec, lineout_gain_reg, 0x40, 0x00);
+ pr_debug("%s: sleeping 5 ms after %s PA turn off\n",
+ __func__, w->name);
+ /* Wait for CnP time after PA disable */
+ usleep_range(5000, 5100);
break;
}
return 0;
diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
index fce1940..f6702c5 100644
--- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
@@ -129,6 +129,8 @@
uint32_t stream_available;
uint32_t next_stream;
+ uint64_t marker_timestamp;
+
struct msm_compr_gapless_state gapless_state;
atomic_t start;
@@ -1064,6 +1066,7 @@
prtd->app_pointer = 0;
prtd->bytes_received = 0;
prtd->bytes_sent = 0;
+ prtd->marker_timestamp = 0;
atomic_set(&prtd->xrun, 0);
spin_unlock_irqrestore(&prtd->lock, flags);
@@ -1196,6 +1199,8 @@
prtd->first_buffer = 1;
prtd->last_buffer = 0;
prtd->gapless_state.gapless_transition = 1;
+ prtd->marker_timestamp = 0;
+
/*
Don't reset these as these vars map to
total_bytes_transferred and total_bytes_available
@@ -1251,23 +1256,23 @@
q6asm_stream_cmd_nowait(ac, CMD_PAUSE, ac->stream_id);
prtd->cmd_ack = 0;
spin_unlock_irqrestore(&prtd->lock, flags);
- pr_debug("%s:issue CMD_FLUSH ac->stream_id %d",
- __func__, ac->stream_id);
- q6asm_stream_cmd(ac, CMD_FLUSH, ac->stream_id);
- wait_event_timeout(prtd->flush_wait,
- prtd->cmd_ack, 1 * HZ / 4);
+ /*
+ * Cache this time as last known time
+ */
+ q6asm_get_session_time(prtd->audio_client,
+ &prtd->marker_timestamp);
spin_lock_irqsave(&prtd->lock, flags);
/*
- Don't reset these as these vars map to
- total_bytes_transferred and total_bytes_available
- directly, only total_bytes_transferred will be updated
- in the next avail() ioctl
- prtd->copied_total = 0;
- prtd->bytes_received = 0;
- do not reset prtd->bytes_sent as well as the same
- session is used for gapless playback
- */
+ * Don't reset these as these vars map to
+ * total_bytes_transferred and total_bytes_available.
+ * Just total_bytes_transferred will be updated
+ * in the next avail() ioctl.
+ * prtd->copied_total = 0;
+ * prtd->bytes_received = 0;
+ * do not reset prtd->bytes_sent as well as the same
+ * session is used for gapless playback
+ */
prtd->byte_offset = 0;
prtd->app_pointer = 0;
@@ -1275,8 +1280,15 @@
prtd->last_buffer = 0;
atomic_set(&prtd->drain, 0);
atomic_set(&prtd->xrun, 1);
- q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
spin_unlock_irqrestore(&prtd->lock, flags);
+
+ pr_debug("%s:issue CMD_FLUSH ac->stream_id %d",
+ __func__, ac->stream_id);
+ q6asm_stream_cmd(ac, CMD_FLUSH, ac->stream_id);
+ wait_event_timeout(prtd->flush_wait,
+ prtd->cmd_ack, 1 * HZ / 4);
+
+ q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
}
prtd->cmd_interrupt = 0;
break;
@@ -1404,6 +1416,8 @@
__func__, timestamp);
return -EAGAIN;
}
+ } else {
+ timestamp = prtd->marker_timestamp;
}
/* DSP returns timestamp in usec */