18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * console.c: Routines that deal with sending and receiving IO
48c2ecf20Sopenharmony_ci *            to/from the current console device using the PROM.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
78c2ecf20Sopenharmony_ci * Copyright (C) 1998 Pete Zaitcev <zaitcev@yahoo.com>
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <linux/types.h>
118c2ecf20Sopenharmony_ci#include <linux/kernel.h>
128c2ecf20Sopenharmony_ci#include <linux/sched.h>
138c2ecf20Sopenharmony_ci#include <asm/openprom.h>
148c2ecf20Sopenharmony_ci#include <asm/oplib.h>
158c2ecf20Sopenharmony_ci#include <linux/string.h>
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ciextern void restore_current(void);
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci/* Non blocking put character to console device, returns -1 if
208c2ecf20Sopenharmony_ci * unsuccessful.
218c2ecf20Sopenharmony_ci */
228c2ecf20Sopenharmony_cistatic int prom_nbputchar(const char *buf)
238c2ecf20Sopenharmony_ci{
248c2ecf20Sopenharmony_ci	unsigned long flags;
258c2ecf20Sopenharmony_ci	int i = -1;
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci	spin_lock_irqsave(&prom_lock, flags);
288c2ecf20Sopenharmony_ci	switch(prom_vers) {
298c2ecf20Sopenharmony_ci	case PROM_V0:
308c2ecf20Sopenharmony_ci		if ((*(romvec->pv_nbputchar))(*buf))
318c2ecf20Sopenharmony_ci			i = 1;
328c2ecf20Sopenharmony_ci		break;
338c2ecf20Sopenharmony_ci	case PROM_V2:
348c2ecf20Sopenharmony_ci	case PROM_V3:
358c2ecf20Sopenharmony_ci		if ((*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout,
368c2ecf20Sopenharmony_ci							  buf, 0x1) == 1)
378c2ecf20Sopenharmony_ci			i = 1;
388c2ecf20Sopenharmony_ci		break;
398c2ecf20Sopenharmony_ci	default:
408c2ecf20Sopenharmony_ci		break;
418c2ecf20Sopenharmony_ci	}
428c2ecf20Sopenharmony_ci	restore_current();
438c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&prom_lock, flags);
448c2ecf20Sopenharmony_ci	return i; /* Ugh, we could spin forever on unsupported proms ;( */
458c2ecf20Sopenharmony_ci}
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_civoid prom_console_write_buf(const char *buf, int len)
488c2ecf20Sopenharmony_ci{
498c2ecf20Sopenharmony_ci	while (len) {
508c2ecf20Sopenharmony_ci		int n = prom_nbputchar(buf);
518c2ecf20Sopenharmony_ci		if (n < 0)
528c2ecf20Sopenharmony_ci			continue;
538c2ecf20Sopenharmony_ci		len--;
548c2ecf20Sopenharmony_ci		buf++;
558c2ecf20Sopenharmony_ci	}
568c2ecf20Sopenharmony_ci}
578c2ecf20Sopenharmony_ci
58