diff options
-rw-r--r-- | drivers/tty/vt/vt.c | 43 | ||||
-rw-r--r-- | drivers/video/console/fbcon.c | 4 | ||||
-rw-r--r-- | drivers/video/fbmem.c | 4 | ||||
-rw-r--r-- | include/linux/console.h | 1 | ||||
-rw-r--r-- | include/linux/vt_kern.h | 2 |
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 | */ |
3136 | int unbind_con_driver(const struct consw *csw, int first, int last, int deflt) | 3136 | int 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 | } | ||
3145 | EXPORT_SYMBOL(unbind_con_driver); | ||
3146 | |||
3147 | /* unlocked version of unbind_con_driver() */ | ||
3148 | int 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(); | ||
3216 | err: | 3221 | err: |
3217 | module_put(owner); | 3222 | module_put(owner); |
3218 | return retval; | 3223 | return retval; |
3219 | 3224 | ||
3220 | } | 3225 | } |
3221 | EXPORT_SYMBOL(unbind_con_driver); | 3226 | EXPORT_SYMBOL_GPL(do_unbind_con_driver); |
3222 | 3227 | ||
3223 | static int vt_bind(struct con_driver *con) | 3228 | static int vt_bind(struct con_driver *con) |
3224 | { | 3229 | { |
@@ -3605,9 +3610,18 @@ EXPORT_SYMBOL(register_con_driver); | |||
3605 | */ | 3610 | */ |
3606 | int unregister_con_driver(const struct consw *csw) | 3611 | int 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 | } | ||
3620 | EXPORT_SYMBOL(unregister_con_driver); | ||
3621 | |||
3622 | int 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 | } |
3635 | err: | 3649 | err: |
3636 | console_unlock(); | ||
3637 | return retval; | 3650 | return retval; |
3638 | } | 3651 | } |
3639 | EXPORT_SYMBOL(unregister_con_driver); | 3652 | EXPORT_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 */ | |||
77 | int con_is_bound(const struct consw *csw); | 77 | int con_is_bound(const struct consw *csw); |
78 | int register_con_driver(const struct consw *csw, int first, int last); | 78 | int register_con_driver(const struct consw *csw, int first, int last); |
79 | int unregister_con_driver(const struct consw *csw); | 79 | int unregister_con_driver(const struct consw *csw); |
80 | int do_unregister_con_driver(const struct consw *csw); | ||
80 | int take_over_console(const struct consw *sw, int first, int last, int deflt); | 81 | int take_over_console(const struct consw *sw, int first, int last, int deflt); |
81 | int do_take_over_console(const struct consw *sw, int first, int last, int deflt); | 82 | int do_take_over_console(const struct consw *sw, int first, int last, int deflt); |
82 | void give_up_console(const struct consw *sw); | 83 | void 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); | |||
130 | int vt_waitactive(int n); | 130 | int vt_waitactive(int n); |
131 | void change_console(struct vc_data *new_vc); | 131 | void change_console(struct vc_data *new_vc); |
132 | void reset_vc(struct vc_data *vc); | 132 | void reset_vc(struct vc_data *vc); |
133 | extern int do_unbind_con_driver(const struct consw *csw, int first, int last, | ||
134 | int deflt); | ||
133 | extern int unbind_con_driver(const struct consw *csw, int first, int last, | 135 | extern int unbind_con_driver(const struct consw *csw, int first, int last, |
134 | int deflt); | 136 | int deflt); |
135 | int vty_init(const struct file_operations *console_fops); | 137 | int vty_init(const struct file_operations *console_fops); |