diff options
author | Sean Young <sean@mess.org> | 2012-09-07 14:06:24 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-09-26 16:25:41 -0400 |
commit | 65ecc9c02dbad033a73a32916d17c107c5b25031 (patch) | |
tree | 05aa1e55b3b43bd3647ffd8d6d2194e187af6b3e /drivers/tty | |
parent | 835d844d1a28efba81d5aca7385e24c29d3a6db2 (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.c | 16 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_pnp.c | 20 |
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 | ||
30 | static const struct pnp_device_id pnp_dev_table[] = { | 30 | static 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 | */ |
412 | static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags) | 415 | static 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)); |