xref: /openbmc/linux/drivers/tty/serial/8250/8250_of.c (revision c997aabb)
1 /*
2  *  Serial Port driver for Open Firmware platform devices
3  *
4  *    Copyright (C) 2006 Arnd Bergmann <arnd@arndb.de>, IBM Corp.
5  *
6  *  This program is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU General Public License
8  *  as published by the Free Software Foundation; either version
9  *  2 of the License, or (at your option) any later version.
10  *
11  */
12 #include <linux/console.h>
13 #include <linux/module.h>
14 #include <linux/slab.h>
15 #include <linux/delay.h>
16 #include <linux/serial_core.h>
17 #include <linux/serial_reg.h>
18 #include <linux/of_address.h>
19 #include <linux/of_irq.h>
20 #include <linux/of_platform.h>
21 #include <linux/clk.h>
22 #include <linux/reset.h>
23 
24 #include "8250.h"
25 
26 struct of_serial_info {
27 	struct clk *clk;
28 	struct reset_control *rst;
29 	int type;
30 	int line;
31 };
32 
33 #ifdef CONFIG_ARCH_TEGRA
34 static void tegra_serial_handle_break(struct uart_port *p)
35 {
36 	unsigned int status, tmout = 10000;
37 
38 	do {
39 		status = p->serial_in(p, UART_LSR);
40 		if (status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS))
41 			status = p->serial_in(p, UART_RX);
42 		else
43 			break;
44 		if (--tmout == 0)
45 			break;
46 		udelay(1);
47 	} while (1);
48 }
49 #else
50 static inline void tegra_serial_handle_break(struct uart_port *port)
51 {
52 }
53 #endif
54 
55 /*
56  * Fill a struct uart_port for a given device node
57  */
58 static int of_platform_serial_setup(struct platform_device *ofdev,
59 			int type, struct uart_port *port,
60 			struct of_serial_info *info)
61 {
62 	struct resource resource;
63 	struct device_node *np = ofdev->dev.of_node;
64 	u32 clk, spd, prop;
65 	int ret;
66 
67 	memset(port, 0, sizeof *port);
68 	if (of_property_read_u32(np, "clock-frequency", &clk)) {
69 
70 		/* Get clk rate through clk driver if present */
71 		info->clk = devm_clk_get(&ofdev->dev, NULL);
72 		if (IS_ERR(info->clk)) {
73 			dev_warn(&ofdev->dev,
74 				"clk or clock-frequency not defined\n");
75 			return PTR_ERR(info->clk);
76 		}
77 
78 		ret = clk_prepare_enable(info->clk);
79 		if (ret < 0)
80 			return ret;
81 
82 		clk = clk_get_rate(info->clk);
83 	}
84 	/* If current-speed was set, then try not to change it. */
85 	if (of_property_read_u32(np, "current-speed", &spd) == 0)
86 		port->custom_divisor = clk / (16 * spd);
87 
88 	ret = of_address_to_resource(np, 0, &resource);
89 	if (ret) {
90 		dev_warn(&ofdev->dev, "invalid address\n");
91 		goto out;
92 	}
93 
94 	spin_lock_init(&port->lock);
95 	port->mapbase = resource.start;
96 	port->mapsize = resource_size(&resource);
97 
98 	/* Check for shifted address mapping */
99 	if (of_property_read_u32(np, "reg-offset", &prop) == 0)
100 		port->mapbase += prop;
101 
102 	/* Check for registers offset within the devices address range */
103 	if (of_property_read_u32(np, "reg-shift", &prop) == 0)
104 		port->regshift = prop;
105 
106 	/* Check for fifo size */
107 	if (of_property_read_u32(np, "fifo-size", &prop) == 0)
108 		port->fifosize = prop;
109 
110 	/* Check for a fixed line number */
111 	ret = of_alias_get_id(np, "serial");
112 	if (ret >= 0)
113 		port->line = ret;
114 
115 	port->irq = irq_of_parse_and_map(np, 0);
116 	port->iotype = UPIO_MEM;
117 	if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
118 		switch (prop) {
119 		case 1:
120 			port->iotype = UPIO_MEM;
121 			break;
122 		case 2:
123 			port->iotype = UPIO_MEM16;
124 			break;
125 		case 4:
126 			port->iotype = of_device_is_big_endian(np) ?
127 				       UPIO_MEM32BE : UPIO_MEM32;
128 			break;
129 		default:
130 			dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n",
131 				 prop);
132 			ret = -EINVAL;
133 			goto out;
134 		}
135 	}
136 
137 	info->rst = devm_reset_control_get_optional_shared(&ofdev->dev, NULL);
138 	if (IS_ERR(info->rst))
139 		goto out;
140 	ret = reset_control_deassert(info->rst);
141 	if (ret)
142 		goto out;
143 
144 	port->type = type;
145 	port->uartclk = clk;
146 	port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP
147 		| UPF_FIXED_PORT | UPF_FIXED_TYPE;
148 
149 	if (of_find_property(np, "no-loopback-test", NULL))
150 		port->flags |= UPF_SKIP_TEST;
151 
152 	port->dev = &ofdev->dev;
153 
154 	switch (type) {
155 	case PORT_TEGRA:
156 		port->handle_break = tegra_serial_handle_break;
157 		break;
158 
159 	case PORT_RT2880:
160 		port->iotype = UPIO_AU;
161 		break;
162 	}
163 
164 	if (IS_ENABLED(CONFIG_SERIAL_8250_FSL) &&
165 	    (of_device_is_compatible(np, "fsl,ns16550") ||
166 	     of_device_is_compatible(np, "fsl,16550-FIFO64")))
167 		port->handle_irq = fsl8250_handle_irq;
168 
169 	return 0;
170 out:
171 	if (info->clk)
172 		clk_disable_unprepare(info->clk);
173 	return ret;
174 }
175 
176 /*
177  * Try to register a serial port
178  */
179 static const struct of_device_id of_platform_serial_table[];
180 static int of_platform_serial_probe(struct platform_device *ofdev)
181 {
182 	const struct of_device_id *match;
183 	struct of_serial_info *info;
184 	struct uart_8250_port port8250;
185 	u32 tx_threshold;
186 	int port_type;
187 	int ret;
188 
189 	match = of_match_device(of_platform_serial_table, &ofdev->dev);
190 	if (!match)
191 		return -EINVAL;
192 
193 	if (of_find_property(ofdev->dev.of_node, "used-by-rtas", NULL))
194 		return -EBUSY;
195 
196 	info = kzalloc(sizeof(*info), GFP_KERNEL);
197 	if (info == NULL)
198 		return -ENOMEM;
199 
200 	port_type = (unsigned long)match->data;
201 	memset(&port8250, 0, sizeof(port8250));
202 	ret = of_platform_serial_setup(ofdev, port_type, &port8250.port, info);
203 	if (ret)
204 		goto out;
205 
206 	if (port8250.port.fifosize)
207 		port8250.capabilities = UART_CAP_FIFO;
208 
209 	/* Check for TX FIFO threshold & set tx_loadsz */
210 	if ((of_property_read_u32(ofdev->dev.of_node, "tx-threshold",
211 				  &tx_threshold) == 0) &&
212 	    (tx_threshold < port8250.port.fifosize))
213 		port8250.tx_loadsz = port8250.port.fifosize - tx_threshold;
214 
215 	if (of_property_read_bool(ofdev->dev.of_node, "auto-flow-control"))
216 		port8250.capabilities |= UART_CAP_AFE;
217 
218 	ret = serial8250_register_8250_port(&port8250);
219 	if (ret < 0)
220 		goto out;
221 
222 	info->type = port_type;
223 	info->line = ret;
224 	platform_set_drvdata(ofdev, info);
225 	return 0;
226 out:
227 	kfree(info);
228 	irq_dispose_mapping(port8250.port.irq);
229 	return ret;
230 }
231 
232 /*
233  * Release a line
234  */
235 static int of_platform_serial_remove(struct platform_device *ofdev)
236 {
237 	struct of_serial_info *info = platform_get_drvdata(ofdev);
238 
239 	serial8250_unregister_port(info->line);
240 
241 	reset_control_assert(info->rst);
242 	if (info->clk)
243 		clk_disable_unprepare(info->clk);
244 	kfree(info);
245 	return 0;
246 }
247 
248 #ifdef CONFIG_PM_SLEEP
249 static int of_serial_suspend(struct device *dev)
250 {
251 	struct of_serial_info *info = dev_get_drvdata(dev);
252 	struct uart_8250_port *port8250 = serial8250_get_port(info->line);
253 	struct uart_port *port = &port8250->port;
254 
255 	serial8250_suspend_port(info->line);
256 
257 	if (info->clk && (!uart_console(port) || console_suspend_enabled))
258 		clk_disable_unprepare(info->clk);
259 
260 	return 0;
261 }
262 
263 static int of_serial_resume(struct device *dev)
264 {
265 	struct of_serial_info *info = dev_get_drvdata(dev);
266 	struct uart_8250_port *port8250 = serial8250_get_port(info->line);
267 	struct uart_port *port = &port8250->port;
268 
269 	if (info->clk && (!uart_console(port) || console_suspend_enabled))
270 		clk_prepare_enable(info->clk);
271 
272 	serial8250_resume_port(info->line);
273 
274 	return 0;
275 }
276 #endif
277 static SIMPLE_DEV_PM_OPS(of_serial_pm_ops, of_serial_suspend, of_serial_resume);
278 
279 /*
280  * A few common types, add more as needed.
281  */
282 static const struct of_device_id of_platform_serial_table[] = {
283 	{ .compatible = "ns8250",   .data = (void *)PORT_8250, },
284 	{ .compatible = "ns16450",  .data = (void *)PORT_16450, },
285 	{ .compatible = "ns16550a", .data = (void *)PORT_16550A, },
286 	{ .compatible = "ns16550",  .data = (void *)PORT_16550, },
287 	{ .compatible = "ns16750",  .data = (void *)PORT_16750, },
288 	{ .compatible = "ns16850",  .data = (void *)PORT_16850, },
289 	{ .compatible = "nvidia,tegra20-uart", .data = (void *)PORT_TEGRA, },
290 	{ .compatible = "nxp,lpc3220-uart", .data = (void *)PORT_LPC3220, },
291 	{ .compatible = "ralink,rt2880-uart", .data = (void *)PORT_RT2880, },
292 	{ .compatible = "altr,16550-FIFO32",
293 		.data = (void *)PORT_ALTR_16550_F32, },
294 	{ .compatible = "altr,16550-FIFO64",
295 		.data = (void *)PORT_ALTR_16550_F64, },
296 	{ .compatible = "altr,16550-FIFO128",
297 		.data = (void *)PORT_ALTR_16550_F128, },
298 	{ .compatible = "mrvl,mmp-uart",
299 		.data = (void *)PORT_XSCALE, },
300 	{ .compatible = "ti,da830-uart", .data = (void *)PORT_DA830, },
301 	{ /* end of list */ },
302 };
303 MODULE_DEVICE_TABLE(of, of_platform_serial_table);
304 
305 static struct platform_driver of_platform_serial_driver = {
306 	.driver = {
307 		.name = "of_serial",
308 		.of_match_table = of_platform_serial_table,
309 		.pm = &of_serial_pm_ops,
310 	},
311 	.probe = of_platform_serial_probe,
312 	.remove = of_platform_serial_remove,
313 };
314 
315 module_platform_driver(of_platform_serial_driver);
316 
317 MODULE_AUTHOR("Arnd Bergmann <arnd@arndb.de>");
318 MODULE_LICENSE("GPL");
319 MODULE_DESCRIPTION("Serial Port driver for Open Firmware platform devices");
320