aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorSean Young <sean@mess.org>2012-09-07 14:06:24 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-09-26 16:25:41 -0400
commit65ecc9c02dbad033a73a32916d17c107c5b25031 (patch)
tree05aa1e55b3b43bd3647ffd8d6d2194e187af6b3e /drivers/tty
parent835d844d1a28efba81d5aca7385e24c29d3a6db2 (diff)
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: Sean Young <sean@mess.org> Acked-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/8250/8250.c16
-rw-r--r--drivers/tty/serial/8250/8250_pnp.c20
2 files changed, 29 insertions, 7 deletions
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
index a2042c6673af..3ba4234592bc 100644
--- a/drivers/tty/serial/8250/8250.c
+++ b/drivers/tty/serial/8250/8250.c
@@ -290,6 +290,9 @@ static const struct serial8250_config uart_config[] = {
290 UART_FCR_R_TRIG_00 | UART_FCR_T_TRIG_00, 290 UART_FCR_R_TRIG_00 | UART_FCR_T_TRIG_00,
291 .flags = UART_CAP_FIFO, 291 .flags = UART_CAP_FIFO,
292 }, 292 },
293 [PORT_8250_CIR] = {
294 .name = "CIR port"
295 }
293}; 296};
294 297
295/* Uart divisor latch read */ 298/* Uart divisor latch read */
@@ -1900,6 +1903,9 @@ static int serial8250_startup(struct uart_port *port)
1900 unsigned char lsr, iir; 1903 unsigned char lsr, iir;
1901 int retval; 1904 int retval;
1902 1905
1906 if (port->type == PORT_8250_CIR)
1907 return -ENODEV;
1908
1903 port->fifosize = uart_config[up->port.type].fifo_size; 1909 port->fifosize = uart_config[up->port.type].fifo_size;
1904 up->tx_loadsz = uart_config[up->port.type].tx_loadsz; 1910 up->tx_loadsz = uart_config[up->port.type].tx_loadsz;
1905 up->capabilities = uart_config[up->port.type].flags; 1911 up->capabilities = uart_config[up->port.type].flags;
@@ -2557,7 +2563,10 @@ static int serial8250_request_port(struct uart_port *port)
2557{ 2563{
2558 struct uart_8250_port *up = 2564 struct uart_8250_port *up =
2559 container_of(port, struct uart_8250_port, port); 2565 container_of(port, struct uart_8250_port, port);
2560 int ret = 0; 2566 int ret;
2567
2568 if (port->type == PORT_8250_CIR)
2569 return -ENODEV;
2561 2570
2562 ret = serial8250_request_std_resource(up); 2571 ret = serial8250_request_std_resource(up);
2563 if (ret == 0 && port->type == PORT_RSA) { 2572 if (ret == 0 && port->type == PORT_RSA) {
@@ -2576,6 +2585,9 @@ static void serial8250_config_port(struct uart_port *port, int flags)
2576 int probeflags = PROBE_ANY; 2585 int probeflags = PROBE_ANY;
2577 int ret; 2586 int ret;
2578 2587
2588 if (port->type == PORT_8250_CIR)
2589 return;
2590
2579 /* 2591 /*
2580 * Find the region that we can probe for. This in turn 2592 * Find the region that we can probe for. This in turn
2581 * tells us whether we can probe for the type of port. 2593 * 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)
3147 mutex_lock(&serial_mutex); 3159 mutex_lock(&serial_mutex);
3148 3160
3149 uart = serial8250_find_match_or_unused(&up->port); 3161 uart = serial8250_find_match_or_unused(&up->port);
3150 if (uart) { 3162 if (uart && uart->port.type != PORT_8250_CIR) {
3151 if (uart->port.dev) 3163 if (uart->port.dev)
3152 uart_remove_one_port(&serial8250_reg, &uart->port); 3164 uart_remove_one_port(&serial8250_reg, &uart->port);
3153 3165
diff --git a/drivers/tty/serial/8250/8250_pnp.c b/drivers/tty/serial/8250/8250_pnp.c
index 28bf830603aa..f8ee25001dd0 100644
--- a/drivers/tty/serial/8250/8250_pnp.c
+++ b/drivers/tty/serial/8250/8250_pnp.c
@@ -25,7 +25,7 @@
25#include "8250.h" 25#include "8250.h"
26 26
27#define UNKNOWN_DEV 0x3000 27#define UNKNOWN_DEV 0x3000
28 28#define CIR_PORT 0x0800
29 29
30static const struct pnp_device_id pnp_dev_table[] = { 30static const struct pnp_device_id pnp_dev_table[] = {
31 /* Archtek America Corp. */ 31 /* Archtek America Corp. */
@@ -362,6 +362,9 @@ static const struct pnp_device_id pnp_dev_table[] = {
362 { "PNPCXXX", UNKNOWN_DEV }, 362 { "PNPCXXX", UNKNOWN_DEV },
363 /* More unknown PnP modems */ 363 /* More unknown PnP modems */
364 { "PNPDXXX", UNKNOWN_DEV }, 364 { "PNPDXXX", UNKNOWN_DEV },
365 /* Winbond CIR port, should not be probed. We should keep track
366 of it to prevent the legacy serial driver from probing it */
367 { "WEC1022", CIR_PORT },
365 { "", 0 } 368 { "", 0 }
366}; 369};
367 370
@@ -409,7 +412,7 @@ static int __devinit check_resources(struct pnp_dev *dev)
409 * PnP modems, alternatively we must hardcode all modems in pnp_devices[] 412 * PnP modems, alternatively we must hardcode all modems in pnp_devices[]
410 * table. 413 * table.
411 */ 414 */
412static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags) 415static int __devinit serial_pnp_guess_board(struct pnp_dev *dev)
413{ 416{
414 if (!(check_name(pnp_dev_name(dev)) || 417 if (!(check_name(pnp_dev_name(dev)) ||
415 (dev->card && check_name(dev->card->name)))) 418 (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)
428 int ret, line, flags = dev_id->driver_data; 431 int ret, line, flags = dev_id->driver_data;
429 432
430 if (flags & UNKNOWN_DEV) { 433 if (flags & UNKNOWN_DEV) {
431 ret = serial_pnp_guess_board(dev, &flags); 434 ret = serial_pnp_guess_board(dev);
432 if (ret < 0) 435 if (ret < 0)
433 return ret; 436 return ret;
434 } 437 }
@@ -436,7 +439,10 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
436 memset(&uart, 0, sizeof(uart)); 439 memset(&uart, 0, sizeof(uart));
437 if (pnp_irq_valid(dev, 0)) 440 if (pnp_irq_valid(dev, 0))
438 uart.port.irq = pnp_irq(dev, 0); 441 uart.port.irq = pnp_irq(dev, 0);
439 if (pnp_port_valid(dev, 0)) { 442 if ((flags & CIR_PORT) && pnp_port_valid(dev, 2)) {
443 uart.port.iobase = pnp_port_start(dev, 2);
444 uart.port.iotype = UPIO_PORT;
445 } else if (pnp_port_valid(dev, 0)) {
440 uart.port.iobase = pnp_port_start(dev, 0); 446 uart.port.iobase = pnp_port_start(dev, 0);
441 uart.port.iotype = UPIO_PORT; 447 uart.port.iotype = UPIO_PORT;
442 } else if (pnp_mem_valid(dev, 0)) { 448 } 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)
451 "Setup PNP port: port %x, mem 0x%lx, irq %d, type %d\n", 457 "Setup PNP port: port %x, mem 0x%lx, irq %d, type %d\n",
452 uart.port.iobase, uart.port.mapbase, uart.port.irq, uart.port.iotype); 458 uart.port.iobase, uart.port.mapbase, uart.port.irq, uart.port.iotype);
453#endif 459#endif
460 if (flags & CIR_PORT) {
461 uart.port.flags |= UPF_FIXED_PORT | UPF_FIXED_TYPE;
462 uart.port.type = PORT_8250_CIR;
463 }
454 464
455 uart.port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; 465 uart.port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
456 if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE) 466 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)
459 uart.port.dev = &dev->dev; 469 uart.port.dev = &dev->dev;
460 470
461 line = serial8250_register_8250_port(&uart); 471 line = serial8250_register_8250_port(&uart);
462 if (line < 0) 472 if (line < 0 || (flags & CIR_PORT))
463 return -ENODEV; 473 return -ENODEV;
464 474
465 pnp_set_drvdata(dev, (void *)((long)line + 1)); 475 pnp_set_drvdata(dev, (void *)((long)line + 1));