Linux Audio

Check our new training course

Loading...
v3.1
  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
 50	return __c;
 51}
 52
 53static inline void __dcc_putchar(char c)
 54{
 55	asm volatile("mcr p14, 0, %0, c0, c5, 0	@ write a char"
 56		: /* no output register */
 57		: "r" (c));
 58}
 59
 60static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count)
 61{
 62	int i;
 63
 64	for (i = 0; i < count; i++) {
 65		while (__dcc_getstatus() & DCC_STATUS_TX)
 66			cpu_relax();
 67
 68		__dcc_putchar(buf[i]);
 69	}
 70
 71	return count;
 72}
 73
 74static int hvc_dcc_get_chars(uint32_t vt, char *buf, int count)
 75{
 76	int i;
 77
 78	for (i = 0; i < count; ++i)
 79		if (__dcc_getstatus() & DCC_STATUS_RX)
 80			buf[i] = __dcc_getchar();
 81		else
 82			break;
 83
 84	return i;
 85}
 86
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 87static const struct hv_ops hvc_dcc_get_put_ops = {
 88	.get_chars = hvc_dcc_get_chars,
 89	.put_chars = hvc_dcc_put_chars,
 90};
 91
 92static int __init hvc_dcc_console_init(void)
 93{
 94	hvc_instantiate(0, 0, &hvc_dcc_get_put_ops);
 95	return 0;
 
 
 
 
 
 
 
 96}
 97console_initcall(hvc_dcc_console_init);
 98
 99static int __init hvc_dcc_init(void)
100{
101	hvc_alloc(0, 0, &hvc_dcc_get_put_ops, 128);
102	return 0;
 
 
 
 
 
 
103}
104device_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);