aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/hvc_console.c21
-rw-r--r--drivers/char/hvc_vio.c9
-rw-r--r--include/asm-ppc64/hvconsole.h9
3 files changed, 27 insertions, 12 deletions
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index df282cc9a7ab..cddb789902db 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -85,6 +85,7 @@ struct hvc_struct {
85 char outbuf[N_OUTBUF] __ALIGNED__; 85 char outbuf[N_OUTBUF] __ALIGNED__;
86 int n_outbuf; 86 int n_outbuf;
87 uint32_t vtermno; 87 uint32_t vtermno;
88 struct hv_ops *ops;
88 int irq_requested; 89 int irq_requested;
89 int irq; 90 int irq;
90 struct list_head next; 91 struct list_head next;
@@ -142,6 +143,7 @@ struct hvc_struct *hvc_get_by_index(int index)
142 * console interfaces but can still be used as a tty device. This has to be 143 * console interfaces but can still be used as a tty device. This has to be
143 * static because kmalloc will not work during early console init. 144 * static because kmalloc will not work during early console init.
144 */ 145 */
146static struct hv_ops *cons_ops[MAX_NR_HVC_CONSOLES];
145static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] = 147static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] =
146 {[0 ... MAX_NR_HVC_CONSOLES - 1] = -1}; 148 {[0 ... MAX_NR_HVC_CONSOLES - 1] = -1};
147 149
@@ -154,14 +156,14 @@ void hvc_console_print(struct console *co, const char *b, unsigned count)
154{ 156{
155 char c[16] __ALIGNED__; 157 char c[16] __ALIGNED__;
156 unsigned i = 0, n = 0; 158 unsigned i = 0, n = 0;
157 int r, donecr = 0; 159 int r, donecr = 0, index = co->index;
158 160
159 /* Console access attempt outside of acceptable console range. */ 161 /* Console access attempt outside of acceptable console range. */
160 if (co->index >= MAX_NR_HVC_CONSOLES) 162 if (index >= MAX_NR_HVC_CONSOLES)
161 return; 163 return;
162 164
163 /* This console adapter was removed so it is not useable. */ 165 /* This console adapter was removed so it is not useable. */
164 if (vtermnos[co->index] < 0) 166 if (vtermnos[index] < 0)
165 return; 167 return;
166 168
167 while (count > 0 || i > 0) { 169 while (count > 0 || i > 0) {
@@ -175,7 +177,7 @@ void hvc_console_print(struct console *co, const char *b, unsigned count)
175 --count; 177 --count;
176 } 178 }
177 } else { 179 } else {
178 r = hvc_put_chars(vtermnos[co->index], c, i); 180 r = cons_ops[index]->put_chars(vtermnos[index], c, i);
179 if (r < 0) { 181 if (r < 0) {
180 /* throw away chars on error */ 182 /* throw away chars on error */
181 i = 0; 183 i = 0;
@@ -245,7 +247,7 @@ console_initcall(hvc_console_init);
245 * vty adapters do NOT get an hvc_instantiate() callback since they 247 * vty adapters do NOT get an hvc_instantiate() callback since they
246 * appear after early console init. 248 * appear after early console init.
247 */ 249 */
248int hvc_instantiate(uint32_t vtermno, int index) 250int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops)
249{ 251{
250 struct hvc_struct *hp; 252 struct hvc_struct *hp;
251 253
@@ -263,6 +265,7 @@ int hvc_instantiate(uint32_t vtermno, int index)
263 } 265 }
264 266
265 vtermnos[index] = vtermno; 267 vtermnos[index] = vtermno;
268 cons_ops[index] = ops;
266 269
267 /* reserve all indices upto and including this index */ 270 /* reserve all indices upto and including this index */
268 if (last_hvc < index) 271 if (last_hvc < index)
@@ -466,7 +469,7 @@ static void hvc_push(struct hvc_struct *hp)
466{ 469{
467 int n; 470 int n;
468 471
469 n = hvc_put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf); 472 n = hp->ops->put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf);
470 if (n <= 0) { 473 if (n <= 0) {
471 if (n == 0) 474 if (n == 0)
472 return; 475 return;
@@ -604,7 +607,7 @@ static int hvc_poll(struct hvc_struct *hp)
604 break; 607 break;
605 } 608 }
606 609
607 n = hvc_get_chars(hp->vtermno, buf, count); 610 n = hp->ops->get_chars(hp->vtermno, buf, count);
608 if (n <= 0) { 611 if (n <= 0) {
609 /* Hangup the tty when disconnected from host */ 612 /* Hangup the tty when disconnected from host */
610 if (n == -EPIPE) { 613 if (n == -EPIPE) {
@@ -737,7 +740,8 @@ static struct kobj_type hvc_kobj_type = {
737 .release = destroy_hvc_struct, 740 .release = destroy_hvc_struct,
738}; 741};
739 742
740struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq) 743struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq,
744 struct hv_ops *ops)
741{ 745{
742 struct hvc_struct *hp; 746 struct hvc_struct *hp;
743 int i; 747 int i;
@@ -750,6 +754,7 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq)
750 754
751 hp->vtermno = vtermno; 755 hp->vtermno = vtermno;
752 hp->irq = irq; 756 hp->irq = irq;
757 hp->ops = ops;
753 758
754 kobject_init(&hp->kobj); 759 kobject_init(&hp->kobj);
755 hp->kobj.ktype = &hvc_kobj_type; 760 hp->kobj.ktype = &hvc_kobj_type;
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c
index d2928f90ab51..430a2c284ad2 100644
--- a/drivers/char/hvc_vio.c
+++ b/drivers/char/hvc_vio.c
@@ -43,6 +43,11 @@ static struct vio_device_id hvc_driver_table[] __devinitdata = {
43}; 43};
44MODULE_DEVICE_TABLE(vio, hvc_driver_table); 44MODULE_DEVICE_TABLE(vio, hvc_driver_table);
45 45
46static struct hv_ops hvc_get_put_ops = {
47 .get_chars = hvc_get_chars,
48 .put_chars = hvc_put_chars,
49};
50
46static int __devinit hvc_vio_probe(struct vio_dev *vdev, 51static int __devinit hvc_vio_probe(struct vio_dev *vdev,
47 const struct vio_device_id *id) 52 const struct vio_device_id *id)
48{ 53{
@@ -52,7 +57,7 @@ static int __devinit hvc_vio_probe(struct vio_dev *vdev,
52 if (!vdev || !id) 57 if (!vdev || !id)
53 return -EPERM; 58 return -EPERM;
54 59
55 hp = hvc_alloc(vdev->unit_address, vdev->irq); 60 hp = hvc_alloc(vdev->unit_address, vdev->irq, &hvc_get_put_ops);
56 if (IS_ERR(hp)) 61 if (IS_ERR(hp))
57 return PTR_ERR(hp); 62 return PTR_ERR(hp);
58 dev_set_drvdata(&vdev->dev, hp); 63 dev_set_drvdata(&vdev->dev, hp);
@@ -115,7 +120,7 @@ static int hvc_find_vtys(void)
115 continue; 120 continue;
116 121
117 if (device_is_compatible(vty, "hvterm1")) { 122 if (device_is_compatible(vty, "hvterm1")) {
118 hvc_instantiate(*vtermno, num_found); 123 hvc_instantiate(*vtermno, num_found, &hvc_get_put_ops);
119 ++num_found; 124 ++num_found;
120 } 125 }
121 } 126 }
diff --git a/include/asm-ppc64/hvconsole.h b/include/asm-ppc64/hvconsole.h
index 14667a78716d..6da93ce74dc0 100644
--- a/include/asm-ppc64/hvconsole.h
+++ b/include/asm-ppc64/hvconsole.h
@@ -30,15 +30,20 @@
30#define MAX_NR_HVC_CONSOLES 16 30#define MAX_NR_HVC_CONSOLES 16
31 31
32/* implemented by a low level driver */ 32/* implemented by a low level driver */
33struct hv_ops {
34 int (*get_chars)(uint32_t vtermno, char *buf, int count);
35 int (*put_chars)(uint32_t vtermno, const char *buf, int count);
36};
33extern int hvc_get_chars(uint32_t vtermno, char *buf, int count); 37extern int hvc_get_chars(uint32_t vtermno, char *buf, int count);
34extern int hvc_put_chars(uint32_t vtermno, const char *buf, int count); 38extern int hvc_put_chars(uint32_t vtermno, const char *buf, int count);
35 39
36struct hvc_struct; 40struct hvc_struct;
37 41
38/* Register a vterm and a slot index for use as a console (console_init) */ 42/* Register a vterm and a slot index for use as a console (console_init) */
39extern int hvc_instantiate(uint32_t vtermno, int index); 43extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops);
40/* register a vterm for hvc tty operation (module_init or hotplug add) */ 44/* register a vterm for hvc tty operation (module_init or hotplug add) */
41extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq); 45extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq,
46 struct hv_ops *ops);
42/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */ 47/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */
43extern int __devexit hvc_remove(struct hvc_struct *hp); 48extern int __devexit hvc_remove(struct hvc_struct *hp);
44#endif /* _PPC64_HVCONSOLE_H */ 49#endif /* _PPC64_HVCONSOLE_H */