Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 65ecc9c0 authored by Sean Young's avatar Sean Young Committed by Greg Kroah-Hartman
Browse files

8250: blacklist Winbond CIR port



The legacy serial driver will detect the Winbond CIR device as a serial
port, since it looks exactly like a serial port unless you know what
it is from the PNP ID.

Here we track this port as a special PORT_8250_CIR type, preventing the
legacy serial driver from probing it.

Signed-off-by: default avatarSean Young <sean@mess.org>
Acked-by: default avatarAlan Cox <alan@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 835d844d
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
@@ -290,6 +290,9 @@ static const struct serial8250_config uart_config[] = {
				  UART_FCR_R_TRIG_00 | UART_FCR_T_TRIG_00,
		.flags		= UART_CAP_FIFO,
	},
	[PORT_8250_CIR] = {
		.name		= "CIR port"
	}
};

/* Uart divisor latch read */
@@ -1900,6 +1903,9 @@ static int serial8250_startup(struct uart_port *port)
	unsigned char lsr, iir;
	int retval;

	if (port->type == PORT_8250_CIR)
		return -ENODEV;

	port->fifosize = uart_config[up->port.type].fifo_size;
	up->tx_loadsz = uart_config[up->port.type].tx_loadsz;
	up->capabilities = uart_config[up->port.type].flags;
@@ -2557,7 +2563,10 @@ static int serial8250_request_port(struct uart_port *port)
{
	struct uart_8250_port *up =
		container_of(port, struct uart_8250_port, port);
	int ret = 0;
	int ret;

	if (port->type == PORT_8250_CIR)
		return -ENODEV;

	ret = serial8250_request_std_resource(up);
	if (ret == 0 && port->type == PORT_RSA) {
@@ -2576,6 +2585,9 @@ static void serial8250_config_port(struct uart_port *port, int flags)
	int probeflags = PROBE_ANY;
	int ret;

	if (port->type == PORT_8250_CIR)
		return;

	/*
	 * Find the region that we can probe for.  This in turn
	 * tells us whether we can probe for the type of port.
@@ -3147,7 +3159,7 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
	mutex_lock(&serial_mutex);

	uart = serial8250_find_match_or_unused(&up->port);
	if (uart) {
	if (uart && uart->port.type != PORT_8250_CIR) {
		if (uart->port.dev)
			uart_remove_one_port(&serial8250_reg, &uart->port);

+15 −5
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@
#include "8250.h"

#define UNKNOWN_DEV 0x3000

#define CIR_PORT	0x0800

static const struct pnp_device_id pnp_dev_table[] = {
	/* Archtek America Corp. */
@@ -362,6 +362,9 @@ static const struct pnp_device_id pnp_dev_table[] = {
	{	"PNPCXXX",		UNKNOWN_DEV	},
	/* More unknown PnP modems */
	{	"PNPDXXX",		UNKNOWN_DEV	},
	/* Winbond CIR port, should not be probed. We should keep track
	   of it to prevent the legacy serial driver from probing it */
	{	"WEC1022",		CIR_PORT	},
	{	"",			0	}
};

@@ -409,7 +412,7 @@ static int __devinit check_resources(struct pnp_dev *dev)
 * PnP modems, alternatively we must hardcode all modems in pnp_devices[]
 * table.
 */
static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags)
static int __devinit serial_pnp_guess_board(struct pnp_dev *dev)
{
	if (!(check_name(pnp_dev_name(dev)) ||
		(dev->card && check_name(dev->card->name))))
@@ -428,7 +431,7 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
	int ret, line, flags = dev_id->driver_data;

	if (flags & UNKNOWN_DEV) {
		ret = serial_pnp_guess_board(dev, &flags);
		ret = serial_pnp_guess_board(dev);
		if (ret < 0)
			return ret;
	}
@@ -436,7 +439,10 @@ 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 (pnp_port_valid(dev, 0)) {
	if ((flags & CIR_PORT) && pnp_port_valid(dev, 2)) {
		uart.port.iobase = pnp_port_start(dev, 2);
		uart.port.iotype = UPIO_PORT;
	} else if (pnp_port_valid(dev, 0)) {
		uart.port.iobase = pnp_port_start(dev, 0);
		uart.port.iotype = UPIO_PORT;
	} else if (pnp_mem_valid(dev, 0)) {
@@ -451,6 +457,10 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
		"Setup PNP port: port %x, mem 0x%lx, irq %d, type %d\n",
		       uart.port.iobase, uart.port.mapbase, uart.port.irq, uart.port.iotype);
#endif
	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)
@@ -459,7 +469,7 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
	uart.port.dev = &dev->dev;

	line = serial8250_register_8250_port(&uart);
	if (line < 0)
	if (line < 0 || (flags & CIR_PORT))
		return -ENODEV;

	pnp_set_drvdata(dev, (void *)((long)line + 1));
+2 −1
Original line number Diff line number Diff line
@@ -48,7 +48,8 @@
#define PORT_TEGRA	20	/* NVIDIA Tegra internal UART */
#define PORT_XR17D15X	21	/* Exar XR17D15x UART */
#define PORT_LPC3220	22	/* NXP LPC32xx SoC "Standard" UART */
#define PORT_MAX_8250	22	/* max port ID */
#define PORT_8250_CIR	23	/* CIR infrared port, has its own driver */
#define PORT_MAX_8250	23	/* max port ID */

/*
 * ARM specific type numbers.  These are not currently guaranteed