]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.1.1/fb-sh-mobile-fix-deadlock-risk-between-lock_fb_info-and-console_lock.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.1.1 / fb-sh-mobile-fix-deadlock-risk-between-lock_fb_info-and-console_lock.patch
CommitLineData
14818f4b
GKH
1From 4a47a0e09c504e3ce0ccdb405411aefc5b09deb8 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Bruno=20Pr=C3=A9mont?= <bonbons@linux-vserver.org>
3Date: Fri, 2 Sep 2011 19:24:03 +0200
4Subject: fb: sh-mobile: Fix deadlock risk between lock_fb_info() and console_lock()
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9From: =?UTF-8?q?Bruno=20Pr=C3=A9mont?= <bonbons@linux-vserver.org>
10
11commit 4a47a0e09c504e3ce0ccdb405411aefc5b09deb8 upstream.
12
13Following on Herton's patch "fb: avoid possible deadlock caused by
14fb_set_suspend" which moves lock_fb_info() out of fb_set_suspend()
15to its callers, correct sh-mobile's locking around call to
16fb_set_suspend() and the same sort of deaklocks with console_lock()
17due to order of taking the lock.
18
19console_lock() must be taken while fb_info is already locked and fb_info
20must be locked while calling fb_set_suspend().
21
22Signed-off-by: Bruno Prémont <bonbons@linux-vserver.org>
23Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
24Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
25Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
26
27---
28 drivers/video/sh_mobile_hdmi.c | 47 ++++++++++++++++++++++-------------------
29 1 file changed, 26 insertions(+), 21 deletions(-)
30
31--- a/drivers/video/sh_mobile_hdmi.c
32+++ b/drivers/video/sh_mobile_hdmi.c
33@@ -1111,6 +1111,7 @@ static long sh_hdmi_clk_configure(struct
34 static void sh_hdmi_edid_work_fn(struct work_struct *work)
35 {
36 struct sh_hdmi *hdmi = container_of(work, struct sh_hdmi, edid_work.work);
37+ struct fb_info *info;
38 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
39 struct sh_mobile_lcdc_chan *ch;
40 int ret;
41@@ -1123,8 +1124,9 @@ static void sh_hdmi_edid_work_fn(struct
42
43 mutex_lock(&hdmi->mutex);
44
45+ info = hdmi->info;
46+
47 if (hdmi->hp_state == HDMI_HOTPLUG_CONNECTED) {
48- struct fb_info *info = hdmi->info;
49 unsigned long parent_rate = 0, hdmi_rate;
50
51 ret = sh_hdmi_read_edid(hdmi, &hdmi_rate, &parent_rate);
52@@ -1148,42 +1150,45 @@ static void sh_hdmi_edid_work_fn(struct
53
54 ch = info->par;
55
56- console_lock();
57+ if (lock_fb_info(info)) {
58+ console_lock();
59
60- /* HDMI plug in */
61- if (!sh_hdmi_must_reconfigure(hdmi) &&
62- info->state == FBINFO_STATE_RUNNING) {
63- /*
64- * First activation with the default monitor - just turn
65- * on, if we run a resume here, the logo disappears
66- */
67- if (lock_fb_info(info)) {
68+ /* HDMI plug in */
69+ if (!sh_hdmi_must_reconfigure(hdmi) &&
70+ info->state == FBINFO_STATE_RUNNING) {
71+ /*
72+ * First activation with the default monitor - just turn
73+ * on, if we run a resume here, the logo disappears
74+ */
75 info->var.width = hdmi->var.width;
76 info->var.height = hdmi->var.height;
77 sh_hdmi_display_on(hdmi, info);
78- unlock_fb_info(info);
79+ } else {
80+ /* New monitor or have to wake up */
81+ fb_set_suspend(info, 0);
82 }
83- } else {
84- /* New monitor or have to wake up */
85- fb_set_suspend(info, 0);
86- }
87
88- console_unlock();
89+ console_unlock();
90+ unlock_fb_info(info);
91+ }
92 } else {
93 ret = 0;
94- if (!hdmi->info)
95+ if (!info)
96 goto out;
97
98 hdmi->monspec.modedb_len = 0;
99 fb_destroy_modedb(hdmi->monspec.modedb);
100 hdmi->monspec.modedb = NULL;
101
102- console_lock();
103+ if (lock_fb_info(info)) {
104+ console_lock();
105
106- /* HDMI disconnect */
107- fb_set_suspend(hdmi->info, 1);
108+ /* HDMI disconnect */
109+ fb_set_suspend(info, 1);
110
111- console_unlock();
112+ console_unlock();
113+ unlock_fb_info(info);
114+ }
115 }
116
117 out: