Merge "msm: kgsl: Add a work item for processing expired timestamps" into msm-3.0
diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c
index 8a7ab35..064b05e 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -1520,6 +1520,7 @@
if (status & (CP_INT_CNTL__IB1_INT_MASK | CP_INT_CNTL__RB_INT_MASK)) {
KGSL_CMD_WARN(rb->device, "ringbuffer ib1/rb interrupt\n");
+ queue_work(device->work_queue, &device->ts_expired_ws);
wake_up_interruptible_all(&device->wait_queue);
atomic_notifier_call_chain(&(device->ts_notifier_list),
device->id,
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index e146ab8..165bbbf 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -180,35 +180,28 @@
list_add_tail(&entry->list, &device->memqueue);
}
-static void kgsl_memqueue_drain(struct kgsl_device *device)
+static void kgsl_timestamp_expired(struct work_struct *work)
{
+ struct kgsl_device *device = container_of(work, struct kgsl_device,
+ ts_expired_ws);
struct kgsl_mem_entry *entry, *entry_tmp;
uint32_t ts_processed;
- BUG_ON(!mutex_is_locked(&device->mutex));
+ mutex_lock(&device->mutex);
/* get current EOP timestamp */
ts_processed = device->ftbl->readtimestamp(device,
KGSL_TIMESTAMP_RETIRED);
+ /* Flush the freememontimestamp queue */
list_for_each_entry_safe(entry, entry_tmp, &device->memqueue, list) {
- KGSL_MEM_INFO(device,
- "ts_processed %d ts_free %d gpuaddr %x)\n",
- ts_processed, entry->free_timestamp,
- entry->memdesc.gpuaddr);
if (!timestamp_cmp(ts_processed, entry->free_timestamp))
break;
list_del(&entry->list);
kgsl_mem_entry_put(entry);
}
-}
-static void kgsl_memqueue_drain_unlocked(struct kgsl_device *device)
-{
- mutex_lock(&device->mutex);
- kgsl_check_suspended(device);
- kgsl_memqueue_drain(device);
mutex_unlock(&device->mutex);
}
@@ -771,8 +764,6 @@
param->timestamp,
param->timeout);
- kgsl_memqueue_drain(dev_priv->device);
-
/* Fire off any pending suspend operations that are in flight */
INIT_COMPLETION(dev_priv->device->suspend_gate);
@@ -950,7 +941,6 @@
if (entry) {
kgsl_memqueue_freememontimestamp(dev_priv->device, entry,
param->timestamp, param->type);
- kgsl_memqueue_drain(dev_priv->device);
} else {
KGSL_DRV_ERR(dev_priv->device,
"invalid gpuaddr %08x\n", param->gpuaddr);
@@ -1062,9 +1052,6 @@
if (!kgsl_mmu_enabled())
return -ENODEV;
- /* Make sure all pending freed memory is collected */
- kgsl_memqueue_drain_unlocked(dev_priv->device);
-
if (!param->hostptr) {
KGSL_CORE_ERR("invalid hostptr %x\n", param->hostptr);
result = -EINVAL;
@@ -1383,8 +1370,6 @@
if (entry == NULL)
return -ENOMEM;
- kgsl_memqueue_drain_unlocked(dev_priv->device);
-
if (_IOC_SIZE(cmd) == sizeof(struct kgsl_sharedmem_from_pmem))
memtype = KGSL_USER_MEM_TYPE_PMEM;
else
@@ -1524,9 +1509,6 @@
if (entry == NULL)
return -ENOMEM;
- /* Make sure all pending freed memory is collected */
- kgsl_memqueue_drain_unlocked(dev_priv->device);
-
result = kgsl_allocate_user(&entry->memdesc, private->pagetable,
param->size, param->flags);
@@ -1914,6 +1896,7 @@
goto err_devlist;
INIT_WORK(&device->idle_check_ws, kgsl_idle_check);
+ INIT_WORK(&device->ts_expired_ws, kgsl_timestamp_expired);
INIT_LIST_HEAD(&device->memqueue);
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 10e345a..2f369ed 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -165,6 +165,7 @@
struct kgsl_pwrscale pwrscale;
struct kobject pwrscale_kobj;
struct pm_qos_request_list pm_qos_req_dma;
+ struct work_struct ts_expired_ws;
};
struct kgsl_context {
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index a81eeaa..61a3edb 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -234,6 +234,7 @@
count &= 255;
z180_dev->timestamp += count;
+ queue_work(device->work_queue, &device->ts_expired_ws);
wake_up_interruptible(&device->wait_queue);
atomic_notifier_call_chain(