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