// SPDX-License-Identifier: GPL-2.0+
/*
 * Serial core port device driver
 *
 * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
 * Author: Tony Lindgren <tony@atomide.com>
 */

#include <linux/device.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include <linux/serial_core.h>
#include <linux/spinlock.h>

#include "serial_base.h"

#define SERIAL_PORT_AUTOSUSPEND_DELAY_MS	500

/* Only considers pending TX for now. Caller must take care of locking */
static int __serial_port_busy(struct uart_port *port)
{
	return !uart_tx_stopped(port) &&
		uart_circ_chars_pending(&port->state->xmit);
}

static int serial_port_runtime_resume(struct device *dev)
{
	struct serial_port_device *port_dev = to_serial_base_port_device(dev);
	struct uart_port *port;
	unsigned long flags;

	port = port_dev->port;

	if (port->flags & UPF_DEAD)
		goto out;

	/* Flush any pending TX for the port */
	uart_port_lock_irqsave(port, &flags);
	if (__serial_port_busy(port))
		port->ops->start_tx(port);
	uart_port_unlock_irqrestore(port, flags);

out:
	pm_runtime_mark_last_busy(dev);

	return 0;
}

static int serial_port_runtime_suspend(struct device *dev)
{
	struct serial_port_device *port_dev = to_serial_base_port_device(dev);
	struct uart_port *port = port_dev->port;
	unsigned long flags;
	bool busy;

	if (port->flags & UPF_DEAD)
		return 0;

	uart_port_lock_irqsave(port, &flags);
	busy = __serial_port_busy(port);
	if (busy)
		port->ops->start_tx(port);
	uart_port_unlock_irqrestore(port, flags);

	if (busy)
		pm_runtime_mark_last_busy(dev);

	return busy ? -EBUSY : 0;
}

static DEFINE_RUNTIME_DEV_PM_OPS(serial_port_pm,
				 serial_port_runtime_suspend,
				 serial_port_runtime_resume, NULL);

static int serial_port_probe(struct device *dev)
{
	pm_runtime_enable(dev);
	pm_runtime_set_autosuspend_delay(dev, SERIAL_PORT_AUTOSUSPEND_DELAY_MS);
	pm_runtime_use_autosuspend(dev);

	return 0;
}

static int serial_port_remove(struct device *dev)
{
	pm_runtime_dont_use_autosuspend(dev);
	pm_runtime_disable(dev);

	return 0;
}

/*
 * Serial core port device init functions. Note that the physical serial
 * port device driver may not have completed probe at this point.
 */
int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
{
	return serial_ctrl_register_port(drv, port);
}
EXPORT_SYMBOL(uart_add_one_port);

void uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
{
	serial_ctrl_unregister_port(drv, port);
}
EXPORT_SYMBOL(uart_remove_one_port);

/**
 * __uart_read_properties - read firmware properties of the given UART port
 * @port: corresponding port
 * @use_defaults: apply defaults (when %true) or validate the values (when %false)
 *
 * The following device properties are supported:
 *   - clock-frequency (optional)
 *   - fifo-size (optional)
 *   - no-loopback-test (optional)
 *   - reg-shift (defaults may apply)
 *   - reg-offset (value may be validated)
 *   - reg-io-width (defaults may apply or value may be validated)
 *   - interrupts (OF only)
 *   - serial [alias ID] (OF only)
 *
 * If the port->dev is of struct platform_device type the interrupt line
 * will be retrieved via platform_get_irq() call against that device.
 * Otherwise it will be assigned by fwnode_irq_get() call. In both cases
 * the index 0 of the resource is used.
 *
 * The caller is responsible to initialize the following fields of the @port
 *   ->dev (must be valid)
 *   ->flags
 *   ->mapbase
 *   ->mapsize
 *   ->regshift (if @use_defaults is false)
 * before calling this function. Alternatively the above mentioned fields
 * may be zeroed, in such case the only ones, that have associated properties
 * found, will be set to the respective values.
 *
 * If no error happened, the ->irq, ->mapbase, ->mapsize will be altered.
 * The ->iotype is always altered.
 *
 * When @use_defaults is true and the respective property is not found
 * the following values will be applied:
 *   ->regshift = 0
 * In this case IRQ must be provided, otherwise an error will be returned.
 *
 * When @use_defaults is false and the respective property is found
 * the following values will be validated:
 *   - reg-io-width (->iotype)
 *   - reg-offset (->mapsize against ->mapbase)
 *
 * Returns: 0 on success or negative errno on failure
 */
static int __uart_read_properties(struct uart_port *port, bool use_defaults)
{
	struct device *dev = port->dev;
	u32 value;
	int ret;

	/* Read optional UART functional clock frequency */
	device_property_read_u32(dev, "clock-frequency", &port->uartclk);

	/* Read the registers alignment (default: 8-bit) */
	ret = device_property_read_u32(dev, "reg-shift", &value);
	if (ret)
		port->regshift = use_defaults ? 0 : port->regshift;
	else
		port->regshift = value;

	/* Read the registers I/O access type (default: MMIO 8-bit) */
	ret = device_property_read_u32(dev, "reg-io-width", &value);
	if (ret) {
		port->iotype = UPIO_MEM;
	} else {
		switch (value) {
		case 1:
			port->iotype = UPIO_MEM;
			break;
		case 2:
			port->iotype = UPIO_MEM16;
			break;
		case 4:
			port->iotype = device_is_big_endian(dev) ? UPIO_MEM32BE : UPIO_MEM32;
			break;
		default:
			if (!use_defaults) {
				dev_err(dev, "Unsupported reg-io-width (%u)\n", value);
				return -EINVAL;
			}
			port->iotype = UPIO_UNKNOWN;
			break;
		}
	}

	/* Read the address mapping base offset (default: no offset) */
	ret = device_property_read_u32(dev, "reg-offset", &value);
	if (ret)
		value = 0;

	/* Check for shifted address mapping overflow */
	if (!use_defaults && port->mapsize < value) {
		dev_err(dev, "reg-offset %u exceeds region size %pa\n", value, &port->mapsize);
		return -EINVAL;
	}

	port->mapbase += value;
	port->mapsize -= value;

	/* Read optional FIFO size */
	device_property_read_u32(dev, "fifo-size", &port->fifosize);

	if (device_property_read_bool(dev, "no-loopback-test"))
		port->flags |= UPF_SKIP_TEST;

	/* Get index of serial line, if found in DT aliases */
	ret = of_alias_get_id(dev_of_node(dev), "serial");
	if (ret >= 0)
		port->line = ret;

	if (dev_is_platform(dev))
		ret = platform_get_irq(to_platform_device(dev), 0);
	else
		ret = fwnode_irq_get(dev_fwnode(dev), 0);
	if (ret == -EPROBE_DEFER)
		return ret;
	if (ret > 0)
		port->irq = ret;
	else if (use_defaults)
		/* By default IRQ support is mandatory */
		return ret;
	else
		port->irq = 0;

	port->flags |= UPF_SHARE_IRQ;

	return 0;
}

int uart_read_port_properties(struct uart_port *port)
{
	return __uart_read_properties(port, true);
}
EXPORT_SYMBOL_GPL(uart_read_port_properties);

int uart_read_and_validate_port_properties(struct uart_port *port)
{
	return __uart_read_properties(port, false);
}
EXPORT_SYMBOL_GPL(uart_read_and_validate_port_properties);

static struct device_driver serial_port_driver = {
	.name = "port",
	.suppress_bind_attrs = true,
	.probe = serial_port_probe,
	.remove = serial_port_remove,
	.pm = pm_ptr(&serial_port_pm),
};

int serial_base_port_init(void)
{
	return serial_base_driver_register(&serial_port_driver);
}

void serial_base_port_exit(void)
{
	serial_base_driver_unregister(&serial_port_driver);
}

MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
MODULE_DESCRIPTION("Serial controller port driver");
MODULE_LICENSE("GPL");
