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 <johan@kernel.org>
Cc: Maximilian Luz <luzmaximilian@gmail.com>
Cc: Rob Herring <robh@kernel.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Link: https://lore.kernel.org/r/20231113080758.30346-1-tony@atomide.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Tony Lindgren
2023-11-13 10:07:52 +02:00
committed by Greg Kroah-Hartman
parent 39ff20f5fd
commit b286f4e87e
6 changed files with 33 additions and 20 deletions
+9 -6
View File
@@ -468,6 +468,7 @@ EXPORT_SYMBOL_GPL(serdev_device_alloc);
/**
* serdev_controller_alloc() - Allocate a new serdev controller
* @host: serial port hardware controller device
* @parent: parent device
* @size: size of private data
*
@@ -476,8 +477,9 @@ EXPORT_SYMBOL_GPL(serdev_device_alloc);
* The allocated private data region may be accessed via
* serdev_controller_get_drvdata()
*/
struct serdev_controller *serdev_controller_alloc(struct device *parent,
size_t size)
struct serdev_controller *serdev_controller_alloc(struct device *host,
struct device *parent,
size_t size)
{
struct serdev_controller *ctrl;
int id;
@@ -502,7 +504,8 @@ struct serdev_controller *serdev_controller_alloc(struct device *parent,
ctrl->dev.type = &serdev_ctrl_type;
ctrl->dev.bus = &serdev_bus_type;
ctrl->dev.parent = parent;
device_set_node(&ctrl->dev, dev_fwnode(parent));
ctrl->host = host;
device_set_node(&ctrl->dev, dev_fwnode(host));
serdev_controller_set_drvdata(ctrl, &ctrl[1]);
dev_set_name(&ctrl->dev, "serial%d", id);
@@ -665,7 +668,7 @@ static int acpi_serdev_check_resources(struct serdev_controller *ctrl,
acpi_get_parent(adev->handle, &lookup.controller_handle);
/* Make sure controller and ResourceSource handle match */
if (!device_match_acpi_handle(ctrl->dev.parent, lookup.controller_handle))
if (!device_match_acpi_handle(ctrl->host, lookup.controller_handle))
return -ENODEV;
return 0;
@@ -730,7 +733,7 @@ static int acpi_serdev_register_devices(struct serdev_controller *ctrl)
bool skip;
int ret;
if (!has_acpi_companion(ctrl->dev.parent))
if (!has_acpi_companion(ctrl->host))
return -ENODEV;
/*
@@ -739,7 +742,7 @@ static int acpi_serdev_register_devices(struct serdev_controller *ctrl)
* succeed in this case, so that the proper serdev devices can be
* added "manually" later.
*/
ret = acpi_quirk_skip_serdev_enumeration(ctrl->dev.parent, &skip);
ret = acpi_quirk_skip_serdev_enumeration(ctrl->host, &skip);
if (ret)
return ret;
if (skip)
+2 -1
View File
@@ -274,6 +274,7 @@ static const struct serdev_controller_ops ctrl_ops = {
};
struct device *serdev_tty_port_register(struct tty_port *port,
struct device *host,
struct device *parent,
struct tty_driver *drv, int idx)
{
@@ -284,7 +285,7 @@ struct device *serdev_tty_port_register(struct tty_port *port,
if (!port || !drv || !parent)
return ERR_PTR(-ENODEV);
ctrl = serdev_controller_alloc(parent, sizeof(struct serport));
ctrl = serdev_controller_alloc(host, parent, sizeof(struct serport));
if (!ctrl)
return ERR_PTR(-ENOMEM);
serport = serdev_controller_get_drvdata(ctrl);