Commit 64c79dfb authored by Guanbing Huang's avatar Guanbing Huang Committed by Greg Kroah-Hartman

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: default avatarGuanbing Huang <albanhuang@tencent.com>
Suggested-by: default avatarAndy Shevchenko <andriy.shevchenko@intel.com>
Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: default avatarBing Fan <tombinfan@tencent.com>
Tested-by: default avatarLinheng Du <dylanlhdu@tencent.com>
Link: https://lore.kernel.org/r/4726ecea8f7bfbfe42501b4f6ad9fe5b38994574.1713234515.git.albanhuang@tencent.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 18ba7f2d
......@@ -435,6 +435,7 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
{
struct uart_8250_port uart, *port;
int ret, line, flags = dev_id->driver_data;
unsigned char iotype;
if (flags & UNKNOWN_DEV) {
ret = serial_pnp_guess_board(dev);
......@@ -443,37 +444,46 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
}
memset(&uart, 0, sizeof(uart));
if (pnp_irq_valid(dev, 0))
uart.port.irq = pnp_irq(dev, 0);
if ((flags & CIR_PORT) && pnp_port_valid(dev, 2)) {
uart.port.iobase = pnp_port_start(dev, 2);
uart.port.iotype = UPIO_PORT;
iotype = UPIO_PORT;
} else if (pnp_port_valid(dev, 0)) {
uart.port.iobase = pnp_port_start(dev, 0);
uart.port.iotype = UPIO_PORT;
iotype = UPIO_PORT;
} else if (pnp_mem_valid(dev, 0)) {
uart.port.mapbase = pnp_mem_start(dev, 0);
uart.port.iotype = UPIO_MEM;
uart.port.mapsize = pnp_mem_len(dev, 0);
iotype = UPIO_MEM;
uart.port.flags = UPF_IOREMAP;
} else
return -ENODEV;
dev_dbg(&dev->dev,
"Setup PNP port: port %#lx, mem %#llx, irq %u, type %u\n",
uart.port.iobase, (unsigned long long)uart.port.mapbase,
uart.port.irq, uart.port.iotype);
uart.port.uartclk = 1843200;
uart.port.dev = &dev->dev;
uart.port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
ret = uart_read_port_properties(&uart.port);
/* no interrupt -> fall back to polling */
if (ret == -ENXIO)
ret = 0;
if (ret)
return ret;
/*
* The previous call may not set iotype correctly when reg-io-width
* property is absent and it doesn't support IO port resource.
*/
uart.port.iotype = iotype;
if (flags & CIR_PORT) {
uart.port.flags |= UPF_FIXED_PORT | UPF_FIXED_TYPE;
uart.port.type = PORT_8250_CIR;
}
uart.port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE)
uart.port.flags |= UPF_SHARE_IRQ;
uart.port.uartclk = 1843200;
device_property_read_u32(&dev->dev, "clock-frequency", &uart.port.uartclk);
uart.port.dev = &dev->dev;
dev_dbg(&dev->dev,
"Setup PNP port: port %#lx, mem %#llx, size %#llx, irq %u, type %u\n",
uart.port.iobase, (unsigned long long)uart.port.mapbase,
(unsigned long long)uart.port.mapsize, uart.port.irq, uart.port.iotype);
line = serial8250_register_8250_port(&uart);
if (line < 0 || (flags & CIR_PORT))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment