xref: /linux/drivers/tty/serial/8250/8250_platform.c (revision 6e7fd890f1d6ac83805409e9c346240de2705584)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *  Universal/legacy platform driver for 8250/16550-type serial ports
4  *
5  *  Supports: ISA-compatible 8250/16550 ports
6  *	      PNP 8250/16550 ports
7  *	      "serial8250" platform devices
8  */
9 #include <linux/array_size.h>
10 #include <linux/module.h>
11 #include <linux/moduleparam.h>
12 #include <linux/once.h>
13 #include <linux/platform_device.h>
14 
15 #include <linux/serial_8250.h>
16 
17 #ifdef CONFIG_SPARC
18 #include <linux/sunserialcore.h>
19 #endif
20 
21 #include "8250.h"
22 
23 /*
24  * Configuration:
25  *    share_irqs   Whether we pass IRQF_SHARED to request_irq().
26  *                 This option is unsafe when used on edge-triggered interrupts.
27  * skip_txen_test  Force skip of txen test at init time.
28  */
29 unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
30 unsigned int skip_txen_test;
31 
32 unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
33 
34 #include <asm/serial.h>
35 
36 /*
37  * SERIAL_PORT_DFNS tells us about built-in ports that have no
38  * standard enumeration mechanism. Platforms that can find all
39  * serial ports via mechanisms like ACPI or PCI need not supply it.
40  */
41 #ifndef SERIAL_PORT_DFNS
42 #define SERIAL_PORT_DFNS
43 #endif
44 
45 static const struct old_serial_port old_serial_port[] = {
46 	SERIAL_PORT_DFNS /* defined in asm/serial.h */
47 };
48 
49 serial8250_isa_config_fn serial8250_isa_config;
50 void serial8250_set_isa_configurator(serial8250_isa_config_fn v)
51 {
52 	serial8250_isa_config = v;
53 }
54 EXPORT_SYMBOL(serial8250_set_isa_configurator);
55 
56 static void __init __serial8250_isa_init_ports(void)
57 {
58 	int i, irqflag = 0;
59 
60 	if (nr_uarts > UART_NR)
61 		nr_uarts = UART_NR;
62 
63 	/*
64 	 * Set up initial isa ports based on nr_uart module param, or else
65 	 * default to CONFIG_SERIAL_8250_RUNTIME_UARTS. Note that we do not
66 	 * need to increase nr_uarts when setting up the initial isa ports.
67 	 */
68 	for (i = 0; i < nr_uarts; i++)
69 		serial8250_setup_port(i);
70 
71 	/* chain base port ops to support Remote Supervisor Adapter */
72 	univ8250_port_ops = *univ8250_port_base_ops;
73 	univ8250_rsa_support(&univ8250_port_ops);
74 
75 	if (share_irqs)
76 		irqflag = IRQF_SHARED;
77 
78 	for (i = 0; i < ARRAY_SIZE(old_serial_port) && i < nr_uarts; i++) {
79 		struct uart_8250_port *up = serial8250_get_port(i);
80 		struct uart_port *port = &up->port;
81 
82 		port->iobase   = old_serial_port[i].port;
83 		port->irq      = irq_canonicalize(old_serial_port[i].irq);
84 		port->irqflags = 0;
85 		port->uartclk  = old_serial_port[i].baud_base * 16;
86 		port->flags    = old_serial_port[i].flags;
87 		port->hub6     = 0;
88 		port->membase  = old_serial_port[i].iomem_base;
89 		port->iotype   = old_serial_port[i].io_type;
90 		port->regshift = old_serial_port[i].iomem_reg_shift;
91 
92 		port->irqflags |= irqflag;
93 		if (serial8250_isa_config != NULL)
94 			serial8250_isa_config(i, &up->port, &up->capabilities);
95 	}
96 }
97 
98 void __init serial8250_isa_init_ports(void)
99 {
100 	DO_ONCE(__serial8250_isa_init_ports);
101 }
102 
103 /*
104  * Register a set of serial devices attached to a platform device.  The
105  * list is terminated with a zero flags entry, which means we expect
106  * all entries to have at least UPF_BOOT_AUTOCONF set.
107  */
108 static int serial8250_probe(struct platform_device *dev)
109 {
110 	struct plat_serial8250_port *p = dev_get_platdata(&dev->dev);
111 	struct uart_8250_port uart;
112 	int ret, i, irqflag = 0;
113 
114 	memset(&uart, 0, sizeof(uart));
115 
116 	if (share_irqs)
117 		irqflag = IRQF_SHARED;
118 
119 	for (i = 0; p && p->flags != 0; p++, i++) {
120 		uart.port.iobase	= p->iobase;
121 		uart.port.membase	= p->membase;
122 		uart.port.irq		= p->irq;
123 		uart.port.irqflags	= p->irqflags;
124 		uart.port.uartclk	= p->uartclk;
125 		uart.port.regshift	= p->regshift;
126 		uart.port.iotype	= p->iotype;
127 		uart.port.flags		= p->flags;
128 		uart.port.mapbase	= p->mapbase;
129 		uart.port.mapsize	= p->mapsize;
130 		uart.port.hub6		= p->hub6;
131 		uart.port.has_sysrq	= p->has_sysrq;
132 		uart.port.private_data	= p->private_data;
133 		uart.port.type		= p->type;
134 		uart.bugs		= p->bugs;
135 		uart.port.serial_in	= p->serial_in;
136 		uart.port.serial_out	= p->serial_out;
137 		uart.dl_read		= p->dl_read;
138 		uart.dl_write		= p->dl_write;
139 		uart.port.handle_irq	= p->handle_irq;
140 		uart.port.handle_break	= p->handle_break;
141 		uart.port.set_termios	= p->set_termios;
142 		uart.port.set_ldisc	= p->set_ldisc;
143 		uart.port.get_mctrl	= p->get_mctrl;
144 		uart.port.pm		= p->pm;
145 		uart.port.dev		= &dev->dev;
146 		uart.port.irqflags	|= irqflag;
147 		ret = serial8250_register_8250_port(&uart);
148 		if (ret < 0) {
149 			dev_err(&dev->dev, "unable to register port at index %d "
150 				"(IO%lx MEM%llx IRQ%d): %d\n", i,
151 				p->iobase, (unsigned long long)p->mapbase,
152 				p->irq, ret);
153 		}
154 	}
155 	return 0;
156 }
157 
158 /*
159  * Remove serial ports registered against a platform device.
160  */
161 static void serial8250_remove(struct platform_device *dev)
162 {
163 	int i;
164 
165 	for (i = 0; i < nr_uarts; i++) {
166 		struct uart_8250_port *up = serial8250_get_port(i);
167 
168 		if (up->port.dev == &dev->dev)
169 			serial8250_unregister_port(i);
170 	}
171 }
172 
173 static int serial8250_suspend(struct platform_device *dev, pm_message_t state)
174 {
175 	int i;
176 
177 	for (i = 0; i < UART_NR; i++) {
178 		struct uart_8250_port *up = serial8250_get_port(i);
179 
180 		if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
181 			uart_suspend_port(&serial8250_reg, &up->port);
182 	}
183 
184 	return 0;
185 }
186 
187 static int serial8250_resume(struct platform_device *dev)
188 {
189 	int i;
190 
191 	for (i = 0; i < UART_NR; i++) {
192 		struct uart_8250_port *up = serial8250_get_port(i);
193 
194 		if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
195 			serial8250_resume_port(i);
196 	}
197 
198 	return 0;
199 }
200 
201 static struct platform_driver serial8250_isa_driver = {
202 	.probe		= serial8250_probe,
203 	.remove_new	= serial8250_remove,
204 	.suspend	= serial8250_suspend,
205 	.resume		= serial8250_resume,
206 	.driver		= {
207 		.name	= "serial8250",
208 	},
209 };
210 
211 /*
212  * This "device" covers _all_ ISA 8250-compatible serial devices listed
213  * in the table in include/asm/serial.h
214  */
215 struct platform_device *serial8250_isa_devs;
216 
217 static int __init serial8250_init(void)
218 {
219 	int ret;
220 
221 	if (nr_uarts == 0)
222 		return -ENODEV;
223 
224 	serial8250_isa_init_ports();
225 
226 	pr_info("Serial: 8250/16550 driver, %d ports, IRQ sharing %s\n",
227 		nr_uarts, str_enabled_disabled(share_irqs));
228 
229 #ifdef CONFIG_SPARC
230 	ret = sunserial_register_minors(&serial8250_reg, UART_NR);
231 #else
232 	serial8250_reg.nr = UART_NR;
233 	ret = uart_register_driver(&serial8250_reg);
234 #endif
235 	if (ret)
236 		goto out;
237 
238 	ret = serial8250_pnp_init();
239 	if (ret)
240 		goto unreg_uart_drv;
241 
242 	serial8250_isa_devs = platform_device_alloc("serial8250",
243 						    PLAT8250_DEV_LEGACY);
244 	if (!serial8250_isa_devs) {
245 		ret = -ENOMEM;
246 		goto unreg_pnp;
247 	}
248 
249 	ret = platform_device_add(serial8250_isa_devs);
250 	if (ret)
251 		goto put_dev;
252 
253 	serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);
254 
255 	ret = platform_driver_register(&serial8250_isa_driver);
256 	if (ret == 0)
257 		goto out;
258 
259 	platform_device_del(serial8250_isa_devs);
260 put_dev:
261 	platform_device_put(serial8250_isa_devs);
262 unreg_pnp:
263 	serial8250_pnp_exit();
264 unreg_uart_drv:
265 #ifdef CONFIG_SPARC
266 	sunserial_unregister_minors(&serial8250_reg, UART_NR);
267 #else
268 	uart_unregister_driver(&serial8250_reg);
269 #endif
270 out:
271 	return ret;
272 }
273 module_init(serial8250_init);
274 
275 static void __exit serial8250_exit(void)
276 {
277 	struct platform_device *isa_dev = serial8250_isa_devs;
278 
279 	/*
280 	 * This tells serial8250_unregister_port() not to re-register
281 	 * the ports (thereby making serial8250_isa_driver permanently
282 	 * in use.)
283 	 */
284 	serial8250_isa_devs = NULL;
285 
286 	platform_driver_unregister(&serial8250_isa_driver);
287 	platform_device_unregister(isa_dev);
288 
289 	serial8250_pnp_exit();
290 
291 #ifdef CONFIG_SPARC
292 	sunserial_unregister_minors(&serial8250_reg, UART_NR);
293 #else
294 	uart_unregister_driver(&serial8250_reg);
295 #endif
296 }
297 module_exit(serial8250_exit);
298 
299 MODULE_LICENSE("GPL");
300 MODULE_DESCRIPTION("Generic 8250/16x50 serial platform driver");
301 
302 module_param_hw(share_irqs, uint, other, 0644);
303 MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices (unsafe)");
304 
305 module_param(nr_uarts, uint, 0644);
306 MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")");
307 
308 module_param(skip_txen_test, uint, 0644);
309 MODULE_PARM_DESC(skip_txen_test, "Skip checking for the TXEN bug at init time");
310 
311 MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
312 
313 #ifdef CONFIG_SERIAL_8250_DEPRECATED_OPTIONS
314 #ifndef MODULE
315 /* This module was renamed to 8250_core in 3.7.  Keep the old "8250" name
316  * working as well for the module options so we don't break people.  We
317  * need to keep the names identical and the convenient macros will happily
318  * refuse to let us do that by failing the build with redefinition errors
319  * of global variables.  So we stick them inside a dummy function to avoid
320  * those conflicts.  The options still get parsed, and the redefined
321  * MODULE_PARAM_PREFIX lets us keep the "8250." syntax alive.
322  *
323  * This is hacky.  I'm sorry.
324  */
325 static void __used s8250_options(void)
326 {
327 #undef MODULE_PARAM_PREFIX
328 #define MODULE_PARAM_PREFIX "8250_core."
329 
330 	module_param_cb(share_irqs, &param_ops_uint, &share_irqs, 0644);
331 	module_param_cb(nr_uarts, &param_ops_uint, &nr_uarts, 0644);
332 	module_param_cb(skip_txen_test, &param_ops_uint, &skip_txen_test, 0644);
333 }
334 #else
335 MODULE_ALIAS("8250_core");
336 #endif
337 #endif
338