summaryrefslogtreecommitdiff
path: root/recipes/linux/linux-omap-pm/dss2/0117-DSS2-Locking-for-VRFB.patch
blob: 7902d2225ccb8836b0e13878234caf17f5601ea1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
From 4044386e8f32ea442478809d945f50c5a3a66f88 Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Date: Tue, 16 Jun 2009 15:18:30 +0300
Subject: [PATCH 117/146] DSS2: Locking for VRFB

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com>
---
 arch/arm/plat-omap/vrfb.c |   25 ++++++++++++++++++++++---
 1 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/arch/arm/plat-omap/vrfb.c b/arch/arm/plat-omap/vrfb.c
index 0c7d943..7cd7c61 100644
--- a/arch/arm/plat-omap/vrfb.c
+++ b/arch/arm/plat-omap/vrfb.c
@@ -3,6 +3,7 @@
 #include <linux/ioport.h>
 #include <linux/io.h>
 #include <linux/bitops.h>
+#include <linux/mutex.h>
 
 #include <mach/io.h>
 #include <mach/vrfb.h>
@@ -42,6 +43,8 @@ static unsigned long ctx_map;
 /* bitmap of contexts for which we have to keep the HW context valid */
 static unsigned long ctx_map_active;
 
+static DEFINE_MUTEX(ctx_lock);
+
 /*
  * Access to this happens from client drivers or the PM core after wake-up.
  * For the first case we require locking at the driver level, for the second
@@ -171,6 +174,8 @@ void omap_vrfb_release_ctx(struct vrfb *vrfb)
 
 	DBG("release ctx %d\n", ctx);
 
+	mutex_lock(&ctx_lock);
+
 	if (!(ctx_map & (1 << ctx))) {
 		BUG();
 		return;
@@ -186,6 +191,8 @@ void omap_vrfb_release_ctx(struct vrfb *vrfb)
 	}
 
 	vrfb->context = 0xff;
+
+	mutex_unlock(&ctx_lock);
 }
 EXPORT_SYMBOL(omap_vrfb_release_ctx);
 
@@ -194,16 +201,20 @@ int omap_vrfb_request_ctx(struct vrfb *vrfb)
 	int rot;
 	u32 paddr;
 	u8 ctx;
+	int r;
 
 	DBG("request ctx\n");
 
+	mutex_lock(&ctx_lock);
+
 	for (ctx = 0; ctx < VRFB_NUM_CTXS; ++ctx)
 		if ((ctx_map & (1 << ctx)) == 0)
 			break;
 
 	if (ctx == VRFB_NUM_CTXS) {
 		printk(KERN_ERR "vrfb: no free contexts\n");
-		return -EBUSY;
+		r = -EBUSY;
+		goto out;
 	}
 
 	DBG("found free ctx %d\n", ctx);
@@ -223,7 +234,8 @@ int omap_vrfb_request_ctx(struct vrfb *vrfb)
 					"area for ctx %d, rotation %d\n",
 					ctx, rot * 90);
 			omap_vrfb_release_ctx(vrfb);
-			return -ENOMEM;
+			r = -ENOMEM;
+			goto out;
 		}
 
 		vrfb->paddr[rot] = paddr;
@@ -231,25 +243,31 @@ int omap_vrfb_request_ctx(struct vrfb *vrfb)
 		DBG("VRFB %d/%d: %lx\n", ctx, rot*90, vrfb->paddr[rot]);
 	}
 
-	return 0;
+	r = 0;
+out:
+	mutex_unlock(&ctx_lock);
+	return r;
 }
 EXPORT_SYMBOL(omap_vrfb_request_ctx);
 
 void omap_vrfb_suspend_ctx(struct vrfb *vrfb)
 {
 	DBG("suspend ctx %d\n", vrfb->context);
+	mutex_lock(&ctx_lock);
 	if (vrfb->context >= VRFB_NUM_CTXS ||
 	    (!(1 << vrfb->context) & ctx_map_active)) {
 		BUG();
 		return;
 	}
 	clear_bit(vrfb->context, &ctx_map_active);
+	mutex_unlock(&ctx_lock);
 }
 EXPORT_SYMBOL(omap_vrfb_suspend_ctx);
 
 void omap_vrfb_resume_ctx(struct vrfb *vrfb)
 {
 	DBG("resume ctx %d\n", vrfb->context);
+	mutex_lock(&ctx_lock);
 	if (vrfb->context >= VRFB_NUM_CTXS ||
 	    ((1 << vrfb->context) & ctx_map_active)) {
 		BUG();
@@ -263,6 +281,7 @@ void omap_vrfb_resume_ctx(struct vrfb *vrfb)
 	 */
 	restore_hw_context(vrfb->context);
 	set_bit(vrfb->context, &ctx_map_active);
+	mutex_unlock(&ctx_lock);
 }
 EXPORT_SYMBOL(omap_vrfb_resume_ctx);
 
-- 
1.6.2.4