aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/vt/vt.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2013-02-07 21:10:18 -0500
committerDave Airlie <airlied@redhat.com>2013-02-07 21:10:18 -0500
commit6dc1c49da6dd3bf020a66b2a135b9625ac01c2c7 (patch)
tree38a6c5d4896de01449e9d224088ae223161fcd3c /drivers/tty/vt/vt.c
parentcd17ef4114ad5c514b17e6a0bb02a309ab90b692 (diff)
parent5845b81bdad374f98f809a658ec747d92c9595c4 (diff)
Merge branch 'fbcon-locking-fixes' of ssh://people.freedesktop.org/~airlied/linux into drm-next
This pulls in most of Linus tree up to -rc6, this fixes the worst lockdep reported issues and re-enables fbcon lockdep. (not the fbcon maintainer) * 'fbcon-locking-fixes' of ssh://people.freedesktop.org/~airlied/linux: (529 commits) Revert "Revert "console: implement lockdep support for console_lock"" fbcon: fix locking harder fb: Yet another band-aid for fixing lockdep mess fb: rework locking to fix lock ordering on takeover
Diffstat (limited to 'drivers/tty/vt/vt.c')
-rw-r--r--drivers/tty/vt/vt.c134
1 files changed, 97 insertions, 37 deletions
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 8fd89687d068..457c41fe7eb9 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2987,7 +2987,7 @@ int __init vty_init(const struct file_operations *console_fops)
2987 2987
2988static struct class *vtconsole_class; 2988static struct class *vtconsole_class;
2989 2989
2990static int bind_con_driver(const struct consw *csw, int first, int last, 2990static int do_bind_con_driver(const struct consw *csw, int first, int last,
2991 int deflt) 2991 int deflt)
2992{ 2992{
2993 struct module *owner = csw->owner; 2993 struct module *owner = csw->owner;
@@ -2998,7 +2998,7 @@ static int bind_con_driver(const struct consw *csw, int first, int last,
2998 if (!try_module_get(owner)) 2998 if (!try_module_get(owner))
2999 return -ENODEV; 2999 return -ENODEV;
3000 3000
3001 console_lock(); 3001 WARN_CONSOLE_UNLOCKED();
3002 3002
3003 /* check if driver is registered */ 3003 /* check if driver is registered */
3004 for (i = 0; i < MAX_NR_CON_DRIVER; i++) { 3004 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
@@ -3083,11 +3083,22 @@ static int bind_con_driver(const struct consw *csw, int first, int last,
3083 3083
3084 retval = 0; 3084 retval = 0;
3085err: 3085err:
3086 console_unlock();
3087 module_put(owner); 3086 module_put(owner);
3088 return retval; 3087 return retval;
3089}; 3088};
3090 3089
3090
3091static int bind_con_driver(const struct consw *csw, int first, int last,
3092 int deflt)
3093{
3094 int ret;
3095
3096 console_lock();
3097 ret = do_bind_con_driver(csw, first, last, deflt);
3098 console_unlock();
3099 return ret;
3100}
3101
3091#ifdef CONFIG_VT_HW_CONSOLE_BINDING 3102#ifdef CONFIG_VT_HW_CONSOLE_BINDING
3092static int con_is_graphics(const struct consw *csw, int first, int last) 3103static int con_is_graphics(const struct consw *csw, int first, int last)
3093{ 3104{
@@ -3124,6 +3135,18 @@ static int con_is_graphics(const struct consw *csw, int first, int last)
3124 */ 3135 */
3125int 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)
3126{ 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{
3127 struct module *owner = csw->owner; 3150 struct module *owner = csw->owner;
3128 const struct consw *defcsw = NULL; 3151 const struct consw *defcsw = NULL;
3129 struct con_driver *con_driver = NULL, *con_back = NULL; 3152 struct con_driver *con_driver = NULL, *con_back = NULL;
@@ -3132,7 +3155,7 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3132 if (!try_module_get(owner)) 3155 if (!try_module_get(owner))
3133 return -ENODEV; 3156 return -ENODEV;
3134 3157
3135 console_lock(); 3158 WARN_CONSOLE_UNLOCKED();
3136 3159
3137 /* check if driver is registered and if it is unbindable */ 3160 /* check if driver is registered and if it is unbindable */
3138 for (i = 0; i < MAX_NR_CON_DRIVER; i++) { 3161 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
@@ -3145,10 +3168,8 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3145 } 3168 }
3146 } 3169 }
3147 3170
3148 if (retval) { 3171 if (retval)
3149 console_unlock();
3150 goto err; 3172 goto err;
3151 }
3152 3173
3153 retval = -ENODEV; 3174 retval = -ENODEV;
3154 3175
@@ -3164,15 +3185,11 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3164 } 3185 }
3165 } 3186 }
3166 3187
3167 if (retval) { 3188 if (retval)
3168 console_unlock();
3169 goto err; 3189 goto err;
3170 }
3171 3190
3172 if (!con_is_bound(csw)) { 3191 if (!con_is_bound(csw))
3173 console_unlock();
3174 goto err; 3192 goto err;
3175 }
3176 3193
3177 first = max(first, con_driver->first); 3194 first = max(first, con_driver->first);
3178 last = min(last, con_driver->last); 3195 last = min(last, con_driver->last);
@@ -3199,15 +3216,14 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3199 if (!con_is_bound(csw)) 3216 if (!con_is_bound(csw))
3200 con_driver->flag &= ~CON_DRIVER_FLAG_INIT; 3217 con_driver->flag &= ~CON_DRIVER_FLAG_INIT;
3201 3218
3202 console_unlock();
3203 /* ignore return value, binding should not fail */ 3219 /* ignore return value, binding should not fail */
3204 bind_con_driver(defcsw, first, last, deflt); 3220 do_bind_con_driver(defcsw, first, last, deflt);
3205err: 3221err:
3206 module_put(owner); 3222 module_put(owner);
3207 return retval; 3223 return retval;
3208 3224
3209} 3225}
3210EXPORT_SYMBOL(unbind_con_driver); 3226EXPORT_SYMBOL_GPL(do_unbind_con_driver);
3211 3227
3212static int vt_bind(struct con_driver *con) 3228static int vt_bind(struct con_driver *con)
3213{ 3229{
@@ -3492,28 +3508,18 @@ int con_debug_leave(void)
3492} 3508}
3493EXPORT_SYMBOL_GPL(con_debug_leave); 3509EXPORT_SYMBOL_GPL(con_debug_leave);
3494 3510
3495/** 3511static int do_register_con_driver(const struct consw *csw, int first, int last)
3496 * register_con_driver - register console driver to console layer
3497 * @csw: console driver
3498 * @first: the first console to take over, minimum value is 0
3499 * @last: the last console to take over, maximum value is MAX_NR_CONSOLES -1
3500 *
3501 * DESCRIPTION: This function registers a console driver which can later
3502 * bind to a range of consoles specified by @first and @last. It will
3503 * also initialize the console driver by calling con_startup().
3504 */
3505int register_con_driver(const struct consw *csw, int first, int last)
3506{ 3512{
3507 struct module *owner = csw->owner; 3513 struct module *owner = csw->owner;
3508 struct con_driver *con_driver; 3514 struct con_driver *con_driver;
3509 const char *desc; 3515 const char *desc;
3510 int i, retval = 0; 3516 int i, retval = 0;
3511 3517
3518 WARN_CONSOLE_UNLOCKED();
3519
3512 if (!try_module_get(owner)) 3520 if (!try_module_get(owner))
3513 return -ENODEV; 3521 return -ENODEV;
3514 3522
3515 console_lock();
3516
3517 for (i = 0; i < MAX_NR_CON_DRIVER; i++) { 3523 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3518 con_driver = &registered_con_driver[i]; 3524 con_driver = &registered_con_driver[i];
3519 3525
@@ -3566,10 +3572,29 @@ int register_con_driver(const struct consw *csw, int first, int last)
3566 } 3572 }
3567 3573
3568err: 3574err:
3569 console_unlock();
3570 module_put(owner); 3575 module_put(owner);
3571 return retval; 3576 return retval;
3572} 3577}
3578
3579/**
3580 * register_con_driver - register console driver to console layer
3581 * @csw: console driver
3582 * @first: the first console to take over, minimum value is 0
3583 * @last: the last console to take over, maximum value is MAX_NR_CONSOLES -1
3584 *
3585 * DESCRIPTION: This function registers a console driver which can later
3586 * bind to a range of consoles specified by @first and @last. It will
3587 * also initialize the console driver by calling con_startup().
3588 */
3589int register_con_driver(const struct consw *csw, int first, int last)
3590{
3591 int retval;
3592
3593 console_lock();
3594 retval = do_register_con_driver(csw, first, last);
3595 console_unlock();
3596 return retval;
3597}
3573EXPORT_SYMBOL(register_con_driver); 3598EXPORT_SYMBOL(register_con_driver);
3574 3599
3575/** 3600/**
@@ -3585,9 +3610,18 @@ EXPORT_SYMBOL(register_con_driver);
3585 */ 3610 */
3586int unregister_con_driver(const struct consw *csw) 3611int unregister_con_driver(const struct consw *csw)
3587{ 3612{
3588 int i, retval = -ENODEV; 3613 int retval;
3589 3614
3590 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;
3591 3625
3592 /* cannot unregister a bound driver */ 3626 /* cannot unregister a bound driver */
3593 if (con_is_bound(csw)) 3627 if (con_is_bound(csw))
@@ -3613,27 +3647,53 @@ int unregister_con_driver(const struct consw *csw)
3613 } 3647 }
3614 } 3648 }
3615err: 3649err:
3616 console_unlock();
3617 return retval; 3650 return retval;
3618} 3651}
3619EXPORT_SYMBOL(unregister_con_driver); 3652EXPORT_SYMBOL_GPL(do_unregister_con_driver);
3620 3653
3621/* 3654/*
3622 * If we support more console drivers, this function is used 3655 * If we support more console drivers, this function is used
3623 * when a driver wants to take over some existing consoles 3656 * when a driver wants to take over some existing consoles
3624 * and become default driver for newly opened ones. 3657 * and become default driver for newly opened ones.
3625 * 3658 *
3626 * take_over_console is basically a register followed by unbind 3659 * take_over_console is basically a register followed by unbind
3660 */
3661int do_take_over_console(const struct consw *csw, int first, int last, int deflt)
3662{
3663 int err;
3664
3665 err = do_register_con_driver(csw, first, last);
3666 /*
3667 * If we get an busy error we still want to bind the console driver
3668 * and return success, as we may have unbound the console driver
3669 * but not unregistered it.
3670 */
3671 if (err == -EBUSY)
3672 err = 0;
3673 if (!err)
3674 do_bind_con_driver(csw, first, last, deflt);
3675
3676 return err;
3677}
3678EXPORT_SYMBOL_GPL(do_take_over_console);
3679
3680/*
3681 * If we support more console drivers, this function is used
3682 * when a driver wants to take over some existing consoles
3683 * and become default driver for newly opened ones.
3684 *
3685 * take_over_console is basically a register followed by unbind
3627 */ 3686 */
3628int take_over_console(const struct consw *csw, int first, int last, int deflt) 3687int take_over_console(const struct consw *csw, int first, int last, int deflt)
3629{ 3688{
3630 int err; 3689 int err;
3631 3690
3632 err = register_con_driver(csw, first, last); 3691 err = register_con_driver(csw, first, last);
3633 /* if we get an busy error we still want to bind the console driver 3692 /*
3693 * If we get an busy error we still want to bind the console driver
3634 * and return success, as we may have unbound the console driver 3694 * and return success, as we may have unbound the console driver
3635  * but not unregistered it. 3695 * but not unregistered it.
3636 */ 3696 */
3637 if (err == -EBUSY) 3697 if (err == -EBUSY)
3638 err = 0; 3698 err = 0;
3639 if (!err) 3699 if (!err)