aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-03-29 14:28:30 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-29 14:28:30 -0500
commit76babde121d2ffef04ca692ce64ef9f8a9866086 (patch)
tree294923bbb4974258d86d223e35eee691abacdfb1 /drivers/char
parente71ac6032edf77a1e4a81f3e3b260807e94b37a5 (diff)
parent15e812ad849e142e3dfc984d33c4d8042389f148 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (67 commits) [PATCH] powerpc: Remove oprofile spinlock backtrace code [PATCH] powerpc: Add oprofile calltrace support to all powerpc cpus [PATCH] powerpc: Add oprofile calltrace support [PATCH] for_each_possible_cpu: ppc [PATCH] for_each_possible_cpu: powerpc [PATCH] lock PTE before updating it in 440/BookE page fault handler [PATCH] powerpc: Kill _machine and hard-coded platform numbers ppc: Fix compile error in arch/ppc/lib/strcase.c [PATCH] git-powerpc: WARN was a dumb idea [PATCH] powerpc: a couple of trivial compile warning fixes powerpc: remove OCP references powerpc: Make uImage default build output for MPC8540 ADS powerpc: move math-emu over to arch/powerpc powerpc: use memparse() for mem= command line parsing ppc: fix strncasecmp prototype [PATCH] powerpc: make ISA floppies work again [PATCH] powerpc: Fix some initcall return values [PATCH] powerpc: Workaround for pSeries RTAS bug [PATCH] spufs: fix __init/__exit annotations [PATCH] powerpc: add hvc backend for rtas ...
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/Kconfig17
-rw-r--r--drivers/char/Makefile4
-rw-r--r--drivers/char/generic_nvram.c5
-rw-r--r--drivers/char/hvc_console.c101
-rw-r--r--drivers/char/hvc_console.h63
-rw-r--r--drivers/char/hvc_rtas.c138
-rw-r--r--drivers/char/hvc_vio.c11
-rw-r--r--drivers/char/hvcs.c1
8 files changed, 283 insertions, 57 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 73d30bf01582..889cad07774e 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -561,14 +561,31 @@ config TIPAR
561 561
562 If unsure, say N. 562 If unsure, say N.
563 563
564config HVC_DRIVER
565 bool
566 help
567 Users of pSeries machines that want to utilize the hvc console front-end
568 module for their backend console driver should select this option.
569 It will automatically be selected if one of the back-end console drivers
570 is selected.
571
572
564config HVC_CONSOLE 573config HVC_CONSOLE
565 bool "pSeries Hypervisor Virtual Console support" 574 bool "pSeries Hypervisor Virtual Console support"
566 depends on PPC_PSERIES 575 depends on PPC_PSERIES
576 select HVC_DRIVER
567 help 577 help
568 pSeries machines when partitioned support a hypervisor virtual 578 pSeries machines when partitioned support a hypervisor virtual
569 console. This driver allows each pSeries partition to have a console 579 console. This driver allows each pSeries partition to have a console
570 which is accessed via the HMC. 580 which is accessed via the HMC.
571 581
582config HVC_RTAS
583 bool "IBM RTAS Console support"
584 depends on PPC_RTAS
585 select HVC_DRIVER
586 help
587 IBM Console device driver which makes use of RTAS
588
572config HVCS 589config HVCS
573 tristate "IBM Hypervisor Virtual Console Server support" 590 tristate "IBM Hypervisor Virtual Console Server support"
574 depends on PPC_PSERIES 591 depends on PPC_PSERIES
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index b2a11245fa95..a73cb4956928 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -41,7 +41,9 @@ obj-$(CONFIG_N_HDLC) += n_hdlc.o
41obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o 41obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
42obj-$(CONFIG_SX) += sx.o generic_serial.o 42obj-$(CONFIG_SX) += sx.o generic_serial.o
43obj-$(CONFIG_RIO) += rio/ generic_serial.o 43obj-$(CONFIG_RIO) += rio/ generic_serial.o
44obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o hvc_vio.o hvsi.o 44obj-$(CONFIG_HVC_DRIVER) += hvc_console.o
45obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi.o
46obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o
45obj-$(CONFIG_RAW_DRIVER) += raw.o 47obj-$(CONFIG_RAW_DRIVER) += raw.o
46obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o 48obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o
47obj-$(CONFIG_MMTIMER) += mmtimer.o 49obj-$(CONFIG_MMTIMER) += mmtimer.o
diff --git a/drivers/char/generic_nvram.c b/drivers/char/generic_nvram.c
index 1b5e01e6e129..43ff59816511 100644
--- a/drivers/char/generic_nvram.c
+++ b/drivers/char/generic_nvram.c
@@ -22,6 +22,9 @@
22#include <linux/smp_lock.h> 22#include <linux/smp_lock.h>
23#include <asm/uaccess.h> 23#include <asm/uaccess.h>
24#include <asm/nvram.h> 24#include <asm/nvram.h>
25#ifdef CONFIG_PPC_PMAC
26#include <asm/machdep.h>
27#endif
25 28
26#define NVRAM_SIZE 8192 29#define NVRAM_SIZE 8192
27 30
@@ -92,7 +95,7 @@ static int nvram_ioctl(struct inode *inode, struct file *file,
92 case IOC_NVRAM_GET_OFFSET: { 95 case IOC_NVRAM_GET_OFFSET: {
93 int part, offset; 96 int part, offset;
94 97
95 if (_machine != _MACH_Pmac) 98 if (!machine_is(powermac))
96 return -EINVAL; 99 return -EINVAL;
97 if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0) 100 if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0)
98 return -EFAULT; 101 return -EFAULT;
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index f65b2e14a485..2b6a56b2bf35 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -39,8 +39,10 @@
39#include <linux/sched.h> 39#include <linux/sched.h>
40#include <linux/spinlock.h> 40#include <linux/spinlock.h>
41#include <linux/delay.h> 41#include <linux/delay.h>
42
42#include <asm/uaccess.h> 43#include <asm/uaccess.h>
43#include <asm/hvconsole.h> 44
45#include "hvc_console.h"
44 46
45#define HVC_MAJOR 229 47#define HVC_MAJOR 229
46#define HVC_MINOR 0 48#define HVC_MINOR 0
@@ -54,17 +56,14 @@
54#define HVC_CLOSE_WAIT (HZ/100) /* 1/10 of a second */ 56#define HVC_CLOSE_WAIT (HZ/100) /* 1/10 of a second */
55 57
56/* 58/*
57 * The Linux TTY code does not support dynamic addition of tty derived devices 59 * These sizes are most efficient for vio, because they are the
58 * so we need to know how many tty devices we might need when space is allocated 60 * native transfer size. We could make them selectable in the
59 * for the tty device. Since this driver supports hotplug of vty adapters we 61 * future to better deal with backends that want other buffer sizes.
60 * need to make sure we have enough allocated.
61 */ 62 */
62#define HVC_ALLOC_TTY_ADAPTERS 8
63
64#define N_OUTBUF 16 63#define N_OUTBUF 16
65#define N_INBUF 16 64#define N_INBUF 16
66 65
67#define __ALIGNED__ __attribute__((__aligned__(8))) 66#define __ALIGNED__ __attribute__((__aligned__(sizeof(long))))
68 67
69static struct tty_driver *hvc_driver; 68static struct tty_driver *hvc_driver;
70static struct task_struct *hvc_task; 69static struct task_struct *hvc_task;
@@ -154,7 +153,7 @@ static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] =
154 153
155void hvc_console_print(struct console *co, const char *b, unsigned count) 154void hvc_console_print(struct console *co, const char *b, unsigned count)
156{ 155{
157 char c[16] __ALIGNED__; 156 char c[N_OUTBUF] __ALIGNED__;
158 unsigned i = 0, n = 0; 157 unsigned i = 0, n = 0;
159 int r, donecr = 0, index = co->index; 158 int r, donecr = 0, index = co->index;
160 159
@@ -473,8 +472,10 @@ static void hvc_push(struct hvc_struct *hp)
473 472
474 n = hp->ops->put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf); 473 n = hp->ops->put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf);
475 if (n <= 0) { 474 if (n <= 0) {
476 if (n == 0) 475 if (n == 0) {
476 hp->do_wakeup = 1;
477 return; 477 return;
478 }
478 /* throw away output on error; this happens when 479 /* throw away output on error; this happens when
479 there is no session connected to the vterm. */ 480 there is no session connected to the vterm. */
480 hp->n_outbuf = 0; 481 hp->n_outbuf = 0;
@@ -486,12 +487,19 @@ static void hvc_push(struct hvc_struct *hp)
486 hp->do_wakeup = 1; 487 hp->do_wakeup = 1;
487} 488}
488 489
489static inline int __hvc_write_kernel(struct hvc_struct *hp, 490static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count)
490 const unsigned char *buf, int count)
491{ 491{
492 struct hvc_struct *hp = tty->driver_data;
492 unsigned long flags; 493 unsigned long flags;
493 int rsize, written = 0; 494 int rsize, written = 0;
494 495
496 /* This write was probably executed during a tty close. */
497 if (!hp)
498 return -EPIPE;
499
500 if (hp->count <= 0)
501 return -EIO;
502
495 spin_lock_irqsave(&hp->lock, flags); 503 spin_lock_irqsave(&hp->lock, flags);
496 504
497 /* Push pending writes */ 505 /* Push pending writes */
@@ -510,26 +518,8 @@ static inline int __hvc_write_kernel(struct hvc_struct *hp,
510 } 518 }
511 spin_unlock_irqrestore(&hp->lock, flags); 519 spin_unlock_irqrestore(&hp->lock, flags);
512 520
513 return written;
514}
515static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count)
516{
517 struct hvc_struct *hp = tty->driver_data;
518 int written;
519
520 /* This write was probably executed during a tty close. */
521 if (!hp)
522 return -EPIPE;
523
524 if (hp->count <= 0)
525 return -EIO;
526
527 written = __hvc_write_kernel(hp, buf, count);
528
529 /* 521 /*
530 * Racy, but harmless, kick thread if there is still pending data. 522 * Racy, but harmless, kick thread if there is still pending data.
531 * There really is nothing wrong with kicking the thread, even if there
532 * is no buffered data.
533 */ 523 */
534 if (hp->n_outbuf) 524 if (hp->n_outbuf)
535 hvc_kick(); 525 hvc_kick();
@@ -614,6 +604,13 @@ static int hvc_poll(struct hvc_struct *hp)
614 spin_unlock_irqrestore(&hp->lock, flags); 604 spin_unlock_irqrestore(&hp->lock, flags);
615 tty_hangup(tty); 605 tty_hangup(tty);
616 spin_lock_irqsave(&hp->lock, flags); 606 spin_lock_irqsave(&hp->lock, flags);
607 } else if ( n == -EAGAIN ) {
608 /*
609 * Some back-ends can only ensure a certain min
610 * num of bytes read, which may be > 'count'.
611 * Let the tty clear the flip buff to make room.
612 */
613 poll_mask |= HVC_POLL_READ;
617 } 614 }
618 break; 615 break;
619 } 616 }
@@ -635,16 +632,7 @@ static int hvc_poll(struct hvc_struct *hp)
635 tty_insert_flip_char(tty, buf[i], 0); 632 tty_insert_flip_char(tty, buf[i], 0);
636 } 633 }
637 634
638 /*
639 * Account for the total amount read in one loop, and if above
640 * 64 bytes, we do a quick schedule loop to let the tty grok
641 * the data and eventually throttle us.
642 */
643 read_total += n; 635 read_total += n;
644 if (read_total >= 64) {
645 poll_mask |= HVC_POLL_QUICK;
646 break;
647 }
648 } 636 }
649 throttled: 637 throttled:
650 /* Wakeup write queue if necessary */ 638 /* Wakeup write queue if necessary */
@@ -767,7 +755,8 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq,
767 * see if this vterm id matches one registered for console. 755 * see if this vterm id matches one registered for console.
768 */ 756 */
769 for (i=0; i < MAX_NR_HVC_CONSOLES; i++) 757 for (i=0; i < MAX_NR_HVC_CONSOLES; i++)
770 if (vtermnos[i] == hp->vtermno) 758 if (vtermnos[i] == hp->vtermno &&
759 cons_ops[i] == hp->ops)
771 break; 760 break;
772 761
773 /* no matching slot, just use a counter */ 762 /* no matching slot, just use a counter */
@@ -823,34 +812,38 @@ EXPORT_SYMBOL(hvc_remove);
823 * interfaces start to become available. */ 812 * interfaces start to become available. */
824int __init hvc_init(void) 813int __init hvc_init(void)
825{ 814{
815 struct tty_driver *drv;
816
826 /* We need more than hvc_count adapters due to hotplug additions. */ 817 /* We need more than hvc_count adapters due to hotplug additions. */
827 hvc_driver = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS); 818 drv = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS);
828 if (!hvc_driver) 819 if (!drv)
829 return -ENOMEM; 820 return -ENOMEM;
830 821
831 hvc_driver->owner = THIS_MODULE; 822 drv->owner = THIS_MODULE;
832 hvc_driver->devfs_name = "hvc/"; 823 drv->devfs_name = "hvc/";
833 hvc_driver->driver_name = "hvc"; 824 drv->driver_name = "hvc";
834 hvc_driver->name = "hvc"; 825 drv->name = "hvc";
835 hvc_driver->major = HVC_MAJOR; 826 drv->major = HVC_MAJOR;
836 hvc_driver->minor_start = HVC_MINOR; 827 drv->minor_start = HVC_MINOR;
837 hvc_driver->type = TTY_DRIVER_TYPE_SYSTEM; 828 drv->type = TTY_DRIVER_TYPE_SYSTEM;
838 hvc_driver->init_termios = tty_std_termios; 829 drv->init_termios = tty_std_termios;
839 hvc_driver->flags = TTY_DRIVER_REAL_RAW; 830 drv->flags = TTY_DRIVER_REAL_RAW;
840 tty_set_operations(hvc_driver, &hvc_ops); 831 tty_set_operations(drv, &hvc_ops);
841 832
842 /* Always start the kthread because there can be hotplug vty adapters 833 /* Always start the kthread because there can be hotplug vty adapters
843 * added later. */ 834 * added later. */
844 hvc_task = kthread_run(khvcd, NULL, "khvcd"); 835 hvc_task = kthread_run(khvcd, NULL, "khvcd");
845 if (IS_ERR(hvc_task)) { 836 if (IS_ERR(hvc_task)) {
846 panic("Couldn't create kthread for console.\n"); 837 panic("Couldn't create kthread for console.\n");
847 put_tty_driver(hvc_driver); 838 put_tty_driver(drv);
848 return -EIO; 839 return -EIO;
849 } 840 }
850 841
851 if (tty_register_driver(hvc_driver)) 842 if (tty_register_driver(drv))
852 panic("Couldn't register hvc console driver\n"); 843 panic("Couldn't register hvc console driver\n");
853 844
845 mb();
846 hvc_driver = drv;
854 return 0; 847 return 0;
855} 848}
856module_init(hvc_init); 849module_init(hvc_init);
diff --git a/drivers/char/hvc_console.h b/drivers/char/hvc_console.h
new file mode 100644
index 000000000000..96b7401319c1
--- /dev/null
+++ b/drivers/char/hvc_console.h
@@ -0,0 +1,63 @@
1/*
2 * hvc_console.h
3 * Copyright (C) 2005 IBM Corporation
4 *
5 * Author(s):
6 * Ryan S. Arnold <rsa@us.ibm.com>
7 *
8 * hvc_console header information:
9 * moved here from include/asm-powerpc/hvconsole.h
10 * and drivers/char/hvc_console.c
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27#ifndef HVC_CONSOLE_H
28#define HVC_CONSOLE_H
29
30/*
31 * This is the max number of console adapters that can/will be found as
32 * console devices on first stage console init. Any number beyond this range
33 * can't be used as a console device but is still a valid tty device.
34 */
35#define MAX_NR_HVC_CONSOLES 16
36
37/*
38 * The Linux TTY code does not support dynamic addition of tty derived devices
39 * so we need to know how many tty devices we might need when space is allocated
40 * for the tty device. Since this driver supports hotplug of vty adapters we
41 * need to make sure we have enough allocated.
42 */
43#define HVC_ALLOC_TTY_ADAPTERS 8
44
45
46/* implemented by a low level driver */
47struct hv_ops {
48 int (*get_chars)(uint32_t vtermno, char *buf, int count);
49 int (*put_chars)(uint32_t vtermno, const char *buf, int count);
50};
51
52struct hvc_struct;
53
54/* Register a vterm and a slot index for use as a console (console_init) */
55extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops);
56
57/* register a vterm for hvc tty operation (module_init or hotplug add) */
58extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq,
59 struct hv_ops *ops);
60/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */
61extern int __devexit hvc_remove(struct hvc_struct *hp);
62
63#endif // HVC_CONSOLE_H
diff --git a/drivers/char/hvc_rtas.c b/drivers/char/hvc_rtas.c
new file mode 100644
index 000000000000..83364ea63cba
--- /dev/null
+++ b/drivers/char/hvc_rtas.c
@@ -0,0 +1,138 @@
1/*
2 * IBM RTAS driver interface to hvc_console.c
3 *
4 * (C) Copyright IBM Corporation 2001-2005
5 * (C) Copyright Red Hat, Inc. 2005
6 *
7 * Author(s): Maximino Augilar <IBM STI Design Center>
8 * : Ryan S. Arnold <rsa@us.ibm.com>
9 * : Utz Bacher <utz.bacher@de.ibm.com>
10 * : David Woodhouse <dwmw2@infradead.org>
11 *
12 * inspired by drivers/char/hvc_console.c
13 * written by Anton Blanchard and Paul Mackerras
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 */
29
30#include <linux/console.h>
31#include <linux/delay.h>
32#include <linux/err.h>
33#include <linux/init.h>
34#include <linux/moduleparam.h>
35#include <linux/types.h>
36
37#include <asm/irq.h>
38#include <asm/rtas.h>
39#include "hvc_console.h"
40
41#define hvc_rtas_cookie 0x67781e15
42struct hvc_struct *hvc_rtas_dev;
43
44#define RTASCONS_PUT_ATTEMPTS 16
45
46static int rtascons_put_char_token = RTAS_UNKNOWN_SERVICE;
47static int rtascons_get_char_token = RTAS_UNKNOWN_SERVICE;
48static int rtascons_put_delay = 100;
49module_param_named(put_delay, rtascons_put_delay, int, 0644);
50
51static inline int hvc_rtas_write_console(uint32_t vtermno, const char *buf, int count)
52{
53 int done;
54
55 /* if there is more than one character to be displayed, wait a bit */
56 for (done = 0; done < count; done++) {
57 int result;
58 result = rtas_call(rtascons_put_char_token, 1, 1, NULL, buf[done]);
59 if (result)
60 break;
61 }
62 /* the calling routine expects to receive the number of bytes sent */
63 return done;
64}
65
66static int hvc_rtas_read_console(uint32_t vtermno, char *buf, int count)
67{
68 int i;
69
70 for (i = 0; i < count; i++) {
71 int c, err;
72
73 err = rtas_call(rtascons_get_char_token, 0, 2, &c);
74 if (err)
75 break;
76
77 buf[i] = c;
78 }
79
80 return i;
81}
82
83static struct hv_ops hvc_rtas_get_put_ops = {
84 .get_chars = hvc_rtas_read_console,
85 .put_chars = hvc_rtas_write_console,
86};
87
88static int hvc_rtas_init(void)
89{
90 struct hvc_struct *hp;
91
92 if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE)
93 rtascons_put_char_token = rtas_token("put-term-char");
94 if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE)
95 return -EIO;
96
97 if (rtascons_get_char_token == RTAS_UNKNOWN_SERVICE)
98 rtascons_get_char_token = rtas_token("get-term-char");
99 if (rtascons_get_char_token == RTAS_UNKNOWN_SERVICE)
100 return -EIO;
101
102 BUG_ON(hvc_rtas_dev);
103
104 /* Allocate an hvc_struct for the console device we instantiated
105 * earlier. Save off hp so that we can return it on exit */
106 hp = hvc_alloc(hvc_rtas_cookie, NO_IRQ, &hvc_rtas_get_put_ops);
107 if (IS_ERR(hp))
108 return PTR_ERR(hp);
109 hvc_rtas_dev = hp;
110 return 0;
111}
112module_init(hvc_rtas_init);
113
114/* This will tear down the tty portion of the driver */
115static void __exit hvc_rtas_exit(void)
116{
117 /* Really the fun isn't over until the worker thread breaks down and the
118 * tty cleans up */
119 if (hvc_rtas_dev)
120 hvc_remove(hvc_rtas_dev);
121}
122module_exit(hvc_rtas_exit);
123
124/* This will happen prior to module init. There is no tty at this time? */
125static int hvc_rtas_console_init(void)
126{
127 rtascons_put_char_token = rtas_token("put-term-char");
128 if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE)
129 return -EIO;
130 rtascons_get_char_token = rtas_token("get-term-char");
131 if (rtascons_get_char_token == RTAS_UNKNOWN_SERVICE)
132 return -EIO;
133
134 hvc_instantiate(hvc_rtas_cookie, 0, &hvc_rtas_get_put_ops );
135 add_preferred_console("hvc", 0, NULL);
136 return 0;
137}
138console_initcall(hvc_rtas_console_init);
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c
index f5212eb2b41d..9add81ceb440 100644
--- a/drivers/char/hvc_vio.c
+++ b/drivers/char/hvc_vio.c
@@ -31,10 +31,13 @@
31 31
32#include <linux/types.h> 32#include <linux/types.h>
33#include <linux/init.h> 33#include <linux/init.h>
34
34#include <asm/hvconsole.h> 35#include <asm/hvconsole.h>
35#include <asm/vio.h> 36#include <asm/vio.h>
36#include <asm/prom.h> 37#include <asm/prom.h>
37 38
39#include "hvc_console.h"
40
38char hvc_driver_name[] = "hvc_console"; 41char hvc_driver_name[] = "hvc_console";
39 42
40static struct vio_device_id hvc_driver_table[] __devinitdata = { 43static struct vio_device_id hvc_driver_table[] __devinitdata = {
@@ -48,6 +51,14 @@ static int filtered_get_chars(uint32_t vtermno, char *buf, int count)
48 unsigned long got; 51 unsigned long got;
49 int i; 52 int i;
50 53
54 /*
55 * Vio firmware will read up to SIZE_VIO_GET_CHARS at its own discretion
56 * so we play safe and avoid the situation where got > count which could
57 * overload the flip buffer.
58 */
59 if (count < SIZE_VIO_GET_CHARS)
60 return -EAGAIN;
61
51 got = hvc_get_chars(vtermno, buf, count); 62 got = hvc_get_chars(vtermno, buf, count);
52 63
53 /* 64 /*
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c
index f7ac31856572..327b00c3c45e 100644
--- a/drivers/char/hvcs.c
+++ b/drivers/char/hvcs.c
@@ -439,7 +439,6 @@ static int hvcs_io(struct hvcs_struct *hvcsd)
439 char buf[HVCS_BUFF_LEN] __ALIGNED__; 439 char buf[HVCS_BUFF_LEN] __ALIGNED__;
440 unsigned long flags; 440 unsigned long flags;
441 int got = 0; 441 int got = 0;
442 int i;
443 442
444 spin_lock_irqsave(&hvcsd->lock, flags); 443 spin_lock_irqsave(&hvcsd->lock, flags);
445 444