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