summaryrefslogtreecommitdiff
path: root/drivers/gpu/msm/kgsl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/msm/kgsl.c')
-rw-r--r--drivers/gpu/msm/kgsl.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index cc3e79dc29bf..db9e5f7d6d6b 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -530,6 +530,16 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv,
struct kgsl_device *device = dev_priv->device;
char name[64];
int ret = 0, id;
+ struct kgsl_process_private *proc_priv = dev_priv->process_priv;
+
+ if (atomic_read(&proc_priv->ctxt_count) > KGSL_MAX_CONTEXTS_PER_PROC) {
+ KGSL_DRV_ERR(device,
+ "Per process context limit reached for pid %u",
+ dev_priv->process_priv->pid);
+ return -ENOSPC;
+ }
+
+ atomic_inc(&proc_priv->ctxt_count);
id = _kgsl_get_context_id(device);
if (id == -ENOSPC) {
@@ -548,7 +558,7 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv,
KGSL_DRV_INFO(device,
"cannot have more than %zu contexts due to memstore limitation\n",
KGSL_MEMSTORE_MAX);
-
+ atomic_dec(&proc_priv->ctxt_count);
return id;
}
@@ -579,6 +589,7 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv,
out:
if (ret) {
+ atomic_dec(&proc_priv->ctxt_count);
write_lock(&device->context_lock);
idr_remove(&dev_priv->device->context_idr, id);
write_unlock(&device->context_lock);
@@ -662,6 +673,7 @@ kgsl_context_destroy(struct kref *kref)
device->pwrctrl.constraint.type = KGSL_CONSTRAINT_NONE;
}
+ atomic_dec(&context->proc_priv->ctxt_count);
idr_remove(&device->context_idr, context->id);
context->id = KGSL_CONTEXT_INVALID;
}
@@ -734,6 +746,8 @@ static int kgsl_suspend_device(struct kgsl_device *device, pm_message_t state)
mutex_lock(&device->mutex);
status = kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND);
+ if (status == 0)
+ device->ftbl->dispatcher_halt(device);
mutex_unlock(&device->mutex);
KGSL_PWR_WARN(device, "suspend end\n");
@@ -748,6 +762,7 @@ static int kgsl_resume_device(struct kgsl_device *device)
KGSL_PWR_WARN(device, "resume start\n");
mutex_lock(&device->mutex);
if (device->state == KGSL_STATE_SUSPEND) {
+ device->ftbl->dispatcher_unhalt(device);
kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER);
} else if (device->state != KGSL_STATE_INIT) {
/*
@@ -3977,6 +3992,7 @@ long kgsl_ioctl_gpuobj_set_info(struct kgsl_device_private *dev_priv,
struct kgsl_process_private *private = dev_priv->process_priv;
struct kgsl_gpuobj_set_info *param = data;
struct kgsl_mem_entry *entry;
+ int ret = 0;
if (param->id == 0)
return -EINVAL;
@@ -3989,12 +4005,16 @@ long kgsl_ioctl_gpuobj_set_info(struct kgsl_device_private *dev_priv,
copy_metadata(entry, param->metadata, param->metadata_len);
if (param->flags & KGSL_GPUOBJ_SET_INFO_TYPE) {
- entry->memdesc.flags &= ~((uint64_t) KGSL_MEMTYPE_MASK);
- entry->memdesc.flags |= param->type << KGSL_MEMTYPE_SHIFT;
+ if (param->type <= (KGSL_MEMTYPE_MASK >> KGSL_MEMTYPE_SHIFT)) {
+ entry->memdesc.flags &= ~((uint64_t) KGSL_MEMTYPE_MASK);
+ entry->memdesc.flags |= (uint64_t)((param->type <<
+ KGSL_MEMTYPE_SHIFT) & KGSL_MEMTYPE_MASK);
+ } else
+ ret = -EINVAL;
}
kgsl_mem_entry_put(entry);
- return 0;
+ return ret;
}
long kgsl_ioctl_cff_syncmem(struct kgsl_device_private *dev_priv,