LCOV - code coverage report
Current view: top level - tty/serial - serial_base_bus.c (source / functions) Coverage Total Hit
Test: TTY Combined Coverage Lines: 0.0 % 143 0
Test Date: 2025-08-26 15:45:50 Functions: 0.0 % 13 0

            Line data    Source code
       1              : // SPDX-License-Identifier: GPL-2.0+
       2              : /*
       3              :  * Serial base bus layer for controllers
       4              :  *
       5              :  * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
       6              :  * Author: Tony Lindgren <[email protected]>
       7              :  *
       8              :  * The serial core bus manages the serial core controller instances.
       9              :  */
      10              : 
      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/of.h>
      17              : #include <linux/serial_core.h>
      18              : #include <linux/slab.h>
      19              : #include <linux/spinlock.h>
      20              : 
      21              : #include "serial_base.h"
      22              : 
      23              : static bool serial_base_initialized;
      24              : 
      25              : static const struct device_type serial_ctrl_type = {
      26              :         .name = "ctrl",
      27              : };
      28              : 
      29              : static const struct device_type serial_port_type = {
      30              :         .name = "port",
      31              : };
      32              : 
      33            0 : static int serial_base_match(struct device *dev, const struct device_driver *drv)
      34              : {
      35            0 :         if (dev->type == &serial_ctrl_type &&
      36            0 :             str_has_prefix(drv->name, serial_ctrl_type.name))
      37            0 :                 return 1;
      38              : 
      39            0 :         if (dev->type == &serial_port_type &&
      40            0 :             str_has_prefix(drv->name, serial_port_type.name))
      41            0 :                 return 1;
      42              : 
      43            0 :         return 0;
      44            0 : }
      45              : 
      46              : static const struct bus_type serial_base_bus_type = {
      47              :         .name = "serial-base",
      48              :         .match = serial_base_match,
      49              : };
      50              : 
      51            0 : int serial_base_driver_register(struct device_driver *driver)
      52              : {
      53            0 :         driver->bus = &serial_base_bus_type;
      54              : 
      55            0 :         return driver_register(driver);
      56              : }
      57              : 
      58            0 : void serial_base_driver_unregister(struct device_driver *driver)
      59              : {
      60            0 :         driver_unregister(driver);
      61            0 : }
      62              : 
      63            0 : static int serial_base_device_init(struct uart_port *port,
      64              :                                    struct device *dev,
      65              :                                    struct device *parent_dev,
      66              :                                    const struct device_type *type,
      67              :                                    void (*release)(struct device *dev),
      68              :                                    unsigned int ctrl_id,
      69              :                                    unsigned int port_id)
      70              : {
      71            0 :         device_initialize(dev);
      72            0 :         dev->type = type;
      73            0 :         dev->parent = parent_dev;
      74            0 :         dev->bus = &serial_base_bus_type;
      75            0 :         dev->release = release;
      76            0 :         device_set_of_node_from_dev(dev, parent_dev);
      77              : 
      78            0 :         if (!serial_base_initialized) {
      79              :                 dev_dbg(port->dev, "uart_add_one_port() called before arch_initcall()?\n");
      80            0 :                 return -EPROBE_DEFER;
      81              :         }
      82              : 
      83            0 :         if (type == &serial_ctrl_type)
      84            0 :                 return dev_set_name(dev, "%s:%d", dev_name(port->dev), ctrl_id);
      85              : 
      86            0 :         if (type == &serial_port_type)
      87            0 :                 return dev_set_name(dev, "%s:%d.%d", dev_name(port->dev),
      88            0 :                                     ctrl_id, port_id);
      89              : 
      90            0 :         return -EINVAL;
      91            0 : }
      92              : 
      93            0 : static void serial_base_ctrl_release(struct device *dev)
      94              : {
      95            0 :         struct serial_ctrl_device *ctrl_dev = to_serial_base_ctrl_device(dev);
      96              : 
      97            0 :         of_node_put(dev->of_node);
      98            0 :         kfree(ctrl_dev);
      99            0 : }
     100              : 
     101            0 : void serial_base_ctrl_device_remove(struct serial_ctrl_device *ctrl_dev)
     102              : {
     103            0 :         if (!ctrl_dev)
     104            0 :                 return;
     105              : 
     106            0 :         device_del(&ctrl_dev->dev);
     107            0 :         put_device(&ctrl_dev->dev);
     108            0 : }
     109              : 
     110            0 : struct serial_ctrl_device *serial_base_ctrl_add(struct uart_port *port,
     111              :                                                 struct device *parent)
     112              : {
     113            0 :         struct serial_ctrl_device *ctrl_dev;
     114            0 :         int err;
     115              : 
     116            0 :         ctrl_dev = kzalloc(sizeof(*ctrl_dev), GFP_KERNEL);
     117            0 :         if (!ctrl_dev)
     118            0 :                 return ERR_PTR(-ENOMEM);
     119              : 
     120            0 :         ida_init(&ctrl_dev->port_ida);
     121              : 
     122            0 :         err = serial_base_device_init(port, &ctrl_dev->dev,
     123            0 :                                       parent, &serial_ctrl_type,
     124              :                                       serial_base_ctrl_release,
     125            0 :                                       port->ctrl_id, 0);
     126            0 :         if (err)
     127            0 :                 goto err_put_device;
     128              : 
     129            0 :         err = device_add(&ctrl_dev->dev);
     130            0 :         if (err)
     131            0 :                 goto err_put_device;
     132              : 
     133            0 :         return ctrl_dev;
     134              : 
     135              : err_put_device:
     136            0 :         put_device(&ctrl_dev->dev);
     137              : 
     138            0 :         return ERR_PTR(err);
     139            0 : }
     140              : 
     141            0 : static void serial_base_port_release(struct device *dev)
     142              : {
     143            0 :         struct serial_port_device *port_dev = to_serial_base_port_device(dev);
     144              : 
     145            0 :         of_node_put(dev->of_node);
     146            0 :         kfree(port_dev);
     147            0 : }
     148              : 
     149            0 : struct serial_port_device *serial_base_port_add(struct uart_port *port,
     150              :                                                 struct serial_ctrl_device *ctrl_dev)
     151              : {
     152            0 :         struct serial_port_device *port_dev;
     153            0 :         int min = 0, max = -1;  /* Use -1 for max to apply IDA defaults */
     154            0 :         int err;
     155              : 
     156            0 :         port_dev = kzalloc(sizeof(*port_dev), GFP_KERNEL);
     157            0 :         if (!port_dev)
     158            0 :                 return ERR_PTR(-ENOMEM);
     159              : 
     160              :         /* Device driver specified port_id vs automatic assignment? */
     161            0 :         if (port->port_id) {
     162            0 :                 min = port->port_id;
     163            0 :                 max = port->port_id;
     164            0 :         }
     165              : 
     166            0 :         err = ida_alloc_range(&ctrl_dev->port_ida, min, max, GFP_KERNEL);
     167            0 :         if (err < 0) {
     168            0 :                 kfree(port_dev);
     169            0 :                 return ERR_PTR(err);
     170              :         }
     171              : 
     172            0 :         port->port_id = err;
     173              : 
     174            0 :         err = serial_base_device_init(port, &port_dev->dev,
     175            0 :                                       &ctrl_dev->dev, &serial_port_type,
     176              :                                       serial_base_port_release,
     177            0 :                                       port->ctrl_id, port->port_id);
     178            0 :         if (err)
     179            0 :                 goto err_put_device;
     180              : 
     181            0 :         port_dev->port = port;
     182              : 
     183            0 :         err = device_add(&port_dev->dev);
     184            0 :         if (err)
     185            0 :                 goto err_put_device;
     186              : 
     187            0 :         return port_dev;
     188              : 
     189              : err_put_device:
     190            0 :         put_device(&port_dev->dev);
     191            0 :         ida_free(&ctrl_dev->port_ida, port->port_id);
     192              : 
     193            0 :         return ERR_PTR(err);
     194            0 : }
     195              : 
     196            0 : void serial_base_port_device_remove(struct serial_port_device *port_dev)
     197              : {
     198            0 :         struct serial_ctrl_device *ctrl_dev;
     199            0 :         struct device *parent;
     200              : 
     201            0 :         if (!port_dev)
     202            0 :                 return;
     203              : 
     204            0 :         parent = port_dev->dev.parent;
     205            0 :         ctrl_dev = to_serial_base_ctrl_device(parent);
     206              : 
     207            0 :         device_del(&port_dev->dev);
     208            0 :         ida_free(&ctrl_dev->port_ida, port_dev->port->port_id);
     209            0 :         put_device(&port_dev->dev);
     210            0 : }
     211              : 
     212              : #ifdef CONFIG_SERIAL_CORE_CONSOLE
     213              : 
     214              : /**
     215              :  * serial_base_match_and_update_preferred_console - Match and update a preferred console
     216              :  * @drv: Serial port device driver
     217              :  * @port: Serial port instance
     218              :  *
     219              :  * Tries to match and update the preferred console for a serial port for
     220              :  * the kernel command line option console=DEVNAME:0.0.
     221              :  *
     222              :  * Cannot be called early for ISA ports, depends on struct device.
     223              :  *
     224              :  * Return: 0 on success, negative error code on failure.
     225              :  */
     226            0 : int serial_base_match_and_update_preferred_console(struct uart_driver *drv,
     227              :                                                    struct uart_port *port)
     228              : {
     229            0 :         const char *port_match __free(kfree) = NULL;
     230            0 :         int ret;
     231              : 
     232            0 :         port_match = kasprintf(GFP_KERNEL, "%s:%d.%d", dev_name(port->dev),
     233            0 :                                port->ctrl_id, port->port_id);
     234            0 :         if (!port_match)
     235            0 :                 return -ENOMEM;
     236              : 
     237            0 :         ret = match_devname_and_update_preferred_console(port_match,
     238            0 :                                                          drv->dev_name,
     239            0 :                                                          port->line);
     240            0 :         if (ret == -ENOENT)
     241            0 :                 return 0;
     242              : 
     243            0 :         return ret;
     244            0 : }
     245              : 
     246              : #endif
     247              : 
     248            0 : static int serial_base_init(void)
     249              : {
     250            0 :         int ret;
     251              : 
     252            0 :         ret = bus_register(&serial_base_bus_type);
     253            0 :         if (ret)
     254            0 :                 return ret;
     255              : 
     256            0 :         ret = serial_base_ctrl_init();
     257            0 :         if (ret)
     258            0 :                 goto err_bus_unregister;
     259              : 
     260            0 :         ret = serial_base_port_init();
     261            0 :         if (ret)
     262            0 :                 goto err_ctrl_exit;
     263              : 
     264            0 :         serial_base_initialized = true;
     265              : 
     266            0 :         return 0;
     267              : 
     268              : err_ctrl_exit:
     269            0 :         serial_base_ctrl_exit();
     270              : 
     271              : err_bus_unregister:
     272            0 :         bus_unregister(&serial_base_bus_type);
     273              : 
     274            0 :         return ret;
     275            0 : }
     276              : arch_initcall(serial_base_init);
     277              : 
     278            0 : static void serial_base_exit(void)
     279              : {
     280            0 :         serial_base_port_exit();
     281            0 :         serial_base_ctrl_exit();
     282            0 :         bus_unregister(&serial_base_bus_type);
     283            0 : }
     284              : module_exit(serial_base_exit);
     285              : 
     286              : MODULE_AUTHOR("Tony Lindgren <[email protected]>");
     287              : MODULE_DESCRIPTION("Serial core bus");
     288              : MODULE_LICENSE("GPL");
        

Generated by: LCOV version 2.0-1