Currently, uart_console_write->putchar's second parameter (the character) is of type int. It makes little sense, provided uart_console_write() accepts the input string as "const char *s" and passes its content -- the characters -- to putchar(). So switch the character's type to unsigned char. We don't use char as that is signed on some platforms. That would cause troubles for drivers which (implicitly) cast the char to u16 when writing to the device. Sign extension would happen in that case and the value written would be completely different to the provided char. DZ is an example of such a driver -- on MIPS, it uses u16 for dz_out in dz_console_putchar(). Note we do the char -> uchar conversion implicitly in uart_console_write(). Provided we do not change size of the data type, sign extension does not happen there, so the problem is void. This makes the types consistent and unified with the rest of the uart layer, which uses unsigned char in most places already. One exception is xmit_buf, but that is going to be converted later. Cc: Paul Cercueil <paul@crapouillou.net> Cc: Tobias Klauser <tklauser@distanz.ch> Cc: Russell King <linux@armlinux.org.uk> Cc: Vineet Gupta <vgupta@kernel.org> Cc: Nicolas Ferre <nicolas.ferre@microchip.com> Cc: Alexandre Belloni <alexandre.belloni@bootlin.com> Cc: Ludovic Desroches <ludovic.desroches@microchip.com> Cc: Florian Fainelli <f.fainelli@gmail.com> Cc: bcm-kernel-feedback-list@broadcom.com Cc: Alexander Shiyan <shc_work@mail.ru> Cc: Baruch Siach <baruch@tkos.co.il> Cc: "Maciej W. Rozycki" <macro@orcam.me.uk> Cc: Paul Walmsley <paul.walmsley@sifive.com> Cc: Palmer Dabbelt <palmer@dabbelt.com> Cc: Albert Ou <aou@eecs.berkeley.edu> Cc: Shawn Guo <shawnguo@kernel.org> Cc: Sascha Hauer <s.hauer@pengutronix.de> Cc: Pengutronix Kernel Team <kernel@pengutronix.de> Cc: Fabio Estevam <festevam@gmail.com> Cc: NXP Linux Team <linux-imx@nxp.com> Cc: Karol Gugala <kgugala@antmicro.com> Cc: Mateusz Holenko <mholenko@antmicro.com> Cc: Vladimir Zapolskiy <vz@mleia.com> Cc: Neil Armstrong <narmstrong@baylibre.com> Cc: Kevin Hilman <khilman@baylibre.com> Cc: Jerome Brunet <jbrunet@baylibre.com> Cc: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Cc: Taichi Sugaya <sugaya.taichi@socionext.com> Cc: Takao Orito <orito.takao@socionext.com> Cc: Liviu Dudau <liviu.dudau@arm.com> Cc: Sudeep Holla <sudeep.holla@arm.com> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Cc: "Andreas Färber" <afaerber@suse.de> Cc: Manivannan Sadhasivam <mani@kernel.org> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Andy Gross <agross@kernel.org> Cc: Bjorn Andersson <bjorn.andersson@linaro.org> Cc: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> Cc: Orson Zhai <orsonzhai@gmail.com> Cc: Baolin Wang <baolin.wang7@gmail.com> Cc: Chunyan Zhang <zhang.lyra@gmail.com> Cc: Patrice Chotard <patrice.chotard@foss.st.com> Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com> Cc: Alexandre Torgue <alexandre.torgue@foss.st.com> Cc: "David S. Miller" <davem@davemloft.net> Cc: Peter Korsgaard <peter@korsgaard.com> Cc: Michal Simek <michal.simek@xilinx.com> Acked-by: Richard Genoud <richard.genoud@gmail.com> [atmel_serial] Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Acked-by: Paul Cercueil <paul@crapouillou.net> Acked-by: Neil Armstrong <narmstrong@baylibre.com> # meson_serial Signed-off-by: Jiri Slaby <jslaby@suse.cz> Link: https://lore.kernel.org/r/20220303080831.21783-1-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
116 lines
2.2 KiB
C
116 lines
2.2 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/* Copyright (c) 2010, 2014 The Linux Foundation. All rights reserved. */
|
|
|
|
#include <linux/console.h>
|
|
#include <linux/init.h>
|
|
#include <linux/serial.h>
|
|
#include <linux/serial_core.h>
|
|
|
|
#include <asm/dcc.h>
|
|
#include <asm/processor.h>
|
|
|
|
#include "hvc_console.h"
|
|
|
|
/* DCC Status Bits */
|
|
#define DCC_STATUS_RX (1 << 30)
|
|
#define DCC_STATUS_TX (1 << 29)
|
|
|
|
static void dcc_uart_console_putchar(struct uart_port *port, unsigned char ch)
|
|
{
|
|
while (__dcc_getstatus() & DCC_STATUS_TX)
|
|
cpu_relax();
|
|
|
|
__dcc_putchar(ch);
|
|
}
|
|
|
|
static void dcc_early_write(struct console *con, const char *s, unsigned n)
|
|
{
|
|
struct earlycon_device *dev = con->data;
|
|
|
|
uart_console_write(&dev->port, s, n, dcc_uart_console_putchar);
|
|
}
|
|
|
|
static int __init dcc_early_console_setup(struct earlycon_device *device,
|
|
const char *opt)
|
|
{
|
|
device->con->write = dcc_early_write;
|
|
|
|
return 0;
|
|
}
|
|
|
|
EARLYCON_DECLARE(dcc, dcc_early_console_setup);
|
|
|
|
static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < count; i++) {
|
|
while (__dcc_getstatus() & DCC_STATUS_TX)
|
|
cpu_relax();
|
|
|
|
__dcc_putchar(buf[i]);
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
static int hvc_dcc_get_chars(uint32_t vt, char *buf, int count)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < count; ++i)
|
|
if (__dcc_getstatus() & DCC_STATUS_RX)
|
|
buf[i] = __dcc_getchar();
|
|
else
|
|
break;
|
|
|
|
return i;
|
|
}
|
|
|
|
static bool hvc_dcc_check(void)
|
|
{
|
|
unsigned long time = jiffies + (HZ / 10);
|
|
|
|
/* Write a test character to check if it is handled */
|
|
__dcc_putchar('\n');
|
|
|
|
while (time_is_after_jiffies(time)) {
|
|
if (!(__dcc_getstatus() & DCC_STATUS_TX))
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
static const struct hv_ops hvc_dcc_get_put_ops = {
|
|
.get_chars = hvc_dcc_get_chars,
|
|
.put_chars = hvc_dcc_put_chars,
|
|
};
|
|
|
|
static int __init hvc_dcc_console_init(void)
|
|
{
|
|
int ret;
|
|
|
|
if (!hvc_dcc_check())
|
|
return -ENODEV;
|
|
|
|
/* Returns -1 if error */
|
|
ret = hvc_instantiate(0, 0, &hvc_dcc_get_put_ops);
|
|
|
|
return ret < 0 ? -ENODEV : 0;
|
|
}
|
|
console_initcall(hvc_dcc_console_init);
|
|
|
|
static int __init hvc_dcc_init(void)
|
|
{
|
|
struct hvc_struct *p;
|
|
|
|
if (!hvc_dcc_check())
|
|
return -ENODEV;
|
|
|
|
p = hvc_alloc(0, 0, &hvc_dcc_get_put_ops, 128);
|
|
|
|
return PTR_ERR_OR_ZERO(p);
|
|
}
|
|
device_initcall(hvc_dcc_init);
|