Add support for new devices: Exar's XR17V35x family of multi-port PCIe UARTs.
Unified · Split
| @@ -282,6 +282,15 @@ static const struct serial8250_config uart_config[] = { · 281 unmodified lines | |||
| 282 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 282 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
| 283 | .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR, | 283 | .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR, |
| 284 | }, | 284 | }, |
| 285 | [PORT_XR17V35X] = { | ||
| 286 | .name = "XR17V35X", | ||
| 287 | .fifo_size = 256, | ||
| 288 | .tx_loadsz = 256, | ||
| 289 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11 | | ||
| 290 | UART_FCR_T_TRIG_11, | ||
| 291 | .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR | | ||
| 292 | UART_CAP_SLEEP, | ||
| 293 | }, | ||
| 285 | [PORT_LPC3220] = { | 294 | [PORT_LPC3220] = { |
| 286 | .name = "LPC3220", | 295 | .name = "LPC3220", |
| 287 | .fifo_size = 64, | 296 | .fifo_size = 64, |
| @@ -455,6 +464,7 @@ static void io_serial_out(struct uart_port *p, int offset, int value) · 167 unmodified lines | |||
| 455 | } | 464 | } |
| 456 | 465 | ||
| 457 | static int serial8250_default_handle_irq(struct uart_port *port); | 466 | static int serial8250_default_handle_irq(struct uart_port *port); |
| 467 | static int exar_handle_irq(struct uart_port *port); | ||
| 458 | 468 | ||
| 459 | static void set_io_from_upio(struct uart_port *p) | 469 | static void set_io_from_upio(struct uart_port *p) |
| 460 | { | 470 | { |
| @@ -574,6 +584,18 @@ EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos); · 113 unmodified lines | |||
| 574 | */ | 584 | */ |
| 575 | static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) | 585 | static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) |
| 576 | { | 586 | { |
| 587 | /* | ||
| 588 | * Exar UARTs have a SLEEP register that enables or disables | ||
| 589 | * each UART to enter sleep mode separately. On the XR17V35x the | ||
| 590 | * register is accessible to each UART at the UART_EXAR_SLEEP | ||
| 591 | * offset but the UART channel may only write to the corresponding | ||
| 592 | * bit. | ||
| 593 | */ | ||
| 594 | if (p->port.type == PORT_XR17V35X) { | ||
| 595 | serial_out(p, UART_EXAR_SLEEP, 0xff); | ||
| 596 | return; | ||
| 597 | } | ||
| 598 | |||
| 577 | if (p->capabilities & UART_CAP_SLEEP) { | 599 | if (p->capabilities & UART_CAP_SLEEP) { |
| 578 | if (p->capabilities & UART_CAP_EFR) { | 600 | if (p->capabilities & UART_CAP_EFR) { |
| 579 | serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); | 601 | serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); |
| @@ -881,6 +903,27 @@ static void autoconfig_16550a(struct uart_8250_port *up) · 301 unmodified lines | |||
| 881 | up->port.type = PORT_16550A; | 903 | up->port.type = PORT_16550A; |
| 882 | up->capabilities |= UART_CAP_FIFO; | 904 | up->capabilities |= UART_CAP_FIFO; |
| 883 | 905 | ||
| 906 | /* | ||
| 907 | * XR17V35x UARTs have an extra divisor register, DLD | ||
| 908 | * that gets enabled with when DLAB is set which will | ||
| 909 | * cause the device to incorrectly match and assign | ||
| 910 | * port type to PORT_16650. The EFR for this UART is | ||
| 911 | * found at offset 0x09. Instead check the Deice ID (DVID) | ||
| 912 | * register for a 2, 4 or 8 port UART. | ||
| 913 | */ | ||
| 914 | status1 = serial_in(up, UART_EXAR_DVID); | ||
| 915 | if (status1 == 0x82 || status1 == 0x84 || status1 == 0x88) { | ||
| 916 | if (up->port.flags & UPF_EXAR_EFR) { | ||
| 917 | DEBUG_AUTOCONF("Exar XR17V35x "); | ||
| 918 | up->port.type = PORT_XR17V35X; | ||
| 919 | up->capabilities |= UART_CAP_AFE | UART_CAP_EFR | | ||
| 920 | UART_CAP_SLEEP; | ||
| 921 | |||
| 922 | return; | ||
| 923 | } | ||
| 924 | |||
| 925 | } | ||
| 926 | |||
| 884 | /* | 927 | /* |
| 885 | * Check for presence of the EFR when DLAB is set. | 928 | * Check for presence of the EFR when DLAB is set. |
| 886 | * Only ST16C650V1 UARTs pass this test. | 929 | * Only ST16C650V1 UARTs pass this test. |
| @@ -1515,6 +1558,30 @@ static int serial8250_default_handle_irq(struct uart_port *port) · 628 unmodified lines | |||
| 1515 | return serial8250_handle_irq(port, iir); | 1558 | return serial8250_handle_irq(port, iir); |
| 1516 | } | 1559 | } |
| 1517 | 1560 | ||
| 1561 | /* | ||
| 1562 | * These Exar UARTs have an extra interrupt indicator that could | ||
| 1563 | * fire for a few unimplemented interrupts. One of which is a | ||
| 1564 | * wakeup event when coming out of sleep. Put this here just | ||
| 1565 | * to be on the safe side that these interrupts don't go unhandled. | ||
| 1566 | */ | ||
| 1567 | static int exar_handle_irq(struct uart_port *port) | ||
| 1568 | { | ||
| 1569 | unsigned char int0, int1, int2, int3; | ||
| 1570 | unsigned int iir = serial_port_in(port, UART_IIR); | ||
| 1571 | int ret; | ||
| 1572 | |||
| 1573 | ret = serial8250_handle_irq(port, iir); | ||
| 1574 | |||
| 1575 | if (port->type == PORT_XR17V35X) { | ||
| 1576 | int0 = serial_port_in(port, 0x80); | ||
| 1577 | int1 = serial_port_in(port, 0x81); | ||
| 1578 | int2 = serial_port_in(port, 0x82); | ||
| 1579 | int3 = serial_port_in(port, 0x83); | ||
| 1580 | } | ||
| 1581 | |||
| 1582 | return ret; | ||
| 1583 | } | ||
| 1584 | |||
| 1518 | /* | 1585 | /* |
| 1519 | * This is the serial driver's interrupt routine. | 1586 | * This is the serial driver's interrupt routine. |
| 1520 | * | 1587 | * |
| @@ -2614,6 +2681,10 @@ static void serial8250_config_port(struct uart_port *port, int flags) · 1093 unmodified lines | |||
| 2614 | serial8250_release_rsa_resource(up); | 2681 | serial8250_release_rsa_resource(up); |
| 2615 | if (port->type == PORT_UNKNOWN) | 2682 | if (port->type == PORT_UNKNOWN) |
| 2616 | serial8250_release_std_resource(up); | 2683 | serial8250_release_std_resource(up); |
| 2684 | |||
| 2685 | /* Fixme: probably not the best place for this */ | ||
| 2686 | if (port->type == PORT_XR17V35X) | ||
| 2687 | port->handle_irq = exar_handle_irq; | ||
| 2617 | } | 2688 | } |
| 2618 | 2689 | ||
| 2619 | static int | 2690 | static int |
| @@ -1164,6 +1164,39 @@ pci_xr17c154_setup(struct serial_private *priv, · 1163 unmodified lines | |||
| 1164 | return pci_default_setup(priv, board, port, idx); | 1164 | return pci_default_setup(priv, board, port, idx); |
| 1165 | } | 1165 | } |
| 1166 | 1166 | ||
| 1167 | static int | ||
| 1168 | pci_xr17v35x_setup(struct serial_private *priv, | ||
| 1169 | const struct pciserial_board *board, | ||
| 1170 | struct uart_8250_port *port, int idx) | ||
| 1171 | { | ||
| 1172 | u8 __iomem *p; | ||
| 1173 | |||
| 1174 | p = pci_ioremap_bar(priv->dev, 0); | ||
| 1175 | |||
| 1176 | port->port.flags |= UPF_EXAR_EFR; | ||
| 1177 | |||
| 1178 | /* | ||
| 1179 | * Setup Multipurpose Input/Output pins. | ||
| 1180 | */ | ||
| 1181 | if (idx == 0) { | ||
| 1182 | writeb(0x00, p + 0x8f); /*MPIOINT[7:0]*/ | ||
| 1183 | writeb(0x00, p + 0x90); /*MPIOLVL[7:0]*/ | ||
| 1184 | writeb(0x00, p + 0x91); /*MPIO3T[7:0]*/ | ||
| 1185 | writeb(0x00, p + 0x92); /*MPIOINV[7:0]*/ | ||
| 1186 | writeb(0x00, p + 0x93); /*MPIOSEL[7:0]*/ | ||
| 1187 | writeb(0x00, p + 0x94); /*MPIOOD[7:0]*/ | ||
| 1188 | writeb(0x00, p + 0x95); /*MPIOINT[15:8]*/ | ||
| 1189 | writeb(0x00, p + 0x96); /*MPIOLVL[15:8]*/ | ||
| 1190 | writeb(0x00, p + 0x97); /*MPIO3T[15:8]*/ | ||
| 1191 | writeb(0x00, p + 0x98); /*MPIOINV[15:8]*/ | ||
| 1192 | writeb(0x00, p + 0x99); /*MPIOSEL[15:8]*/ | ||
| 1193 | writeb(0x00, p + 0x9a); /*MPIOOD[15:8]*/ | ||
| 1194 | } | ||
| 1195 | iounmap(p); | ||
| 1196 | |||
| 1197 | return pci_default_setup(priv, board, port, idx); | ||
| 1198 | } | ||
| 1199 | |||
| 1167 | static int | 1200 | static int |
| 1168 | pci_wch_ch353_setup(struct serial_private *priv, | 1201 | pci_wch_ch353_setup(struct serial_private *priv, |
| 1169 | const struct pciserial_board *board, | 1202 | const struct pciserial_board *board, |
| @@ -1622,6 +1655,27 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { · 452 unmodified lines | |||
| 1622 | .subdevice = PCI_ANY_ID, | 1655 | .subdevice = PCI_ANY_ID, |
| 1623 | .setup = pci_xr17c154_setup, | 1656 | .setup = pci_xr17c154_setup, |
| 1624 | }, | 1657 | }, |
| 1658 | { | ||
| 1659 | .vendor = PCI_VENDOR_ID_EXAR, | ||
| 1660 | .device = PCI_DEVICE_ID_EXAR_XR17V352, | ||
| 1661 | .subvendor = PCI_ANY_ID, | ||
| 1662 | .subdevice = PCI_ANY_ID, | ||
| 1663 | .setup = pci_xr17v35x_setup, | ||
| 1664 | }, | ||
| 1665 | { | ||
| 1666 | .vendor = PCI_VENDOR_ID_EXAR, | ||
| 1667 | .device = PCI_DEVICE_ID_EXAR_XR17V354, | ||
| 1668 | .subvendor = PCI_ANY_ID, | ||
| 1669 | .subdevice = PCI_ANY_ID, | ||
| 1670 | .setup = pci_xr17v35x_setup, | ||
| 1671 | }, | ||
| 1672 | { | ||
| 1673 | .vendor = PCI_VENDOR_ID_EXAR, | ||
| 1674 | .device = PCI_DEVICE_ID_EXAR_XR17V358, | ||
| 1675 | .subvendor = PCI_ANY_ID, | ||
| 1676 | .subdevice = PCI_ANY_ID, | ||
| 1677 | .setup = pci_xr17v35x_setup, | ||
| 1678 | }, | ||
| 1625 | /* | 1679 | /* |
| 1626 | * Xircom cards | 1680 | * Xircom cards |
| 1627 | */ | 1681 | */ |
| @@ -1962,6 +2016,9 @@ enum pci_board_num_t { · 334 unmodified lines | |||
| 1962 | pbn_exar_XR17C152, | 2016 | pbn_exar_XR17C152, |
| 1963 | pbn_exar_XR17C154, | 2017 | pbn_exar_XR17C154, |
| 1964 | pbn_exar_XR17C158, | 2018 | pbn_exar_XR17C158, |
| 2019 | pbn_exar_XR17V352, | ||
| 2020 | pbn_exar_XR17V354, | ||
| 2021 | pbn_exar_XR17V358, | ||
| 1965 | pbn_exar_ibm_saturn, | 2022 | pbn_exar_ibm_saturn, |
| 1966 | pbn_pasemi_1682M, | 2023 | pbn_pasemi_1682M, |
| 1967 | pbn_ni8430_2, | 2024 | pbn_ni8430_2, |
| @@ -2580,6 +2637,30 @@ static struct pciserial_board pci_boards[] = { · 612 unmodified lines | |||
| 2580 | .base_baud = 921600, | 2637 | .base_baud = 921600, |
| 2581 | .uart_offset = 0x200, | 2638 | .uart_offset = 0x200, |
| 2582 | }, | 2639 | }, |
| 2640 | [pbn_exar_XR17V352] = { | ||
| 2641 | .flags = FL_BASE0, | ||
| 2642 | .num_ports = 2, | ||
| 2643 | .base_baud = 7812500, | ||
| 2644 | .uart_offset = 0x400, | ||
| 2645 | .reg_shift = 0, | ||
| 2646 | .first_offset = 0, | ||
| 2647 | }, | ||
| 2648 | [pbn_exar_XR17V354] = { | ||
| 2649 | .flags = FL_BASE0, | ||
| 2650 | .num_ports = 4, | ||
| 2651 | .base_baud = 7812500, | ||
| 2652 | .uart_offset = 0x400, | ||
| 2653 | .reg_shift = 0, | ||
| 2654 | .first_offset = 0, | ||
| 2655 | }, | ||
| 2656 | [pbn_exar_XR17V358] = { | ||
| 2657 | .flags = FL_BASE0, | ||
| 2658 | .num_ports = 8, | ||
| 2659 | .base_baud = 7812500, | ||
| 2660 | .uart_offset = 0x400, | ||
| 2661 | .reg_shift = 0, | ||
| 2662 | .first_offset = 0, | ||
| 2663 | }, | ||
| 2583 | [pbn_exar_ibm_saturn] = { | 2664 | [pbn_exar_ibm_saturn] = { |
| 2584 | .flags = FL_BASE0, | 2665 | .flags = FL_BASE0, |
| 2585 | .num_ports = 1, | 2666 | .num_ports = 1, |
| @@ -3826,6 +3907,21 @@ static struct pci_device_id serial_pci_tbl[] = { · 1240 unmodified lines | |||
| 3826 | PCI_ANY_ID, PCI_ANY_ID, | 3907 | PCI_ANY_ID, PCI_ANY_ID, |
| 3827 | 0, | 3908 | 0, |
| 3828 | 0, pbn_exar_XR17C158 }, | 3909 | 0, pbn_exar_XR17C158 }, |
| 3910 | /* | ||
| 3911 | * Exar Corp. XR17V35[248] Dual/Quad/Octal PCIe UARTs | ||
| 3912 | */ | ||
| 3913 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V352, | ||
| 3914 | PCI_ANY_ID, PCI_ANY_ID, | ||
| 3915 | 0, | ||
| 3916 | 0, pbn_exar_XR17V352 }, | ||
| 3917 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V354, | ||
| 3918 | PCI_ANY_ID, PCI_ANY_ID, | ||
| 3919 | 0, | ||
| 3920 | 0, pbn_exar_XR17V354 }, | ||
| 3921 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V358, | ||
| 3922 | PCI_ANY_ID, PCI_ANY_ID, | ||
| 3923 | 0, | ||
| 3924 | 0, pbn_exar_XR17V358 }, | ||
| 3829 | 3925 | ||
| 3830 | /* | 3926 | /* |
| 3831 | * Topic TP560 Data/Fax/Voice 56k modem (reported by Evan Clarke) | 3927 | * Topic TP560 Data/Fax/Voice 56k modem (reported by Evan Clarke) |
| @@ -1985,6 +1985,9 @@ · 1984 unmodified lines | |||
| 1985 | #define PCI_DEVICE_ID_EXAR_XR17C152 0x0152 | 1985 | #define PCI_DEVICE_ID_EXAR_XR17C152 0x0152 |
| 1986 | #define PCI_DEVICE_ID_EXAR_XR17C154 0x0154 | 1986 | #define PCI_DEVICE_ID_EXAR_XR17C154 0x0154 |
| 1987 | #define PCI_DEVICE_ID_EXAR_XR17C158 0x0158 | 1987 | #define PCI_DEVICE_ID_EXAR_XR17C158 0x0158 |
| 1988 | #define PCI_DEVICE_ID_EXAR_XR17V352 0x0352 | ||
| 1989 | #define PCI_DEVICE_ID_EXAR_XR17V354 0x0354 | ||
| 1990 | #define PCI_DEVICE_ID_EXAR_XR17V358 0x0358 | ||
| 1988 | 1991 | ||
| 1989 | #define PCI_VENDOR_ID_MICROGATE 0x13c0 | 1992 | #define PCI_VENDOR_ID_MICROGATE 0x13c0 |
| 1990 | #define PCI_DEVICE_ID_MICROGATE_USC 0x0010 | 1993 | #define PCI_DEVICE_ID_MICROGATE_USC 0x0010 |
| @@ -49,7 +49,8 @@ · 48 unmodified lines | |||
| 49 | #define PORT_XR17D15X 21 /* Exar XR17D15x UART */ | 49 | #define PORT_XR17D15X 21 /* Exar XR17D15x UART */ |
| 50 | #define PORT_LPC3220 22 /* NXP LPC32xx SoC "Standard" UART */ | 50 | #define PORT_LPC3220 22 /* NXP LPC32xx SoC "Standard" UART */ |
| 51 | #define PORT_8250_CIR 23 /* CIR infrared port, has its own driver */ | 51 | #define PORT_8250_CIR 23 /* CIR infrared port, has its own driver */ |
| 52 | #define PORT_MAX_8250 23 /* max port ID */ | 52 | #define PORT_XR17V35X 24 /* Exar XR17V35x UARTs */ |
| 53 | #define PORT_MAX_8250 24 /* max port ID */ | ||
| 53 | 54 | ||
| 54 | /* | 55 | /* |
| 55 | * ARM specific type numbers. These are not currently guaranteed | 56 | * ARM specific type numbers. These are not currently guaranteed |
| @@ -367,5 +367,11 @@ · 366 unmodified lines | |||
| 367 | #define UART_OMAP_MDR1_CIR_MODE 0x06 /* CIR mode */ | 367 | #define UART_OMAP_MDR1_CIR_MODE 0x06 /* CIR mode */ |
| 368 | #define UART_OMAP_MDR1_DISABLE 0x07 /* Disable (default state) */ | 368 | #define UART_OMAP_MDR1_DISABLE 0x07 /* Disable (default state) */ |
| 369 | 369 | ||
| 370 | /* | ||
| 371 | * These are definitions for the XR17V35X and XR17D15X | ||
| 372 | */ | ||
| 373 | #define UART_EXAR_SLEEP 0x8b /* Sleep mode */ | ||
| 374 | #define UART_EXAR_DVID 0x8d /* Device identification */ | ||
| 375 | |||
| 370 | #endif /* _LINUX_SERIAL_REG_H */ | 376 | #endif /* _LINUX_SERIAL_REG_H */ |
| 371 | 377 | ||