Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * console.c: Routines that deal with sending and receiving IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *            to/from the current console device using the PROM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <asm/openprom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <asm/oplib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) /* Non blocking get character from console input device, returns -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * if no input was taken.  This can be used for polling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) prom_nbgetchar(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	int i = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 		i = (*(romvec->pv_nbgetchar))();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	return i; /* Ugh, we could spin forever on unsupported proms ;( */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) /* Non blocking put character to console device, returns -1 if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * unsuccessful.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) prom_nbputchar(char c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	int i = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		i = (*(romvec->pv_nbputchar))(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	return i; /* Ugh, we could spin forever on unsupported proms ;( */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) /* Blocking version of get character routine above. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) prom_getchar(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	int character;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	while((character = prom_nbgetchar()) == -1) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	return (char) character;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) /* Blocking version of put character routine above. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) prom_putchar(char c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	while(prom_nbputchar(c) == -1) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) /* Query for input device type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) enum prom_input_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) prom_query_input_device()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	int st_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	char propb[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	switch(prom_vers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	case PROM_V0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	case PROM_V2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		switch(*romvec->pv_stdin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		case PROMDEV_KBD:	return PROMDEV_IKBD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		case PROMDEV_TTYA:	return PROMDEV_ITTYA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		case PROMDEV_TTYB:	return PROMDEV_ITTYB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 			return PROMDEV_I_UNK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	case PROM_V3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	case PROM_P1275:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		__asm__ __volatile__("ld [%0], %%g6\n\t" : :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 				     "r" (&current_set[smp_processor_id()]) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 				     "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		if(prom_node_has_property(st_p, "keyboard"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 			return PROMDEV_IKBD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		prom_getproperty(st_p, "device_type", propb, sizeof(propb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		if(strncmp(propb, "serial", sizeof("serial")))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 			return PROMDEV_I_UNK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		prom_getproperty(prom_root_node, "stdin-path", propb, sizeof(propb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		p = propb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		while(*p) p++; p -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		if(p[0] == ':') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			if(p[1] == 'a')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 				return PROMDEV_ITTYA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			else if(p[1] == 'b')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 				return PROMDEV_ITTYB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		return PROMDEV_I_UNK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* Query for output device type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) enum prom_output_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) prom_query_output_device()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	int st_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	char propb[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	int propl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	switch(prom_vers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	case PROM_V0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		switch(*romvec->pv_stdin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		case PROMDEV_SCREEN:	return PROMDEV_OSCREEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		case PROMDEV_TTYA:	return PROMDEV_OTTYA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		case PROMDEV_TTYB:	return PROMDEV_OTTYB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	case PROM_V2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	case PROM_V3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	case PROM_P1275:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		__asm__ __volatile__("ld [%0], %%g6\n\t" : :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 				     "r" (&current_set[smp_processor_id()]) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 				     "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		if (propl >= 0 && propl == sizeof("display") &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 			strncmp("display", propb, sizeof("display")) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 			return PROMDEV_OSCREEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		if(prom_vers == PROM_V3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 			if(strncmp("serial", propb, sizeof("serial")))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 				return PROMDEV_O_UNK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			prom_getproperty(prom_root_node, "stdout-path", propb, sizeof(propb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 			p = propb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 			while(*p) p++; p -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 			if(p[0]==':') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 				if(p[1] == 'a')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 					return PROMDEV_OTTYA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 				else if(p[1] == 'b')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 					return PROMDEV_OTTYB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 			return PROMDEV_O_UNK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			/* This works on SS-2 (an early OpenFirmware) still. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 			switch(*romvec->pv_stdin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			case PROMDEV_TTYA:	return PROMDEV_OTTYA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 			case PROMDEV_TTYB:	return PROMDEV_OTTYB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 			};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	return PROMDEV_O_UNK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #endif