* [PATCH 0/4] serial: vt8500: Clean up the probe
@ 2026-11-11 19:19 Alexey Charkov
2026-11-11 19:19 ` [PATCH 1/4] serial: vt8500: Find console ports in the serial core state Alexey Charkov
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Alexey Charkov @ 2026-11-11 19:19 UTC (permalink / raw)
To: Alexey Charkov, Krzysztof Kozlowski, Greg Kroah-Hartman,
Jiri Slaby, Tony Prisk, Alan Cox
Cc: linux-arm-kernel, linux-kernel, linux-serial, Greg Kroah-Hartman,
Wentao Liang, Sashiko
The driver has been carrying legacy vestiges in the form of a bitmask and
a local array to track which ports should be numbered which, both of them
not really needed anymore with DT aliases and existing in-core tracking.
Remove them altogether to simplify the driver and get rid of leaks Sashiko
found. While here, also convert the clock handling to use the resource
managed API, and propagate errors from uart_add_one_port().
Signed-off-by: Alexey Charkov <alchark@gmail.com>
---
Alexey Charkov (4):
serial: vt8500: Find console ports in the serial core state
serial: vt8500: Use devm_clk_get_enabled()
serial: vt8500: Handle uart_add_one_port() failure
serial: vt8500: Drop the port index bitmap
drivers/tty/serial/vt8500_serial.c | 81 +++++++++++---------------------------
1 file changed, 22 insertions(+), 59 deletions(-)
---
base-commit: 793807ca13bf3072fc6d16ce6d90e9ab9beff2a5
change-id: 20261111-vt8500-serial-cleanup-dfc9731edd70
Best regards,
--
Alexey Charkov <alchark@gmail.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/4] serial: vt8500: Find console ports in the serial core state
2026-11-11 19:19 [PATCH 0/4] serial: vt8500: Clean up the probe Alexey Charkov
@ 2026-11-11 19:19 ` Alexey Charkov
2026-11-11 19:19 ` [PATCH 2/4] serial: vt8500: Use devm_clk_get_enabled() Alexey Charkov
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Alexey Charkov @ 2026-11-11 19:19 UTC (permalink / raw)
To: Alexey Charkov, Krzysztof Kozlowski, Greg Kroah-Hartman,
Jiri Slaby, Tony Prisk, Alan Cox
Cc: linux-arm-kernel, linux-kernel, linux-serial, Greg Kroah-Hartman,
Wentao Liang
Look up the console's port in vt8500_uart_driver.state[], which the
serial core fills before it registers the console, and drop the private
vt8500_uart_ports[] array that only mirrors it and gets in the way.
Signed-off-by: Alexey Charkov <alchark@gmail.com>
---
drivers/tty/serial/vt8500_serial.c | 25 ++++++++++---------------
1 file changed, 10 insertions(+), 15 deletions(-)
diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c
index a7f167a73416..6c53e108756a 100644
--- a/drivers/tty/serial/vt8500_serial.c
+++ b/drivers/tty/serial/vt8500_serial.c
@@ -444,7 +444,6 @@ static int vt8500_verify_port(struct uart_port *port,
return 0;
}
-static struct vt8500_port *vt8500_uart_ports[VT8500_MAX_PORTS];
static struct uart_driver vt8500_uart_driver;
#ifdef CONFIG_SERIAL_VT8500_CONSOLE
@@ -472,28 +471,27 @@ static void vt8500_console_putchar(struct uart_port *port, unsigned char c)
static void vt8500_console_write(struct console *co, const char *s,
unsigned int count)
{
- struct vt8500_port *vt8500_port = vt8500_uart_ports[co->index];
+ struct uart_port *port = vt8500_uart_driver.state[co->index].uart_port;
unsigned long ier;
BUG_ON(co->index < 0 || co->index >= vt8500_uart_driver.nr);
- ier = vt8500_read(&vt8500_port->uart, VT8500_URIER);
- vt8500_write(&vt8500_port->uart, VT8500_URIER, 0);
+ ier = vt8500_read(port, VT8500_URIER);
+ vt8500_write(port, VT8500_URIER, 0);
- uart_console_write(&vt8500_port->uart, s, count,
- vt8500_console_putchar);
+ uart_console_write(port, s, count, vt8500_console_putchar);
/*
* Finally, wait for transmitter to become empty
* and switch back to FIFO
*/
- wait_for_xmitr(&vt8500_port->uart);
- vt8500_write(&vt8500_port->uart, VT8500_URIER, ier);
+ wait_for_xmitr(port);
+ vt8500_write(port, VT8500_URIER, ier);
}
static int __init vt8500_console_setup(struct console *co, char *options)
{
- struct vt8500_port *vt8500_port;
+ struct uart_port *port;
int baud = 9600;
int bits = 8;
int parity = 'n';
@@ -502,16 +500,15 @@ static int __init vt8500_console_setup(struct console *co, char *options)
if (unlikely(co->index >= vt8500_uart_driver.nr || co->index < 0))
return -ENXIO;
- vt8500_port = vt8500_uart_ports[co->index];
+ port = vt8500_uart_driver.state[co->index].uart_port;
- if (!vt8500_port)
+ if (!port)
return -ENODEV;
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
- return uart_set_options(&vt8500_port->uart,
- co, baud, parity, bits, flow);
+ return uart_set_options(port, co, baud, parity, bits, flow);
}
static struct console vt8500_console = {
@@ -683,8 +680,6 @@ static int vt8500_serial_probe(struct platform_device *pdev)
snprintf(vt8500_port->name, sizeof(vt8500_port->name),
"VT8500 UART%d", pdev->id);
- vt8500_uart_ports[port] = vt8500_port;
-
uart_add_one_port(&vt8500_uart_driver, &vt8500_port->uart);
platform_set_drvdata(pdev, vt8500_port);
--
2.56.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/4] serial: vt8500: Use devm_clk_get_enabled()
2026-11-11 19:19 [PATCH 0/4] serial: vt8500: Clean up the probe Alexey Charkov
2026-11-11 19:19 ` [PATCH 1/4] serial: vt8500: Find console ports in the serial core state Alexey Charkov
@ 2026-11-11 19:19 ` Alexey Charkov
2026-11-11 19:19 ` [PATCH 3/4] serial: vt8500: Handle uart_add_one_port() failure Alexey Charkov
2026-11-11 19:19 ` [PATCH 4/4] serial: vt8500: Drop the port index bitmap Alexey Charkov
3 siblings, 0 replies; 5+ messages in thread
From: Alexey Charkov @ 2026-11-11 19:19 UTC (permalink / raw)
To: Alexey Charkov, Krzysztof Kozlowski, Greg Kroah-Hartman,
Jiri Slaby, Tony Prisk, Alan Cox
Cc: linux-arm-kernel, linux-kernel, linux-serial, Greg Kroah-Hartman,
Wentao Liang
Let devres own the UART clock, so that no probe error path, present or
future, has to remember to disable and put it.
Pass the clock lookup error up through dev_err_probe() instead of
replacing it with -EINVAL, so that a clock provider that is not ready
yet defers the probe rather than failing it for good.
Signed-off-by: Alexey Charkov <alchark@gmail.com>
---
drivers/tty/serial/vt8500_serial.c | 17 ++++-------------
1 file changed, 4 insertions(+), 13 deletions(-)
diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c
index 6c53e108756a..17f928a7073a 100644
--- a/drivers/tty/serial/vt8500_serial.c
+++ b/drivers/tty/serial/vt8500_serial.c
@@ -600,7 +600,6 @@ static int vt8500_serial_probe(struct platform_device *pdev)
struct resource *mmres;
struct device_node *np = pdev->dev.of_node;
const unsigned int *flags;
- int ret;
int port;
int irq;
@@ -643,18 +642,10 @@ static int vt8500_serial_probe(struct platform_device *pdev)
if (IS_ERR(vt8500_port->uart.membase))
return PTR_ERR(vt8500_port->uart.membase);
- vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0);
- if (IS_ERR(vt8500_port->clk)) {
- dev_err(&pdev->dev, "failed to get clock\n");
- return -EINVAL;
- }
-
- ret = clk_prepare_enable(vt8500_port->clk);
- if (ret) {
- dev_err(&pdev->dev, "failed to enable clock\n");
- clk_put(vt8500_port->clk);
- return ret;
- }
+ vt8500_port->clk = devm_clk_get_enabled(&pdev->dev, NULL);
+ if (IS_ERR(vt8500_port->clk))
+ return dev_err_probe(&pdev->dev, PTR_ERR(vt8500_port->clk),
+ "failed to get clock\n");
vt8500_port->vt8500_uart_flags = *flags;
vt8500_port->clk_predivisor = DIV_ROUND_CLOSEST(
--
2.56.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 3/4] serial: vt8500: Handle uart_add_one_port() failure
2026-11-11 19:19 [PATCH 0/4] serial: vt8500: Clean up the probe Alexey Charkov
2026-11-11 19:19 ` [PATCH 1/4] serial: vt8500: Find console ports in the serial core state Alexey Charkov
2026-11-11 19:19 ` [PATCH 2/4] serial: vt8500: Use devm_clk_get_enabled() Alexey Charkov
@ 2026-11-11 19:19 ` Alexey Charkov
2026-11-11 19:19 ` [PATCH 4/4] serial: vt8500: Drop the port index bitmap Alexey Charkov
3 siblings, 0 replies; 5+ messages in thread
From: Alexey Charkov @ 2026-11-11 19:19 UTC (permalink / raw)
To: Alexey Charkov, Krzysztof Kozlowski, Greg Kroah-Hartman,
Jiri Slaby, Tony Prisk, Alan Cox
Cc: linux-arm-kernel, linux-kernel, linux-serial, Greg Kroah-Hartman,
Wentao Liang, Sashiko
Return the error from uart_add_one_port() instead of reporting a bound
device for a port that never registered, which would keep its clock
running for nothing. Let devres release the clock and the remaining
resources on that path.
Set the driver data before adding the port, so that the probe can end
on the registration call.
Fixes: 304e12665a4a ("serial: Add support for UART on VIA VT8500 and compatibles")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/bug/linux-ce64cdae-9faa-4109-b7da-29b8a8c99e76
Signed-off-by: Alexey Charkov <alchark@gmail.com>
---
drivers/tty/serial/vt8500_serial.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c
index 17f928a7073a..7c7b4beb51fd 100644
--- a/drivers/tty/serial/vt8500_serial.c
+++ b/drivers/tty/serial/vt8500_serial.c
@@ -671,11 +671,9 @@ static int vt8500_serial_probe(struct platform_device *pdev)
snprintf(vt8500_port->name, sizeof(vt8500_port->name),
"VT8500 UART%d", pdev->id);
- uart_add_one_port(&vt8500_uart_driver, &vt8500_port->uart);
-
platform_set_drvdata(pdev, vt8500_port);
- return 0;
+ return uart_add_one_port(&vt8500_uart_driver, &vt8500_port->uart);
}
static struct platform_driver vt8500_platform_driver = {
--
2.56.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 4/4] serial: vt8500: Drop the port index bitmap
2026-11-11 19:19 [PATCH 0/4] serial: vt8500: Clean up the probe Alexey Charkov
` (2 preceding siblings ...)
2026-11-11 19:19 ` [PATCH 3/4] serial: vt8500: Handle uart_add_one_port() failure Alexey Charkov
@ 2026-11-11 19:19 ` Alexey Charkov
3 siblings, 0 replies; 5+ messages in thread
From: Alexey Charkov @ 2026-11-11 19:19 UTC (permalink / raw)
To: Alexey Charkov, Krzysztof Kozlowski, Greg Kroah-Hartman,
Jiri Slaby, Tony Prisk, Alan Cox
Cc: linux-arm-kernel, linux-kernel, linux-serial, Greg Kroah-Hartman,
Wentao Liang, Sashiko
Stop reserving a line in the vt8500_ports_in_use bitmap before probe
acquires its resources: nothing ever clears the bit, so an early probe
failure strands the line, and a retry then fails with -EBUSY on an
aliased port or drifts to the next free index on an unaliased one.
Pick the line from the serial core state instead and let
uart_add_one_port() claim it, as the core already refuses a taken line
under its port mutex. Rely on that for concurrent probes too, so that a
racing probe fails cleanly with no driver state to roll back.
Keep the allocation policy as is: honour an in-range "serial" alias,
otherwise fall back to the first free line.
Fixes: 4001130df1a7 ("serial: vt8500: Add devicetree support for vt8500-serial")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/bug/linux-ca000721-4a5b-4d88-bdb8-7f1e438dc81e
Signed-off-by: Alexey Charkov <alchark@gmail.com>
---
drivers/tty/serial/vt8500_serial.c | 35 +++++++----------------------------
1 file changed, 7 insertions(+), 28 deletions(-)
diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c
index 7c7b4beb51fd..f9858f10b5db 100644
--- a/drivers/tty/serial/vt8500_serial.c
+++ b/drivers/tty/serial/vt8500_serial.c
@@ -90,7 +90,6 @@
#define VT8500_RECOMMENDED_CLK 12000000
#define VT8500_OVERSAMPLING_DIVISOR 13
-#define VT8500_MAX_PORTS 6
struct vt8500_port {
struct uart_port uart;
@@ -101,13 +100,6 @@ struct vt8500_port {
unsigned int vt8500_uart_flags;
};
-/*
- * we use this variable to keep track of which ports
- * have been allocated as we can't use pdev->id in
- * devicetree
- */
-static DECLARE_BITMAP(vt8500_ports_in_use, VT8500_MAX_PORTS);
-
static inline void vt8500_write(struct uart_port *port, unsigned int val,
unsigned int off)
{
@@ -611,27 +603,14 @@ static int vt8500_serial_probe(struct platform_device *pdev)
if (irq < 0)
return irq;
- if (np) {
- port = of_alias_get_id(np, "serial");
- if (port >= VT8500_MAX_PORTS)
- port = -1;
- } else {
- port = -1;
- }
-
- if (port < 0) {
- /* calculate the port id */
- port = find_first_zero_bit(vt8500_ports_in_use,
- VT8500_MAX_PORTS);
- }
-
- if (port >= VT8500_MAX_PORTS)
- return -ENODEV;
+ port = np ? of_alias_get_id(np, "serial") : -ENODEV;
+ if (port < 0 || port >= vt8500_uart_driver.nr) {
+ for (port = 0; port < vt8500_uart_driver.nr; port++)
+ if (!vt8500_uart_driver.state[port].uart_port)
+ break;
- /* reserve the port id */
- if (test_and_set_bit(port, vt8500_ports_in_use)) {
- /* port already in use - shouldn't really happen */
- return -EBUSY;
+ if (port == vt8500_uart_driver.nr)
+ return -ENODEV;
}
vt8500_port = devm_kzalloc_obj(&pdev->dev, struct vt8500_port);
--
2.56.0
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-11-11 19:19 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-11 19:19 [PATCH 0/4] serial: vt8500: Clean up the probe Alexey Charkov
2026-11-11 19:19 ` [PATCH 1/4] serial: vt8500: Find console ports in the serial core state Alexey Charkov
2026-11-11 19:19 ` [PATCH 2/4] serial: vt8500: Use devm_clk_get_enabled() Alexey Charkov
2026-11-11 19:19 ` [PATCH 3/4] serial: vt8500: Handle uart_add_one_port() failure Alexey Charkov
2026-11-11 19:19 ` [PATCH 4/4] serial: vt8500: Drop the port index bitmap Alexey Charkov
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®