File Index
Files and directories
Sign in
FILE

8250_platform.c

File preview with syntax highlighting.

linux-6.19.14/drivers/tty/serial/8250/8250_platform.c C
  1// SPDX-License-Identifier: GPL-2.0+
  2/*
  3 *  Universal/legacy platform driver for 8250/16550-type serial ports
  4 *
  5 *  Supports:
  6 *	      ISA-compatible 8250/16550 ports
  7 *	      ACPI 8250/16550 ports
  8 *	      PNP 8250/16550 ports
  9 *	      "serial8250" platform devices
 10 */
 11#include <linux/acpi.h>
 12#include <linux/array_size.h>
 13#include <linux/cleanup.h>
 14#include <linux/io.h>
 15#include <linux/module.h>
 16#include <linux/moduleparam.h>
 17#include <linux/once.h>
 18#include <linux/platform_device.h>
 19
 20#include <linux/serial_8250.h>
 21
 22#ifdef CONFIG_SPARC
 23#include <linux/sunserialcore.h>
 24#endif
 25
 26#include "8250.h"
 27
 28/*
 29 * Configuration:
 30 * share_irqs:     Whether we pass IRQF_SHARED to request_irq().
 31 *                 This option is unsafe when used on edge-triggered interrupts.
 32 */
 33static bool share_irqs = IS_ENABLED(CONFIG_SERIAL_8250_SHARE_IRQ);
 34
 35unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
 36
 37#include <asm/serial.h>
 38
 39/*
 40 * SERIAL_PORT_DFNS tells us about built-in ports that have no
 41 * standard enumeration mechanism. Platforms that can find all
 42 * serial ports via mechanisms like ACPI or PCI need not supply it.
 43 */
 44#ifndef SERIAL_PORT_DFNS
 45#define SERIAL_PORT_DFNS
 46#endif
 47
 48static const struct old_serial_port old_serial_port[] = {
 49	SERIAL_PORT_DFNS /* defined in asm/serial.h */
 50};
 51
 52serial8250_isa_config_fn serial8250_isa_config;
 53void serial8250_set_isa_configurator(serial8250_isa_config_fn v)
 54{
 55	serial8250_isa_config = v;
 56}
 57EXPORT_SYMBOL(serial8250_set_isa_configurator);
 58
 59static void __init __serial8250_isa_init_ports(void)
 60{
 61	int i;
 62
 63	if (nr_uarts > UART_NR)
 64		nr_uarts = UART_NR;
 65
 66	/*
 67	 * Set up initial ISA ports based on nr_uart module param, or else
 68	 * default to CONFIG_SERIAL_8250_RUNTIME_UARTS. Note that we do not
 69	 * need to increase nr_uarts when setting up the initial ISA ports.
 70	 */
 71	for (i = 0; i < nr_uarts; i++)
 72		serial8250_setup_port(i);
 73
 74	/* chain base port ops to support Remote Supervisor Adapter */
 75	univ8250_port_ops = *univ8250_port_base_ops;
 76	univ8250_rsa_support(&univ8250_port_ops, univ8250_port_base_ops);
 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		if (share_irqs)
 93			port->irqflags |= IRQF_SHARED;
 94
 95		if (serial8250_isa_config != NULL)
 96			serial8250_isa_config(i, &up->port, &up->capabilities);
 97	}
 98}
 99
100void __init serial8250_isa_init_ports(void)
101{
102	DO_ONCE(__serial8250_isa_init_ports);
103}
104
105/*
106 * Generic 16550A platform devices
107 */
108static int serial8250_probe_acpi(struct platform_device *pdev)
109{
110	struct device *dev = &pdev->dev;
111	struct resource *regs;
112	int ret, line;
113
114	struct uart_8250_port *uart __free(kfree) = kzalloc(sizeof(*uart), GFP_KERNEL);
115	if (!uart)
116		return -ENOMEM;
117
118	regs = platform_get_mem_or_io(pdev, 0);
119	if (!regs)
120		return dev_err_probe(dev, -EINVAL, "no registers defined\n");
121
122	switch (resource_type(regs)) {
123	case IORESOURCE_IO:
124		uart->port.iobase = regs->start;
125		break;
126	case IORESOURCE_MEM:
127		uart->port.mapbase = regs->start;
128		uart->port.mapsize = resource_size(regs);
129		uart->port.flags = UPF_IOREMAP;
130		break;
131	default:
132		return -EINVAL;
133	}
134
135	/* default clock frequency */
136	uart->port.uartclk = 1843200;
137	uart->port.type = PORT_16550A;
138	uart->port.dev = &pdev->dev;
139	uart->port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
140
141	ret = uart_read_and_validate_port_properties(&uart->port);
142	/* no interrupt -> fall back to polling */
143	if (ret == -ENXIO)
144		ret = 0;
145	if (ret)
146		return ret;
147
148	line = serial8250_register_8250_port(uart);
149	if (line < 0)
150		return line;
151
152	return 0;
153}
154
155static int serial8250_probe_platform(struct platform_device *dev, struct plat_serial8250_port *p)
156{
157	int ret, i;
158
159	struct uart_8250_port *uart __free(kfree) = kzalloc(sizeof(*uart), GFP_KERNEL);
160	if (!uart)
161		return -ENOMEM;
162
163	for (i = 0; p && p->flags != 0; p++, i++) {
164		uart->port.iobase	= p->iobase;
165		uart->port.membase	= p->membase;
166		uart->port.irq		= p->irq;
167		uart->port.irqflags	= p->irqflags;
168		uart->port.uartclk	= p->uartclk;
169		uart->port.regshift	= p->regshift;
170		uart->port.iotype	= p->iotype;
171		uart->port.flags		= p->flags;
172		uart->port.mapbase	= p->mapbase;
173		uart->port.mapsize	= p->mapsize;
174		uart->port.hub6		= p->hub6;
175		uart->port.has_sysrq	= p->has_sysrq;
176		uart->port.private_data	= p->private_data;
177		uart->port.type		= p->type;
178		uart->bugs		= p->bugs;
179		uart->port.serial_in	= p->serial_in;
180		uart->port.serial_out	= p->serial_out;
181		uart->dl_read		= p->dl_read;
182		uart->dl_write		= p->dl_write;
183		uart->port.handle_irq	= p->handle_irq;
184		uart->port.handle_break	= p->handle_break;
185		uart->port.set_termios	= p->set_termios;
186		uart->port.set_ldisc	= p->set_ldisc;
187		uart->port.get_mctrl	= p->get_mctrl;
188		uart->port.pm		= p->pm;
189		uart->port.dev		= &dev->dev;
190
191		if (share_irqs)
192			uart->port.irqflags |= IRQF_SHARED;
193
194		ret = serial8250_register_8250_port(uart);
195		if (ret < 0) {
196			dev_err(&dev->dev, "unable to register port at index %d "
197				"(IO%lx MEM%llx IRQ%d): %d\n", i,
198				p->iobase, (unsigned long long)p->mapbase,
199				p->irq, ret);
200		}
201	}
202	return 0;
203}
204
205/*
206 * Register a set of serial devices attached to a platform device.
207 * The list is terminated with a zero flags entry, which means we expect
208 * all entries to have at least UPF_BOOT_AUTOCONF set.
209 */
210static int serial8250_probe(struct platform_device *pdev)
211{
212	struct device *dev = &pdev->dev;
213	struct plat_serial8250_port *p;
214
215	p = dev_get_platdata(dev);
216	if (p)
217		return serial8250_probe_platform(pdev, p);
218
219	/*
220	 * Probe platform UART devices defined using standard hardware
221	 * discovery mechanism like ACPI or DT. Support only ACPI based
222	 * serial device for now.
223	 */
224	if (has_acpi_companion(dev))
225		return serial8250_probe_acpi(pdev);
226
227	return 0;
228}
229
230/*
231 * Remove serial ports registered against a platform device.
232 */
233static void serial8250_remove(struct platform_device *dev)
234{
235	int i;
236
237	for (i = 0; i < nr_uarts; i++) {
238		struct uart_8250_port *up = serial8250_get_port(i);
239
240		if (up->port.dev == &dev->dev)
241			serial8250_unregister_port(i);
242	}
243}
244
245static int serial8250_suspend(struct platform_device *dev, pm_message_t state)
246{
247	int i;
248
249	for (i = 0; i < UART_NR; i++) {
250		struct uart_8250_port *up = serial8250_get_port(i);
251
252		if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
253			uart_suspend_port(&serial8250_reg, &up->port);
254	}
255
256	return 0;
257}
258
259static int serial8250_resume(struct platform_device *dev)
260{
261	int i;
262
263	for (i = 0; i < UART_NR; i++) {
264		struct uart_8250_port *up = serial8250_get_port(i);
265
266		if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
267			serial8250_resume_port(i);
268	}
269
270	return 0;
271}
272
273static const struct acpi_device_id acpi_platform_serial_table[] = {
274	{ "RSCV0003" }, /* RISC-V Generic 16550A UART */
275	{ }
276};
277MODULE_DEVICE_TABLE(acpi, acpi_platform_serial_table);
278
279static struct platform_driver serial8250_isa_driver = {
280	.probe		= serial8250_probe,
281	.remove		= serial8250_remove,
282	.suspend	= serial8250_suspend,
283	.resume		= serial8250_resume,
284	.driver		= {
285		.name	= "serial8250",
286		.acpi_match_table = acpi_platform_serial_table,
287	},
288};
289
290/*
291 * This "device" covers _all_ ISA 8250-compatible serial devices listed
292 * in the table in include/asm/serial.h.
293 */
294struct platform_device *serial8250_isa_devs;
295
296static int __init serial8250_init(void)
297{
298	int ret;
299
300	if (nr_uarts == 0)
301		return -ENODEV;
302
303	serial8250_isa_init_ports();
304
305	pr_info("Serial: 8250/16550 driver, %d ports, IRQ sharing %s\n",
306		nr_uarts, str_enabled_disabled(share_irqs));
307
308#ifdef CONFIG_SPARC
309	ret = sunserial_register_minors(&serial8250_reg, UART_NR);
310#else
311	serial8250_reg.nr = UART_NR;
312	ret = uart_register_driver(&serial8250_reg);
313#endif
314	if (ret)
315		goto out;
316
317	ret = serial8250_pnp_init();
318	if (ret)
319		goto unreg_uart_drv;
320
321	serial8250_isa_devs = platform_device_alloc("serial8250", PLAT8250_DEV_LEGACY);
322	if (!serial8250_isa_devs) {
323		ret = -ENOMEM;
324		goto unreg_pnp;
325	}
326
327	ret = platform_device_add(serial8250_isa_devs);
328	if (ret)
329		goto put_dev;
330
331	serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);
332
333	ret = platform_driver_register(&serial8250_isa_driver);
334	if (ret == 0)
335		goto out;
336
337	platform_device_del(serial8250_isa_devs);
338put_dev:
339	platform_device_put(serial8250_isa_devs);
340unreg_pnp:
341	serial8250_pnp_exit();
342unreg_uart_drv:
343#ifdef CONFIG_SPARC
344	sunserial_unregister_minors(&serial8250_reg, UART_NR);
345#else
346	uart_unregister_driver(&serial8250_reg);
347#endif
348out:
349	return ret;
350}
351module_init(serial8250_init);
352
353static void __exit serial8250_exit(void)
354{
355	struct platform_device *isa_dev = serial8250_isa_devs;
356
357	/*
358	 * This tells serial8250_unregister_port() not to re-register
359	 * the ports (thereby making serial8250_isa_driver permanently
360	 * in use).
361	 */
362	serial8250_isa_devs = NULL;
363
364	platform_driver_unregister(&serial8250_isa_driver);
365	platform_device_unregister(isa_dev);
366
367	serial8250_pnp_exit();
368
369#ifdef CONFIG_SPARC
370	sunserial_unregister_minors(&serial8250_reg, UART_NR);
371#else
372	uart_unregister_driver(&serial8250_reg);
373#endif
374}
375module_exit(serial8250_exit);
376
377MODULE_LICENSE("GPL");
378MODULE_DESCRIPTION("Generic 8250/16x50 serial platform driver");
379
380module_param_hw(share_irqs, bool, other, 0644);
381MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices (unsafe)");
382
383module_param(nr_uarts, uint, 0644);
384MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")");
385
386MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
~/ Read-only file preview.