Re: [PATCH] serial: 8250_exar: Absorb remaining 8250_port INT0 support

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

 



On Wed, Jul 31, 2019 at 12:45:45PM -0500, Aaron Sierra wrote:
> Move INT0 clearing out of common, per-port serial8250_do_startup()
> into PCI device probe/resume.
> 
> As described in commit 2c0ac5b48a35 ("serial: exar: Fix stuck MSIs"),
> the purpose of clearing INT0 is to prevent the PCI interrupt line from
> becoming stuck asserted, "which is fatal with edge-triggered MSIs".
> 
> Like the clearing via interrupt handler that moved from common code in
> commit c7e1b4059075 ("tty: serial: exar: Relocate sleep wake-up
> handling"), this clearing at startup can be better handled at the PCI
> device level.
> 

Looks good to me,
Reviewed-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>

P.S. When you have a chance to test my series, please, give a tag.

> Cc: Jan Kiszka <jan.kiszka@xxxxxxxxxxx>
> Cc: Sudip Mukherjee <sudip.mukherjee@xxxxxxxxxxxxxxx>
> Cc: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>
> Signed-off-by: Aaron Sierra <asierra@xxxxxxxxxxx>
> ---
> 
> The embedded patch is written to follow this patch from Andy Shevchenko:
> [PATCH v4 3/3] serial: 8250_exar: Move custom divisor support out from 8250_port
> 
>  drivers/tty/serial/8250/8250_exar.c | 24 ++++++++++++++++--------
>  drivers/tty/serial/8250/8250_port.c |  9 ---------
>  2 files changed, 16 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c
> index 4f8f45e2fc1d..248be217f528 100644
> --- a/drivers/tty/serial/8250/8250_exar.c
> +++ b/drivers/tty/serial/8250/8250_exar.c
> @@ -492,6 +492,16 @@ static void pci_xr17v35x_exit(struct pci_dev *pcidev)
>  	port->port.private_data = NULL;
>  }
>  
> +static inline void exar_misc_clear(struct exar8250 *priv)
> +{
> +	/* Clear all PCI interrupts by reading INT0. No effect on IIR */
> +	readb(priv->virt + UART_EXAR_INT0);
> +
> +	/* Clear INT0 for Expansion Interface slave ports, too */
> +	if (priv->board->num_ports > 8)
> +		readb(priv->virt + 0x2000 + UART_EXAR_INT0);
> +}
> +
>  /*
>   * These Exar UARTs have an extra interrupt indicator that could fire for a
>   * few interrupts that are not presented/cleared through IIR.  One of which is
> @@ -503,14 +513,7 @@ static void pci_xr17v35x_exit(struct pci_dev *pcidev)
>   */
>  static irqreturn_t exar_misc_handler(int irq, void *data)
>  {
> -	struct exar8250 *priv = data;
> -
> -	/* Clear all PCI interrupts by reading INT0. No effect on IIR */
> -	readb(priv->virt + UART_EXAR_INT0);
> -
> -	/* Clear INT0 for Expansion Interface slave ports, too */
> -	if (priv->board->num_ports > 8)
> -		readb(priv->virt + 0x2000 + UART_EXAR_INT0);
> +	exar_misc_clear(data);
>  
>  	return IRQ_HANDLED;
>  }
> @@ -563,6 +566,9 @@ exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
>  	if (rc)
>  		return rc;
>  
> +	/* Clear interrupts */
> +	exar_misc_clear(priv);
> +
>  	for (i = 0; i < nr_ports && i < maxnr; i++) {
>  		rc = board->setup(priv, pcidev, &uart, i);
>  		if (rc) {
> @@ -622,6 +628,8 @@ static int __maybe_unused exar_resume(struct device *dev)
>  	struct exar8250 *priv = pci_get_drvdata(pcidev);
>  	unsigned int i;
>  
> +	exar_misc_clear(priv);
> +
>  	for (i = 0; i < priv->nr; i++)
>  		if (priv->line[i] >= 0)
>  			serial8250_resume_port(priv->line[i]);
> diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
> index 995a7e8b7839..706645f89132 100644
> --- a/drivers/tty/serial/8250/8250_port.c
> +++ b/drivers/tty/serial/8250/8250_port.c
> @@ -40,11 +40,6 @@
>  
>  #include "8250.h"
>  
> -/*
> - * These are definitions for the Exar XR17V35X and XR17(C|D)15X
> - */
> -#define UART_EXAR_INT0		0x80
> -
>  /* Nuvoton NPCM timeout register */
>  #define UART_NPCM_TOR          7
>  #define UART_NPCM_TOIE         BIT(7)  /* Timeout Interrupt Enable */
> @@ -2138,8 +2133,6 @@ int serial8250_do_startup(struct uart_port *port)
>  	serial_port_in(port, UART_RX);
>  	serial_port_in(port, UART_IIR);
>  	serial_port_in(port, UART_MSR);
> -	if ((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X))
> -		serial_port_in(port, UART_EXAR_INT0);
>  
>  	/*
>  	 * At this point, there's no way the LSR could still be 0xff;
> @@ -2297,8 +2290,6 @@ int serial8250_do_startup(struct uart_port *port)
>  	serial_port_in(port, UART_RX);
>  	serial_port_in(port, UART_IIR);
>  	serial_port_in(port, UART_MSR);
> -	if ((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X))
> -		serial_port_in(port, UART_EXAR_INT0);
>  	up->lsr_saved_flags = 0;
>  	up->msr_saved_flags = 0;
>  
> -- 
> 2.17.1
> 

-- 
With Best Regards,
Andy Shevchenko





[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