Linux Audio

Check our new training course

Loading...
v5.9
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2010, 2014 The Linux Foundation. All rights reserved.  */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  3
  4#include <linux/console.h>
 
 
  5#include <linux/init.h>
  6#include <linux/serial.h>
  7#include <linux/serial_core.h>
  8
  9#include <asm/dcc.h>
 10#include <asm/processor.h>
 11
 12#include "hvc_console.h"
 13
 14/* DCC Status Bits */
 15#define DCC_STATUS_RX		(1 << 30)
 16#define DCC_STATUS_TX		(1 << 29)
 17
 18static void dcc_uart_console_putchar(struct uart_port *port, int ch)
 19{
 20	while (__dcc_getstatus() & DCC_STATUS_TX)
 21		cpu_relax();
 
 22
 23	__dcc_putchar(ch);
 24}
 25
 26static void dcc_early_write(struct console *con, const char *s, unsigned n)
 
 27{
 28	struct earlycon_device *dev = con->data;
 
 
 
 
 29
 30	uart_console_write(&dev->port, s, n, dcc_uart_console_putchar);
 31}
 32
 33static int __init dcc_early_console_setup(struct earlycon_device *device,
 34					  const char *opt)
 35{
 36	device->con->write = dcc_early_write;
 37
 38	return 0;
 
 39}
 40
 41EARLYCON_DECLARE(dcc, dcc_early_console_setup);
 42
 43static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count)
 44{
 45	int i;
 46
 47	for (i = 0; i < count; i++) {
 48		while (__dcc_getstatus() & DCC_STATUS_TX)
 49			cpu_relax();
 50
 51		__dcc_putchar(buf[i]);
 52	}
 53
 54	return count;
 55}
 56
 57static int hvc_dcc_get_chars(uint32_t vt, char *buf, int count)
 58{
 59	int i;
 60
 61	for (i = 0; i < count; ++i)
 62		if (__dcc_getstatus() & DCC_STATUS_RX)
 63			buf[i] = __dcc_getchar();
 64		else
 65			break;
 66
 67	return i;
 68}
 69
 70static bool hvc_dcc_check(void)
 71{
 72	unsigned long time = jiffies + (HZ / 10);
 73
 74	/* Write a test character to check if it is handled */
 75	__dcc_putchar('\n');
 76
 77	while (time_is_after_jiffies(time)) {
 78		if (!(__dcc_getstatus() & DCC_STATUS_TX))
 79			return true;
 80	}
 81
 82	return false;
 83}
 84
 85static const struct hv_ops hvc_dcc_get_put_ops = {
 86	.get_chars = hvc_dcc_get_chars,
 87	.put_chars = hvc_dcc_put_chars,
 88};
 89
 90static int __init hvc_dcc_console_init(void)
 91{
 92	int ret;
 93
 94	if (!hvc_dcc_check())
 95		return -ENODEV;
 96
 97	/* Returns -1 if error */
 98	ret = hvc_instantiate(0, 0, &hvc_dcc_get_put_ops);
 99
100	return ret < 0 ? -ENODEV : 0;
101}
102console_initcall(hvc_dcc_console_init);
103
104static int __init hvc_dcc_init(void)
105{
106	struct hvc_struct *p;
107
108	if (!hvc_dcc_check())
109		return -ENODEV;
110
111	p = hvc_alloc(0, 0, &hvc_dcc_get_put_ops, 128);
112
113	return PTR_ERR_OR_ZERO(p);
114}
115device_initcall(hvc_dcc_init);
v3.15
  1/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
  2 *
  3 * This program is free software; you can redistribute it and/or modify
  4 * it under the terms of the GNU General Public License version 2 and
  5 * only version 2 as published by the Free Software Foundation.
  6 *
  7 * This program is distributed in the hope that it will be useful,
  8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 10 * GNU General Public License for more details.
 11 *
 12 * You should have received a copy of the GNU General Public License
 13 * along with this program; if not, write to the Free Software
 14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 15 * 02110-1301, USA.
 16 */
 17
 18#include <linux/console.h>
 19#include <linux/delay.h>
 20#include <linux/err.h>
 21#include <linux/init.h>
 22#include <linux/moduleparam.h>
 23#include <linux/types.h>
 24
 
 25#include <asm/processor.h>
 26
 27#include "hvc_console.h"
 28
 29/* DCC Status Bits */
 30#define DCC_STATUS_RX		(1 << 30)
 31#define DCC_STATUS_TX		(1 << 29)
 32
 33static inline u32 __dcc_getstatus(void)
 34{
 35	u32 __ret;
 36	asm volatile("mrc p14, 0, %0, c0, c1, 0	@ read comms ctrl reg"
 37		: "=r" (__ret) : : "cc");
 38
 39	return __ret;
 40}
 41
 42
 43static inline char __dcc_getchar(void)
 44{
 45	char __c;
 46
 47	asm volatile("mrc p14, 0, %0, c0, c5, 0	@ read comms data reg"
 48		: "=r" (__c));
 49	isb();
 50
 51	return __c;
 52}
 53
 54static inline void __dcc_putchar(char c)
 
 55{
 56	asm volatile("mcr p14, 0, %0, c0, c5, 0	@ write a char"
 57		: /* no output register */
 58		: "r" (c));
 59	isb();
 60}
 61
 
 
 62static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count)
 63{
 64	int i;
 65
 66	for (i = 0; i < count; i++) {
 67		while (__dcc_getstatus() & DCC_STATUS_TX)
 68			cpu_relax();
 69
 70		__dcc_putchar(buf[i]);
 71	}
 72
 73	return count;
 74}
 75
 76static int hvc_dcc_get_chars(uint32_t vt, char *buf, int count)
 77{
 78	int i;
 79
 80	for (i = 0; i < count; ++i)
 81		if (__dcc_getstatus() & DCC_STATUS_RX)
 82			buf[i] = __dcc_getchar();
 83		else
 84			break;
 85
 86	return i;
 87}
 88
 89static bool hvc_dcc_check(void)
 90{
 91	unsigned long time = jiffies + (HZ / 10);
 92
 93	/* Write a test character to check if it is handled */
 94	__dcc_putchar('\n');
 95
 96	while (time_is_after_jiffies(time)) {
 97		if (!(__dcc_getstatus() & DCC_STATUS_TX))
 98			return true;
 99	}
100
101	return false;
102}
103
104static const struct hv_ops hvc_dcc_get_put_ops = {
105	.get_chars = hvc_dcc_get_chars,
106	.put_chars = hvc_dcc_put_chars,
107};
108
109static int __init hvc_dcc_console_init(void)
110{
 
 
111	if (!hvc_dcc_check())
112		return -ENODEV;
113
114	hvc_instantiate(0, 0, &hvc_dcc_get_put_ops);
115	return 0;
 
 
116}
117console_initcall(hvc_dcc_console_init);
118
119static int __init hvc_dcc_init(void)
120{
 
 
121	if (!hvc_dcc_check())
122		return -ENODEV;
123
124	hvc_alloc(0, 0, &hvc_dcc_get_put_ops, 128);
125	return 0;
 
126}
127device_initcall(hvc_dcc_init);