xref: /openbmc/linux/arch/sparc/prom/console_32.c (revision e62cac1f)
1708d4f09SSam Ravnborg /*
2708d4f09SSam Ravnborg  * console.c: Routines that deal with sending and receiving IO
3708d4f09SSam Ravnborg  *            to/from the current console device using the PROM.
4708d4f09SSam Ravnborg  *
5708d4f09SSam Ravnborg  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
6708d4f09SSam Ravnborg  * Copyright (C) 1998 Pete Zaitcev <zaitcev@yahoo.com>
7708d4f09SSam Ravnborg  */
8708d4f09SSam Ravnborg 
9708d4f09SSam Ravnborg #include <linux/types.h>
10708d4f09SSam Ravnborg #include <linux/kernel.h>
11708d4f09SSam Ravnborg #include <linux/sched.h>
12708d4f09SSam Ravnborg #include <asm/openprom.h>
13708d4f09SSam Ravnborg #include <asm/oplib.h>
14708d4f09SSam Ravnborg #include <asm/system.h>
15708d4f09SSam Ravnborg #include <linux/string.h>
16708d4f09SSam Ravnborg 
17708d4f09SSam Ravnborg extern void restore_current(void);
18708d4f09SSam Ravnborg 
19708d4f09SSam Ravnborg /* Non blocking get character from console input device, returns -1
20708d4f09SSam Ravnborg  * if no input was taken.  This can be used for polling.
21708d4f09SSam Ravnborg  */
22e62cac1fSDavid S. Miller static int prom_nbgetchar(char *buf)
23708d4f09SSam Ravnborg {
24708d4f09SSam Ravnborg 	unsigned long flags;
25e62cac1fSDavid S. Miller 	int i = -1;
26708d4f09SSam Ravnborg 
27708d4f09SSam Ravnborg 	spin_lock_irqsave(&prom_lock, flags);
28708d4f09SSam Ravnborg 	switch(prom_vers) {
29708d4f09SSam Ravnborg 	case PROM_V0:
30708d4f09SSam Ravnborg 		i = (*(romvec->pv_nbgetchar))();
31e62cac1fSDavid S. Miller 		if (i != -1) {
32e62cac1fSDavid S. Miller 			*buf = i;
33e62cac1fSDavid S. Miller 			i = 0;
34e62cac1fSDavid S. Miller 		}
35708d4f09SSam Ravnborg 		break;
36708d4f09SSam Ravnborg 	case PROM_V2:
37708d4f09SSam Ravnborg 	case PROM_V3:
38e62cac1fSDavid S. Miller 		if ((*(romvec->pv_v2devops).v2_dev_read)(*romvec->pv_v2bootargs.fd_stdin,
39e62cac1fSDavid S. Miller 							 buf, 0x1) == 1)
40e62cac1fSDavid S. Miller 			i = 0;
41708d4f09SSam Ravnborg 		break;
42708d4f09SSam Ravnborg 	default:
43708d4f09SSam Ravnborg 		break;
44708d4f09SSam Ravnborg 	};
45708d4f09SSam Ravnborg 	restore_current();
46708d4f09SSam Ravnborg 	spin_unlock_irqrestore(&prom_lock, flags);
47708d4f09SSam Ravnborg 	return i; /* Ugh, we could spin forever on unsupported proms ;( */
48708d4f09SSam Ravnborg }
49708d4f09SSam Ravnborg 
50708d4f09SSam Ravnborg /* Non blocking put character to console device, returns -1 if
51708d4f09SSam Ravnborg  * unsuccessful.
52708d4f09SSam Ravnborg  */
53e62cac1fSDavid S. Miller static int prom_nbputchar(const char *buf)
54708d4f09SSam Ravnborg {
55708d4f09SSam Ravnborg 	unsigned long flags;
56708d4f09SSam Ravnborg 	int i = -1;
57708d4f09SSam Ravnborg 
58708d4f09SSam Ravnborg 	spin_lock_irqsave(&prom_lock, flags);
59708d4f09SSam Ravnborg 	switch(prom_vers) {
60708d4f09SSam Ravnborg 	case PROM_V0:
61e62cac1fSDavid S. Miller 		i = (*(romvec->pv_nbputchar))(*buf);
62708d4f09SSam Ravnborg 		break;
63708d4f09SSam Ravnborg 	case PROM_V2:
64708d4f09SSam Ravnborg 	case PROM_V3:
65e62cac1fSDavid S. Miller 		if ((*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout,
66e62cac1fSDavid S. Miller 							  buf, 0x1) == 1)
67708d4f09SSam Ravnborg 			i = 0;
68708d4f09SSam Ravnborg 		break;
69708d4f09SSam Ravnborg 	default:
70708d4f09SSam Ravnborg 		break;
71708d4f09SSam Ravnborg 	};
72708d4f09SSam Ravnborg 	restore_current();
73708d4f09SSam Ravnborg 	spin_unlock_irqrestore(&prom_lock, flags);
74708d4f09SSam Ravnborg 	return i; /* Ugh, we could spin forever on unsupported proms ;( */
75708d4f09SSam Ravnborg }
76708d4f09SSam Ravnborg 
77708d4f09SSam Ravnborg /* Blocking version of get character routine above. */
78e62cac1fSDavid S. Miller void prom_getchar(char *buf)
79708d4f09SSam Ravnborg {
80e62cac1fSDavid S. Miller 	while (1) {
81e62cac1fSDavid S. Miller 		int err = prom_nbgetchar(buf);
82e62cac1fSDavid S. Miller 		if (!err)
83e62cac1fSDavid S. Miller 			break;
84e62cac1fSDavid S. Miller 	}
85708d4f09SSam Ravnborg }
86708d4f09SSam Ravnborg 
87708d4f09SSam Ravnborg /* Blocking version of put character routine above. */
88e62cac1fSDavid S. Miller void prom_putchar(const char *buf)
89708d4f09SSam Ravnborg {
90e62cac1fSDavid S. Miller 	while (1) {
91e62cac1fSDavid S. Miller 		int err = prom_nbputchar(buf);
92e62cac1fSDavid S. Miller 		if (!err)
93e62cac1fSDavid S. Miller 			break;
94e62cac1fSDavid S. Miller 	}
95708d4f09SSam Ravnborg }
96