msm: kgsl: Send the correct timestamp to an expired event

Instead of sending the currently expired timestamp to expired
events, send the timestamp that the event expected. This avoids
confusion for events that don't compare the actual timestamp
to the one they expected.  Canceled events send the current
timestamp when they were canceled.

The kgsl_sync handler wasn't prepared for the second case so
add a check to prevent strange things from happening on the
timeline when a event is canceled.

Change-Id: Ic0dedbad3681db6222720884688dcddb9b06bda2
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
diff --git a/drivers/gpu/msm/kgsl_events.c b/drivers/gpu/msm/kgsl_events.c
index 3ea8f4b..ce98fa4 100644
--- a/drivers/gpu/msm/kgsl_events.c
+++ b/drivers/gpu/msm/kgsl_events.c
@@ -63,10 +63,15 @@
 	}
 	cur_ts = kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_RETIRED);
 
-	/* Check to see if the requested timestamp has already fired */
+	/*
+	 * Check to see if the requested timestamp has already fired.  If it
+	 * did do the callback right away.  Make sure to send the timestamp that
+	 * the event expected instead of the current timestamp because sometimes
+	 * the event handlers can get confused.
+	 */
 
 	if (timestamp_cmp(cur_ts, ts) >= 0) {
-		cb(device, priv, id, cur_ts);
+		cb(device, priv, id, ts);
 		return 0;
 	}
 
@@ -127,7 +132,11 @@
 		 * Currently, events are used for lock and memory
 		 * management, so if the process is dying the right
 		 * thing to do is release or free.
+		 *
+		 * Send the current timestamp so the event knows how far the
+		 * system got before the event was canceled
 		 */
+
 		if (event->func)
 			event->func(device, event->priv, id, cur);
 
@@ -162,7 +171,9 @@
 		 * "cancel" the events by calling their callback.
 		 * Currently, events are used for lock and memory
 		 * management, so if the process is dying the right
-		 * thing to do is release or free.
+		 * thing to do is release or free. Send the current timestamp so
+		 * the callback knows how far the GPU made it before things went
+		 * explosion
 		 */
 		if (event->func)
 			event->func(device, event->priv, KGSL_MEMSTORE_GLOBAL,
@@ -189,8 +200,15 @@
 
 		id = event->context ? event->context->id : KGSL_MEMSTORE_GLOBAL;
 
+		/*
+		 * Send the timestamp of the expired event, not the current
+		 * timestamp.  This prevents the event handlers from getting
+		 * confused if they don't bother comparing the current timetamp
+		 * to the timestamp they wanted
+		 */
+
 		if (event->func)
-			event->func(device, event->priv, id, timestamp);
+			event->func(device, event->priv, id, event->timestamp);
 
 		if (event->context)
 			kgsl_context_put(event->context);
diff --git a/drivers/gpu/msm/kgsl_sync.c b/drivers/gpu/msm/kgsl_sync.c
index a2dfe3b..9325124 100644
--- a/drivers/gpu/msm/kgsl_sync.c
+++ b/drivers/gpu/msm/kgsl_sync.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -204,7 +204,9 @@
 {
 	struct kgsl_sync_timeline *ktimeline =
 		(struct kgsl_sync_timeline *) timeline;
-	ktimeline->last_timestamp = timestamp;
+
+	if (timestamp_cmp(timestamp, ktimeline->last_timestamp > 0))
+		ktimeline->last_timestamp = timestamp;
 	sync_timeline_signal(timeline);
 }