1 // SPDX-License-Identifier: GPL-2.0+
3 * Serial base bus layer for controllers
5 * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
6 * Author: Tony Lindgren <tony@atomide.com>
8 * The serial core bus manages the serial core controller instances.
11 #include <linux/cleanup.h>
12 #include <linux/container_of.h>
13 #include <linux/device.h>
14 #include <linux/idr.h>
15 #include <linux/module.h>
16 #include <linux/serial_core.h>
17 #include <linux/slab.h>
18 #include <linux/spinlock.h>
20 #include "serial_base.h"
22 static bool serial_base_initialized
;
24 static const struct device_type serial_ctrl_type
= {
28 static const struct device_type serial_port_type
= {
32 static int serial_base_match(struct device
*dev
, const struct device_driver
*drv
)
34 if (dev
->type
== &serial_ctrl_type
&&
35 str_has_prefix(drv
->name
, serial_ctrl_type
.name
))
38 if (dev
->type
== &serial_port_type
&&
39 str_has_prefix(drv
->name
, serial_port_type
.name
))
45 static const struct bus_type serial_base_bus_type
= {
46 .name
= "serial-base",
47 .match
= serial_base_match
,
50 int serial_base_driver_register(struct device_driver
*driver
)
52 driver
->bus
= &serial_base_bus_type
;
54 return driver_register(driver
);
57 void serial_base_driver_unregister(struct device_driver
*driver
)
59 driver_unregister(driver
);
62 static int serial_base_device_init(struct uart_port
*port
,
64 struct device
*parent_dev
,
65 const struct device_type
*type
,
66 void (*release
)(struct device
*dev
),
70 device_initialize(dev
);
72 dev
->parent
= parent_dev
;
73 dev
->bus
= &serial_base_bus_type
;
74 dev
->release
= release
;
76 if (!serial_base_initialized
) {
77 dev_dbg(port
->dev
, "uart_add_one_port() called before arch_initcall()?\n");
81 if (type
== &serial_ctrl_type
)
82 return dev_set_name(dev
, "%s:%d", dev_name(port
->dev
), ctrl_id
);
84 if (type
== &serial_port_type
)
85 return dev_set_name(dev
, "%s:%d.%d", dev_name(port
->dev
),
91 static void serial_base_ctrl_release(struct device
*dev
)
93 struct serial_ctrl_device
*ctrl_dev
= to_serial_base_ctrl_device(dev
);
98 void serial_base_ctrl_device_remove(struct serial_ctrl_device
*ctrl_dev
)
103 device_del(&ctrl_dev
->dev
);
104 put_device(&ctrl_dev
->dev
);
107 struct serial_ctrl_device
*serial_base_ctrl_add(struct uart_port
*port
,
108 struct device
*parent
)
110 struct serial_ctrl_device
*ctrl_dev
;
113 ctrl_dev
= kzalloc(sizeof(*ctrl_dev
), GFP_KERNEL
);
115 return ERR_PTR(-ENOMEM
);
117 ida_init(&ctrl_dev
->port_ida
);
119 err
= serial_base_device_init(port
, &ctrl_dev
->dev
,
120 parent
, &serial_ctrl_type
,
121 serial_base_ctrl_release
,
126 err
= device_add(&ctrl_dev
->dev
);
133 put_device(&ctrl_dev
->dev
);
138 static void serial_base_port_release(struct device
*dev
)
140 struct serial_port_device
*port_dev
= to_serial_base_port_device(dev
);
145 struct serial_port_device
*serial_base_port_add(struct uart_port
*port
,
146 struct serial_ctrl_device
*ctrl_dev
)
148 struct serial_port_device
*port_dev
;
149 int min
= 0, max
= -1; /* Use -1 for max to apply IDA defaults */
152 port_dev
= kzalloc(sizeof(*port_dev
), GFP_KERNEL
);
154 return ERR_PTR(-ENOMEM
);
156 /* Device driver specified port_id vs automatic assignment? */
162 err
= ida_alloc_range(&ctrl_dev
->port_ida
, min
, max
, GFP_KERNEL
);
170 err
= serial_base_device_init(port
, &port_dev
->dev
,
171 &ctrl_dev
->dev
, &serial_port_type
,
172 serial_base_port_release
,
173 port
->ctrl_id
, port
->port_id
);
177 port_dev
->port
= port
;
179 err
= device_add(&port_dev
->dev
);
186 put_device(&port_dev
->dev
);
187 ida_free(&ctrl_dev
->port_ida
, port
->port_id
);
192 void serial_base_port_device_remove(struct serial_port_device
*port_dev
)
194 struct serial_ctrl_device
*ctrl_dev
;
195 struct device
*parent
;
200 parent
= port_dev
->dev
.parent
;
201 ctrl_dev
= to_serial_base_ctrl_device(parent
);
203 device_del(&port_dev
->dev
);
204 ida_free(&ctrl_dev
->port_ida
, port_dev
->port
->port_id
);
205 put_device(&port_dev
->dev
);
208 #ifdef CONFIG_SERIAL_CORE_CONSOLE
211 * serial_base_match_and_update_preferred_console - Match and update a preferred console
212 * @drv: Serial port device driver
213 * @port: Serial port instance
215 * Tries to match and update the preferred console for a serial port for
216 * the kernel command line option console=DEVNAME:0.0.
218 * Cannot be called early for ISA ports, depends on struct device.
220 * Return: 0 on success, negative error code on failure.
222 int serial_base_match_and_update_preferred_console(struct uart_driver
*drv
,
223 struct uart_port
*port
)
225 const char *port_match
__free(kfree
) = NULL
;
228 port_match
= kasprintf(GFP_KERNEL
, "%s:%d.%d", dev_name(port
->dev
),
229 port
->ctrl_id
, port
->port_id
);
233 ret
= match_devname_and_update_preferred_console(port_match
,
244 static int serial_base_init(void)
248 ret
= bus_register(&serial_base_bus_type
);
252 ret
= serial_base_ctrl_init();
254 goto err_bus_unregister
;
256 ret
= serial_base_port_init();
260 serial_base_initialized
= true;
265 serial_base_ctrl_exit();
268 bus_unregister(&serial_base_bus_type
);
272 arch_initcall(serial_base_init
);
274 static void serial_base_exit(void)
276 serial_base_port_exit();
277 serial_base_ctrl_exit();
278 bus_unregister(&serial_base_bus_type
);
280 module_exit(serial_base_exit
);
282 MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
283 MODULE_DESCRIPTION("Serial core bus");
284 MODULE_LICENSE("GPL");