Re: [PATCH v10 1/3] uart: pl011: Support registers offset with LUT

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Jun 01, 2015 at 10:51:32AM +0800, Jun Nie wrote:
> Both ARM and ST uart use the same pl011 IP, but some registers
> have different offset. Support the different offset with look
> up table.
> 
> Signed-off-by: Jun Nie <jun.nie@xxxxxxxxxx>
> Reviewed-by: Peter Hurley <peter@xxxxxxxxxxxxxxxxxx>
> ---
>  drivers/tty/serial/amba-pl011.c | 320 ++++++++++++++++++++++++----------------
>  include/linux/amba/serial.h     |   2 +
>  2 files changed, 194 insertions(+), 128 deletions(-)
> 
> diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
> index 6f5a072..b32f61a 100644
> --- a/drivers/tty/serial/amba-pl011.c
> +++ b/drivers/tty/serial/amba-pl011.c
> @@ -29,7 +29,6 @@
>   * and hooked into this driver.
>   */
>  
> -
>  #if defined(CONFIG_SERIAL_AMBA_PL011_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
>  #define SUPPORT_SYSRQ
>  #endif
> @@ -67,6 +66,8 @@
>  #define SERIAL_AMBA_NR		UART_NR
>  
>  #define AMBA_ISR_PASS_LIMIT	256
> +#define REG_NR			19
> +#define IDX(x)			((x) >> 2)
>  
>  #define UART_DR_ERROR		(UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE)
>  #define UART_DUMMY_DR_RX	(1 << 16)
> @@ -74,8 +75,7 @@
>  /* There is by now at least one vendor with differing details, so handle it */
>  struct vendor_data {
>  	unsigned int		ifls;
> -	unsigned int		lcrh_tx;
> -	unsigned int		lcrh_rx;
> +	u8			*reg_lut;
>  	bool			oversampling;
>  	bool			dma_threshold;
>  	bool			cts_event_workaround;
> @@ -88,10 +88,32 @@ static unsigned int get_fifosize_arm(struct amba_device *dev)
>  	return amba_rev(dev) < 3 ? 16 : 32;
>  }
>  
> +static u8 arm_reg[] = {
> +	/*  All registers offset are in order except [8]=0x2c */
> +	[IDX(UART01x_DR)]	= UART01x_DR,
> +	[IDX(UART01x_RSR)]	= UART01x_RSR,
> +	[IDX(ST_UART011_DMAWM)]	= ST_UART011_DMAWM,

I thought I already commented on things like this.  It's sad to see the
same problems appearing in these patches with new iterations.

The naming scheme for the registers include the ST_ suffix on definitions
which are _only_ applicable to the ST devices, but not the ARM devices.

Why do we have a ST_* register name on the right hand side in the _ARM_
lookup table?  ST_UART011_DMAWM does not exist on the ARM part.

I think the whole patch series needs to be done in the reverse order
(which, again, I think I already commented about.)

Create the enum for the register offsets first:

enum {
	REG_DR		= UART01x_DR,
	REG_RSR		= UART01x_RSR,
	REG_ST_DMAWM	= ST_UART011_DMAWM,
	...
};

and subsitute the UART01x_DR (etc) definitions in the driver for the
REG_* enumerated type.  When it comes to the LCRH registers, use this:

	REG_ST_LCRH_RX	= ST_UART011_LCRH_RX,
	REG_LCRH	= UART01x_LCRH,

and do not introduce REG_ST_LCRH_RX and REG_ST_LCRH_TX etc.  Keep the 
.lcrh_tx and .lcrh_rx in the vendor data structure, and do not try to
eliminate these.

Then, when you introduce the accessors, you can change the above to be:

enum {
	REG_DR		= IDX(UART01x_DR),
	REG_RSR		= IDX(UART01x_RSR),
	REG_ST_DMAWM	= IDX(ST_UART011_DMAWM),
	...
};

Finally, you can then introduce the lookup tables with this:

static u16 arm_reg[] = {
	[REG_DR]		= UART01x_DR,
	[REG_RSR]		= UART01x_RSR,
	[REG_ST_DMAWM]		= ~0,			/* not implemented */
	...
	[REG_ST_LCRH_RX]	= ~0,
	[REG_LCRH]		= UART01x_LCRH,
};

Remembering to check for that "undefined" value.  This table needs to be
at least u16, and not u8 as the register offsets do extend above 255 bytes:

#define ST_UART011_ABCR         0x100   /* Autobaud control register. */
#define ST_UART011_ABIMSC       0x15C   /* Autobaud interrupt mask/clear register */

An "improvement" patch on top of that would then be changing the driver
decision on the LCRH_TX/LCRH_RX registers, potentially using:

	uap->reg_lut[REG_ST_LCRH_RX] != (u16)~0

or better:

	is_implemented(uap, REG_ST_LCRH_RX)

where is_implemented() is:

static bool is_implemented(struct uart_amba_port *uap, unsigned int reg)
{
	return uap->reg_lut[reg] != (u16)~0;
}

If done properly, the first three patches should _just_ be obvious
transformations of the existing code: step 1, renaming the definitions.
step 2, adding the accessors.  step 3, adding the lookup tables.

Then comes the functional change in the way the driver makes decisions
as the final step.

This way, if some problem is later identified with the functional changes,
the remainder can stay behind.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux