* [PATCH v3 0/6] serial: Separate RT288x/Au1xxx code into own file
@ 2023-05-09 11:39 Ilpo Järvinen
2023-05-09 11:39 ` [PATCH v3 1/6] serial: 8250: Change dl_read/write to handle value as u32 Ilpo Järvinen
` (5 more replies)
0 siblings, 6 replies; 9+ messages in thread
From: Ilpo Järvinen @ 2023-05-09 11:39 UTC (permalink / raw)
To: linux-serial, Greg Kroah-Hartman, Jiri Slaby,
Philippe Mathieu-Daudé
Cc: linux-kernel, Niklas Schnelle, Ilpo Järvinen
A non-trivial amount of RT288x/Au1xxx code is encapsulated into
ifdeffery in 8250_port / 8250_early and some if/switch UPIO_AU blocks.
Create a separate file from them and do a few additional cleanups.
I kept the Kconfig entry as bool because the code has somewhat tricky
dependency chain (mips arch code and 8250_of driver).
v3:
- Convert dl_read/write() to take u32 arg + name the args
- Separatate the non-driver datastructure changes & document them better
- Fix build when SERIAL_8250=m + SERIAL_8250_RT288X=y (+note reasoning
in the commit message for future reference)
- Use u8 for arrays that no longer have < 0 values
v2:
- Define register map array lengths explicitly to avoid creating
declaration trap.
Ilpo Järvinen (6):
serial: 8250: Change dl_read/write to handle value as u32
serial: 8250: Document uart_8250_port's ->dl_read/write()
serial: 8250: Add dl_read/write, bugs and mapsize into plat_serial8250_port
serial: 8250: RT288x/Au1xxx code away from core
serial: 8250_rt288x: Name non-standard divisor latch reg
serial: 8250_rt288x: Remove unnecessary UART_REG_UNMAPPED
arch/mips/alchemy/common/platform.c | 10 +-
drivers/tty/serial/8250/8250.h | 4 +-
drivers/tty/serial/8250/8250_core.c | 4 +
drivers/tty/serial/8250/8250_early.c | 21 ----
drivers/tty/serial/8250/8250_em.c | 4 +-
drivers/tty/serial/8250/8250_of.c | 4 +-
drivers/tty/serial/8250/8250_port.c | 84 +--------------
drivers/tty/serial/8250/8250_pxa.c | 2 +-
drivers/tty/serial/8250/8250_rt288x.c | 136 ++++++++++++++++++++++++
drivers/tty/serial/8250/8250_uniphier.c | 4 +-
drivers/tty/serial/8250/Makefile | 1 +
drivers/tty/serial/Makefile | 2 +-
include/linux/serial_8250.h | 42 +++++++-
13 files changed, 200 insertions(+), 118 deletions(-)
create mode 100644 drivers/tty/serial/8250/8250_rt288x.c
--
2.30.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v3 1/6] serial: 8250: Change dl_read/write to handle value as u32
2023-05-09 11:39 [PATCH v3 0/6] serial: Separate RT288x/Au1xxx code into own file Ilpo Järvinen
@ 2023-05-09 11:39 ` Ilpo Järvinen
2023-05-10 5:47 ` Jiri Slaby
2023-05-09 11:39 ` [PATCH v3 2/6] serial: 8250: Document uart_8250_port's ->dl_read/write() Ilpo Järvinen
` (4 subsequent siblings)
5 siblings, 1 reply; 9+ messages in thread
From: Ilpo Järvinen @ 2023-05-09 11:39 UTC (permalink / raw)
To: linux-serial, Greg Kroah-Hartman, Jiri Slaby,
Philippe Mathieu-Daudé,
Kunihiko Hayashi, Masami Hiramatsu, linux-kernel,
linux-arm-kernel
Cc: Niklas Schnelle, Ilpo Järvinen
Divisor latch read/write functions currently handle the value is int.
As the value is related to HW context, u32 makes much more sense than a
signed type.
While at it, name the parameters in the callback signature.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
drivers/tty/serial/8250/8250.h | 4 ++--
drivers/tty/serial/8250/8250_em.c | 4 ++--
drivers/tty/serial/8250/8250_port.c | 10 +++++-----
drivers/tty/serial/8250/8250_pxa.c | 2 +-
drivers/tty/serial/8250/8250_uniphier.c | 4 ++--
include/linux/serial_8250.h | 4 ++--
6 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
index 1e8fe44a7099..5418708f4631 100644
--- a/drivers/tty/serial/8250/8250.h
+++ b/drivers/tty/serial/8250/8250.h
@@ -167,12 +167,12 @@ static unsigned int __maybe_unused serial_icr_read(struct uart_8250_port *up,
void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p);
-static inline int serial_dl_read(struct uart_8250_port *up)
+static inline u32 serial_dl_read(struct uart_8250_port *up)
{
return up->dl_read(up);
}
-static inline void serial_dl_write(struct uart_8250_port *up, int value)
+static inline void serial_dl_write(struct uart_8250_port *up, u32 value)
{
up->dl_write(up, value);
}
diff --git a/drivers/tty/serial/8250/8250_em.c b/drivers/tty/serial/8250/8250_em.c
index 25a9ecf26be6..ef5019e944ea 100644
--- a/drivers/tty/serial/8250/8250_em.c
+++ b/drivers/tty/serial/8250/8250_em.c
@@ -139,12 +139,12 @@ static void serial8250_em_serial_out(struct uart_port *p, int offset, int value)
}
}
-static int serial8250_em_serial_dl_read(struct uart_8250_port *up)
+static u32 serial8250_em_serial_dl_read(struct uart_8250_port *up)
{
return serial_in(up, UART_DLL_EM) | serial_in(up, UART_DLM_EM) << 8;
}
-static void serial8250_em_serial_dl_write(struct uart_8250_port *up, int value)
+static void serial8250_em_serial_dl_write(struct uart_8250_port *up, u32 value)
{
serial_out(up, UART_DLL_EM, value & 0xff);
serial_out(up, UART_DLM_EM, value >> 8 & 0xff);
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index fe8d79c4ae95..0622c11f0064 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -325,7 +325,7 @@ static const struct serial8250_config uart_config[] = {
};
/* Uart divisor latch read */
-static int default_serial_dl_read(struct uart_8250_port *up)
+static u32 default_serial_dl_read(struct uart_8250_port *up)
{
/* Assign these in pieces to truncate any bits above 7. */
unsigned char dll = serial_in(up, UART_DLL);
@@ -335,7 +335,7 @@ static int default_serial_dl_read(struct uart_8250_port *up)
}
/* Uart divisor latch write */
-static void default_serial_dl_write(struct uart_8250_port *up, int value)
+static void default_serial_dl_write(struct uart_8250_port *up, u32 value)
{
serial_out(up, UART_DLL, value & 0xff);
serial_out(up, UART_DLM, value >> 8 & 0xff);
@@ -389,12 +389,12 @@ void au_serial_out(struct uart_port *p, int offset, int value)
}
/* Au1x00 haven't got a standard divisor latch */
-static int au_serial_dl_read(struct uart_8250_port *up)
+static u32 au_serial_dl_read(struct uart_8250_port *up)
{
return __raw_readl(up->port.membase + 0x28);
}
-static void au_serial_dl_write(struct uart_8250_port *up, int value)
+static void au_serial_dl_write(struct uart_8250_port *up, u32 value)
{
__raw_writel(value, up->port.membase + 0x28);
}
@@ -847,7 +847,7 @@ static void disable_rsa(struct uart_8250_port *up)
static int size_fifo(struct uart_8250_port *up)
{
unsigned char old_fcr, old_mcr, old_lcr;
- unsigned short old_dl;
+ unsigned int old_dl;
int count;
old_lcr = serial_in(up, UART_LCR);
diff --git a/drivers/tty/serial/8250/8250_pxa.c b/drivers/tty/serial/8250/8250_pxa.c
index 795e55142d4c..28b341f602c6 100644
--- a/drivers/tty/serial/8250/8250_pxa.c
+++ b/drivers/tty/serial/8250/8250_pxa.c
@@ -60,7 +60,7 @@ static const struct of_device_id serial_pxa_dt_ids[] = {
MODULE_DEVICE_TABLE(of, serial_pxa_dt_ids);
/* Uart divisor latch write */
-static void serial_pxa_dl_write(struct uart_8250_port *up, int value)
+static void serial_pxa_dl_write(struct uart_8250_port *up, u32 value)
{
unsigned int dll;
diff --git a/drivers/tty/serial/8250/8250_uniphier.c b/drivers/tty/serial/8250/8250_uniphier.c
index a2978abab0db..a405155264b1 100644
--- a/drivers/tty/serial/8250/8250_uniphier.c
+++ b/drivers/tty/serial/8250/8250_uniphier.c
@@ -145,12 +145,12 @@ static void uniphier_serial_out(struct uart_port *p, int offset, int value)
* The divisor latch register exists at different address.
* Override dl_read/write callbacks.
*/
-static int uniphier_serial_dl_read(struct uart_8250_port *up)
+static u32 uniphier_serial_dl_read(struct uart_8250_port *up)
{
return readl(up->port.membase + UNIPHIER_UART_DLR);
}
-static void uniphier_serial_dl_write(struct uart_8250_port *up, int value)
+static void uniphier_serial_dl_write(struct uart_8250_port *up, u32 value)
{
writel(value, up->port.membase + UNIPHIER_UART_DLR);
}
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index 6f78f302d272..7b5d558e4e0c 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -129,8 +129,8 @@ struct uart_8250_port {
const struct uart_8250_ops *ops;
/* 8250 specific callbacks */
- int (*dl_read)(struct uart_8250_port *);
- void (*dl_write)(struct uart_8250_port *, int);
+ u32 (*dl_read)(struct uart_8250_port *up);
+ void (*dl_write)(struct uart_8250_port *up, u32 value);
struct uart_8250_em485 *em485;
void (*rs485_start_tx)(struct uart_8250_port *);
--
2.30.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v3 2/6] serial: 8250: Document uart_8250_port's ->dl_read/write()
2023-05-09 11:39 [PATCH v3 0/6] serial: Separate RT288x/Au1xxx code into own file Ilpo Järvinen
2023-05-09 11:39 ` [PATCH v3 1/6] serial: 8250: Change dl_read/write to handle value as u32 Ilpo Järvinen
@ 2023-05-09 11:39 ` Ilpo Järvinen
2023-05-09 11:39 ` [PATCH v3 3/6] serial: 8250: Add dl_read/write, bugs and mapsize into plat_serial8250_port Ilpo Järvinen
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Ilpo Järvinen @ 2023-05-09 11:39 UTC (permalink / raw)
To: linux-serial, Greg Kroah-Hartman, Jiri Slaby,
Philippe Mathieu-Daudé,
linux-kernel
Cc: Niklas Schnelle, Ilpo Järvinen
Add documentation for the struct uart_8250_port divisor latch function
pointers. Documentation is in kernel doc format but don't enable kernel
doc yet as many other fields remain undocumented.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
include/linux/serial_8250.h | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index 7b5d558e4e0c..d64e7bbe1f2f 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -90,8 +90,17 @@ struct uart_8250_em485 {
* their own 8250 ports without registering their own
* platform device. Using these will make your driver
* dependent on the 8250 driver.
+ *
+ * @dl_read: ``u32 ()(struct uart_8250_port *port)``
+ *
+ * UART divisor latch read.
+ *
+ * @dl_write: ``void ()(struct uart_8250_port *port, u32 value)``
+ *
+ * Write @value into UART divisor latch.
+ *
+ * Locking: Caller holds port's lock.
*/
-
struct uart_8250_port {
struct uart_port port;
struct timer_list timer; /* "no irq" timer */
--
2.30.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v3 3/6] serial: 8250: Add dl_read/write, bugs and mapsize into plat_serial8250_port
2023-05-09 11:39 [PATCH v3 0/6] serial: Separate RT288x/Au1xxx code into own file Ilpo Järvinen
2023-05-09 11:39 ` [PATCH v3 1/6] serial: 8250: Change dl_read/write to handle value as u32 Ilpo Järvinen
2023-05-09 11:39 ` [PATCH v3 2/6] serial: 8250: Document uart_8250_port's ->dl_read/write() Ilpo Järvinen
@ 2023-05-09 11:39 ` Ilpo Järvinen
2023-05-10 5:55 ` Jiri Slaby
2023-05-09 11:39 ` [PATCH v3 4/6] serial: 8250: RT288x/Au1xxx code away from core Ilpo Järvinen
` (2 subsequent siblings)
5 siblings, 1 reply; 9+ messages in thread
From: Ilpo Järvinen @ 2023-05-09 11:39 UTC (permalink / raw)
To: linux-serial, Greg Kroah-Hartman, Jiri Slaby,
Philippe Mathieu-Daudé,
linux-kernel
Cc: Niklas Schnelle, Ilpo Järvinen
Add mapsize, bugs, and divisor latch read/write functions
(->dl_read/write()) into plat_serial8250_port to carry the setup
necessary for RT288x/Au1xxx devices over to uart port.
Document the added members with kerneldoc style but do not enable
kerneldoc yet as there are many fields which remain undocumented.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
drivers/tty/serial/8250/8250_core.c | 4 ++++
include/linux/serial_8250.h | 19 +++++++++++++++++++
2 files changed, 23 insertions(+)
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 13bf535eedcd..21b15b130d12 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -822,12 +822,16 @@ static int serial8250_probe(struct platform_device *dev)
uart.port.iotype = p->iotype;
uart.port.flags = p->flags;
uart.port.mapbase = p->mapbase;
+ uart.port.mapsize = p->mapsize;
uart.port.hub6 = p->hub6;
uart.port.has_sysrq = p->has_sysrq;
uart.port.private_data = p->private_data;
uart.port.type = p->type;
+ uart.bugs = p->bugs;
uart.port.serial_in = p->serial_in;
uart.port.serial_out = p->serial_out;
+ uart.dl_read = p->dl_read;
+ uart.dl_write = p->dl_write;
uart.port.handle_irq = p->handle_irq;
uart.port.handle_break = p->handle_break;
uart.port.set_termios = p->set_termios;
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index d64e7bbe1f2f..82cd8d90a040 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -11,13 +11,29 @@
#include <linux/serial_reg.h>
#include <linux/platform_device.h>
+struct uart_8250_port;
+
/*
* This is the platform device platform_data structure
+ *
+ * @mapsize: Port size for ioremap()
+ * @bugs: Port bugs
+ *
+ * @dl_read: ``u32 ()(struct uart_8250_port *up)``
+ *
+ * UART divisor latch read.
+ *
+ * @dl_write: ``void ()(struct uart_8250_port *up, u32 value)``
+ *
+ * Write @value into UART divisor latch.
+ *
+ * Locking: Caller holds port's lock.
*/
struct plat_serial8250_port {
unsigned long iobase; /* io base address */
void __iomem *membase; /* ioremap cookie or NULL */
resource_size_t mapbase; /* resource base */
+ resource_size_t mapsize;
unsigned int uartclk; /* UART clock rate */
unsigned int irq; /* interrupt number */
unsigned long irqflags; /* request_irq flags */
@@ -28,8 +44,11 @@ struct plat_serial8250_port {
unsigned char has_sysrq; /* supports magic SysRq */
unsigned int type; /* If UPF_FIXED_TYPE */
upf_t flags; /* UPF_* flags */
+ unsigned short bugs; /* port bugs */
unsigned int (*serial_in)(struct uart_port *, int);
void (*serial_out)(struct uart_port *, int, int);
+ u32 (*dl_read)(struct uart_8250_port *up);
+ void (*dl_write)(struct uart_8250_port *up, u32 value);
void (*set_termios)(struct uart_port *,
struct ktermios *new,
const struct ktermios *old);
--
2.30.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v3 4/6] serial: 8250: RT288x/Au1xxx code away from core
2023-05-09 11:39 [PATCH v3 0/6] serial: Separate RT288x/Au1xxx code into own file Ilpo Järvinen
` (2 preceding siblings ...)
2023-05-09 11:39 ` [PATCH v3 3/6] serial: 8250: Add dl_read/write, bugs and mapsize into plat_serial8250_port Ilpo Järvinen
@ 2023-05-09 11:39 ` Ilpo Järvinen
2023-05-09 11:39 ` [PATCH v3 5/6] serial: 8250_rt288x: Name non-standard divisor latch reg Ilpo Järvinen
2023-05-09 11:39 ` [PATCH v3 6/6] serial: 8250_rt288x: Remove unnecessary UART_REG_UNMAPPED Ilpo Järvinen
5 siblings, 0 replies; 9+ messages in thread
From: Ilpo Järvinen @ 2023-05-09 11:39 UTC (permalink / raw)
To: linux-serial, Greg Kroah-Hartman, Jiri Slaby,
Philippe Mathieu-Daudé,
Thomas Bogendoerfer, linux-mips, linux-kernel
Cc: Niklas Schnelle, Ilpo Järvinen
A non-trivial amount of RT288x/Au1xxx code is encapsulated into
ifdeffery in 8250_port / 8250_early and some if UPIO_AU blocks.
Create a separate file from them.
Also handle errors properly in the cases where RT288x/Au1xxx code is
not configured.
It seems that 0x1000 mapsize is likely overkill but I've kept it the
same as previously (the value was shrunk to that value in commit
b2b13cdfd05e ("SERIAL 8250: Fixes for Alchemy UARTs.")). Seemingly, the
driver only needs to access register at 0x28 for the divisor latch.
The Kconfig side is a bit tricky. As SERIAL_8250_RT288X is bool it can
only be =y. It is possible to have SERIAL_8250=m + SERIAL_8250_RT288X=y
which required altering when 8250/ is included or the rt288x would not
be built.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
arch/mips/alchemy/common/platform.c | 10 +-
drivers/tty/serial/8250/8250_early.c | 21 ----
drivers/tty/serial/8250/8250_of.c | 4 +-
drivers/tty/serial/8250/8250_port.c | 78 --------------
drivers/tty/serial/8250/8250_rt288x.c | 142 ++++++++++++++++++++++++++
drivers/tty/serial/8250/Makefile | 1 +
drivers/tty/serial/Makefile | 2 +-
include/linux/serial_8250.h | 8 +-
8 files changed, 161 insertions(+), 105 deletions(-)
create mode 100644 drivers/tty/serial/8250/8250_rt288x.c
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c
index b8f3397c59c9..d4ab34b3b404 100644
--- a/arch/mips/alchemy/common/platform.c
+++ b/arch/mips/alchemy/common/platform.c
@@ -51,9 +51,9 @@ static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
#define PORT(_base, _irq) \
{ \
.mapbase = _base, \
+ .mapsize = 0x1000, \
.irq = _irq, \
.regshift = 2, \
- .iotype = UPIO_AU, \
.flags = UPF_SKIP_TEST | UPF_IOREMAP | \
UPF_FIXED_TYPE, \
.type = PORT_16550A, \
@@ -124,8 +124,14 @@ static void __init alchemy_setup_uarts(int ctype)
au1xx0_uart_device.dev.platform_data = ports;
/* Fill up uartclk. */
- for (s = 0; s < c; s++)
+ for (s = 0; s < c; s++) {
ports[s].uartclk = uartclk;
+ if (au_platform_setup(&ports[s]) < 0) {
+ kfree(ports);
+ printk(KERN_INFO "Alchemy: missing support for UARTs\n");
+ return;
+ }
+ }
if (platform_device_register(&au1xx0_uart_device))
printk(KERN_INFO "Alchemy: failed to register UARTs\n");
}
diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c
index 0ebde0ab8167..4299a8bd83d9 100644
--- a/drivers/tty/serial/8250/8250_early.c
+++ b/drivers/tty/serial/8250/8250_early.c
@@ -36,7 +36,6 @@
static unsigned int serial8250_early_in(struct uart_port *port, int offset)
{
- int reg_offset = offset;
offset <<= port->regshift;
switch (port->iotype) {
@@ -50,8 +49,6 @@ static unsigned int serial8250_early_in(struct uart_port *port, int offset)
return ioread32be(port->membase + offset);
case UPIO_PORT:
return inb(port->iobase + offset);
- case UPIO_AU:
- return port->serial_in(port, reg_offset);
default:
return 0;
}
@@ -59,7 +56,6 @@ static unsigned int serial8250_early_in(struct uart_port *port, int offset)
static void serial8250_early_out(struct uart_port *port, int offset, int value)
{
- int reg_offset = offset;
offset <<= port->regshift;
switch (port->iotype) {
@@ -78,9 +74,6 @@ static void serial8250_early_out(struct uart_port *port, int offset, int value)
case UPIO_PORT:
outb(value, port->iobase + offset);
break;
- case UPIO_AU:
- port->serial_out(port, reg_offset, value);
- break;
}
}
@@ -199,17 +192,3 @@ OF_EARLYCON_DECLARE(omap8250, "ti,omap3-uart", early_omap8250_setup);
OF_EARLYCON_DECLARE(omap8250, "ti,omap4-uart", early_omap8250_setup);
#endif
-
-#ifdef CONFIG_SERIAL_8250_RT288X
-
-static int __init early_au_setup(struct earlycon_device *dev, const char *opt)
-{
- dev->port.serial_in = au_serial_in;
- dev->port.serial_out = au_serial_out;
- dev->port.iotype = UPIO_AU;
- dev->con->write = early_serial8250_write;
- return 0;
-}
-OF_EARLYCON_DECLARE(palmchip, "ralink,rt2880-uart", early_au_setup);
-
-#endif
diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c
index 1b461fba15a3..c9f6bd7a7038 100644
--- a/drivers/tty/serial/8250/8250_of.c
+++ b/drivers/tty/serial/8250/8250_of.c
@@ -171,7 +171,9 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
switch (type) {
case PORT_RT2880:
- port->iotype = UPIO_AU;
+ ret = rt288x_setup(port);
+ if (ret)
+ goto err_unprepare;
break;
}
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index 0622c11f0064..ae50744c6878 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -341,66 +341,6 @@ static void default_serial_dl_write(struct uart_8250_port *up, u32 value)
serial_out(up, UART_DLM, value >> 8 & 0xff);
}
-#ifdef CONFIG_SERIAL_8250_RT288X
-
-#define UART_REG_UNMAPPED -1
-
-/* Au1x00/RT288x UART hardware has a weird register layout */
-static const s8 au_io_in_map[8] = {
- [UART_RX] = 0,
- [UART_IER] = 2,
- [UART_IIR] = 3,
- [UART_LCR] = 5,
- [UART_MCR] = 6,
- [UART_LSR] = 7,
- [UART_MSR] = 8,
- [UART_SCR] = UART_REG_UNMAPPED,
-};
-
-static const s8 au_io_out_map[8] = {
- [UART_TX] = 1,
- [UART_IER] = 2,
- [UART_FCR] = 4,
- [UART_LCR] = 5,
- [UART_MCR] = 6,
- [UART_LSR] = UART_REG_UNMAPPED,
- [UART_MSR] = UART_REG_UNMAPPED,
- [UART_SCR] = UART_REG_UNMAPPED,
-};
-
-unsigned int au_serial_in(struct uart_port *p, int offset)
-{
- if (offset >= ARRAY_SIZE(au_io_in_map))
- return UINT_MAX;
- offset = au_io_in_map[offset];
- if (offset == UART_REG_UNMAPPED)
- return UINT_MAX;
- return __raw_readl(p->membase + (offset << p->regshift));
-}
-
-void au_serial_out(struct uart_port *p, int offset, int value)
-{
- if (offset >= ARRAY_SIZE(au_io_out_map))
- return;
- offset = au_io_out_map[offset];
- if (offset == UART_REG_UNMAPPED)
- return;
- __raw_writel(value, p->membase + (offset << p->regshift));
-}
-
-/* Au1x00 haven't got a standard divisor latch */
-static u32 au_serial_dl_read(struct uart_8250_port *up)
-{
- return __raw_readl(up->port.membase + 0x28);
-}
-
-static void au_serial_dl_write(struct uart_8250_port *up, u32 value)
-{
- __raw_writel(value, up->port.membase + 0x28);
-}
-
-#endif
-
static unsigned int hub6_serial_in(struct uart_port *p, int offset)
{
offset = offset << p->regshift;
@@ -510,15 +450,6 @@ static void set_io_from_upio(struct uart_port *p)
p->serial_out = mem32be_serial_out;
break;
-#ifdef CONFIG_SERIAL_8250_RT288X
- case UPIO_AU:
- p->serial_in = au_serial_in;
- p->serial_out = au_serial_out;
- up->dl_read = au_serial_dl_read;
- up->dl_write = au_serial_dl_write;
- break;
-#endif
-
default:
p->serial_in = io_serial_in;
p->serial_out = io_serial_out;
@@ -2968,11 +2899,6 @@ static unsigned int serial8250_port_size(struct uart_8250_port *pt)
{
if (pt->port.mapsize)
return pt->port.mapsize;
- if (pt->port.iotype == UPIO_AU) {
- if (pt->port.type == PORT_RT2880)
- return 0x100;
- return 0x1000;
- }
if (is_omap1_8250(pt))
return 0x16 << pt->port.regshift;
@@ -3222,10 +3148,6 @@ static void serial8250_config_port(struct uart_port *port, int flags)
if (flags & UART_CONFIG_TYPE)
autoconfig(up);
- /* if access method is AU, it is a 16550 with a quirk */
- if (port->type == PORT_16550A && port->iotype == UPIO_AU)
- up->bugs |= UART_BUG_NOMSR;
-
/* HW bugs may trigger IRQ while IIR == NO_INT */
if (port->type == PORT_TEGRA)
up->bugs |= UART_BUG_NOMSR;
diff --git a/drivers/tty/serial/8250/8250_rt288x.c b/drivers/tty/serial/8250/8250_rt288x.c
new file mode 100644
index 000000000000..51b1cf5476dd
--- /dev/null
+++ b/drivers/tty/serial/8250/8250_rt288x.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * RT288x/Au1xxx driver
+ */
+
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+
+#include "8250.h"
+
+#define UART_REG_UNMAPPED -1
+
+/* Au1x00/RT288x UART hardware has a weird register layout */
+static const s8 au_io_in_map[8] = {
+ [UART_RX] = 0,
+ [UART_IER] = 2,
+ [UART_IIR] = 3,
+ [UART_LCR] = 5,
+ [UART_MCR] = 6,
+ [UART_LSR] = 7,
+ [UART_MSR] = 8,
+ [UART_SCR] = UART_REG_UNMAPPED,
+};
+
+static const s8 au_io_out_map[8] = {
+ [UART_TX] = 1,
+ [UART_IER] = 2,
+ [UART_FCR] = 4,
+ [UART_LCR] = 5,
+ [UART_MCR] = 6,
+ [UART_LSR] = UART_REG_UNMAPPED,
+ [UART_MSR] = UART_REG_UNMAPPED,
+ [UART_SCR] = UART_REG_UNMAPPED,
+};
+
+static unsigned int au_serial_in(struct uart_port *p, int offset)
+{
+ if (offset >= ARRAY_SIZE(au_io_in_map))
+ return UINT_MAX;
+ offset = au_io_in_map[offset];
+ if (offset == UART_REG_UNMAPPED)
+ return UINT_MAX;
+ return __raw_readl(p->membase + (offset << p->regshift));
+}
+
+static void au_serial_out(struct uart_port *p, int offset, int value)
+{
+ if (offset >= ARRAY_SIZE(au_io_out_map))
+ return;
+ offset = au_io_out_map[offset];
+ if (offset == UART_REG_UNMAPPED)
+ return;
+ __raw_writel(value, p->membase + (offset << p->regshift));
+}
+
+/* Au1x00 haven't got a standard divisor latch */
+static u32 au_serial_dl_read(struct uart_8250_port *up)
+{
+ return __raw_readl(up->port.membase + 0x28);
+}
+
+static void au_serial_dl_write(struct uart_8250_port *up, u32 value)
+{
+ __raw_writel(value, up->port.membase + 0x28);
+}
+
+int au_platform_setup(struct plat_serial8250_port *p)
+{
+ p->iotype = UPIO_AU;
+
+ p->serial_in = au_serial_in;
+ p->serial_out = au_serial_out;
+ p->dl_read = au_serial_dl_read;
+ p->dl_write = au_serial_dl_write;
+
+ p->mapsize = 0x1000;
+
+ p->bugs |= UART_BUG_NOMSR;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(au_platform_setup);
+
+int rt288x_setup(struct uart_port *p)
+{
+ struct uart_8250_port *up = up_to_u8250p(p);
+
+ p->iotype = UPIO_AU;
+
+ p->serial_in = au_serial_in;
+ p->serial_out = au_serial_out;
+ up->dl_read = au_serial_dl_read;
+ up->dl_write = au_serial_dl_write;
+
+ p->mapsize = 0x100;
+
+ up->bugs |= UART_BUG_NOMSR;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rt288x_setup);
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+static void au_putc(struct uart_port *port, unsigned char c)
+{
+ unsigned int status;
+
+ au_serial_out(port, UART_TX, c);
+
+ for (;;) {
+ status = au_serial_in(port, UART_LSR);
+ if (uart_lsr_tx_empty(status))
+ break;
+ cpu_relax();
+ }
+}
+
+static void au_early_serial8250_write(struct console *console,
+ const char *s, unsigned int count)
+{
+ struct earlycon_device *device = console->data;
+ struct uart_port *port = &device->port;
+
+ uart_console_write(port, s, count, au_putc);
+}
+
+static int __init early_au_setup(struct earlycon_device *dev, const char *opt)
+{
+ rt288x_setup(&dev->port);
+ dev->con->write = au_early_serial8250_write;
+
+ return 0;
+}
+OF_EARLYCON_DECLARE(palmchip, "ralink,rt2880-uart", early_au_setup);
+#endif
+
+MODULE_DESCRIPTION("RT288x/Au1xxx UART driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
index 4fc2fc1f41b6..628b75be312e 100644
--- a/drivers/tty/serial/8250/Makefile
+++ b/drivers/tty/serial/8250/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o
obj-$(CONFIG_SERIAL_8250_IOC3) += 8250_ioc3.o
obj-$(CONFIG_SERIAL_8250_OMAP) += 8250_omap.o
+obj-$(CONFIG_SERIAL_8250_RT288X) += 8250_rt288x.o
obj-$(CONFIG_SERIAL_8250_LPC18XX) += 8250_lpc18xx.o
obj-$(CONFIG_SERIAL_8250_MT6577) += 8250_mtk.o
obj-$(CONFIG_SERIAL_8250_UNIPHIER) += 8250_uniphier.o
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index cd9afd9e3018..531ec3a19dae 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -21,7 +21,7 @@ obj-$(CONFIG_SERIAL_SUNSAB) += sunsab.o
obj-$(CONFIG_SERIAL_21285) += 21285.o
# Now bring in any enabled 8250/16450/16550 type drivers.
-obj-$(CONFIG_SERIAL_8250) += 8250/
+obj-y += 8250/
obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index 82cd8d90a040..8f38be25eefa 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -7,6 +7,7 @@
#ifndef _LINUX_SERIAL_8250_H
#define _LINUX_SERIAL_8250_H
+#include <linux/errno.h>
#include <linux/serial_core.h>
#include <linux/serial_reg.h>
#include <linux/platform_device.h>
@@ -211,8 +212,11 @@ void serial8250_set_isa_configurator(void (*v)(int port, struct uart_port *up,
u32 *capabilities));
#ifdef CONFIG_SERIAL_8250_RT288X
-unsigned int au_serial_in(struct uart_port *p, int offset);
-void au_serial_out(struct uart_port *p, int offset, int value);
+int rt288x_setup(struct uart_port *p);
+int au_platform_setup(struct plat_serial8250_port *p);
+#else
+static inline int rt288x_setup(struct uart_port *p) { return -ENODEV; }
+static inline int au_platform_setup(struct plat_serial8250_port *p) { return -ENODEV; }
#endif
#endif
--
2.30.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v3 5/6] serial: 8250_rt288x: Name non-standard divisor latch reg
2023-05-09 11:39 [PATCH v3 0/6] serial: Separate RT288x/Au1xxx code into own file Ilpo Järvinen
` (3 preceding siblings ...)
2023-05-09 11:39 ` [PATCH v3 4/6] serial: 8250: RT288x/Au1xxx code away from core Ilpo Järvinen
@ 2023-05-09 11:39 ` Ilpo Järvinen
2023-05-09 11:39 ` [PATCH v3 6/6] serial: 8250_rt288x: Remove unnecessary UART_REG_UNMAPPED Ilpo Järvinen
5 siblings, 0 replies; 9+ messages in thread
From: Ilpo Järvinen @ 2023-05-09 11:39 UTC (permalink / raw)
To: linux-serial, Greg Kroah-Hartman, Jiri Slaby,
Philippe Mathieu-Daudé,
linux-kernel
Cc: Niklas Schnelle, Ilpo Järvinen
Instead of a literal, add proper name for the non-standard divisor
latch register.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
drivers/tty/serial/8250/8250_rt288x.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/8250/8250_rt288x.c b/drivers/tty/serial/8250/8250_rt288x.c
index 51b1cf5476dd..b091a1269bfa 100644
--- a/drivers/tty/serial/8250/8250_rt288x.c
+++ b/drivers/tty/serial/8250/8250_rt288x.c
@@ -12,6 +12,8 @@
#include "8250.h"
+#define RT288X_DL 0x28
+
#define UART_REG_UNMAPPED -1
/* Au1x00/RT288x UART hardware has a weird register layout */
@@ -60,12 +62,12 @@ static void au_serial_out(struct uart_port *p, int offset, int value)
/* Au1x00 haven't got a standard divisor latch */
static u32 au_serial_dl_read(struct uart_8250_port *up)
{
- return __raw_readl(up->port.membase + 0x28);
+ return __raw_readl(up->port.membase + RT288X_DL);
}
static void au_serial_dl_write(struct uart_8250_port *up, u32 value)
{
- __raw_writel(value, up->port.membase + 0x28);
+ __raw_writel(value, up->port.membase + RT288X_DL);
}
int au_platform_setup(struct plat_serial8250_port *p)
--
2.30.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v3 6/6] serial: 8250_rt288x: Remove unnecessary UART_REG_UNMAPPED
2023-05-09 11:39 [PATCH v3 0/6] serial: Separate RT288x/Au1xxx code into own file Ilpo Järvinen
` (4 preceding siblings ...)
2023-05-09 11:39 ` [PATCH v3 5/6] serial: 8250_rt288x: Name non-standard divisor latch reg Ilpo Järvinen
@ 2023-05-09 11:39 ` Ilpo Järvinen
5 siblings, 0 replies; 9+ messages in thread
From: Ilpo Järvinen @ 2023-05-09 11:39 UTC (permalink / raw)
To: linux-serial, Greg Kroah-Hartman, Jiri Slaby,
Philippe Mathieu-Daudé,
linux-kernel
Cc: Niklas Schnelle, Ilpo Järvinen
As unmapped registers are at the tail of the array, the ARRAY_SIZE()
condition will catch them just fine. No need to define special
value for them.
Convert the arrays to u8 as all entiries are now positive.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
drivers/tty/serial/8250/8250_rt288x.c | 16 ++++------------
1 file changed, 4 insertions(+), 12 deletions(-)
diff --git a/drivers/tty/serial/8250/8250_rt288x.c b/drivers/tty/serial/8250/8250_rt288x.c
index b091a1269bfa..6415ca8d3adf 100644
--- a/drivers/tty/serial/8250/8250_rt288x.c
+++ b/drivers/tty/serial/8250/8250_rt288x.c
@@ -14,10 +14,8 @@
#define RT288X_DL 0x28
-#define UART_REG_UNMAPPED -1
-
/* Au1x00/RT288x UART hardware has a weird register layout */
-static const s8 au_io_in_map[8] = {
+static const u8 au_io_in_map[7] = {
[UART_RX] = 0,
[UART_IER] = 2,
[UART_IIR] = 3,
@@ -25,18 +23,14 @@ static const s8 au_io_in_map[8] = {
[UART_MCR] = 6,
[UART_LSR] = 7,
[UART_MSR] = 8,
- [UART_SCR] = UART_REG_UNMAPPED,
};
-static const s8 au_io_out_map[8] = {
+static const u8 au_io_out_map[5] = {
[UART_TX] = 1,
[UART_IER] = 2,
[UART_FCR] = 4,
[UART_LCR] = 5,
[UART_MCR] = 6,
- [UART_LSR] = UART_REG_UNMAPPED,
- [UART_MSR] = UART_REG_UNMAPPED,
- [UART_SCR] = UART_REG_UNMAPPED,
};
static unsigned int au_serial_in(struct uart_port *p, int offset)
@@ -44,8 +38,7 @@ static unsigned int au_serial_in(struct uart_port *p, int offset)
if (offset >= ARRAY_SIZE(au_io_in_map))
return UINT_MAX;
offset = au_io_in_map[offset];
- if (offset == UART_REG_UNMAPPED)
- return UINT_MAX;
+
return __raw_readl(p->membase + (offset << p->regshift));
}
@@ -54,8 +47,7 @@ static void au_serial_out(struct uart_port *p, int offset, int value)
if (offset >= ARRAY_SIZE(au_io_out_map))
return;
offset = au_io_out_map[offset];
- if (offset == UART_REG_UNMAPPED)
- return;
+
__raw_writel(value, p->membase + (offset << p->regshift));
}
--
2.30.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 1/6] serial: 8250: Change dl_read/write to handle value as u32
2023-05-09 11:39 ` [PATCH v3 1/6] serial: 8250: Change dl_read/write to handle value as u32 Ilpo Järvinen
@ 2023-05-10 5:47 ` Jiri Slaby
0 siblings, 0 replies; 9+ messages in thread
From: Jiri Slaby @ 2023-05-10 5:47 UTC (permalink / raw)
To: Ilpo Järvinen, linux-serial, Greg Kroah-Hartman,
Philippe Mathieu-Daudé,
Kunihiko Hayashi, Masami Hiramatsu, linux-kernel,
linux-arm-kernel
Cc: Niklas Schnelle
On 09. 05. 23, 13:39, Ilpo Järvinen wrote:
> Divisor latch read/write functions currently handle the value is int.
*as* int?
> As the value is related to HW context, u32 makes much more sense than a
> signed type.
>
> While at it, name the parameters in the callback signature.
...
> --- a/drivers/tty/serial/8250/8250_port.c
> +++ b/drivers/tty/serial/8250/8250_port.c
...
> @@ -847,7 +847,7 @@ static void disable_rsa(struct uart_8250_port *up)
> static int size_fifo(struct uart_8250_port *up)
> {
> unsigned char old_fcr, old_mcr, old_lcr;
> - unsigned short old_dl;
> + unsigned int old_dl;
I am missing the context, but why not u32 here?
thanks,
--
js
suse labs
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 3/6] serial: 8250: Add dl_read/write, bugs and mapsize into plat_serial8250_port
2023-05-09 11:39 ` [PATCH v3 3/6] serial: 8250: Add dl_read/write, bugs and mapsize into plat_serial8250_port Ilpo Järvinen
@ 2023-05-10 5:55 ` Jiri Slaby
0 siblings, 0 replies; 9+ messages in thread
From: Jiri Slaby @ 2023-05-10 5:55 UTC (permalink / raw)
To: Ilpo Järvinen, linux-serial, Greg Kroah-Hartman,
Philippe Mathieu-Daudé,
linux-kernel
Cc: Niklas Schnelle
On 09. 05. 23, 13:39, Ilpo Järvinen wrote:
> Add mapsize, bugs, and divisor latch read/write functions
> (->dl_read/write()) into plat_serial8250_port to carry the setup
> necessary for RT288x/Au1xxx devices over to uart port.
>
> Document the added members with kerneldoc style but do not enable
> kerneldoc yet as there are many fields which remain undocumented.
>
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> --- a/include/linux/serial_8250.h
> +++ b/include/linux/serial_8250.h
...
> @@ -28,8 +44,11 @@ struct plat_serial8250_port {
> unsigned char has_sysrq; /* supports magic SysRq */
> unsigned int type; /* If UPF_FIXED_TYPE */
> upf_t flags; /* UPF_* flags */
> + unsigned short bugs; /* port bugs */
I would suggest u16 for bitfields like this. (Or DECLARE_BITMAP, but
that would unnecessarily eat a long.)
thanks,
--
js
suse labs
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2023-05-10 5:55 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-09 11:39 [PATCH v3 0/6] serial: Separate RT288x/Au1xxx code into own file Ilpo Järvinen
2023-05-09 11:39 ` [PATCH v3 1/6] serial: 8250: Change dl_read/write to handle value as u32 Ilpo Järvinen
2023-05-10 5:47 ` Jiri Slaby
2023-05-09 11:39 ` [PATCH v3 2/6] serial: 8250: Document uart_8250_port's ->dl_read/write() Ilpo Järvinen
2023-05-09 11:39 ` [PATCH v3 3/6] serial: 8250: Add dl_read/write, bugs and mapsize into plat_serial8250_port Ilpo Järvinen
2023-05-10 5:55 ` Jiri Slaby
2023-05-09 11:39 ` [PATCH v3 4/6] serial: 8250: RT288x/Au1xxx code away from core Ilpo Järvinen
2023-05-09 11:39 ` [PATCH v3 5/6] serial: 8250_rt288x: Name non-standard divisor latch reg Ilpo Järvinen
2023-05-09 11:39 ` [PATCH v3 6/6] serial: 8250_rt288x: Remove unnecessary UART_REG_UNMAPPED Ilpo Järvinen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®