aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@nokia.com>2010-01-11 09:33:56 -0500
committerTomi Valkeinen <tomi.valkeinen@nokia.com>2010-02-24 07:31:26 -0500
commitb9eb5d7d0b9bf7c6430374333e4b9dae73bbba20 (patch)
treec8a746cf672ff1c6781b6f4dbcae4dc712920500
parent63cf28ac3e3166a02a4e0db6168cf403ed66e3a5 (diff)
OMAP: DSS2: DSI: change DSI bus_lock to semaphore
Physical DSI bus is protected by a mutex. This patch changed the mutex to a semaphore, so that we can lock and unlock the bus_lock from different threads. This is needed as the update process is started by user space program, and thus the lock is acquired in that context, but the lock can be released in different context, a work thread via irq. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com>
-rw-r--r--drivers/video/omap2/dss/dsi.c20
1 files changed, 6 insertions, 14 deletions
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 928b5e44a3dd..53fc0f8cb1a0 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -27,6 +27,7 @@
27#include <linux/interrupt.h> 27#include <linux/interrupt.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/mutex.h> 29#include <linux/mutex.h>
30#include <linux/semaphore.h>
30#include <linux/seq_file.h> 31#include <linux/seq_file.h>
31#include <linux/platform_device.h> 32#include <linux/platform_device.h>
32#include <linux/regulator/consumer.h> 33#include <linux/regulator/consumer.h>
@@ -227,7 +228,7 @@ static struct
227 } vc[4]; 228 } vc[4];
228 229
229 struct mutex lock; 230 struct mutex lock;
230 struct mutex bus_lock; 231 struct semaphore bus_lock;
231 232
232 unsigned pll_locked; 233 unsigned pll_locked;
233 234
@@ -298,19 +299,19 @@ void dsi_restore_context(void)
298 299
299void dsi_bus_lock(void) 300void dsi_bus_lock(void)
300{ 301{
301 mutex_lock(&dsi.bus_lock); 302 down(&dsi.bus_lock);
302} 303}
303EXPORT_SYMBOL(dsi_bus_lock); 304EXPORT_SYMBOL(dsi_bus_lock);
304 305
305void dsi_bus_unlock(void) 306void dsi_bus_unlock(void)
306{ 307{
307 mutex_unlock(&dsi.bus_lock); 308 up(&dsi.bus_lock);
308} 309}
309EXPORT_SYMBOL(dsi_bus_unlock); 310EXPORT_SYMBOL(dsi_bus_unlock);
310 311
311static bool dsi_bus_is_locked(void) 312static bool dsi_bus_is_locked(void)
312{ 313{
313 return mutex_is_locked(&dsi.bus_lock); 314 return dsi.bus_lock.count == 0;
314} 315}
315 316
316static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum, 317static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum,
@@ -3002,8 +3003,6 @@ static int dsi_update_thread(void *data)
3002 u16 x, y, w, h; 3003 u16 x, y, w, h;
3003 3004
3004 while (1) { 3005 while (1) {
3005 bool sched;
3006
3007 wait_event_interruptible(dsi.waitqueue, 3006 wait_event_interruptible(dsi.waitqueue,
3008 dsi.update_mode == OMAP_DSS_UPDATE_AUTO || 3007 dsi.update_mode == OMAP_DSS_UPDATE_AUTO ||
3009 (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL && 3008 (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL &&
@@ -3089,16 +3088,9 @@ static int dsi_update_thread(void *data)
3089 dsi_perf_show("L4"); 3088 dsi_perf_show("L4");
3090 } 3089 }
3091 3090
3092 sched = atomic_read(&dsi.bus_lock.count) < 0;
3093
3094 complete_all(&dsi.update_completion); 3091 complete_all(&dsi.update_completion);
3095 3092
3096 dsi_bus_unlock(); 3093 dsi_bus_unlock();
3097
3098 /* XXX We need to give others chance to get the bus lock. Is
3099 * there a better way for this? */
3100 if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO && sched)
3101 schedule_timeout_interruptible(1);
3102 } 3094 }
3103 3095
3104 DSSDBG("update thread exiting\n"); 3096 DSSDBG("update thread exiting\n");
@@ -3798,7 +3790,7 @@ int dsi_init(struct platform_device *pdev)
3798 spin_lock_init(&dsi.update_lock); 3790 spin_lock_init(&dsi.update_lock);
3799 3791
3800 mutex_init(&dsi.lock); 3792 mutex_init(&dsi.lock);
3801 mutex_init(&dsi.bus_lock); 3793 sema_init(&dsi.bus_lock, 1);
3802 3794
3803#ifdef DSI_CATCH_MISSING_TE 3795#ifdef DSI_CATCH_MISSING_TE
3804 init_timer(&dsi.te_timer); 3796 init_timer(&dsi.te_timer);