1*b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2f30828a6SAdrian Bunk /*
31da177e4SLinus Torvalds * console.c: Routines that deal with sending and receiving IO
41da177e4SLinus Torvalds * to/from the current console device using the PROM.
51da177e4SLinus Torvalds *
61da177e4SLinus Torvalds * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
71da177e4SLinus Torvalds */
81da177e4SLinus Torvalds
91da177e4SLinus Torvalds #include <linux/types.h>
101da177e4SLinus Torvalds #include <linux/kernel.h>
111da177e4SLinus Torvalds #include <linux/sched.h>
121da177e4SLinus Torvalds #include <asm/openprom.h>
131da177e4SLinus Torvalds #include <asm/oplib.h>
141da177e4SLinus Torvalds #include <linux/string.h>
151da177e4SLinus Torvalds
161da177e4SLinus Torvalds /* Non blocking get character from console input device, returns -1
171da177e4SLinus Torvalds * if no input was taken. This can be used for polling.
181da177e4SLinus Torvalds */
191da177e4SLinus Torvalds int
prom_nbgetchar(void)201da177e4SLinus Torvalds prom_nbgetchar(void)
211da177e4SLinus Torvalds {
221da177e4SLinus Torvalds int i = -1;
231da177e4SLinus Torvalds unsigned long flags;
241da177e4SLinus Torvalds
251da177e4SLinus Torvalds local_irq_save(flags);
261da177e4SLinus Torvalds i = (*(romvec->pv_nbgetchar))();
271da177e4SLinus Torvalds local_irq_restore(flags);
281da177e4SLinus Torvalds return i; /* Ugh, we could spin forever on unsupported proms ;( */
291da177e4SLinus Torvalds }
301da177e4SLinus Torvalds
311da177e4SLinus Torvalds /* Non blocking put character to console device, returns -1 if
321da177e4SLinus Torvalds * unsuccessful.
331da177e4SLinus Torvalds */
341da177e4SLinus Torvalds int
prom_nbputchar(char c)351da177e4SLinus Torvalds prom_nbputchar(char c)
361da177e4SLinus Torvalds {
371da177e4SLinus Torvalds unsigned long flags;
381da177e4SLinus Torvalds int i = -1;
391da177e4SLinus Torvalds
401da177e4SLinus Torvalds local_irq_save(flags);
411da177e4SLinus Torvalds i = (*(romvec->pv_nbputchar))(c);
421da177e4SLinus Torvalds local_irq_restore(flags);
431da177e4SLinus Torvalds return i; /* Ugh, we could spin forever on unsupported proms ;( */
441da177e4SLinus Torvalds }
451da177e4SLinus Torvalds
461da177e4SLinus Torvalds /* Blocking version of get character routine above. */
471da177e4SLinus Torvalds char
prom_getchar(void)481da177e4SLinus Torvalds prom_getchar(void)
491da177e4SLinus Torvalds {
501da177e4SLinus Torvalds int character;
511da177e4SLinus Torvalds while((character = prom_nbgetchar()) == -1) ;
521da177e4SLinus Torvalds return (char) character;
531da177e4SLinus Torvalds }
541da177e4SLinus Torvalds
551da177e4SLinus Torvalds /* Blocking version of put character routine above. */
561da177e4SLinus Torvalds void
prom_putchar(char c)571da177e4SLinus Torvalds prom_putchar(char c)
581da177e4SLinus Torvalds {
591da177e4SLinus Torvalds while(prom_nbputchar(c) == -1) ;
601da177e4SLinus Torvalds return;
611da177e4SLinus Torvalds }
621da177e4SLinus Torvalds
631da177e4SLinus Torvalds /* Query for input device type */
641da177e4SLinus Torvalds #if 0
651da177e4SLinus Torvalds enum prom_input_device
661da177e4SLinus Torvalds prom_query_input_device()
671da177e4SLinus Torvalds {
681da177e4SLinus Torvalds unsigned long flags;
691da177e4SLinus Torvalds int st_p;
701da177e4SLinus Torvalds char propb[64];
711da177e4SLinus Torvalds char *p;
721da177e4SLinus Torvalds
731da177e4SLinus Torvalds switch(prom_vers) {
741da177e4SLinus Torvalds case PROM_V0:
751da177e4SLinus Torvalds case PROM_V2:
761da177e4SLinus Torvalds default:
771da177e4SLinus Torvalds switch(*romvec->pv_stdin) {
781da177e4SLinus Torvalds case PROMDEV_KBD: return PROMDEV_IKBD;
791da177e4SLinus Torvalds case PROMDEV_TTYA: return PROMDEV_ITTYA;
801da177e4SLinus Torvalds case PROMDEV_TTYB: return PROMDEV_ITTYB;
811da177e4SLinus Torvalds default:
821da177e4SLinus Torvalds return PROMDEV_I_UNK;
831da177e4SLinus Torvalds };
841da177e4SLinus Torvalds case PROM_V3:
851da177e4SLinus Torvalds case PROM_P1275:
861da177e4SLinus Torvalds local_irq_save(flags);
871da177e4SLinus Torvalds st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdin);
881da177e4SLinus Torvalds __asm__ __volatile__("ld [%0], %%g6\n\t" : :
891da177e4SLinus Torvalds "r" (¤t_set[smp_processor_id()]) :
901da177e4SLinus Torvalds "memory");
911da177e4SLinus Torvalds local_irq_restore(flags);
921da177e4SLinus Torvalds if(prom_node_has_property(st_p, "keyboard"))
931da177e4SLinus Torvalds return PROMDEV_IKBD;
941da177e4SLinus Torvalds prom_getproperty(st_p, "device_type", propb, sizeof(propb));
951da177e4SLinus Torvalds if(strncmp(propb, "serial", sizeof("serial")))
961da177e4SLinus Torvalds return PROMDEV_I_UNK;
971da177e4SLinus Torvalds prom_getproperty(prom_root_node, "stdin-path", propb, sizeof(propb));
981da177e4SLinus Torvalds p = propb;
991da177e4SLinus Torvalds while(*p) p++; p -= 2;
1001da177e4SLinus Torvalds if(p[0] == ':') {
1011da177e4SLinus Torvalds if(p[1] == 'a')
1021da177e4SLinus Torvalds return PROMDEV_ITTYA;
1031da177e4SLinus Torvalds else if(p[1] == 'b')
1041da177e4SLinus Torvalds return PROMDEV_ITTYB;
1051da177e4SLinus Torvalds }
1061da177e4SLinus Torvalds return PROMDEV_I_UNK;
1071da177e4SLinus Torvalds };
1081da177e4SLinus Torvalds }
1091da177e4SLinus Torvalds #endif
1101da177e4SLinus Torvalds
1111da177e4SLinus Torvalds /* Query for output device type */
1121da177e4SLinus Torvalds
1131da177e4SLinus Torvalds #if 0
1141da177e4SLinus Torvalds enum prom_output_device
1151da177e4SLinus Torvalds prom_query_output_device()
1161da177e4SLinus Torvalds {
1171da177e4SLinus Torvalds unsigned long flags;
1181da177e4SLinus Torvalds int st_p;
1191da177e4SLinus Torvalds char propb[64];
1201da177e4SLinus Torvalds char *p;
1211da177e4SLinus Torvalds int propl;
1221da177e4SLinus Torvalds
1231da177e4SLinus Torvalds switch(prom_vers) {
1241da177e4SLinus Torvalds case PROM_V0:
1251da177e4SLinus Torvalds switch(*romvec->pv_stdin) {
1261da177e4SLinus Torvalds case PROMDEV_SCREEN: return PROMDEV_OSCREEN;
1271da177e4SLinus Torvalds case PROMDEV_TTYA: return PROMDEV_OTTYA;
1281da177e4SLinus Torvalds case PROMDEV_TTYB: return PROMDEV_OTTYB;
1291da177e4SLinus Torvalds };
1301da177e4SLinus Torvalds break;
1311da177e4SLinus Torvalds case PROM_V2:
1321da177e4SLinus Torvalds case PROM_V3:
1331da177e4SLinus Torvalds case PROM_P1275:
1341da177e4SLinus Torvalds local_irq_save(flags);
1351da177e4SLinus Torvalds st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdout);
1361da177e4SLinus Torvalds __asm__ __volatile__("ld [%0], %%g6\n\t" : :
1371da177e4SLinus Torvalds "r" (¤t_set[smp_processor_id()]) :
1381da177e4SLinus Torvalds "memory");
1391da177e4SLinus Torvalds local_irq_restore(flags);
1401da177e4SLinus Torvalds propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb));
1411da177e4SLinus Torvalds if (propl >= 0 && propl == sizeof("display") &&
1421da177e4SLinus Torvalds strncmp("display", propb, sizeof("display")) == 0)
1431da177e4SLinus Torvalds {
1441da177e4SLinus Torvalds return PROMDEV_OSCREEN;
1451da177e4SLinus Torvalds }
1461da177e4SLinus Torvalds if(prom_vers == PROM_V3) {
1471da177e4SLinus Torvalds if(strncmp("serial", propb, sizeof("serial")))
1481da177e4SLinus Torvalds return PROMDEV_O_UNK;
1491da177e4SLinus Torvalds prom_getproperty(prom_root_node, "stdout-path", propb, sizeof(propb));
1501da177e4SLinus Torvalds p = propb;
1511da177e4SLinus Torvalds while(*p) p++; p -= 2;
1521da177e4SLinus Torvalds if(p[0]==':') {
1531da177e4SLinus Torvalds if(p[1] == 'a')
1541da177e4SLinus Torvalds return PROMDEV_OTTYA;
1551da177e4SLinus Torvalds else if(p[1] == 'b')
1561da177e4SLinus Torvalds return PROMDEV_OTTYB;
1571da177e4SLinus Torvalds }
1581da177e4SLinus Torvalds return PROMDEV_O_UNK;
1591da177e4SLinus Torvalds } else {
1601da177e4SLinus Torvalds /* This works on SS-2 (an early OpenFirmware) still. */
1611da177e4SLinus Torvalds switch(*romvec->pv_stdin) {
1621da177e4SLinus Torvalds case PROMDEV_TTYA: return PROMDEV_OTTYA;
1631da177e4SLinus Torvalds case PROMDEV_TTYB: return PROMDEV_OTTYB;
1641da177e4SLinus Torvalds };
1651da177e4SLinus Torvalds }
1661da177e4SLinus Torvalds break;
1671da177e4SLinus Torvalds };
1681da177e4SLinus Torvalds return PROMDEV_O_UNK;
1691da177e4SLinus Torvalds }
1701da177e4SLinus Torvalds #endif
171