Re: [PATCH v3 2/2] serial: 8250: Add Airoha SoC UART and HSUART support

Andy Shevchenko <[email protected]>
Newsgroups org.kernel.vger.linux-kernel,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-serial
Organization Intel Finland Oy - BIC 0357606-4 - c/o Alberga Business Park, 6 krs, Bertel Jungin Aukio 5, 02600 Espoo
Message-ID <[email protected]>
On Sat, Aug 08, 2026 at 12:20:40AM +0200, Christian Marangi wrote:
> Add support for Airoha AN7523 UART and AN7581 HSUART.
> 
> These implement a standard 16550 UART with only some custom logic
> for baud rate handling.

Some cosmetic issues below.
With that being addressed,
Reviewed-by: Andy Shevchenko <[email protected]>

...


> +++ b/drivers/tty/serial/8250/8250_airoha.c


> + * Author: Benjamin Larsson <[email protected]>
> + *	   Christian Marangi <[email protected]>

Authors:

...

> +#include <linux/array_size.h>
> +#include <linux/bits.h>
> +#include <linux/bitfield.h>

+ errno.h

> +#include <linux/math64.h>
> +#include <linux/module.h>
> +#include <linux/property.h>
> +#include <linux/platform_device.h>
> +#include <linux/serial_8250.h>

> +#include <linux/serial_core.h>
> +#include <linux/serial_reg.h>

These two are kinda guaranteed by serial_8250.h. At least IIRC some other 8250
drivers rely on this and it sounds logical.

+ types.h // uXX

> +#include <linux/units.h>

...

> +#define UART_BRD_20M		0x1

Perhaps 0x0001 to show that this is 16-bit value?

...

> +static unsigned int airoha_get_divisor(struct uart_port *port,
> +				       unsigned int baud,
> +				       unsigned int *frac)
> +{
> +	/* Hardware always uses BRDIV = 1. */
> +	*frac = 0;
> +
> +	return 1;

Shouldn't this be the same as UART_BRD_20M? I mean return a defined constant.

> +}

...

> +static void airoha_set_divisor(struct uart_port *port, unsigned int baud,
> +			       unsigned int quot, unsigned int quot_frac)
> +{
> +	struct uart_8250_port *up = up_to_u8250p(port);
> +	u32 xindiv_clk;
> +	u64 xyd_x, nom;
> +	int div_bit;
> +
> +	/* Set baud rate calculation defaults (BRDIV ([BRDH,BRDL]) to 1) */

Inner parentheses are not needed.

> +	serial8250_do_set_divisor(port, baud, UART_BRD_20M);
> +
> +	/*
> +	 * Calculate XYD_x and XINCLKDR register by searching
> +	 * through a table of crystal_clock divisors.
> +	 */
> +	nom = (u64)baud * XYD_Y;

> +	for (div_bit = ARRAY_SIZE(airoha_clk_divs) - 1;
> +	     div_bit >= 0; div_bit--) {

It's okay to place these on a single line.

> +		unsigned int div = airoha_clk_divs[div_bit];
> +
> +		xindiv_clk = XINDIV_CLOCK / div;
> +		xyd_x = div_u64(nom * 16, xindiv_clk);
> +
> +		/* For the HSUART xyd_x needs to be scaled by a factor of 2 */
> +		if (port->type == UART_PORT_AIROHA_HS)
> +			xyd_x /= 2;
> +
> +		if (xyd_x < XYD_Y)
> +			break;
> +	}
> +
> +	/* Couldn't find a valid xyd_x */
> +	if (div_bit < 0) {
> +		dev_err(port->dev, "failed to find suitable clock divisor for baud %u\n",
> +			baud);
> +		return;
> +	}
> +
> +	serial_port_out(port, UART_AIROHA_XINCLKDR, BIT(div_bit));
> +	serial_port_out(port, UART_AIROHA_XYD,
> +			FIELD_PREP(UART_AIROHA_XYD_X, xyd_x) |
> +			FIELD_PREP(UART_AIROHA_XYD_Y, XYD_Y));
> +
> +	/* Restore normal register access. */
> +	serial_port_out(port, UART_LCR, up->lcr);
> +}

-- 
With Best Regards,
Andy Shevchenko
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.