aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-01-24 19:28:18 -0500
committerDave Airlie <airlied@redhat.com>2013-02-07 21:02:41 -0500
commite93a9a868792ad71cdd09d75e5a02d8067473c4e (patch)
treed2affabcd5a7e48a77ca148c9dc9be4f23de9936
parent50e244cc793d511b86adea24972f3a7264cae114 (diff)
fb: Yet another band-aid for fixing lockdep mess
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> Cc: stable <stable@vger.kernel.org> 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>
-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 c076af0b300b..457c41fe7eb9 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -3135,6 +3135,18 @@ static int con_is_graphics(const struct consw *csw, int first, int last)
3135 */ 3135 */
3136int unbind_con_driver(const struct consw *csw, int first, int last, int deflt) 3136int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3137{ 3137{
3138 int retval;
3139
3140 console_lock();
3141 retval = do_unbind_con_driver(csw, first, last, deflt);
3142 console_unlock();
3143 return retval;
3144}
3145EXPORT_SYMBOL(unbind_con_driver);
3146
3147/* unlocked version of unbind_con_driver() */
3148int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3149{
3138 struct module *owner = csw->owner; 3150 struct module *owner = csw->owner;
3139 const struct consw *defcsw = NULL; 3151 const struct consw *defcsw = NULL;
3140 struct con_driver *con_driver = NULL, *con_back = NULL; 3152 struct con_driver *con_driver = NULL, *con_back = NULL;
@@ -3143,7 +3155,7 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3143 if (!try_module_get(owner)) 3155 if (!try_module_get(owner))
3144 return -ENODEV; 3156 return -ENODEV;
3145 3157
3146 console_lock(); 3158 WARN_CONSOLE_UNLOCKED();
3147 3159
3148 /* check if driver is registered and if it is unbindable */ 3160 /* check if driver is registered and if it is unbindable */
3149 for (i = 0; i < MAX_NR_CON_DRIVER; i++) { 3161 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
@@ -3156,10 +3168,8 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3156 } 3168 }
3157 } 3169 }
3158 3170
3159 if (retval) { 3171 if (retval)
3160 console_unlock();
3161 goto err; 3172 goto err;
3162 }
3163 3173
3164 retval = -ENODEV; 3174 retval = -ENODEV;
3165 3175
@@ -3175,15 +3185,11 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3175 } 3185 }
3176 } 3186 }
3177 3187
3178 if (retval) { 3188 if (retval)
3179 console_unlock();
3180 goto err; 3189 goto err;
3181 }
3182 3190
3183 if (!con_is_bound(csw)) { 3191 if (!con_is_bound(csw))
3184 console_unlock();
3185 goto err; 3192 goto err;
3186 }
3187 3193
3188 first = max(first, con_driver->first); 3194 first = max(first, con_driver->first);
3189 last = min(last, con_driver->last); 3195 last = min(last, con_driver->last);
@@ -3212,13 +3218,12 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3212 3218
3213 /* ignore return value, binding should not fail */ 3219 /* ignore return value, binding should not fail */
3214 do_bind_con_driver(defcsw, first, last, deflt); 3220 do_bind_con_driver(defcsw, first, last, deflt);
3215 console_unlock();
3216err: 3221err:
3217 module_put(owner); 3222 module_put(owner);
3218 return retval; 3223 return retval;
3219 3224
3220} 3225}
3221EXPORT_SYMBOL(unbind_con_driver); 3226EXPORT_SYMBOL_GPL(do_unbind_con_driver);
3222 3227
3223static int vt_bind(struct con_driver *con) 3228static int vt_bind(struct con_driver *con)
3224{ 3229{
@@ -3605,9 +3610,18 @@ EXPORT_SYMBOL(register_con_driver);
3605 */ 3610 */
3606int unregister_con_driver(const struct consw *csw) 3611int unregister_con_driver(const struct consw *csw)
3607{ 3612{
3608 int i, retval = -ENODEV; 3613 int retval;
3609 3614
3610 console_lock(); 3615 console_lock();
3616 retval = do_unregister_con_driver(csw);
3617 console_unlock();
3618 return retval;
3619}
3620EXPORT_SYMBOL(unregister_con_driver);
3621
3622int do_unregister_con_driver(const struct consw *csw)
3623{
3624 int i, retval = -ENODEV;
3611 3625
3612 /* cannot unregister a bound driver */ 3626 /* cannot unregister a bound driver */
3613 if (con_is_bound(csw)) 3627 if (con_is_bound(csw))
@@ -3633,10 +3647,9 @@ int unregister_con_driver(const struct consw *csw)
3633 } 3647 }
3634 } 3648 }
3635err: 3649err:
3636 console_unlock();
3637 return retval; 3650 return retval;
3638} 3651}
3639EXPORT_SYMBOL(unregister_con_driver); 3652EXPORT_SYMBOL_GPL(do_unregister_con_driver);
3640 3653
3641/* 3654/*
3642 * If we support more console drivers, this function is used 3655 * 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 4bd7820cf4d0..2aef9cac4d18 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -3004,7 +3004,7 @@ static int fbcon_unbind(void)
3004{ 3004{
3005 int ret; 3005 int ret;
3006 3006
3007 ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc, 3007 ret = do_unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc,
3008 fbcon_is_default); 3008 fbcon_is_default);
3009 3009
3010 if (!ret) 3010 if (!ret)
@@ -3077,7 +3077,7 @@ static int fbcon_fb_unregistered(struct fb_info *info)
3077 primary_device = -1; 3077 primary_device = -1;
3078 3078
3079 if (!num_registered_fb) 3079 if (!num_registered_fb)
3080 unregister_con_driver(&fb_con); 3080 do_unregister_con_driver(&fb_con);
3081 3081
3082 return 0; 3082 return 0;
3083} 3083}
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index d8d9831b3fdb..070b9a13d892 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1668,8 +1668,10 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
1668 1668
1669 if (!lock_fb_info(fb_info)) 1669 if (!lock_fb_info(fb_info))
1670 return -ENODEV; 1670 return -ENODEV;
1671 console_lock();
1671 event.info = fb_info; 1672 event.info = fb_info;
1672 ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event); 1673 ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event);
1674 console_unlock();
1673 unlock_fb_info(fb_info); 1675 unlock_fb_info(fb_info);
1674 1676
1675 if (ret) 1677 if (ret)
@@ -1684,7 +1686,9 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
1684 num_registered_fb--; 1686 num_registered_fb--;
1685 fb_cleanup_device(fb_info); 1687 fb_cleanup_device(fb_info);
1686 event.info = fb_info; 1688 event.info = fb_info;
1689 console_lock();
1687 fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); 1690 fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
1691 console_unlock();
1688 1692
1689 /* this may free fb info */ 1693 /* this may free fb info */
1690 put_fb_info(fb_info); 1694 put_fb_info(fb_info);
diff --git a/include/linux/console.h b/include/linux/console.h
index 4ef4307dfb82..47b858cffc47 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 50ae7d0c279e..dbbc6bfee71f 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -130,6 +130,8 @@ void vt_event_post(unsigned int event, unsigned int old, unsigned int new);
130int vt_waitactive(int n); 130int vt_waitactive(int n);
131void change_console(struct vc_data *new_vc); 131void change_console(struct vc_data *new_vc);
132void reset_vc(struct vc_data *vc); 132void reset_vc(struct vc_data *vc);
133extern int do_unbind_con_driver(const struct consw *csw, int first, int last,
134 int deflt);
133extern int unbind_con_driver(const struct consw *csw, int first, int last, 135extern int unbind_con_driver(const struct consw *csw, int first, int last,
134 int deflt); 136 int deflt);
135int vty_init(const struct file_operations *console_fops); 137int vty_init(const struct file_operations *console_fops);