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);
v4.17
 1// SPDX-License-Identifier: GPL-2.0
 2/* Copyright (c) 2010, 2014 The Linux Foundation. All rights reserved.  */
 3
 
 4#include <linux/init.h>
 
 
 5
 6#include <asm/dcc.h>
 7#include <asm/processor.h>
 8
 9#include "hvc_console.h"
10
11/* DCC Status Bits */
12#define DCC_STATUS_RX		(1 << 30)
13#define DCC_STATUS_TX		(1 << 29)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
15static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count)
16{
17	int i;
18
19	for (i = 0; i < count; i++) {
20		while (__dcc_getstatus() & DCC_STATUS_TX)
21			cpu_relax();
22
23		__dcc_putchar(buf[i]);
24	}
25
26	return count;
27}
28
29static int hvc_dcc_get_chars(uint32_t vt, char *buf, int count)
30{
31	int i;
32
33	for (i = 0; i < count; ++i)
34		if (__dcc_getstatus() & DCC_STATUS_RX)
35			buf[i] = __dcc_getchar();
36		else
37			break;
38
39	return i;
40}
41
42static bool hvc_dcc_check(void)
43{
44	unsigned long time = jiffies + (HZ / 10);
45
46	/* Write a test character to check if it is handled */
47	__dcc_putchar('\n');
48
49	while (time_is_after_jiffies(time)) {
50		if (!(__dcc_getstatus() & DCC_STATUS_TX))
51			return true;
52	}
53
54	return false;
55}
56
57static const struct hv_ops hvc_dcc_get_put_ops = {
58	.get_chars = hvc_dcc_get_chars,
59	.put_chars = hvc_dcc_put_chars,
60};
61
62static int __init hvc_dcc_console_init(void)
63{
64	int ret;
65
66	if (!hvc_dcc_check())
67		return -ENODEV;
68
69	/* Returns -1 if error */
70	ret = hvc_instantiate(0, 0, &hvc_dcc_get_put_ops);
71
72	return ret < 0 ? -ENODEV : 0;
73}
74console_initcall(hvc_dcc_console_init);
75
76static int __init hvc_dcc_init(void)
77{
78	struct hvc_struct *p;
79
80	if (!hvc_dcc_check())
81		return -ENODEV;
82
83	p = hvc_alloc(0, 0, &hvc_dcc_get_put_ops, 128);
84
85	return PTR_ERR_OR_ZERO(p);
86}
87device_initcall(hvc_dcc_init);