diff options
author | Jiri Kosina <jkosina@suse.cz> | 2012-10-28 14:28:52 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2012-10-28 14:29:19 -0400 |
commit | 3bd7bf1f0fe14f591c089ae61bbfa9bd356f178a (patch) | |
tree | 0058693cc9e70b7461dae551f8a19aff2efd13ca /drivers/tty/hvc/hvc_vio.c | |
parent | f16f84937d769c893492160b1a8c3672e3992beb (diff) | |
parent | e657e078d3dfa9f96976db7a2b5fd7d7c9f1f1a6 (diff) |
Merge branch 'master' into for-next
Sync up with Linus' tree to be able to apply Cesar's patch
against newer version of the code.
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/tty/hvc/hvc_vio.c')
-rw-r--r-- | drivers/tty/hvc/hvc_vio.c | 123 |
1 files changed, 70 insertions, 53 deletions
diff --git a/drivers/tty/hvc/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c index 56e97258e55a..1a5894c6dfa4 100644 --- a/drivers/tty/hvc/hvc_vio.c +++ b/drivers/tty/hvc/hvc_vio.c | |||
@@ -230,6 +230,69 @@ static const struct hv_ops hvterm_hvsi_ops = { | |||
230 | .tiocmset = hvterm_hvsi_tiocmset, | 230 | .tiocmset = hvterm_hvsi_tiocmset, |
231 | }; | 231 | }; |
232 | 232 | ||
233 | static void udbg_hvc_putc(char c) | ||
234 | { | ||
235 | int count = -1; | ||
236 | |||
237 | if (!hvterm_privs[0]) | ||
238 | return; | ||
239 | |||
240 | if (c == '\n') | ||
241 | udbg_hvc_putc('\r'); | ||
242 | |||
243 | do { | ||
244 | switch(hvterm_privs[0]->proto) { | ||
245 | case HV_PROTOCOL_RAW: | ||
246 | count = hvterm_raw_put_chars(0, &c, 1); | ||
247 | break; | ||
248 | case HV_PROTOCOL_HVSI: | ||
249 | count = hvterm_hvsi_put_chars(0, &c, 1); | ||
250 | break; | ||
251 | } | ||
252 | } while(count == 0); | ||
253 | } | ||
254 | |||
255 | static int udbg_hvc_getc_poll(void) | ||
256 | { | ||
257 | int rc = 0; | ||
258 | char c; | ||
259 | |||
260 | if (!hvterm_privs[0]) | ||
261 | return -1; | ||
262 | |||
263 | switch(hvterm_privs[0]->proto) { | ||
264 | case HV_PROTOCOL_RAW: | ||
265 | rc = hvterm_raw_get_chars(0, &c, 1); | ||
266 | break; | ||
267 | case HV_PROTOCOL_HVSI: | ||
268 | rc = hvterm_hvsi_get_chars(0, &c, 1); | ||
269 | break; | ||
270 | } | ||
271 | if (!rc) | ||
272 | return -1; | ||
273 | return c; | ||
274 | } | ||
275 | |||
276 | static int udbg_hvc_getc(void) | ||
277 | { | ||
278 | int ch; | ||
279 | |||
280 | if (!hvterm_privs[0]) | ||
281 | return -1; | ||
282 | |||
283 | for (;;) { | ||
284 | ch = udbg_hvc_getc_poll(); | ||
285 | if (ch == -1) { | ||
286 | /* This shouldn't be needed...but... */ | ||
287 | volatile unsigned long delay; | ||
288 | for (delay=0; delay < 2000000; delay++) | ||
289 | ; | ||
290 | } else { | ||
291 | return ch; | ||
292 | } | ||
293 | } | ||
294 | } | ||
295 | |||
233 | static int __devinit hvc_vio_probe(struct vio_dev *vdev, | 296 | static int __devinit hvc_vio_probe(struct vio_dev *vdev, |
234 | const struct vio_device_id *id) | 297 | const struct vio_device_id *id) |
235 | { | 298 | { |
@@ -289,6 +352,13 @@ static int __devinit hvc_vio_probe(struct vio_dev *vdev, | |||
289 | return PTR_ERR(hp); | 352 | return PTR_ERR(hp); |
290 | dev_set_drvdata(&vdev->dev, hp); | 353 | dev_set_drvdata(&vdev->dev, hp); |
291 | 354 | ||
355 | /* register udbg if it's not there already for console 0 */ | ||
356 | if (hp->index == 0 && !udbg_putc) { | ||
357 | udbg_putc = udbg_hvc_putc; | ||
358 | udbg_getc = udbg_hvc_getc; | ||
359 | udbg_getc_poll = udbg_hvc_getc_poll; | ||
360 | } | ||
361 | |||
292 | return 0; | 362 | return 0; |
293 | } | 363 | } |
294 | 364 | ||
@@ -331,59 +401,6 @@ static void __exit hvc_vio_exit(void) | |||
331 | } | 401 | } |
332 | module_exit(hvc_vio_exit); | 402 | module_exit(hvc_vio_exit); |
333 | 403 | ||
334 | static void udbg_hvc_putc(char c) | ||
335 | { | ||
336 | int count = -1; | ||
337 | |||
338 | if (c == '\n') | ||
339 | udbg_hvc_putc('\r'); | ||
340 | |||
341 | do { | ||
342 | switch(hvterm_priv0.proto) { | ||
343 | case HV_PROTOCOL_RAW: | ||
344 | count = hvterm_raw_put_chars(0, &c, 1); | ||
345 | break; | ||
346 | case HV_PROTOCOL_HVSI: | ||
347 | count = hvterm_hvsi_put_chars(0, &c, 1); | ||
348 | break; | ||
349 | } | ||
350 | } while(count == 0); | ||
351 | } | ||
352 | |||
353 | static int udbg_hvc_getc_poll(void) | ||
354 | { | ||
355 | int rc = 0; | ||
356 | char c; | ||
357 | |||
358 | switch(hvterm_priv0.proto) { | ||
359 | case HV_PROTOCOL_RAW: | ||
360 | rc = hvterm_raw_get_chars(0, &c, 1); | ||
361 | break; | ||
362 | case HV_PROTOCOL_HVSI: | ||
363 | rc = hvterm_hvsi_get_chars(0, &c, 1); | ||
364 | break; | ||
365 | } | ||
366 | if (!rc) | ||
367 | return -1; | ||
368 | return c; | ||
369 | } | ||
370 | |||
371 | static int udbg_hvc_getc(void) | ||
372 | { | ||
373 | int ch; | ||
374 | for (;;) { | ||
375 | ch = udbg_hvc_getc_poll(); | ||
376 | if (ch == -1) { | ||
377 | /* This shouldn't be needed...but... */ | ||
378 | volatile unsigned long delay; | ||
379 | for (delay=0; delay < 2000000; delay++) | ||
380 | ; | ||
381 | } else { | ||
382 | return ch; | ||
383 | } | ||
384 | } | ||
385 | } | ||
386 | |||
387 | void __init hvc_vio_init_early(void) | 404 | void __init hvc_vio_init_early(void) |
388 | { | 405 | { |
389 | struct device_node *stdout_node; | 406 | struct device_node *stdout_node; |