Add a hook for `uart_report_port' to let serial ports report extra properties beyond `irq' and `base_baud'. Use it with the 8250 backend to report extra baud rates supported above the base rate for ports with the UPF_MAGIC_MULTIPLIER property, so that people have a way to find out that they are supported with their system, e.g.: Serial: 8250/16550 driver, 5 ports, IRQ sharing enabled printk: console [ttyS0] disabled serial8250.0: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200 [+230400, 460800]) is a 16550A printk: console [ttyS0] enabled printk: console [ttyS0] enabled printk: bootconsole [uart8250] disabled printk: bootconsole [uart8250] disabled serial8250.0: ttyS1 at I/O 0x2f8 (irq = 3, base_baud = 115200 [+230400, 460800]) is a 16550A serial8250.0: ttyS2 at MMIO 0x1f000900 (irq = 20, base_baud = 230400) is a 16550A Otherwise there is no clear way to figure this out. Signed-off-by: Maciej W. Rozycki <macro@xxxxxxxxxxx> --- drivers/tty/serial/8250/8250_core.c | 10 ++++++++++ drivers/tty/serial/serial_core.c | 11 +++++++++-- include/linux/serial_core.h | 3 +++ 3 files changed, 22 insertions(+), 2 deletions(-) linux-serial-core-baud-extra.diff Index: linux-malta-cbus-uart/drivers/tty/serial/8250/8250_core.c =================================================================== --- linux-malta-cbus-uart.orig/drivers/tty/serial/8250/8250_core.c +++ linux-malta-cbus-uart/drivers/tty/serial/8250/8250_core.c @@ -952,6 +952,13 @@ static struct uart_8250_port *serial8250 return NULL; } +static void serial8250_report_magic(struct uart_port *port, + char *report_buf, size_t report_size) +{ + snprintf(report_buf, report_size, + " [+%d, %d]", port->uartclk / 8, port->uartclk / 4); +} + static void serial_8250_overrun_backoff_work(struct work_struct *work) { struct uart_8250_port *up = @@ -1048,6 +1055,9 @@ int serial8250_register_8250_port(struct } } + if (up->port.flags & UPF_MAGIC_MULTIPLIER) + uart->port.report_extra = serial8250_report_magic; + serial8250_set_defaults(uart); /* Possibly override default I/O functions. */ Index: linux-malta-cbus-uart/drivers/tty/serial/serial_core.c =================================================================== --- linux-malta-cbus-uart.orig/drivers/tty/serial/serial_core.c +++ linux-malta-cbus-uart/drivers/tty/serial/serial_core.c @@ -2309,6 +2309,7 @@ int uart_resume_port(struct uart_driver static inline void uart_report_port(struct uart_driver *drv, struct uart_port *port) { + char report_extra[64]; char address[64]; switch (port->iotype) { @@ -2333,11 +2334,17 @@ uart_report_port(struct uart_driver *drv break; } - pr_info("%s%s%s at %s (irq = %d, base_baud = %d) is a %s\n", + if (port->report_extra) + port->report_extra(port, report_extra, sizeof(report_extra)); + else + report_extra[0] = '\0'; + + pr_info("%s%s%s at %s (irq = %d, base_baud = %d%s) is a %s\n", port->dev ? dev_name(port->dev) : "", port->dev ? ": " : "", port->name, - address, port->irq, port->uartclk / 16, uart_type(port)); + address, port->irq, port->uartclk / 16, report_extra, + uart_type(port)); } static void Index: linux-malta-cbus-uart/include/linux/serial_core.h =================================================================== --- linux-malta-cbus-uart.orig/include/linux/serial_core.h +++ linux-malta-cbus-uart/include/linux/serial_core.h @@ -135,6 +135,9 @@ struct uart_port { struct serial_rs485 *rs485); int (*iso7816_config)(struct uart_port *, struct serial_iso7816 *iso7816); + void (*report_extra)(struct uart_port *port, + char *report_buf, + size_t report_size); unsigned int irq; /* irq number */ unsigned long irqflags; /* irq flags */ unsigned int uartclk; /* base uart clock */