summaryrefslogtreecommitdiff
path: root/drivers/tty
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2014-06-05 18:29:56 +0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-06-07 00:19:32 +0400
commitd9c660e750fdf982e1e2bdd0e76c1e6c4db4217b (patch)
tree60a016b9ecc5964759a22f8967b75c872e36d06d /drivers/tty
parent249f7b3e1383d6889889927351b7b018532d2ca1 (diff)
downloadlinux-d9c660e750fdf982e1e2bdd0e76c1e6c4db4217b.tar.xz
vt: Fix up unregistration of vt drivers
A bunch of issues: - We should not kick out the default console (which is tracked in conswitchp), so check for that. - Add better error codes so callers can differentiate between "something went wrong" and "your driver isn't registered already". i915 needs that so it doesn't fall over when reloading the driver and hence vga_con is already unregistered. - There's a mess with the driver flags: What we need to check for is that the driver isn't used any more, i.e. unbound completely (FLAG_INIT). And not whether it's the boot console or not (which is the only one which doesn't have FLAG_MODULE). Otherwise there's no way to kick out the boot console, which i915 wants to do to prevent havoc with vga_con interferring (which tends to hang machines). Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Jiri Slaby <jslaby@suse.cz> Reviewed-by: David Herrmann <dh.herrmann@gmail.com> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/vt/vt.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index ea600f482eeb..5077fe87324d 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -3573,17 +3573,20 @@ err:
*/
int do_unregister_con_driver(const struct consw *csw)
{
- int i, retval = -ENODEV;
+ int i;
/* cannot unregister a bound driver */
if (con_is_bound(csw))
- goto err;
+ return -EBUSY;
+
+ if (csw == conswitchp)
+ return -EINVAL;
for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
struct con_driver *con_driver = &registered_con_driver[i];
if (con_driver->con == csw &&
- con_driver->flag & CON_DRIVER_FLAG_MODULE) {
+ con_driver->flag & CON_DRIVER_FLAG_INIT) {
vtconsole_deinit_device(con_driver);
device_destroy(vtconsole_class,
MKDEV(0, con_driver->node));
@@ -3594,12 +3597,11 @@ int do_unregister_con_driver(const struct consw *csw)
con_driver->flag = 0;
con_driver->first = 0;
con_driver->last = 0;
- retval = 0;
- break;
+ return 0;
}
}
-err:
- return retval;
+
+ return -ENODEV;
}
EXPORT_SYMBOL_GPL(do_unregister_con_driver);