Skip to content

Commit 04c7f60

Browse files
tmlindgregkh
authored andcommitted
serial: core: Fix serial core port id, including multiport devices
We want to fix the serial core port DEVNAME to use a port id of the hardware specific controller port instance instead of the port->line. For example, the 8250 driver sets up a number of serial8250 ports initially that can be inherited by the hardware specific driver. At that the port->line no longer decribes the port's relation to the serial core controller instance. Let's fix the issue by assigning port->port_id for each serial core controller port instance. Fixes: 7d695d8 ("serial: core: Fix serial_base_match() after fixing controller port name") Tested-by: Guenter Roeck <linux@roeck-us.net> Reviewed-by: Dhruva Gole <d-gole@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Link: https://lore.kernel.org/r/20230811103648.2826-1-tony@atomide.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 3d9e6f5 commit 04c7f60

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

drivers/tty/serial/serial_base.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ struct device;
1616

1717
struct serial_ctrl_device {
1818
struct device dev;
19+
struct ida port_ida;
1920
};
2021

2122
struct serial_port_device {

drivers/tty/serial/serial_base_bus.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <linux/container_of.h>
1212
#include <linux/device.h>
13+
#include <linux/idr.h>
1314
#include <linux/module.h>
1415
#include <linux/serial_core.h>
1516
#include <linux/slab.h>
@@ -112,6 +113,8 @@ struct serial_ctrl_device *serial_base_ctrl_add(struct uart_port *port,
112113
if (!ctrl_dev)
113114
return ERR_PTR(-ENOMEM);
114115

116+
ida_init(&ctrl_dev->port_ida);
117+
115118
err = serial_base_device_init(port, &ctrl_dev->dev,
116119
parent, &serial_ctrl_type,
117120
serial_base_ctrl_release,
@@ -142,16 +145,31 @@ struct serial_port_device *serial_base_port_add(struct uart_port *port,
142145
struct serial_ctrl_device *ctrl_dev)
143146
{
144147
struct serial_port_device *port_dev;
148+
int min = 0, max = -1; /* Use -1 for max to apply IDA defaults */
145149
int err;
146150

147151
port_dev = kzalloc(sizeof(*port_dev), GFP_KERNEL);
148152
if (!port_dev)
149153
return ERR_PTR(-ENOMEM);
150154

155+
/* Device driver specified port_id vs automatic assignment? */
156+
if (port->port_id) {
157+
min = port->port_id;
158+
max = port->port_id;
159+
}
160+
161+
err = ida_alloc_range(&ctrl_dev->port_ida, min, max, GFP_KERNEL);
162+
if (err < 0) {
163+
kfree(port_dev);
164+
return ERR_PTR(err);
165+
}
166+
167+
port->port_id = err;
168+
151169
err = serial_base_device_init(port, &port_dev->dev,
152170
&ctrl_dev->dev, &serial_port_type,
153171
serial_base_port_release,
154-
port->ctrl_id, port->line);
172+
port->ctrl_id, port->port_id);
155173
if (err)
156174
goto err_put_device;
157175

@@ -165,16 +183,24 @@ struct serial_port_device *serial_base_port_add(struct uart_port *port,
165183

166184
err_put_device:
167185
put_device(&port_dev->dev);
186+
ida_free(&ctrl_dev->port_ida, port->port_id);
168187

169188
return ERR_PTR(err);
170189
}
171190

172191
void serial_base_port_device_remove(struct serial_port_device *port_dev)
173192
{
193+
struct serial_ctrl_device *ctrl_dev;
194+
struct device *parent;
195+
174196
if (!port_dev)
175197
return;
176198

199+
parent = port_dev->dev.parent;
200+
ctrl_dev = to_serial_base_ctrl_device(parent);
201+
177202
device_del(&port_dev->dev);
203+
ida_free(&ctrl_dev->port_ida, port_dev->port->port_id);
178204
put_device(&port_dev->dev);
179205
}
180206

0 commit comments

Comments
 (0)