diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-25 22:59:39 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-25 22:59:39 -0700 |
commit | 184475029a724b6b900d88fc3a5f462a6107d5af (patch) | |
tree | 408320b46df221a2424bf94282b1b8e5b7aff7a1 /drivers/tty/hvc/hvc_console.c | |
parent | 3b76eefe0f970c2e19f165d4a1650abc523d10bc (diff) | |
parent | f1f4ee01c0d3dce0e3aa7d04e4332677db7af478 (diff) |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (99 commits)
drivers/virt: add missing linux/interrupt.h to fsl_hypervisor.c
powerpc/85xx: fix mpic configuration in CAMP mode
powerpc: Copy back TIF flags on return from softirq stack
powerpc/64: Make server perfmon only built on ppc64 server devices
powerpc/pseries: Fix hvc_vio.c build due to recent changes
powerpc: Exporting boot_cpuid_phys
powerpc: Add CFAR to oops output
hvc_console: Add kdb support
powerpc/pseries: Fix hvterm_raw_get_chars to accept < 16 chars, fixing xmon
powerpc/irq: Quieten irq mapping printks
powerpc: Enable lockup and hung task detectors in pseries and ppc64 defeconfigs
powerpc: Add mpt2sas driver to pseries and ppc64 defconfig
powerpc: Disable IRQs off tracer in ppc64 defconfig
powerpc: Sync pseries and ppc64 defconfigs
powerpc/pseries/hvconsole: Fix dropped console output
hvc_console: Improve tty/console put_chars handling
powerpc/kdump: Fix timeout in crash_kexec_wait_realmode
powerpc/mm: Fix output of total_ram.
powerpc/cpufreq: Add cpufreq driver for Momentum Maple boards
powerpc: Correct annotations of pmu registration functions
...
Fix up trivial Kconfig/Makefile conflicts in arch/powerpc, drivers, and
drivers/cpufreq
Diffstat (limited to 'drivers/tty/hvc/hvc_console.c')
-rw-r--r-- | drivers/tty/hvc/hvc_console.c | 70 |
1 files changed, 66 insertions, 4 deletions
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index e9cba13ee800..e1aaf4f309b3 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -39,6 +39,7 @@ #include <linux/delay.h> #include <linux/freezer.h> #include <linux/slab.h> +#include <linux/serial_core.h> #include <asm/uaccess.h> @@ -163,8 +164,10 @@ static void hvc_console_print(struct console *co, const char *b, } else { r = cons_ops[index]->put_chars(vtermnos[index], c, i); if (r <= 0) { - /* throw away chars on error */ - i = 0; + /* throw away characters on error + * but spin in case of -EAGAIN */ + if (r != -EAGAIN) + i = 0; } else if (r > 0) { i -= r; if (i > 0) @@ -184,7 +187,7 @@ static struct tty_driver *hvc_console_device(struct console *c, int *index) } static int __init hvc_console_setup(struct console *co, char *options) -{ +{ if (co->index < 0 || co->index >= MAX_NR_HVC_CONSOLES) return -ENODEV; @@ -448,7 +451,7 @@ static int hvc_push(struct hvc_struct *hp) n = hp->ops->put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf); if (n <= 0) { - if (n == 0) { + if (n == 0 || n == -EAGAIN) { hp->do_wakeup = 1; return 0; } @@ -745,6 +748,58 @@ static int khvcd(void *unused) return 0; } +static int hvc_tiocmget(struct tty_struct *tty) +{ + struct hvc_struct *hp = tty->driver_data; + + if (!hp || !hp->ops->tiocmget) + return -EINVAL; + return hp->ops->tiocmget(hp); +} + +static int hvc_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) +{ + struct hvc_struct *hp = tty->driver_data; + + if (!hp || !hp->ops->tiocmset) + return -EINVAL; + return hp->ops->tiocmset(hp, set, clear); +} + +#ifdef CONFIG_CONSOLE_POLL +int hvc_poll_init(struct tty_driver *driver, int line, char *options) +{ + return 0; +} + +static int hvc_poll_get_char(struct tty_driver *driver, int line) +{ + struct tty_struct *tty = driver->ttys[0]; + struct hvc_struct *hp = tty->driver_data; + int n; + char ch; + + n = hp->ops->get_chars(hp->vtermno, &ch, 1); + + if (n == 0) + return NO_POLL_CHAR; + + return ch; +} + +static void hvc_poll_put_char(struct tty_driver *driver, int line, char ch) +{ + struct tty_struct *tty = driver->ttys[0]; + struct hvc_struct *hp = tty->driver_data; + int n; + + do { + n = hp->ops->put_chars(hp->vtermno, &ch, 1); + } while (n <= 0); +} +#endif + static const struct tty_operations hvc_ops = { .open = hvc_open, .close = hvc_close, @@ -753,6 +808,13 @@ static const struct tty_operations hvc_ops = { .unthrottle = hvc_unthrottle, .write_room = hvc_write_room, .chars_in_buffer = hvc_chars_in_buffer, + .tiocmget = hvc_tiocmget, + .tiocmset = hvc_tiocmset, +#ifdef CONFIG_CONSOLE_POLL + .poll_init = hvc_poll_init, + .poll_get_char = hvc_poll_get_char, + .poll_put_char = hvc_poll_put_char, +#endif }; struct hvc_struct *hvc_alloc(uint32_t vtermno, int data, |