diff options
Diffstat (limited to 'drivers/tty/hvc/hvc_console.c')
-rw-r--r-- | drivers/tty/hvc/hvc_console.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index 2d691eb7c40a..7f80f15681cd 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c | |||
@@ -299,20 +299,33 @@ static void hvc_unthrottle(struct tty_struct *tty) | |||
299 | hvc_kick(); | 299 | hvc_kick(); |
300 | } | 300 | } |
301 | 301 | ||
302 | static int hvc_install(struct tty_driver *driver, struct tty_struct *tty) | ||
303 | { | ||
304 | struct hvc_struct *hp; | ||
305 | int rc; | ||
306 | |||
307 | /* Auto increments kref reference if found. */ | ||
308 | if (!(hp = hvc_get_by_index(tty->index))) | ||
309 | return -ENODEV; | ||
310 | |||
311 | tty->driver_data = hp; | ||
312 | |||
313 | rc = tty_port_install(&hp->port, driver, tty); | ||
314 | if (rc) | ||
315 | tty_port_put(&hp->port); | ||
316 | return rc; | ||
317 | } | ||
318 | |||
302 | /* | 319 | /* |
303 | * The TTY interface won't be used until after the vio layer has exposed the vty | 320 | * The TTY interface won't be used until after the vio layer has exposed the vty |
304 | * adapter to the kernel. | 321 | * adapter to the kernel. |
305 | */ | 322 | */ |
306 | static int hvc_open(struct tty_struct *tty, struct file * filp) | 323 | static int hvc_open(struct tty_struct *tty, struct file * filp) |
307 | { | 324 | { |
308 | struct hvc_struct *hp; | 325 | struct hvc_struct *hp = tty->driver_data; |
309 | unsigned long flags; | 326 | unsigned long flags; |
310 | int rc = 0; | 327 | int rc = 0; |
311 | 328 | ||
312 | /* Auto increments kref reference if found. */ | ||
313 | if (!(hp = hvc_get_by_index(tty->index))) | ||
314 | return -ENODEV; | ||
315 | |||
316 | spin_lock_irqsave(&hp->port.lock, flags); | 329 | spin_lock_irqsave(&hp->port.lock, flags); |
317 | /* Check and then increment for fast path open. */ | 330 | /* Check and then increment for fast path open. */ |
318 | if (hp->port.count++ > 0) { | 331 | if (hp->port.count++ > 0) { |
@@ -322,7 +335,6 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) | |||
322 | } /* else count == 0 */ | 335 | } /* else count == 0 */ |
323 | spin_unlock_irqrestore(&hp->port.lock, flags); | 336 | spin_unlock_irqrestore(&hp->port.lock, flags); |
324 | 337 | ||
325 | tty->driver_data = hp; | ||
326 | tty_port_tty_set(&hp->port, tty); | 338 | tty_port_tty_set(&hp->port, tty); |
327 | 339 | ||
328 | if (hp->ops->notifier_add) | 340 | if (hp->ops->notifier_add) |
@@ -389,6 +401,11 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) | |||
389 | hp->vtermno, hp->port.count); | 401 | hp->vtermno, hp->port.count); |
390 | spin_unlock_irqrestore(&hp->port.lock, flags); | 402 | spin_unlock_irqrestore(&hp->port.lock, flags); |
391 | } | 403 | } |
404 | } | ||
405 | |||
406 | static void hvc_cleanup(struct tty_struct *tty) | ||
407 | { | ||
408 | struct hvc_struct *hp = tty->driver_data; | ||
392 | 409 | ||
393 | tty_port_put(&hp->port); | 410 | tty_port_put(&hp->port); |
394 | } | 411 | } |
@@ -792,8 +809,10 @@ static void hvc_poll_put_char(struct tty_driver *driver, int line, char ch) | |||
792 | #endif | 809 | #endif |
793 | 810 | ||
794 | static const struct tty_operations hvc_ops = { | 811 | static const struct tty_operations hvc_ops = { |
812 | .install = hvc_install, | ||
795 | .open = hvc_open, | 813 | .open = hvc_open, |
796 | .close = hvc_close, | 814 | .close = hvc_close, |
815 | .cleanup = hvc_cleanup, | ||
797 | .write = hvc_write, | 816 | .write = hvc_write, |
798 | .hangup = hvc_hangup, | 817 | .hangup = hvc_hangup, |
799 | .unthrottle = hvc_unthrottle, | 818 | .unthrottle = hvc_unthrottle, |