aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-tty19
-rw-r--r--drivers/tty/tty_io.c47
-rw-r--r--drivers/tty/vt/vt.c23
-rw-r--r--include/linux/console.h2
-rw-r--r--kernel/printk.c2
5 files changed, 87 insertions, 6 deletions
diff --git a/Documentation/ABI/testing/sysfs-tty b/Documentation/ABI/testing/sysfs-tty
new file mode 100644
index 000000000000..b138b663bf54
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-tty
@@ -0,0 +1,19 @@
1What: /sys/class/tty/console/active
2Date: Nov 2010
3Contact: Kay Sievers <kay.sievers@vrfy.org>
4Description:
5 Shows the list of currently configured
6 console devices, like 'tty1 ttyS0'.
7 The last entry in the file is the active
8 device connected to /dev/console.
9 The file supports poll() to detect virtual
10 console switches.
11
12What: /sys/class/tty/tty0/active
13Date: Nov 2010
14Contact: Kay Sievers <kay.sievers@vrfy.org>
15Description:
16 Shows the currently active virtual console
17 device, like 'tty1'.
18 The file supports poll() to detect virtual
19 console switches.
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index c05c5af5aa04..be5ab4ac0b93 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -3232,9 +3232,45 @@ static int __init tty_class_init(void)
3232postcore_initcall(tty_class_init); 3232postcore_initcall(tty_class_init);
3233 3233
3234/* 3/2004 jmc: why do these devices exist? */ 3234/* 3/2004 jmc: why do these devices exist? */
3235
3236static struct cdev tty_cdev, console_cdev; 3235static struct cdev tty_cdev, console_cdev;
3237 3236
3237static ssize_t show_cons_active(struct device *dev,
3238 struct device_attribute *attr, char *buf)
3239{
3240 struct console *cs[16];
3241 int i = 0;
3242 struct console *c;
3243 ssize_t count = 0;
3244
3245 acquire_console_sem();
3246 for (c = console_drivers; c; c = c->next) {
3247 if (!c->device)
3248 continue;
3249 if (!c->write)
3250 continue;
3251 if ((c->flags & CON_ENABLED) == 0)
3252 continue;
3253 cs[i++] = c;
3254 if (i >= ARRAY_SIZE(cs))
3255 break;
3256 }
3257 while (i--)
3258 count += sprintf(buf + count, "%s%d%c",
3259 cs[i]->name, cs[i]->index, i ? ' ':'\n');
3260 release_console_sem();
3261
3262 return count;
3263}
3264static DEVICE_ATTR(active, S_IRUGO, show_cons_active, NULL);
3265
3266static struct device *consdev;
3267
3268void console_sysfs_notify(void)
3269{
3270 if (consdev)
3271 sysfs_notify(&consdev->kobj, NULL, "active");
3272}
3273
3238/* 3274/*
3239 * Ok, now we can initialize the rest of the tty devices and can count 3275 * Ok, now we can initialize the rest of the tty devices and can count
3240 * on memory allocations, interrupts etc.. 3276 * on memory allocations, interrupts etc..
@@ -3245,15 +3281,18 @@ int __init tty_init(void)
3245 if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || 3281 if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||
3246 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) 3282 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
3247 panic("Couldn't register /dev/tty driver\n"); 3283 panic("Couldn't register /dev/tty driver\n");
3248 device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, 3284 device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty");
3249 "tty");
3250 3285
3251 cdev_init(&console_cdev, &console_fops); 3286 cdev_init(&console_cdev, &console_fops);
3252 if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || 3287 if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
3253 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) 3288 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
3254 panic("Couldn't register /dev/console driver\n"); 3289 panic("Couldn't register /dev/console driver\n");
3255 device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, 3290 consdev = device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL,
3256 "console"); 3291 "console");
3292 if (IS_ERR(consdev))
3293 consdev = NULL;
3294 else
3295 device_create_file(consdev, &dev_attr_active);
3257 3296
3258#ifdef CONFIG_VT 3297#ifdef CONFIG_VT
3259 vty_init(&console_fops); 3298 vty_init(&console_fops);
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index a8ec48ed14d9..76407eca9ab0 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -236,6 +236,14 @@ enum {
236}; 236};
237 237
238/* 238/*
239 * /sys/class/tty/tty0/
240 *
241 * the attribute 'active' contains the name of the current vc
242 * console and it supports poll() to detect vc switches
243 */
244static struct device *tty0dev;
245
246/*
239 * Notifier list for console events. 247 * Notifier list for console events.
240 */ 248 */
241static ATOMIC_NOTIFIER_HEAD(vt_notifier_list); 249static ATOMIC_NOTIFIER_HEAD(vt_notifier_list);
@@ -688,6 +696,8 @@ void redraw_screen(struct vc_data *vc, int is_switch)
688 save_screen(old_vc); 696 save_screen(old_vc);
689 set_origin(old_vc); 697 set_origin(old_vc);
690 } 698 }
699 if (tty0dev)
700 sysfs_notify(&tty0dev->kobj, NULL, "active");
691 } else { 701 } else {
692 hide_cursor(vc); 702 hide_cursor(vc);
693 redraw = 1; 703 redraw = 1;
@@ -2967,13 +2977,24 @@ static const struct tty_operations con_ops = {
2967 2977
2968static struct cdev vc0_cdev; 2978static struct cdev vc0_cdev;
2969 2979
2980static ssize_t show_tty_active(struct device *dev,
2981 struct device_attribute *attr, char *buf)
2982{
2983 return sprintf(buf, "tty%d\n", fg_console + 1);
2984}
2985static DEVICE_ATTR(active, S_IRUGO, show_tty_active, NULL);
2986
2970int __init vty_init(const struct file_operations *console_fops) 2987int __init vty_init(const struct file_operations *console_fops)
2971{ 2988{
2972 cdev_init(&vc0_cdev, console_fops); 2989 cdev_init(&vc0_cdev, console_fops);
2973 if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) || 2990 if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||
2974 register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) 2991 register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
2975 panic("Couldn't register /dev/tty0 driver\n"); 2992 panic("Couldn't register /dev/tty0 driver\n");
2976 device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); 2993 tty0dev = device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
2994 if (IS_ERR(tty0dev))
2995 tty0dev = NULL;
2996 else
2997 device_create_file(tty0dev, &dev_attr_active);
2977 2998
2978 vcs_init(); 2999 vcs_init();
2979 3000
diff --git a/include/linux/console.h b/include/linux/console.h
index 875cfb1c8132..9774fe6a1a97 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -151,7 +151,7 @@ extern int is_console_locked(void);
151extern int braille_register_console(struct console *, int index, 151extern int braille_register_console(struct console *, int index,
152 char *console_options, char *braille_options); 152 char *console_options, char *braille_options);
153extern int braille_unregister_console(struct console *); 153extern int braille_unregister_console(struct console *);
154 154extern void console_sysfs_notify(void);
155extern int console_suspend_enabled; 155extern int console_suspend_enabled;
156 156
157/* Suspend and resume console messages over PM events */ 157/* Suspend and resume console messages over PM events */
diff --git a/kernel/printk.c b/kernel/printk.c
index bf0420a92a1a..5417784a76b5 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -1332,6 +1332,7 @@ void register_console(struct console *newcon)
1332 spin_unlock_irqrestore(&logbuf_lock, flags); 1332 spin_unlock_irqrestore(&logbuf_lock, flags);
1333 } 1333 }
1334 release_console_sem(); 1334 release_console_sem();
1335 console_sysfs_notify();
1335 1336
1336 /* 1337 /*
1337 * By unregistering the bootconsoles after we enable the real console 1338 * By unregistering the bootconsoles after we enable the real console
@@ -1390,6 +1391,7 @@ int unregister_console(struct console *console)
1390 console_drivers->flags |= CON_CONSDEV; 1391 console_drivers->flags |= CON_CONSDEV;
1391 1392
1392 release_console_sem(); 1393 release_console_sem();
1394 console_sysfs_notify();
1393 return res; 1395 return res;
1394} 1396}
1395EXPORT_SYMBOL(unregister_console); 1397EXPORT_SYMBOL(unregister_console);