aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai2013-01-24 18:28:18 -0600
committerGreg Kroah-Hartman2013-02-28 08:32:27 -0600
commit49a656f8337670ffc66f28235f371767f5d25f42 (patch)
tree7256282b8c67a54c3a0eee50201ae6824a09bf22
parentabd9120040d5f427b950561277f2846b0a80be44 (diff)
downloadkernel-common-49a656f8337670ffc66f28235f371767f5d25f42.tar.gz
kernel-common-49a656f8337670ffc66f28235f371767f5d25f42.tar.xz
kernel-common-49a656f8337670ffc66f28235f371767f5d25f42.zip
fb: Yet another band-aid for fixing lockdep mess
commit e93a9a868792ad71cdd09d75e5a02d8067473c4e upstream. I've still got lockdep warnings even after Alan's patch, and it seems that yet more band aids are required to paper over similar paths for unbind_con_driver() and unregister_con_driver(). After this hack, lockdep warnings are finally gone. Signed-off-by: Takashi Iwai <tiwai@suse.de> Cc: Alan Cox <alan@linux.intel.com> Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de> Cc: Jiri Kosina <jkosina@suse.cz> Tested-by: Sedat Dilek <sedat.dilek@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Dave Airlie <airlied@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/vt/vt.c43
-rw-r--r--drivers/video/console/fbcon.c4
-rw-r--r--drivers/video/fbmem.c4
-rw-r--r--include/linux/console.h1
-rw-r--r--include/linux/vt_kern.h2
5 files changed, 37 insertions, 17 deletions
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index eb80f01dcbd..e41288a0003 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -3164,6 +3164,18 @@ static int con_is_graphics(const struct consw *csw, int first, int last)
3164 */ 3164 */
3165int unbind_con_driver(const struct consw *csw, int first, int last, int deflt) 3165int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3166{ 3166{
3167 int retval;
3168
3169 console_lock();
3170 retval = do_unbind_con_driver(csw, first, last, deflt);
3171 console_unlock();
3172 return retval;
3173}
3174EXPORT_SYMBOL(unbind_con_driver);
3175
3176/* unlocked version of unbind_con_driver() */
3177int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3178{
3167 struct module *owner = csw->owner; 3179 struct module *owner = csw->owner;
3168 const struct consw *defcsw = NULL; 3180 const struct consw *defcsw = NULL;
3169 struct con_driver *con_driver = NULL, *con_back = NULL; 3181 struct con_driver *con_driver = NULL, *con_back = NULL;
@@ -3172,7 +3184,7 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3172 if (!try_module_get(owner)) 3184 if (!try_module_get(owner))
3173 return -ENODEV; 3185 return -ENODEV;
3174 3186
3175 console_lock(); 3187 WARN_CONSOLE_UNLOCKED();
3176 3188
3177 /* check if driver is registered and if it is unbindable */ 3189 /* check if driver is registered and if it is unbindable */
3178 for (i = 0; i < MAX_NR_CON_DRIVER; i++) { 3190 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
@@ -3185,10 +3197,8 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3185 } 3197 }
3186 } 3198 }
3187 3199
3188 if (retval) { 3200 if (retval)
3189 console_unlock();
3190 goto err; 3201 goto err;
3191 }
3192 3202
3193 retval = -ENODEV; 3203 retval = -ENODEV;
3194 3204
@@ -3204,15 +3214,11 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3204 } 3214 }
3205 } 3215 }
3206 3216
3207 if (retval) { 3217 if (retval)
3208 console_unlock();
3209 goto err; 3218 goto err;
3210 }
3211 3219
3212 if (!con_is_bound(csw)) { 3220 if (!con_is_bound(csw))
3213 console_unlock();
3214 goto err; 3221 goto err;
3215 }
3216 3222
3217 first = max(first, con_driver->first); 3223 first = max(first, con_driver->first);
3218 last = min(last, con_driver->last); 3224 last = min(last, con_driver->last);
@@ -3241,13 +3247,12 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3241 3247
3242 /* ignore return value, binding should not fail */ 3248 /* ignore return value, binding should not fail */
3243 do_bind_con_driver(defcsw, first, last, deflt); 3249 do_bind_con_driver(defcsw, first, last, deflt);
3244 console_unlock();
3245err: 3250err:
3246 module_put(owner); 3251 module_put(owner);
3247 return retval; 3252 return retval;
3248 3253
3249} 3254}
3250EXPORT_SYMBOL(unbind_con_driver); 3255EXPORT_SYMBOL_GPL(do_unbind_con_driver);
3251 3256
3252static int vt_bind(struct con_driver *con) 3257static int vt_bind(struct con_driver *con)
3253{ 3258{
@@ -3621,9 +3626,18 @@ EXPORT_SYMBOL(register_con_driver);
3621 */ 3626 */
3622int unregister_con_driver(const struct consw *csw) 3627int unregister_con_driver(const struct consw *csw)
3623{ 3628{
3624 int i, retval = -ENODEV; 3629 int retval;
3625 3630
3626 console_lock(); 3631 console_lock();
3632 retval = do_unregister_con_driver(csw);
3633 console_unlock();
3634 return retval;
3635}
3636EXPORT_SYMBOL(unregister_con_driver);
3637
3638int do_unregister_con_driver(const struct consw *csw)
3639{
3640 int i, retval = -ENODEV;
3627 3641
3628 /* cannot unregister a bound driver */ 3642 /* cannot unregister a bound driver */
3629 if (con_is_bound(csw)) 3643 if (con_is_bound(csw))
@@ -3649,10 +3663,9 @@ int unregister_con_driver(const struct consw *csw)
3649 } 3663 }
3650 } 3664 }
3651err: 3665err:
3652 console_unlock();
3653 return retval; 3666 return retval;
3654} 3667}
3655EXPORT_SYMBOL(unregister_con_driver); 3668EXPORT_SYMBOL_GPL(do_unregister_con_driver);
3656 3669
3657/* 3670/*
3658 * If we support more console drivers, this function is used 3671 * If we support more console drivers, this function is used
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 18d02c6af70..9b8bcab0ae3 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -3011,7 +3011,7 @@ static int fbcon_unbind(void)
3011{ 3011{
3012 int ret; 3012 int ret;
3013 3013
3014 ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc, 3014 ret = do_unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc,
3015 fbcon_is_default); 3015 fbcon_is_default);
3016 3016
3017 if (!ret) 3017 if (!ret)
@@ -3084,7 +3084,7 @@ static int fbcon_fb_unregistered(struct fb_info *info)
3084 primary_device = -1; 3084 primary_device = -1;
3085 3085
3086 if (!num_registered_fb) 3086 if (!num_registered_fb)
3087 unregister_con_driver(&fb_con); 3087 do_unregister_con_driver(&fb_con);
3088 3088
3089 return 0; 3089 return 0;
3090} 3090}
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index a94edc3f58b..c133dde79cd 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1646,8 +1646,10 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
1646 1646
1647 if (!lock_fb_info(fb_info)) 1647 if (!lock_fb_info(fb_info))
1648 return -ENODEV; 1648 return -ENODEV;
1649 console_lock();
1649 event.info = fb_info; 1650 event.info = fb_info;
1650 ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event); 1651 ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event);
1652 console_unlock();
1651 unlock_fb_info(fb_info); 1653 unlock_fb_info(fb_info);
1652 1654
1653 if (ret) 1655 if (ret)
@@ -1662,7 +1664,9 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
1662 num_registered_fb--; 1664 num_registered_fb--;
1663 fb_cleanup_device(fb_info); 1665 fb_cleanup_device(fb_info);
1664 event.info = fb_info; 1666 event.info = fb_info;
1667 console_lock();
1665 fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); 1668 fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
1669 console_unlock();
1666 1670
1667 /* this may free fb info */ 1671 /* this may free fb info */
1668 put_fb_info(fb_info); 1672 put_fb_info(fb_info);
diff --git a/include/linux/console.h b/include/linux/console.h
index 49b1061f3a0..6ae6a15eb95 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -77,6 +77,7 @@ extern const struct consw prom_con; /* SPARC PROM console */
77int con_is_bound(const struct consw *csw); 77int con_is_bound(const struct consw *csw);
78int register_con_driver(const struct consw *csw, int first, int last); 78int register_con_driver(const struct consw *csw, int first, int last);
79int unregister_con_driver(const struct consw *csw); 79int unregister_con_driver(const struct consw *csw);
80int do_unregister_con_driver(const struct consw *csw);
80int take_over_console(const struct consw *sw, int first, int last, int deflt); 81int take_over_console(const struct consw *sw, int first, int last, int deflt);
81int do_take_over_console(const struct consw *sw, int first, int last, int deflt); 82int do_take_over_console(const struct consw *sw, int first, int last, int deflt);
82void give_up_console(const struct consw *sw); 83void give_up_console(const struct consw *sw);
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index 4d05e14ea60..90538b47072 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -131,6 +131,8 @@ void vt_event_post(unsigned int event, unsigned int old, unsigned int new);
131int vt_waitactive(int n); 131int vt_waitactive(int n);
132void change_console(struct vc_data *new_vc); 132void change_console(struct vc_data *new_vc);
133void reset_vc(struct vc_data *vc); 133void reset_vc(struct vc_data *vc);
134extern int do_unbind_con_driver(const struct consw *csw, int first, int last,
135 int deflt);
134extern int unbind_con_driver(const struct consw *csw, int first, int last, 136extern int unbind_con_driver(const struct consw *csw, int first, int last,
135 int deflt); 137 int deflt);
136int vty_init(const struct file_operations *console_fops); 138int vty_init(const struct file_operations *console_fops);