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 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 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 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 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