cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

8250_of.c (9549B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 *  Serial Port driver for Open Firmware platform devices
      4 *
      5 *    Copyright (C) 2006 Arnd Bergmann <arnd@arndb.de>, IBM Corp.
      6 */
      7#include <linux/console.h>
      8#include <linux/module.h>
      9#include <linux/slab.h>
     10#include <linux/serial_core.h>
     11#include <linux/serial_reg.h>
     12#include <linux/of_address.h>
     13#include <linux/of_irq.h>
     14#include <linux/of_platform.h>
     15#include <linux/pm_runtime.h>
     16#include <linux/clk.h>
     17#include <linux/reset.h>
     18
     19#include "8250.h"
     20
     21struct of_serial_info {
     22	struct clk *clk;
     23	struct reset_control *rst;
     24	int type;
     25	int line;
     26};
     27
     28/*
     29 * Fill a struct uart_port for a given device node
     30 */
     31static int of_platform_serial_setup(struct platform_device *ofdev,
     32			int type, struct uart_8250_port *up,
     33			struct of_serial_info *info)
     34{
     35	struct resource resource;
     36	struct device_node *np = ofdev->dev.of_node;
     37	struct uart_port *port = &up->port;
     38	u32 clk, spd, prop;
     39	int ret, irq;
     40
     41	memset(port, 0, sizeof *port);
     42
     43	pm_runtime_enable(&ofdev->dev);
     44	pm_runtime_get_sync(&ofdev->dev);
     45
     46	if (of_property_read_u32(np, "clock-frequency", &clk)) {
     47
     48		/* Get clk rate through clk driver if present */
     49		info->clk = devm_clk_get(&ofdev->dev, NULL);
     50		if (IS_ERR(info->clk)) {
     51			ret = PTR_ERR(info->clk);
     52			if (ret != -EPROBE_DEFER)
     53				dev_warn(&ofdev->dev,
     54					 "failed to get clock: %d\n", ret);
     55			goto err_pmruntime;
     56		}
     57
     58		ret = clk_prepare_enable(info->clk);
     59		if (ret < 0)
     60			goto err_pmruntime;
     61
     62		clk = clk_get_rate(info->clk);
     63	}
     64	/* If current-speed was set, then try not to change it. */
     65	if (of_property_read_u32(np, "current-speed", &spd) == 0)
     66		port->custom_divisor = clk / (16 * spd);
     67
     68	ret = of_address_to_resource(np, 0, &resource);
     69	if (ret) {
     70		dev_warn(&ofdev->dev, "invalid address\n");
     71		goto err_unprepare;
     72	}
     73
     74	port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT |
     75				  UPF_FIXED_TYPE;
     76	spin_lock_init(&port->lock);
     77
     78	if (resource_type(&resource) == IORESOURCE_IO) {
     79		port->iotype = UPIO_PORT;
     80		port->iobase = resource.start;
     81	} else {
     82		port->mapbase = resource.start;
     83		port->mapsize = resource_size(&resource);
     84
     85		/* Check for shifted address mapping */
     86		if (of_property_read_u32(np, "reg-offset", &prop) == 0) {
     87			if (prop >= port->mapsize) {
     88				dev_warn(&ofdev->dev, "reg-offset %u exceeds region size %pa\n",
     89					 prop, &port->mapsize);
     90				ret = -EINVAL;
     91				goto err_unprepare;
     92			}
     93
     94			port->mapbase += prop;
     95			port->mapsize -= prop;
     96		}
     97
     98		port->iotype = UPIO_MEM;
     99		if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
    100			switch (prop) {
    101			case 1:
    102				port->iotype = UPIO_MEM;
    103				break;
    104			case 2:
    105				port->iotype = UPIO_MEM16;
    106				break;
    107			case 4:
    108				port->iotype = of_device_is_big_endian(np) ?
    109					       UPIO_MEM32BE : UPIO_MEM32;
    110				break;
    111			default:
    112				dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n",
    113					 prop);
    114				ret = -EINVAL;
    115				goto err_unprepare;
    116			}
    117		}
    118		port->flags |= UPF_IOREMAP;
    119	}
    120
    121	/* Compatibility with the deprecated pxa driver and 8250_pxa drivers. */
    122	if (of_device_is_compatible(np, "mrvl,mmp-uart"))
    123		port->regshift = 2;
    124
    125	/* Check for registers offset within the devices address range */
    126	if (of_property_read_u32(np, "reg-shift", &prop) == 0)
    127		port->regshift = prop;
    128
    129	/* Check for fifo size */
    130	if (of_property_read_u32(np, "fifo-size", &prop) == 0)
    131		port->fifosize = prop;
    132
    133	/* Check for a fixed line number */
    134	ret = of_alias_get_id(np, "serial");
    135	if (ret >= 0)
    136		port->line = ret;
    137
    138	irq = of_irq_get(np, 0);
    139	if (irq < 0) {
    140		if (irq == -EPROBE_DEFER) {
    141			ret = -EPROBE_DEFER;
    142			goto err_unprepare;
    143		}
    144		/* IRQ support not mandatory */
    145		irq = 0;
    146	}
    147
    148	port->irq = irq;
    149
    150	info->rst = devm_reset_control_get_optional_shared(&ofdev->dev, NULL);
    151	if (IS_ERR(info->rst)) {
    152		ret = PTR_ERR(info->rst);
    153		goto err_unprepare;
    154	}
    155
    156	ret = reset_control_deassert(info->rst);
    157	if (ret)
    158		goto err_unprepare;
    159
    160	port->type = type;
    161	port->uartclk = clk;
    162
    163	if (of_property_read_bool(np, "no-loopback-test"))
    164		port->flags |= UPF_SKIP_TEST;
    165
    166	port->dev = &ofdev->dev;
    167	port->rs485_config = serial8250_em485_config;
    168	up->rs485_start_tx = serial8250_em485_start_tx;
    169	up->rs485_stop_tx = serial8250_em485_stop_tx;
    170
    171	switch (type) {
    172	case PORT_RT2880:
    173		port->iotype = UPIO_AU;
    174		break;
    175	}
    176
    177	if (IS_ENABLED(CONFIG_SERIAL_8250_FSL) &&
    178	    (of_device_is_compatible(np, "fsl,ns16550") ||
    179	     of_device_is_compatible(np, "fsl,16550-FIFO64"))) {
    180		port->handle_irq = fsl8250_handle_irq;
    181		port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_8250_CONSOLE);
    182	}
    183
    184	return 0;
    185err_unprepare:
    186	clk_disable_unprepare(info->clk);
    187err_pmruntime:
    188	pm_runtime_put_sync(&ofdev->dev);
    189	pm_runtime_disable(&ofdev->dev);
    190	return ret;
    191}
    192
    193/*
    194 * Try to register a serial port
    195 */
    196static int of_platform_serial_probe(struct platform_device *ofdev)
    197{
    198	struct of_serial_info *info;
    199	struct uart_8250_port port8250;
    200	unsigned int port_type;
    201	u32 tx_threshold;
    202	int ret;
    203
    204	if (IS_ENABLED(CONFIG_SERIAL_8250_BCM7271) &&
    205	    of_device_is_compatible(ofdev->dev.of_node, "brcm,bcm7271-uart"))
    206		return -ENODEV;
    207
    208	port_type = (unsigned long)of_device_get_match_data(&ofdev->dev);
    209	if (port_type == PORT_UNKNOWN)
    210		return -EINVAL;
    211
    212	if (of_property_read_bool(ofdev->dev.of_node, "used-by-rtas"))
    213		return -EBUSY;
    214
    215	info = kzalloc(sizeof(*info), GFP_KERNEL);
    216	if (info == NULL)
    217		return -ENOMEM;
    218
    219	memset(&port8250, 0, sizeof(port8250));
    220	ret = of_platform_serial_setup(ofdev, port_type, &port8250, info);
    221	if (ret)
    222		goto err_free;
    223
    224	if (port8250.port.fifosize)
    225		port8250.capabilities = UART_CAP_FIFO;
    226
    227	/* Check for TX FIFO threshold & set tx_loadsz */
    228	if ((of_property_read_u32(ofdev->dev.of_node, "tx-threshold",
    229				  &tx_threshold) == 0) &&
    230	    (tx_threshold < port8250.port.fifosize))
    231		port8250.tx_loadsz = port8250.port.fifosize - tx_threshold;
    232
    233	if (of_property_read_bool(ofdev->dev.of_node, "auto-flow-control"))
    234		port8250.capabilities |= UART_CAP_AFE;
    235
    236	if (of_property_read_u32(ofdev->dev.of_node,
    237			"overrun-throttle-ms",
    238			&port8250.overrun_backoff_time_ms) != 0)
    239		port8250.overrun_backoff_time_ms = 0;
    240
    241	ret = serial8250_register_8250_port(&port8250);
    242	if (ret < 0)
    243		goto err_dispose;
    244
    245	info->type = port_type;
    246	info->line = ret;
    247	platform_set_drvdata(ofdev, info);
    248	return 0;
    249err_dispose:
    250	irq_dispose_mapping(port8250.port.irq);
    251	pm_runtime_put_sync(&ofdev->dev);
    252	pm_runtime_disable(&ofdev->dev);
    253	clk_disable_unprepare(info->clk);
    254err_free:
    255	kfree(info);
    256	return ret;
    257}
    258
    259/*
    260 * Release a line
    261 */
    262static int of_platform_serial_remove(struct platform_device *ofdev)
    263{
    264	struct of_serial_info *info = platform_get_drvdata(ofdev);
    265
    266	serial8250_unregister_port(info->line);
    267
    268	reset_control_assert(info->rst);
    269	pm_runtime_put_sync(&ofdev->dev);
    270	pm_runtime_disable(&ofdev->dev);
    271	clk_disable_unprepare(info->clk);
    272	kfree(info);
    273	return 0;
    274}
    275
    276#ifdef CONFIG_PM_SLEEP
    277static int of_serial_suspend(struct device *dev)
    278{
    279	struct of_serial_info *info = dev_get_drvdata(dev);
    280	struct uart_8250_port *port8250 = serial8250_get_port(info->line);
    281	struct uart_port *port = &port8250->port;
    282
    283	serial8250_suspend_port(info->line);
    284
    285	if (!uart_console(port) || console_suspend_enabled) {
    286		pm_runtime_put_sync(dev);
    287		clk_disable_unprepare(info->clk);
    288	}
    289	return 0;
    290}
    291
    292static int of_serial_resume(struct device *dev)
    293{
    294	struct of_serial_info *info = dev_get_drvdata(dev);
    295	struct uart_8250_port *port8250 = serial8250_get_port(info->line);
    296	struct uart_port *port = &port8250->port;
    297
    298	if (!uart_console(port) || console_suspend_enabled) {
    299		pm_runtime_get_sync(dev);
    300		clk_prepare_enable(info->clk);
    301	}
    302
    303	serial8250_resume_port(info->line);
    304
    305	return 0;
    306}
    307#endif
    308static SIMPLE_DEV_PM_OPS(of_serial_pm_ops, of_serial_suspend, of_serial_resume);
    309
    310/*
    311 * A few common types, add more as needed.
    312 */
    313static const struct of_device_id of_platform_serial_table[] = {
    314	{ .compatible = "ns8250",   .data = (void *)PORT_8250, },
    315	{ .compatible = "ns16450",  .data = (void *)PORT_16450, },
    316	{ .compatible = "ns16550a", .data = (void *)PORT_16550A, },
    317	{ .compatible = "ns16550",  .data = (void *)PORT_16550, },
    318	{ .compatible = "ns16750",  .data = (void *)PORT_16750, },
    319	{ .compatible = "ns16850",  .data = (void *)PORT_16850, },
    320	{ .compatible = "nxp,lpc3220-uart", .data = (void *)PORT_LPC3220, },
    321	{ .compatible = "ralink,rt2880-uart", .data = (void *)PORT_RT2880, },
    322	{ .compatible = "intel,xscale-uart", .data = (void *)PORT_XSCALE, },
    323	{ .compatible = "altr,16550-FIFO32",
    324		.data = (void *)PORT_ALTR_16550_F32, },
    325	{ .compatible = "altr,16550-FIFO64",
    326		.data = (void *)PORT_ALTR_16550_F64, },
    327	{ .compatible = "altr,16550-FIFO128",
    328		.data = (void *)PORT_ALTR_16550_F128, },
    329	{ .compatible = "fsl,16550-FIFO64",
    330		.data = (void *)PORT_16550A_FSL64, },
    331	{ .compatible = "mediatek,mtk-btif",
    332		.data = (void *)PORT_MTK_BTIF, },
    333	{ .compatible = "mrvl,mmp-uart",
    334		.data = (void *)PORT_XSCALE, },
    335	{ .compatible = "ti,da830-uart", .data = (void *)PORT_DA830, },
    336	{ .compatible = "nuvoton,wpcm450-uart", .data = (void *)PORT_NPCM, },
    337	{ .compatible = "nuvoton,npcm750-uart", .data = (void *)PORT_NPCM, },
    338	{ /* end of list */ },
    339};
    340MODULE_DEVICE_TABLE(of, of_platform_serial_table);
    341
    342static struct platform_driver of_platform_serial_driver = {
    343	.driver = {
    344		.name = "of_serial",
    345		.of_match_table = of_platform_serial_table,
    346		.pm = &of_serial_pm_ops,
    347	},
    348	.probe = of_platform_serial_probe,
    349	.remove = of_platform_serial_remove,
    350};
    351
    352module_platform_driver(of_platform_serial_driver);
    353
    354MODULE_AUTHOR("Arnd Bergmann <arnd@arndb.de>");
    355MODULE_LICENSE("GPL");
    356MODULE_DESCRIPTION("Serial Port driver for Open Firmware platform devices");