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

            Line data    Source code
       1              : // SPDX-License-Identifier: GPL-2.0+
       2              : /*
       3              :  * Serial core port device driver
       4              :  *
       5              :  * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
       6              :  * Author: Tony Lindgren <[email protected]>
       7              :  */
       8              : 
       9              : #include <linux/device.h>
      10              : #include <linux/module.h>
      11              : #include <linux/of.h>
      12              : #include <linux/platform_device.h>
      13              : #include <linux/pm_runtime.h>
      14              : #include <linux/pnp.h>
      15              : #include <linux/property.h>
      16              : #include <linux/serial_core.h>
      17              : #include <linux/spinlock.h>
      18              : 
      19              : #include "serial_base.h"
      20              : 
      21              : #define SERIAL_PORT_AUTOSUSPEND_DELAY_MS        500
      22              : 
      23              : /* Only considers pending TX for now. Caller must take care of locking */
      24            0 : static int __serial_port_busy(struct uart_port *port)
      25              : {
      26            0 :         return !uart_tx_stopped(port) &&
      27            0 :                 !kfifo_is_empty(&port->state->port.xmit_fifo);
      28              : }
      29              : 
      30            0 : static int serial_port_runtime_resume(struct device *dev)
      31              : {
      32            0 :         struct serial_port_device *port_dev = to_serial_base_port_device(dev);
      33            0 :         struct uart_port *port;
      34            0 :         unsigned long flags;
      35              : 
      36            0 :         port = port_dev->port;
      37              : 
      38            0 :         if (port->flags & UPF_DEAD)
      39            0 :                 goto out;
      40              : 
      41              :         /* Flush any pending TX for the port */
      42            0 :         uart_port_lock_irqsave(port, &flags);
      43            0 :         if (!port_dev->tx_enabled)
      44            0 :                 goto unlock;
      45            0 :         if (__serial_port_busy(port))
      46            0 :                 port->ops->start_tx(port);
      47              : 
      48              : unlock:
      49            0 :         uart_port_unlock_irqrestore(port, flags);
      50              : 
      51              : out:
      52            0 :         pm_runtime_mark_last_busy(dev);
      53              : 
      54            0 :         return 0;
      55            0 : }
      56              : 
      57            0 : static int serial_port_runtime_suspend(struct device *dev)
      58              : {
      59            0 :         struct serial_port_device *port_dev = to_serial_base_port_device(dev);
      60            0 :         struct uart_port *port = port_dev->port;
      61            0 :         unsigned long flags;
      62            0 :         bool busy;
      63              : 
      64            0 :         if (port->flags & UPF_DEAD)
      65            0 :                 return 0;
      66              : 
      67              :         /*
      68              :          * Nothing to do on pm_runtime_force_suspend(), see
      69              :          * DEFINE_RUNTIME_DEV_PM_OPS.
      70              :          */
      71            0 :         if (!pm_runtime_enabled(dev))
      72            0 :                 return 0;
      73              : 
      74            0 :         uart_port_lock_irqsave(port, &flags);
      75            0 :         if (!port_dev->tx_enabled) {
      76            0 :                 uart_port_unlock_irqrestore(port, flags);
      77            0 :                 return 0;
      78              :         }
      79              : 
      80            0 :         busy = __serial_port_busy(port);
      81            0 :         if (busy)
      82            0 :                 port->ops->start_tx(port);
      83            0 :         uart_port_unlock_irqrestore(port, flags);
      84              : 
      85            0 :         if (busy)
      86            0 :                 pm_runtime_mark_last_busy(dev);
      87              : 
      88            0 :         return busy ? -EBUSY : 0;
      89            0 : }
      90              : 
      91            0 : static void serial_base_port_set_tx(struct uart_port *port,
      92              :                                     struct serial_port_device *port_dev,
      93              :                                     bool enabled)
      94              : {
      95            0 :         unsigned long flags;
      96              : 
      97            0 :         uart_port_lock_irqsave(port, &flags);
      98            0 :         port_dev->tx_enabled = enabled;
      99            0 :         uart_port_unlock_irqrestore(port, flags);
     100            0 : }
     101              : 
     102            0 : void serial_base_port_startup(struct uart_port *port)
     103              : {
     104            0 :         struct serial_port_device *port_dev = port->port_dev;
     105              : 
     106            0 :         serial_base_port_set_tx(port, port_dev, true);
     107            0 : }
     108              : 
     109            0 : void serial_base_port_shutdown(struct uart_port *port)
     110              : {
     111            0 :         struct serial_port_device *port_dev = port->port_dev;
     112              : 
     113            0 :         serial_base_port_set_tx(port, port_dev, false);
     114            0 : }
     115              : 
     116              : static DEFINE_RUNTIME_DEV_PM_OPS(serial_port_pm,
     117              :                                  serial_port_runtime_suspend,
     118              :                                  serial_port_runtime_resume, NULL);
     119              : 
     120            0 : static int serial_port_probe(struct device *dev)
     121              : {
     122            0 :         pm_runtime_enable(dev);
     123            0 :         pm_runtime_set_autosuspend_delay(dev, SERIAL_PORT_AUTOSUSPEND_DELAY_MS);
     124            0 :         pm_runtime_use_autosuspend(dev);
     125              : 
     126            0 :         return 0;
     127              : }
     128              : 
     129            0 : static int serial_port_remove(struct device *dev)
     130              : {
     131            0 :         pm_runtime_dont_use_autosuspend(dev);
     132            0 :         pm_runtime_disable(dev);
     133              : 
     134            0 :         return 0;
     135              : }
     136              : 
     137              : /*
     138              :  * Serial core port device init functions. Note that the physical serial
     139              :  * port device driver may not have completed probe at this point.
     140              :  */
     141            0 : int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
     142              : {
     143            0 :         return serial_ctrl_register_port(drv, port);
     144              : }
     145              : EXPORT_SYMBOL(uart_add_one_port);
     146              : 
     147            0 : void uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
     148              : {
     149            0 :         serial_ctrl_unregister_port(drv, port);
     150            0 : }
     151              : EXPORT_SYMBOL(uart_remove_one_port);
     152              : 
     153              : /**
     154              :  * __uart_read_properties - read firmware properties of the given UART port
     155              :  * @port: corresponding port
     156              :  * @use_defaults: apply defaults (when %true) or validate the values (when %false)
     157              :  *
     158              :  * The following device properties are supported:
     159              :  *   - clock-frequency (optional)
     160              :  *   - fifo-size (optional)
     161              :  *   - no-loopback-test (optional)
     162              :  *   - reg-shift (defaults may apply)
     163              :  *   - reg-offset (value may be validated)
     164              :  *   - reg-io-width (defaults may apply or value may be validated)
     165              :  *   - interrupts (OF only)
     166              :  *   - serial [alias ID] (OF only)
     167              :  *
     168              :  * If the port->dev is of struct platform_device type the interrupt line
     169              :  * will be retrieved via platform_get_irq() call against that device.
     170              :  * Otherwise it will be assigned by fwnode_irq_get() call. In both cases
     171              :  * the index 0 of the resource is used.
     172              :  *
     173              :  * The caller is responsible to initialize the following fields of the @port
     174              :  *   ->dev (must be valid)
     175              :  *   ->flags
     176              :  *   ->iobase
     177              :  *   ->mapbase
     178              :  *   ->mapsize
     179              :  *   ->regshift (if @use_defaults is false)
     180              :  * before calling this function. Alternatively the above mentioned fields
     181              :  * may be zeroed, in such case the only ones, that have associated properties
     182              :  * found, will be set to the respective values.
     183              :  *
     184              :  * If no error happened, the ->irq, ->mapbase, ->mapsize will be altered.
     185              :  * The ->iotype is always altered.
     186              :  *
     187              :  * When @use_defaults is true and the respective property is not found
     188              :  * the following values will be applied:
     189              :  *   ->regshift = 0
     190              :  * In this case IRQ must be provided, otherwise an error will be returned.
     191              :  *
     192              :  * When @use_defaults is false and the respective property is found
     193              :  * the following values will be validated:
     194              :  *   - reg-io-width (->iotype)
     195              :  *   - reg-offset (->mapsize against ->mapbase)
     196              :  *
     197              :  * Returns: 0 on success or negative errno on failure
     198              :  */
     199            0 : static int __uart_read_properties(struct uart_port *port, bool use_defaults)
     200              : {
     201            0 :         struct device *dev = port->dev;
     202            0 :         u32 value;
     203            0 :         int ret;
     204              : 
     205              :         /* Read optional UART functional clock frequency */
     206            0 :         device_property_read_u32(dev, "clock-frequency", &port->uartclk);
     207              : 
     208              :         /* Read the registers alignment (default: 8-bit) */
     209            0 :         ret = device_property_read_u32(dev, "reg-shift", &value);
     210            0 :         if (ret)
     211            0 :                 port->regshift = use_defaults ? 0 : port->regshift;
     212              :         else
     213            0 :                 port->regshift = value;
     214              : 
     215              :         /* Read the registers I/O access type (default: MMIO 8-bit) */
     216            0 :         ret = device_property_read_u32(dev, "reg-io-width", &value);
     217            0 :         if (ret) {
     218            0 :                 port->iotype = port->iobase ? UPIO_PORT : UPIO_MEM;
     219            0 :         } else {
     220            0 :                 switch (value) {
     221              :                 case 1:
     222            0 :                         port->iotype = UPIO_MEM;
     223            0 :                         break;
     224              :                 case 2:
     225            0 :                         port->iotype = UPIO_MEM16;
     226            0 :                         break;
     227              :                 case 4:
     228            0 :                         port->iotype = device_is_big_endian(dev) ? UPIO_MEM32BE : UPIO_MEM32;
     229            0 :                         break;
     230              :                 default:
     231            0 :                         port->iotype = UPIO_UNKNOWN;
     232            0 :                         break;
     233              :                 }
     234              :         }
     235              : 
     236            0 :         if (!use_defaults && port->iotype == UPIO_UNKNOWN) {
     237            0 :                 dev_err(dev, "Unsupported reg-io-width (%u)\n", value);
     238            0 :                 return -EINVAL;
     239              :         }
     240              : 
     241              :         /* Read the address mapping base offset (default: no offset) */
     242            0 :         ret = device_property_read_u32(dev, "reg-offset", &value);
     243            0 :         if (ret)
     244            0 :                 value = 0;
     245              : 
     246              :         /* Check for shifted address mapping overflow */
     247            0 :         if (!use_defaults && port->mapsize < value) {
     248            0 :                 dev_err(dev, "reg-offset %u exceeds region size %pa\n", value, &port->mapsize);
     249            0 :                 return -EINVAL;
     250              :         }
     251              : 
     252            0 :         port->mapbase += value;
     253            0 :         port->mapsize -= value;
     254              : 
     255              :         /* Read optional FIFO size */
     256            0 :         device_property_read_u32(dev, "fifo-size", &port->fifosize);
     257              : 
     258            0 :         if (device_property_read_bool(dev, "no-loopback-test"))
     259            0 :                 port->flags |= UPF_SKIP_TEST;
     260              : 
     261              :         /* Get index of serial line, if found in DT aliases */
     262            0 :         ret = of_alias_get_id(dev_of_node(dev), "serial");
     263            0 :         if (ret >= 0)
     264            0 :                 port->line = ret;
     265              : 
     266            0 :         if (dev_is_platform(dev))
     267            0 :                 ret = platform_get_irq(to_platform_device(dev), 0);
     268            0 :         else if (dev_is_pnp(dev)) {
     269            0 :                 ret = pnp_irq(to_pnp_dev(dev), 0);
     270            0 :                 if (ret < 0)
     271            0 :                         ret = -ENXIO;
     272            0 :         } else
     273            0 :                 ret = fwnode_irq_get(dev_fwnode(dev), 0);
     274            0 :         if (ret == -EPROBE_DEFER)
     275            0 :                 return ret;
     276            0 :         if (ret > 0)
     277            0 :                 port->irq = ret;
     278            0 :         else if (use_defaults)
     279              :                 /* By default IRQ support is mandatory */
     280            0 :                 return ret;
     281              :         else
     282            0 :                 port->irq = 0;
     283              : 
     284            0 :         port->flags |= UPF_SHARE_IRQ;
     285              : 
     286            0 :         return 0;
     287            0 : }
     288              : 
     289            0 : int uart_read_port_properties(struct uart_port *port)
     290              : {
     291            0 :         return __uart_read_properties(port, true);
     292              : }
     293              : EXPORT_SYMBOL_GPL(uart_read_port_properties);
     294              : 
     295            0 : int uart_read_and_validate_port_properties(struct uart_port *port)
     296              : {
     297            0 :         return __uart_read_properties(port, false);
     298              : }
     299              : EXPORT_SYMBOL_GPL(uart_read_and_validate_port_properties);
     300              : 
     301              : static struct device_driver serial_port_driver = {
     302              :         .name = "port",
     303              :         .suppress_bind_attrs = true,
     304              :         .probe = serial_port_probe,
     305              :         .remove = serial_port_remove,
     306              :         .pm = pm_ptr(&serial_port_pm),
     307              : };
     308              : 
     309            0 : int serial_base_port_init(void)
     310              : {
     311            0 :         return serial_base_driver_register(&serial_port_driver);
     312              : }
     313              : 
     314            0 : void serial_base_port_exit(void)
     315              : {
     316            0 :         serial_base_driver_unregister(&serial_port_driver);
     317            0 : }
     318              : 
     319              : MODULE_AUTHOR("Tony Lindgren <[email protected]>");
     320              : MODULE_DESCRIPTION("Serial controller port driver");
     321              : MODULE_LICENSE("GPL");
        

Generated by: LCOV version 2.0-1