diff options
-rw-r--r-- | drivers/char/hvc_console.c | 21 | ||||
-rw-r--r-- | drivers/char/hvc_vio.c | 9 | ||||
-rw-r--r-- | include/asm-ppc64/hvconsole.h | 9 |
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 | */ |
146 | static struct hv_ops *cons_ops[MAX_NR_HVC_CONSOLES]; | ||
145 | static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] = | 147 | static 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 | */ |
248 | int hvc_instantiate(uint32_t vtermno, int index) | 250 | int 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 | ||
740 | struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq) | 743 | struct 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 | }; |
44 | MODULE_DEVICE_TABLE(vio, hvc_driver_table); | 44 | MODULE_DEVICE_TABLE(vio, hvc_driver_table); |
45 | 45 | ||
46 | static struct hv_ops hvc_get_put_ops = { | ||
47 | .get_chars = hvc_get_chars, | ||
48 | .put_chars = hvc_put_chars, | ||
49 | }; | ||
50 | |||
46 | static int __devinit hvc_vio_probe(struct vio_dev *vdev, | 51 | static 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 */ |
33 | struct 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 | }; | ||
33 | extern int hvc_get_chars(uint32_t vtermno, char *buf, int count); | 37 | extern int hvc_get_chars(uint32_t vtermno, char *buf, int count); |
34 | extern int hvc_put_chars(uint32_t vtermno, const char *buf, int count); | 38 | extern int hvc_put_chars(uint32_t vtermno, const char *buf, int count); |
35 | 39 | ||
36 | struct hvc_struct; | 40 | struct 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) */ |
39 | extern int hvc_instantiate(uint32_t vtermno, int index); | 43 | extern 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) */ |
41 | extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq); | 45 | extern 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) */ |
43 | extern int __devexit hvc_remove(struct hvc_struct *hp); | 48 | extern int __devexit hvc_remove(struct hvc_struct *hp); |
44 | #endif /* _PPC64_HVCONSOLE_H */ | 49 | #endif /* _PPC64_HVCONSOLE_H */ |