Skip to content

Commit b286f4e

Browse files
tmlindgregkh
authored andcommitted
serial: core: Move tty and serdev to be children of serial core port device
Let's move tty and serdev controller to be children of the serial core port device. This way the runtime PM usage count of a child device propagates to the serial hardware device. The tty and serdev devices are associated with a specific serial port of a serial hardware controller device, and we now have serial core hierarchy of controllers and ports. The tty device moves happily with just a change of the parent device and update of device_find_child() handling. The serdev device init needs some changes to separate the serial hardware controller device from the parent device. With this change the tty devices move under sysfs similar to this x86_64 qemu example of a diff of "find /sys -name ttyS*": /sys/class/tty/ttyS0 /sys/class/tty/ttyS3 /sys/class/tty/ttyS1 -/sys/devices/pnp0/00:04/tty/ttyS0 -/sys/devices/platform/serial8250/tty/ttyS2 -/sys/devices/platform/serial8250/tty/ttyS3 -/sys/devices/platform/serial8250/tty/ttyS1 +/sys/devices/pnp0/00:04/00:04:0/00:04:0.0/tty/ttyS0 +/sys/devices/platform/serial8250/serial8250:0/serial8250:0.3/tty/ttyS3 +/sys/devices/platform/serial8250/serial8250:0/serial8250:0.1/tty/ttyS1 +/sys/devices/platform/serial8250/serial8250:0/serial8250:0.2/tty/ttyS2 If a serdev device is used instead of a tty, it moves in a similar way. Suggested-by: Johan Hovold <[email protected]> Cc: Maximilian Luz <[email protected]> Cc: Rob Herring <[email protected]> Signed-off-by: Tony Lindgren <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 39ff20f commit b286f4e

File tree

6 files changed

+33
-20
lines changed

6 files changed

+33
-20
lines changed

drivers/tty/serdev/core.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,7 @@ EXPORT_SYMBOL_GPL(serdev_device_alloc);
468468

469469
/**
470470
* serdev_controller_alloc() - Allocate a new serdev controller
471+
* @host: serial port hardware controller device
471472
* @parent: parent device
472473
* @size: size of private data
473474
*
@@ -476,8 +477,9 @@ EXPORT_SYMBOL_GPL(serdev_device_alloc);
476477
* The allocated private data region may be accessed via
477478
* serdev_controller_get_drvdata()
478479
*/
479-
struct serdev_controller *serdev_controller_alloc(struct device *parent,
480-
size_t size)
480+
struct serdev_controller *serdev_controller_alloc(struct device *host,
481+
struct device *parent,
482+
size_t size)
481483
{
482484
struct serdev_controller *ctrl;
483485
int id;
@@ -502,7 +504,8 @@ struct serdev_controller *serdev_controller_alloc(struct device *parent,
502504
ctrl->dev.type = &serdev_ctrl_type;
503505
ctrl->dev.bus = &serdev_bus_type;
504506
ctrl->dev.parent = parent;
505-
device_set_node(&ctrl->dev, dev_fwnode(parent));
507+
ctrl->host = host;
508+
device_set_node(&ctrl->dev, dev_fwnode(host));
506509
serdev_controller_set_drvdata(ctrl, &ctrl[1]);
507510

508511
dev_set_name(&ctrl->dev, "serial%d", id);
@@ -665,7 +668,7 @@ static int acpi_serdev_check_resources(struct serdev_controller *ctrl,
665668
acpi_get_parent(adev->handle, &lookup.controller_handle);
666669

667670
/* Make sure controller and ResourceSource handle match */
668-
if (!device_match_acpi_handle(ctrl->dev.parent, lookup.controller_handle))
671+
if (!device_match_acpi_handle(ctrl->host, lookup.controller_handle))
669672
return -ENODEV;
670673

671674
return 0;
@@ -730,7 +733,7 @@ static int acpi_serdev_register_devices(struct serdev_controller *ctrl)
730733
bool skip;
731734
int ret;
732735

733-
if (!has_acpi_companion(ctrl->dev.parent))
736+
if (!has_acpi_companion(ctrl->host))
734737
return -ENODEV;
735738

736739
/*
@@ -739,7 +742,7 @@ static int acpi_serdev_register_devices(struct serdev_controller *ctrl)
739742
* succeed in this case, so that the proper serdev devices can be
740743
* added "manually" later.
741744
*/
742-
ret = acpi_quirk_skip_serdev_enumeration(ctrl->dev.parent, &skip);
745+
ret = acpi_quirk_skip_serdev_enumeration(ctrl->host, &skip);
743746
if (ret)
744747
return ret;
745748
if (skip)

drivers/tty/serdev/serdev-ttyport.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ static const struct serdev_controller_ops ctrl_ops = {
274274
};
275275

276276
struct device *serdev_tty_port_register(struct tty_port *port,
277+
struct device *host,
277278
struct device *parent,
278279
struct tty_driver *drv, int idx)
279280
{
@@ -284,7 +285,7 @@ struct device *serdev_tty_port_register(struct tty_port *port,
284285
if (!port || !drv || !parent)
285286
return ERR_PTR(-ENODEV);
286287

287-
ctrl = serdev_controller_alloc(parent, sizeof(struct serport));
288+
ctrl = serdev_controller_alloc(host, parent, sizeof(struct serport));
288289
if (!ctrl)
289290
return ERR_PTR(-ENOMEM);
290291
serport = serdev_controller_get_drvdata(ctrl);

drivers/tty/serial/serial_core.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2342,7 +2342,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
23422342

23432343
mutex_lock(&port->mutex);
23442344

2345-
tty_dev = device_find_child(uport->dev, &match, serial_match_port);
2345+
tty_dev = device_find_child(&uport->port_dev->dev, &match, serial_match_port);
23462346
if (tty_dev && device_may_wakeup(tty_dev)) {
23472347
enable_irq_wake(uport->irq);
23482348
put_device(tty_dev);
@@ -2423,7 +2423,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
24232423

24242424
mutex_lock(&port->mutex);
24252425

2426-
tty_dev = device_find_child(uport->dev, &match, serial_match_port);
2426+
tty_dev = device_find_child(&uport->port_dev->dev, &match, serial_match_port);
24272427
if (!uport->suspended && device_may_wakeup(tty_dev)) {
24282428
if (irqd_is_wakeup_set(irq_get_irq_data((uport->irq))))
24292429
disable_irq_wake(uport->irq);
@@ -3153,7 +3153,8 @@ static int serial_core_add_one_port(struct uart_driver *drv, struct uart_port *u
31533153
* setserial to be used to alter this port's parameters.
31543154
*/
31553155
tty_dev = tty_port_register_device_attr_serdev(port, drv->tty_driver,
3156-
uport->line, uport->dev, port, uport->tty_groups);
3156+
uport->line, uport->dev, &uport->port_dev->dev, port,
3157+
uport->tty_groups);
31573158
if (!IS_ERR(tty_dev)) {
31583159
device_set_wakeup_capable(tty_dev, 1);
31593160
} else {

drivers/tty/tty_port.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,8 @@ EXPORT_SYMBOL_GPL(tty_port_register_device_attr);
171171
* @port: tty_port of the device
172172
* @driver: tty_driver for this device
173173
* @index: index of the tty
174-
* @device: parent if exists, otherwise NULL
174+
* @host: serial port hardware device
175+
* @parent: parent if exists, otherwise NULL
175176
* @drvdata: driver data for the device
176177
* @attr_grp: attribute group for the device
177178
*
@@ -180,20 +181,20 @@ EXPORT_SYMBOL_GPL(tty_port_register_device_attr);
180181
*/
181182
struct device *tty_port_register_device_attr_serdev(struct tty_port *port,
182183
struct tty_driver *driver, unsigned index,
183-
struct device *device, void *drvdata,
184+
struct device *host, struct device *parent, void *drvdata,
184185
const struct attribute_group **attr_grp)
185186
{
186187
struct device *dev;
187188

188189
tty_port_link_device(port, driver, index);
189190

190-
dev = serdev_tty_port_register(port, device, driver, index);
191+
dev = serdev_tty_port_register(port, host, parent, driver, index);
191192
if (PTR_ERR(dev) != -ENODEV) {
192193
/* Skip creating cdev if we registered a serdev device */
193194
return dev;
194195
}
195196

196-
return tty_register_device_attr(driver, index, device, drvdata,
197+
return tty_register_device_attr(driver, index, parent, drvdata,
197198
attr_grp);
198199
}
199200
EXPORT_SYMBOL_GPL(tty_port_register_device_attr_serdev);
@@ -203,17 +204,18 @@ EXPORT_SYMBOL_GPL(tty_port_register_device_attr_serdev);
203204
* @port: tty_port of the device
204205
* @driver: tty_driver for this device
205206
* @index: index of the tty
206-
* @device: parent if exists, otherwise NULL
207+
* @host: serial port hardware controller device
208+
* @parent: parent if exists, otherwise NULL
207209
*
208210
* Register a serdev or tty device depending on if the parent device has any
209211
* defined serdev clients or not.
210212
*/
211213
struct device *tty_port_register_device_serdev(struct tty_port *port,
212214
struct tty_driver *driver, unsigned index,
213-
struct device *device)
215+
struct device *host, struct device *parent)
214216
{
215217
return tty_port_register_device_attr_serdev(port, driver, index,
216-
device, NULL, NULL);
218+
host, parent, NULL, NULL);
217219
}
218220
EXPORT_SYMBOL_GPL(tty_port_register_device_serdev);
219221

include/linux/serdev.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,14 @@ struct serdev_controller_ops {
9999
/**
100100
* struct serdev_controller - interface to the serdev controller
101101
* @dev: Driver model representation of the device.
102+
* @host: Serial port hardware controller device
102103
* @nr: number identifier for this controller/bus.
103104
* @serdev: Pointer to slave device for this controller.
104105
* @ops: Controller operations.
105106
*/
106107
struct serdev_controller {
107108
struct device dev;
109+
struct device *host;
108110
unsigned int nr;
109111
struct serdev_device *serdev;
110112
const struct serdev_controller_ops *ops;
@@ -167,7 +169,9 @@ struct serdev_device *serdev_device_alloc(struct serdev_controller *);
167169
int serdev_device_add(struct serdev_device *);
168170
void serdev_device_remove(struct serdev_device *);
169171

170-
struct serdev_controller *serdev_controller_alloc(struct device *, size_t);
172+
struct serdev_controller *serdev_controller_alloc(struct device *host,
173+
struct device *parent,
174+
size_t size);
171175
int serdev_controller_add(struct serdev_controller *);
172176
void serdev_controller_remove(struct serdev_controller *);
173177

@@ -311,11 +315,13 @@ struct tty_driver;
311315

312316
#ifdef CONFIG_SERIAL_DEV_CTRL_TTYPORT
313317
struct device *serdev_tty_port_register(struct tty_port *port,
318+
struct device *host,
314319
struct device *parent,
315320
struct tty_driver *drv, int idx);
316321
int serdev_tty_port_unregister(struct tty_port *port);
317322
#else
318323
static inline struct device *serdev_tty_port_register(struct tty_port *port,
324+
struct device *host,
319325
struct device *parent,
320326
struct tty_driver *drv, int idx)
321327
{

include/linux/tty_port.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,10 @@ struct device *tty_port_register_device_attr(struct tty_port *port,
149149
const struct attribute_group **attr_grp);
150150
struct device *tty_port_register_device_serdev(struct tty_port *port,
151151
struct tty_driver *driver, unsigned index,
152-
struct device *device);
152+
struct device *host, struct device *parent);
153153
struct device *tty_port_register_device_attr_serdev(struct tty_port *port,
154154
struct tty_driver *driver, unsigned index,
155-
struct device *device, void *drvdata,
155+
struct device *host, struct device *parent, void *drvdata,
156156
const struct attribute_group **attr_grp);
157157
void tty_port_unregister_device(struct tty_port *port,
158158
struct tty_driver *driver, unsigned index);

0 commit comments

Comments
 (0)