Skip to content

Commit 64c79df

Browse files
Guanbing Huanggregkh
authored andcommitted
serial: 8250_pnp: Support configurable reg shift property
The 16550a serial port based on the ACPI table requires obtaining the reg-shift attribute. In the ACPI scenario, If the reg-shift property is not configured like in DTS, the 16550a serial driver cannot read or write controller registers properly during initialization. Signed-off-by: Guanbing Huang <[email protected]> Suggested-by: Andy Shevchenko <[email protected]> Reviewed-by: Andy Shevchenko <[email protected]> Reviewed-by: Bing Fan <[email protected]> Tested-by: Linheng Du <[email protected]> Link: https://lore.kernel.org/r/4726ecea8f7bfbfe42501b4f6ad9fe5b38994574.1713234515.git.albanhuang@tencent.com Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 18ba7f2 commit 64c79df

File tree

1 file changed

+25
-15
lines changed

1 file changed

+25
-15
lines changed

drivers/tty/serial/8250/8250_pnp.c

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,7 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
435435
{
436436
struct uart_8250_port uart, *port;
437437
int ret, line, flags = dev_id->driver_data;
438+
unsigned char iotype;
438439

439440
if (flags & UNKNOWN_DEV) {
440441
ret = serial_pnp_guess_board(dev);
@@ -443,37 +444,46 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
443444
}
444445

445446
memset(&uart, 0, sizeof(uart));
446-
if (pnp_irq_valid(dev, 0))
447-
uart.port.irq = pnp_irq(dev, 0);
448447
if ((flags & CIR_PORT) && pnp_port_valid(dev, 2)) {
449448
uart.port.iobase = pnp_port_start(dev, 2);
450-
uart.port.iotype = UPIO_PORT;
449+
iotype = UPIO_PORT;
451450
} else if (pnp_port_valid(dev, 0)) {
452451
uart.port.iobase = pnp_port_start(dev, 0);
453-
uart.port.iotype = UPIO_PORT;
452+
iotype = UPIO_PORT;
454453
} else if (pnp_mem_valid(dev, 0)) {
455454
uart.port.mapbase = pnp_mem_start(dev, 0);
456-
uart.port.iotype = UPIO_MEM;
455+
uart.port.mapsize = pnp_mem_len(dev, 0);
456+
iotype = UPIO_MEM;
457457
uart.port.flags = UPF_IOREMAP;
458458
} else
459459
return -ENODEV;
460460

461-
dev_dbg(&dev->dev,
462-
"Setup PNP port: port %#lx, mem %#llx, irq %u, type %u\n",
463-
uart.port.iobase, (unsigned long long)uart.port.mapbase,
464-
uart.port.irq, uart.port.iotype);
461+
uart.port.uartclk = 1843200;
462+
uart.port.dev = &dev->dev;
463+
uart.port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
464+
465+
ret = uart_read_port_properties(&uart.port);
466+
/* no interrupt -> fall back to polling */
467+
if (ret == -ENXIO)
468+
ret = 0;
469+
if (ret)
470+
return ret;
471+
472+
/*
473+
* The previous call may not set iotype correctly when reg-io-width
474+
* property is absent and it doesn't support IO port resource.
475+
*/
476+
uart.port.iotype = iotype;
465477

466478
if (flags & CIR_PORT) {
467479
uart.port.flags |= UPF_FIXED_PORT | UPF_FIXED_TYPE;
468480
uart.port.type = PORT_8250_CIR;
469481
}
470482

471-
uart.port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
472-
if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE)
473-
uart.port.flags |= UPF_SHARE_IRQ;
474-
uart.port.uartclk = 1843200;
475-
device_property_read_u32(&dev->dev, "clock-frequency", &uart.port.uartclk);
476-
uart.port.dev = &dev->dev;
483+
dev_dbg(&dev->dev,
484+
"Setup PNP port: port %#lx, mem %#llx, size %#llx, irq %u, type %u\n",
485+
uart.port.iobase, (unsigned long long)uart.port.mapbase,
486+
(unsigned long long)uart.port.mapsize, uart.port.irq, uart.port.iotype);
477487

478488
line = serial8250_register_8250_port(&uart);
479489
if (line < 0 || (flags & CIR_PORT))

0 commit comments

Comments
 (0)