aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2013-01-24 19:28:15 -0500
committerDave Airlie <airlied@redhat.com>2013-02-07 21:02:40 -0500
commit50e244cc793d511b86adea24972f3a7264cae114 (patch)
treede59e5f228a256ad09521524639e1b5b6e49b8cc /drivers/video
parent84b603abd23300df8ee5fb1c23c83634c2aaedea (diff)
fb: rework locking to fix lock ordering on takeover
Adjust the console layer to allow a take over call where the caller already holds the locks. Make the fb layer lock in order. This is partly a band aid, the fb layer is terminally confused about the locking rules it uses for its notifiers it seems. [akpm@linux-foundation.org: remove stray non-ascii char, tidy comment] [akpm@linux-foundation.org: export do_take_over_console()] [airlied: cleanup another non-ascii char] Signed-off-by: Alan Cox <alan@linux.intel.com> Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de> Cc: Stephen Rothwell <sfr@canb.auug.org.au> Cc: Jiri Kosina <jkosina@suse.cz> Cc: stable <stable@vger.kernel.org> Tested-by: Sedat Dilek <sedat.dilek@gmail.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/console/fbcon.c29
-rw-r--r--drivers/video/fbmem.c5
-rw-r--r--drivers/video/fbsysfs.c3
3 files changed, 33 insertions, 4 deletions
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index fdefa8fd72c4..4bd7820cf4d0 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -529,6 +529,33 @@ static int search_for_mapped_con(void)
529 return retval; 529 return retval;
530} 530}
531 531
532static int do_fbcon_takeover(int show_logo)
533{
534 int err, i;
535
536 if (!num_registered_fb)
537 return -ENODEV;
538
539 if (!show_logo)
540 logo_shown = FBCON_LOGO_DONTSHOW;
541
542 for (i = first_fb_vc; i <= last_fb_vc; i++)
543 con2fb_map[i] = info_idx;
544
545 err = do_take_over_console(&fb_con, first_fb_vc, last_fb_vc,
546 fbcon_is_default);
547
548 if (err) {
549 for (i = first_fb_vc; i <= last_fb_vc; i++)
550 con2fb_map[i] = -1;
551 info_idx = -1;
552 } else {
553 fbcon_has_console_bind = 1;
554 }
555
556 return err;
557}
558
532static int fbcon_takeover(int show_logo) 559static int fbcon_takeover(int show_logo)
533{ 560{
534 int err, i; 561 int err, i;
@@ -3115,7 +3142,7 @@ static int fbcon_fb_registered(struct fb_info *info)
3115 } 3142 }
3116 3143
3117 if (info_idx != -1) 3144 if (info_idx != -1)
3118 ret = fbcon_takeover(1); 3145 ret = do_fbcon_takeover(1);
3119 } else { 3146 } else {
3120 for (i = first_fb_vc; i <= last_fb_vc; i++) { 3147 for (i = first_fb_vc; i <= last_fb_vc; i++) {
3121 if (con2fb_map_boot[i] == idx) 3148 if (con2fb_map_boot[i] == idx)
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 3ff0105a496a..d8d9831b3fdb 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1650,7 +1650,9 @@ static int do_register_framebuffer(struct fb_info *fb_info)
1650 event.info = fb_info; 1650 event.info = fb_info;
1651 if (!lock_fb_info(fb_info)) 1651 if (!lock_fb_info(fb_info))
1652 return -ENODEV; 1652 return -ENODEV;
1653 console_lock();
1653 fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event); 1654 fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event);
1655 console_unlock();
1654 unlock_fb_info(fb_info); 1656 unlock_fb_info(fb_info);
1655 return 0; 1657 return 0;
1656} 1658}
@@ -1853,11 +1855,8 @@ int fb_new_modelist(struct fb_info *info)
1853 err = 1; 1855 err = 1;
1854 1856
1855 if (!list_empty(&info->modelist)) { 1857 if (!list_empty(&info->modelist)) {
1856 if (!lock_fb_info(info))
1857 return -ENODEV;
1858 event.info = info; 1858 event.info = info;
1859 err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event); 1859 err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event);
1860 unlock_fb_info(info);
1861 } 1860 }
1862 1861
1863 return err; 1862 return err;
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index a55e3669d135..ef476b02fbe5 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -177,6 +177,8 @@ static ssize_t store_modes(struct device *device,
177 if (i * sizeof(struct fb_videomode) != count) 177 if (i * sizeof(struct fb_videomode) != count)
178 return -EINVAL; 178 return -EINVAL;
179 179
180 if (!lock_fb_info(fb_info))
181 return -ENODEV;
180 console_lock(); 182 console_lock();
181 list_splice(&fb_info->modelist, &old_list); 183 list_splice(&fb_info->modelist, &old_list);
182 fb_videomode_to_modelist((const struct fb_videomode *)buf, i, 184 fb_videomode_to_modelist((const struct fb_videomode *)buf, i,
@@ -188,6 +190,7 @@ static ssize_t store_modes(struct device *device,
188 fb_destroy_modelist(&old_list); 190 fb_destroy_modelist(&old_list);
189 191
190 console_unlock(); 192 console_unlock();
193 unlock_fb_info(fb_info);
191 194
192 return 0; 195 return 0;
193} 196}