| 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 | * skip_txen_test: Force skip of txen test at init time. | 
|---|
| 33 | */ | 
|---|
| 34 | unsigned int share_irqs = SERIAL8250_SHARE_IRQS; | 
|---|
| 35 | unsigned int skip_txen_test; | 
|---|
| 36 |  | 
|---|
| 37 | unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS; | 
|---|
| 38 |  | 
|---|
| 39 | #include <asm/serial.h> | 
|---|
| 40 |  | 
|---|
| 41 | /* | 
|---|
| 42 | * SERIAL_PORT_DFNS tells us about built-in ports that have no | 
|---|
| 43 | * standard enumeration mechanism. Platforms that can find all | 
|---|
| 44 | * serial ports via mechanisms like ACPI or PCI need not supply it. | 
|---|
| 45 | */ | 
|---|
| 46 | #ifndef SERIAL_PORT_DFNS | 
|---|
| 47 | #define SERIAL_PORT_DFNS | 
|---|
| 48 | #endif | 
|---|
| 49 |  | 
|---|
| 50 | static const struct old_serial_port old_serial_port[] = { | 
|---|
| 51 | SERIAL_PORT_DFNS /* defined in asm/serial.h */ | 
|---|
| 52 | }; | 
|---|
| 53 |  | 
|---|
| 54 | serial8250_isa_config_fn serial8250_isa_config; | 
|---|
| 55 | void serial8250_set_isa_configurator(serial8250_isa_config_fn v) | 
|---|
| 56 | { | 
|---|
| 57 | serial8250_isa_config = v; | 
|---|
| 58 | } | 
|---|
| 59 | EXPORT_SYMBOL(serial8250_set_isa_configurator); | 
|---|
| 60 |  | 
|---|
| 61 | static void __init __serial8250_isa_init_ports(void) | 
|---|
| 62 | { | 
|---|
| 63 | int i, irqflag = 0; | 
|---|
| 64 |  | 
|---|
| 65 | if (nr_uarts > UART_NR) | 
|---|
| 66 | nr_uarts = UART_NR; | 
|---|
| 67 |  | 
|---|
| 68 | /* | 
|---|
| 69 | * Set up initial ISA ports based on nr_uart module param, or else | 
|---|
| 70 | * default to CONFIG_SERIAL_8250_RUNTIME_UARTS. Note that we do not | 
|---|
| 71 | * need to increase nr_uarts when setting up the initial ISA ports. | 
|---|
| 72 | */ | 
|---|
| 73 | for (i = 0; i < nr_uarts; i++) | 
|---|
| 74 | serial8250_setup_port(index: i); | 
|---|
| 75 |  | 
|---|
| 76 | /* chain base port ops to support Remote Supervisor Adapter */ | 
|---|
| 77 | univ8250_port_ops = *univ8250_port_base_ops; | 
|---|
| 78 | univ8250_rsa_support(ops: &univ8250_port_ops); | 
|---|
| 79 |  | 
|---|
| 80 | if (share_irqs) | 
|---|
| 81 | irqflag = IRQF_SHARED; | 
|---|
| 82 |  | 
|---|
| 83 | for (i = 0; i < ARRAY_SIZE(old_serial_port) && i < nr_uarts; i++) { | 
|---|
| 84 | struct uart_8250_port *up = serial8250_get_port(line: i); | 
|---|
| 85 | struct uart_port *port = &up->port; | 
|---|
| 86 |  | 
|---|
| 87 | port->iobase   = old_serial_port[i].port; | 
|---|
| 88 | port->irq      = irq_canonicalize(irq: old_serial_port[i].irq); | 
|---|
| 89 | port->irqflags = 0; | 
|---|
| 90 | port->uartclk  = old_serial_port[i].baud_base * 16; | 
|---|
| 91 | port->flags    = old_serial_port[i].flags; | 
|---|
| 92 | port->hub6     = 0; | 
|---|
| 93 | port->membase  = old_serial_port[i].iomem_base; | 
|---|
| 94 | port->iotype   = old_serial_port[i].io_type; | 
|---|
| 95 | port->regshift = old_serial_port[i].iomem_reg_shift; | 
|---|
| 96 |  | 
|---|
| 97 | port->irqflags |= irqflag; | 
|---|
| 98 | if (serial8250_isa_config != NULL) | 
|---|
| 99 | serial8250_isa_config(i, &up->port, &up->capabilities); | 
|---|
| 100 | } | 
|---|
| 101 | } | 
|---|
| 102 |  | 
|---|
| 103 | void __init serial8250_isa_init_ports(void) | 
|---|
| 104 | { | 
|---|
| 105 | DO_ONCE(__serial8250_isa_init_ports); | 
|---|
| 106 | } | 
|---|
| 107 |  | 
|---|
| 108 | /* | 
|---|
| 109 | * Generic 16550A platform devices | 
|---|
| 110 | */ | 
|---|
| 111 | static int serial8250_probe_acpi(struct platform_device *pdev) | 
|---|
| 112 | { | 
|---|
| 113 | struct device *dev = &pdev->dev; | 
|---|
| 114 | struct resource *regs; | 
|---|
| 115 | int ret, line; | 
|---|
| 116 |  | 
|---|
| 117 | struct uart_8250_port *uart __free(kfree) = kzalloc(sizeof(*uart), GFP_KERNEL); | 
|---|
| 118 | if (!uart) | 
|---|
| 119 | return -ENOMEM; | 
|---|
| 120 |  | 
|---|
| 121 | regs = platform_get_mem_or_io(pdev, 0); | 
|---|
| 122 | if (!regs) | 
|---|
| 123 | return dev_err_probe(dev, err: -EINVAL, fmt: "no registers defined\n"); | 
|---|
| 124 |  | 
|---|
| 125 | switch (resource_type(res: regs)) { | 
|---|
| 126 | case IORESOURCE_IO: | 
|---|
| 127 | uart->port.iobase = regs->start; | 
|---|
| 128 | break; | 
|---|
| 129 | case IORESOURCE_MEM: | 
|---|
| 130 | uart->port.mapbase = regs->start; | 
|---|
| 131 | uart->port.mapsize = resource_size(res: regs); | 
|---|
| 132 | uart->port.flags = UPF_IOREMAP; | 
|---|
| 133 | break; | 
|---|
| 134 | default: | 
|---|
| 135 | return -EINVAL; | 
|---|
| 136 | } | 
|---|
| 137 |  | 
|---|
| 138 | /* default clock frequency */ | 
|---|
| 139 | uart->port.uartclk = 1843200; | 
|---|
| 140 | uart->port.type = PORT_16550A; | 
|---|
| 141 | uart->port.dev = &pdev->dev; | 
|---|
| 142 | uart->port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; | 
|---|
| 143 |  | 
|---|
| 144 | ret = uart_read_and_validate_port_properties(port: &uart->port); | 
|---|
| 145 | /* no interrupt -> fall back to polling */ | 
|---|
| 146 | if (ret == -ENXIO) | 
|---|
| 147 | ret = 0; | 
|---|
| 148 | if (ret) | 
|---|
| 149 | return ret; | 
|---|
| 150 |  | 
|---|
| 151 | line = serial8250_register_8250_port(uart); | 
|---|
| 152 | if (line < 0) | 
|---|
| 153 | return line; | 
|---|
| 154 |  | 
|---|
| 155 | return 0; | 
|---|
| 156 | } | 
|---|
| 157 |  | 
|---|
| 158 | static int serial8250_probe_platform(struct platform_device *dev, struct plat_serial8250_port *p) | 
|---|
| 159 | { | 
|---|
| 160 | int ret, i, irqflag = 0; | 
|---|
| 161 |  | 
|---|
| 162 | struct uart_8250_port *uart __free(kfree) = kzalloc(sizeof(*uart), GFP_KERNEL); | 
|---|
| 163 | if (!uart) | 
|---|
| 164 | return -ENOMEM; | 
|---|
| 165 |  | 
|---|
| 166 | if (share_irqs) | 
|---|
| 167 | irqflag = IRQF_SHARED; | 
|---|
| 168 |  | 
|---|
| 169 | for (i = 0; p && p->flags != 0; p++, i++) { | 
|---|
| 170 | uart->port.iobase	= p->iobase; | 
|---|
| 171 | uart->port.membase	= p->membase; | 
|---|
| 172 | uart->port.irq		= p->irq; | 
|---|
| 173 | uart->port.irqflags	= p->irqflags; | 
|---|
| 174 | uart->port.uartclk	= p->uartclk; | 
|---|
| 175 | uart->port.regshift	= p->regshift; | 
|---|
| 176 | uart->port.iotype	= p->iotype; | 
|---|
| 177 | uart->port.flags		= p->flags; | 
|---|
| 178 | uart->port.mapbase	= p->mapbase; | 
|---|
| 179 | uart->port.mapsize	= p->mapsize; | 
|---|
| 180 | uart->port.hub6		= p->hub6; | 
|---|
| 181 | uart->port.has_sysrq	= p->has_sysrq; | 
|---|
| 182 | uart->port.private_data	= p->private_data; | 
|---|
| 183 | uart->port.type		= p->type; | 
|---|
| 184 | uart->bugs		= p->bugs; | 
|---|
| 185 | uart->port.serial_in	= p->serial_in; | 
|---|
| 186 | uart->port.serial_out	= p->serial_out; | 
|---|
| 187 | uart->dl_read		= p->dl_read; | 
|---|
| 188 | uart->dl_write		= p->dl_write; | 
|---|
| 189 | uart->port.handle_irq	= p->handle_irq; | 
|---|
| 190 | uart->port.handle_break	= p->handle_break; | 
|---|
| 191 | uart->port.set_termios	= p->set_termios; | 
|---|
| 192 | uart->port.set_ldisc	= p->set_ldisc; | 
|---|
| 193 | uart->port.get_mctrl	= p->get_mctrl; | 
|---|
| 194 | uart->port.pm		= p->pm; | 
|---|
| 195 | uart->port.dev		= &dev->dev; | 
|---|
| 196 | uart->port.irqflags	|= irqflag; | 
|---|
| 197 | ret = serial8250_register_8250_port(uart); | 
|---|
| 198 | if (ret < 0) { | 
|---|
| 199 | dev_err(&dev->dev, "unable to register port at index %d " | 
|---|
| 200 | "(IO%lx MEM%llx IRQ%d): %d\n", i, | 
|---|
| 201 | p->iobase, (unsigned long long)p->mapbase, | 
|---|
| 202 | p->irq, ret); | 
|---|
| 203 | } | 
|---|
| 204 | } | 
|---|
| 205 | return 0; | 
|---|
| 206 | } | 
|---|
| 207 |  | 
|---|
| 208 | /* | 
|---|
| 209 | * Register a set of serial devices attached to a platform device. | 
|---|
| 210 | * The list is terminated with a zero flags entry, which means we expect | 
|---|
| 211 | * all entries to have at least UPF_BOOT_AUTOCONF set. | 
|---|
| 212 | */ | 
|---|
| 213 | static int serial8250_probe(struct platform_device *pdev) | 
|---|
| 214 | { | 
|---|
| 215 | struct device *dev = &pdev->dev; | 
|---|
| 216 | struct plat_serial8250_port *p; | 
|---|
| 217 |  | 
|---|
| 218 | p = dev_get_platdata(dev); | 
|---|
| 219 | if (p) | 
|---|
| 220 | return serial8250_probe_platform(dev: pdev, p); | 
|---|
| 221 |  | 
|---|
| 222 | /* | 
|---|
| 223 | * Probe platform UART devices defined using standard hardware | 
|---|
| 224 | * discovery mechanism like ACPI or DT. Support only ACPI based | 
|---|
| 225 | * serial device for now. | 
|---|
| 226 | */ | 
|---|
| 227 | if (has_acpi_companion(dev)) | 
|---|
| 228 | return serial8250_probe_acpi(pdev); | 
|---|
| 229 |  | 
|---|
| 230 | return 0; | 
|---|
| 231 | } | 
|---|
| 232 |  | 
|---|
| 233 | /* | 
|---|
| 234 | * Remove serial ports registered against a platform device. | 
|---|
| 235 | */ | 
|---|
| 236 | static void serial8250_remove(struct platform_device *dev) | 
|---|
| 237 | { | 
|---|
| 238 | int i; | 
|---|
| 239 |  | 
|---|
| 240 | for (i = 0; i < nr_uarts; i++) { | 
|---|
| 241 | struct uart_8250_port *up = serial8250_get_port(line: i); | 
|---|
| 242 |  | 
|---|
| 243 | if (up->port.dev == &dev->dev) | 
|---|
| 244 | serial8250_unregister_port(line: i); | 
|---|
| 245 | } | 
|---|
| 246 | } | 
|---|
| 247 |  | 
|---|
| 248 | static int serial8250_suspend(struct platform_device *dev, pm_message_t state) | 
|---|
| 249 | { | 
|---|
| 250 | int i; | 
|---|
| 251 |  | 
|---|
| 252 | for (i = 0; i < UART_NR; i++) { | 
|---|
| 253 | struct uart_8250_port *up = serial8250_get_port(line: i); | 
|---|
| 254 |  | 
|---|
| 255 | if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev) | 
|---|
| 256 | uart_suspend_port(reg: &serial8250_reg, port: &up->port); | 
|---|
| 257 | } | 
|---|
| 258 |  | 
|---|
| 259 | return 0; | 
|---|
| 260 | } | 
|---|
| 261 |  | 
|---|
| 262 | static int serial8250_resume(struct platform_device *dev) | 
|---|
| 263 | { | 
|---|
| 264 | int i; | 
|---|
| 265 |  | 
|---|
| 266 | for (i = 0; i < UART_NR; i++) { | 
|---|
| 267 | struct uart_8250_port *up = serial8250_get_port(line: i); | 
|---|
| 268 |  | 
|---|
| 269 | if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev) | 
|---|
| 270 | serial8250_resume_port(line: i); | 
|---|
| 271 | } | 
|---|
| 272 |  | 
|---|
| 273 | return 0; | 
|---|
| 274 | } | 
|---|
| 275 |  | 
|---|
| 276 | static const struct acpi_device_id acpi_platform_serial_table[] = { | 
|---|
| 277 | { "RSCV0003"}, /* RISC-V Generic 16550A UART */ | 
|---|
| 278 | { } | 
|---|
| 279 | }; | 
|---|
| 280 | MODULE_DEVICE_TABLE(acpi, acpi_platform_serial_table); | 
|---|
| 281 |  | 
|---|
| 282 | static struct platform_driver serial8250_isa_driver = { | 
|---|
| 283 | .probe		= serial8250_probe, | 
|---|
| 284 | .remove		= serial8250_remove, | 
|---|
| 285 | .suspend	= serial8250_suspend, | 
|---|
| 286 | .resume		= serial8250_resume, | 
|---|
| 287 | .driver		= { | 
|---|
| 288 | .name	= "serial8250", | 
|---|
| 289 | .acpi_match_table = acpi_platform_serial_table, | 
|---|
| 290 | }, | 
|---|
| 291 | }; | 
|---|
| 292 |  | 
|---|
| 293 | /* | 
|---|
| 294 | * This "device" covers _all_ ISA 8250-compatible serial devices listed | 
|---|
| 295 | * in the table in include/asm/serial.h. | 
|---|
| 296 | */ | 
|---|
| 297 | struct platform_device *serial8250_isa_devs; | 
|---|
| 298 |  | 
|---|
| 299 | static int __init serial8250_init(void) | 
|---|
| 300 | { | 
|---|
| 301 | int ret; | 
|---|
| 302 |  | 
|---|
| 303 | if (nr_uarts == 0) | 
|---|
| 304 | return -ENODEV; | 
|---|
| 305 |  | 
|---|
| 306 | serial8250_isa_init_ports(); | 
|---|
| 307 |  | 
|---|
| 308 | pr_info( "Serial: 8250/16550 driver, %d ports, IRQ sharing %s\n", | 
|---|
| 309 | nr_uarts, str_enabled_disabled(share_irqs)); | 
|---|
| 310 |  | 
|---|
| 311 | #ifdef CONFIG_SPARC | 
|---|
| 312 | ret = sunserial_register_minors(&serial8250_reg, UART_NR); | 
|---|
| 313 | #else | 
|---|
| 314 | serial8250_reg.nr = UART_NR; | 
|---|
| 315 | ret = uart_register_driver(uart: &serial8250_reg); | 
|---|
| 316 | #endif | 
|---|
| 317 | if (ret) | 
|---|
| 318 | goto out; | 
|---|
| 319 |  | 
|---|
| 320 | ret = serial8250_pnp_init(); | 
|---|
| 321 | if (ret) | 
|---|
| 322 | goto unreg_uart_drv; | 
|---|
| 323 |  | 
|---|
| 324 | serial8250_isa_devs = platform_device_alloc(name: "serial8250", id: PLAT8250_DEV_LEGACY); | 
|---|
| 325 | if (!serial8250_isa_devs) { | 
|---|
| 326 | ret = -ENOMEM; | 
|---|
| 327 | goto unreg_pnp; | 
|---|
| 328 | } | 
|---|
| 329 |  | 
|---|
| 330 | ret = platform_device_add(pdev: serial8250_isa_devs); | 
|---|
| 331 | if (ret) | 
|---|
| 332 | goto put_dev; | 
|---|
| 333 |  | 
|---|
| 334 | serial8250_register_ports(drv: &serial8250_reg, dev: &serial8250_isa_devs->dev); | 
|---|
| 335 |  | 
|---|
| 336 | ret = platform_driver_register(&serial8250_isa_driver); | 
|---|
| 337 | if (ret == 0) | 
|---|
| 338 | goto out; | 
|---|
| 339 |  | 
|---|
| 340 | platform_device_del(pdev: serial8250_isa_devs); | 
|---|
| 341 | put_dev: | 
|---|
| 342 | platform_device_put(pdev: serial8250_isa_devs); | 
|---|
| 343 | unreg_pnp: | 
|---|
| 344 | serial8250_pnp_exit(); | 
|---|
| 345 | unreg_uart_drv: | 
|---|
| 346 | #ifdef CONFIG_SPARC | 
|---|
| 347 | sunserial_unregister_minors(&serial8250_reg, UART_NR); | 
|---|
| 348 | #else | 
|---|
| 349 | uart_unregister_driver(uart: &serial8250_reg); | 
|---|
| 350 | #endif | 
|---|
| 351 | out: | 
|---|
| 352 | return ret; | 
|---|
| 353 | } | 
|---|
| 354 | module_init(serial8250_init); | 
|---|
| 355 |  | 
|---|
| 356 | static void __exit serial8250_exit(void) | 
|---|
| 357 | { | 
|---|
| 358 | struct platform_device *isa_dev = serial8250_isa_devs; | 
|---|
| 359 |  | 
|---|
| 360 | /* | 
|---|
| 361 | * This tells serial8250_unregister_port() not to re-register | 
|---|
| 362 | * the ports (thereby making serial8250_isa_driver permanently | 
|---|
| 363 | * in use). | 
|---|
| 364 | */ | 
|---|
| 365 | serial8250_isa_devs = NULL; | 
|---|
| 366 |  | 
|---|
| 367 | platform_driver_unregister(&serial8250_isa_driver); | 
|---|
| 368 | platform_device_unregister(isa_dev); | 
|---|
| 369 |  | 
|---|
| 370 | serial8250_pnp_exit(); | 
|---|
| 371 |  | 
|---|
| 372 | #ifdef CONFIG_SPARC | 
|---|
| 373 | sunserial_unregister_minors(&serial8250_reg, UART_NR); | 
|---|
| 374 | #else | 
|---|
| 375 | uart_unregister_driver(uart: &serial8250_reg); | 
|---|
| 376 | #endif | 
|---|
| 377 | } | 
|---|
| 378 | module_exit(serial8250_exit); | 
|---|
| 379 |  | 
|---|
| 380 | MODULE_LICENSE( "GPL"); | 
|---|
| 381 | MODULE_DESCRIPTION( "Generic 8250/16x50 serial platform driver"); | 
|---|
| 382 |  | 
|---|
| 383 | module_param_hw(share_irqs, uint, other, 0644); | 
|---|
| 384 | MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices (unsafe)"); | 
|---|
| 385 |  | 
|---|
| 386 | module_param(nr_uarts, uint, 0644); | 
|---|
| 387 | MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-"__MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")"); | 
|---|
| 388 |  | 
|---|
| 389 | module_param(skip_txen_test, uint, 0644); | 
|---|
| 390 | MODULE_PARM_DESC(skip_txen_test, "Skip checking for the TXEN bug at init time"); | 
|---|
| 391 |  | 
|---|
| 392 | MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR); | 
|---|
| 393 |  | 
|---|
| 394 | #ifdef CONFIG_SERIAL_8250_DEPRECATED_OPTIONS | 
|---|
| 395 | #ifndef MODULE | 
|---|
| 396 | /* | 
|---|
| 397 | * This module was renamed to 8250_core in 3.7. Keep the old "8250" name | 
|---|
| 398 | * working as well for the module options so we don't break people. We | 
|---|
| 399 | * need to keep the names identical and the convenient macros will happily | 
|---|
| 400 | * refuse to let us do that by failing the build with redefinition errors | 
|---|
| 401 | * of global variables. So we stick them inside a dummy function to avoid | 
|---|
| 402 | * those conflicts. The options still get parsed, and the redefined | 
|---|
| 403 | * MODULE_PARAM_PREFIX lets us keep the "8250." syntax alive. | 
|---|
| 404 | * | 
|---|
| 405 | * This is hacky.  I'm sorry. | 
|---|
| 406 | */ | 
|---|
| 407 | static void __used s8250_options(void) | 
|---|
| 408 | { | 
|---|
| 409 | #undef MODULE_PARAM_PREFIX | 
|---|
| 410 | #define MODULE_PARAM_PREFIX "8250_core." | 
|---|
| 411 |  | 
|---|
| 412 | module_param_cb(share_irqs, ¶m_ops_uint, &share_irqs, 0644); | 
|---|
| 413 | module_param_cb(nr_uarts, ¶m_ops_uint, &nr_uarts, 0644); | 
|---|
| 414 | module_param_cb(skip_txen_test, ¶m_ops_uint, &skip_txen_test, 0644); | 
|---|
| 415 | } | 
|---|
| 416 | #else | 
|---|
| 417 | MODULE_ALIAS( "8250_core"); | 
|---|
| 418 | #endif | 
|---|
| 419 | #endif | 
|---|
| 420 |  | 
|---|