Commit ebebd49a authored by Stephen Hurd's avatar Stephen Hurd Committed by Greg Kroah-Hartman

8250/16?50: Add support for Broadcom TruManage redirected serial port

Add support for the UART device present in Broadcom TruManage capable
NetXtreme chips (ie: 5761m 5762, and 5725).

This implementation has a hidden transmit FIFO, so running in single-byte
interrupt mode results in too many interrupts.  The UART_CAP_HFIFO
capability was added to track this.  It continues to reload the THR as long
as the THRE and TSRE bits are set in the LSR up to a specified limit (1024
is used here).
Signed-off-by: default avatarStephen Hurd <shurd@broadcom.com>
Signed-off-by: default avatarMichael Chan <mchan@broadcom.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent ded2f295
...@@ -300,6 +300,12 @@ static const struct serial8250_config uart_config[] = { ...@@ -300,6 +300,12 @@ static const struct serial8250_config uart_config[] = {
UART_FCR_R_TRIG_00 | UART_FCR_T_TRIG_00, UART_FCR_R_TRIG_00 | UART_FCR_T_TRIG_00,
.flags = UART_CAP_FIFO, .flags = UART_CAP_FIFO,
}, },
[PORT_BRCM_TRUMANAGE] = {
.name = "TruManage",
.fifo_size = 1,
.tx_loadsz = 1024,
.flags = UART_CAP_HFIFO,
},
[PORT_8250_CIR] = { [PORT_8250_CIR] = {
.name = "CIR port" .name = "CIR port"
} }
...@@ -1490,6 +1496,11 @@ void serial8250_tx_chars(struct uart_8250_port *up) ...@@ -1490,6 +1496,11 @@ void serial8250_tx_chars(struct uart_8250_port *up)
port->icount.tx++; port->icount.tx++;
if (uart_circ_empty(xmit)) if (uart_circ_empty(xmit))
break; break;
if (up->capabilities & UART_CAP_HFIFO) {
if ((serial_port_in(port, UART_LSR) & BOTH_EMPTY) !=
BOTH_EMPTY)
break;
}
} while (--count > 0); } while (--count > 0);
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
......
...@@ -40,6 +40,7 @@ struct serial8250_config { ...@@ -40,6 +40,7 @@ struct serial8250_config {
#define UART_CAP_AFE (1 << 11) /* MCR-based hw flow control */ #define UART_CAP_AFE (1 << 11) /* MCR-based hw flow control */
#define UART_CAP_UUE (1 << 12) /* UART needs IER bit 6 set (Xscale) */ #define UART_CAP_UUE (1 << 12) /* UART needs IER bit 6 set (Xscale) */
#define UART_CAP_RTOIE (1 << 13) /* UART needs IER bit 4 set (Xscale, Tegra) */ #define UART_CAP_RTOIE (1 << 13) /* UART needs IER bit 4 set (Xscale, Tegra) */
#define UART_CAP_HFIFO (1 << 14) /* UART has a "hidden" FIFO */
#define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */ #define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */
#define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */ #define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */
......
...@@ -1085,6 +1085,18 @@ pci_omegapci_setup(struct serial_private *priv, ...@@ -1085,6 +1085,18 @@ pci_omegapci_setup(struct serial_private *priv,
return setup_port(priv, port, 2, idx * 8, 0); return setup_port(priv, port, 2, idx * 8, 0);
} }
static int
pci_brcm_trumanage_setup(struct serial_private *priv,
const struct pciserial_board *board,
struct uart_8250_port *port, int idx)
{
int ret = pci_default_setup(priv, board, port, idx);
port->port.type = PORT_BRCM_TRUMANAGE;
port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE);
return ret;
}
static int skip_tx_en_setup(struct serial_private *priv, static int skip_tx_en_setup(struct serial_private *priv,
const struct pciserial_board *board, const struct pciserial_board *board,
struct uart_8250_port *port, int idx) struct uart_8250_port *port, int idx)
...@@ -1304,6 +1316,7 @@ pci_wch_ch353_setup(struct serial_private *priv, ...@@ -1304,6 +1316,7 @@ pci_wch_ch353_setup(struct serial_private *priv,
#define PCI_DEVICE_ID_COMMTECH_4224PCIE 0x0020 #define PCI_DEVICE_ID_COMMTECH_4224PCIE 0x0020
#define PCI_DEVICE_ID_COMMTECH_4228PCIE 0x0021 #define PCI_DEVICE_ID_COMMTECH_4228PCIE 0x0021
#define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0022 #define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0022
#define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a
/* Unknown vendors/cards - this should not be in linux/pci_ids.h */ /* Unknown vendors/cards - this should not be in linux/pci_ids.h */
...@@ -1953,6 +1966,17 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { ...@@ -1953,6 +1966,17 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID, .subdevice = PCI_ANY_ID,
.setup = pci_xr17v35x_setup, .setup = pci_xr17v35x_setup,
}, },
/*
* Broadcom TruManage (NetXtreme)
*/
{
.vendor = PCI_VENDOR_ID_BROADCOM,
.device = PCI_DEVICE_ID_BROADCOM_TRUMANAGE,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_brcm_trumanage_setup,
},
/* /*
* Default "match everything" terminator entry * Default "match everything" terminator entry
*/ */
...@@ -2148,6 +2172,7 @@ enum pci_board_num_t { ...@@ -2148,6 +2172,7 @@ enum pci_board_num_t {
pbn_ce4100_1_115200, pbn_ce4100_1_115200,
pbn_omegapci, pbn_omegapci,
pbn_NETMOS9900_2s_115200, pbn_NETMOS9900_2s_115200,
pbn_brcm_trumanage,
}; };
/* /*
...@@ -2892,6 +2917,12 @@ static struct pciserial_board pci_boards[] = { ...@@ -2892,6 +2917,12 @@ static struct pciserial_board pci_boards[] = {
.num_ports = 2, .num_ports = 2,
.base_baud = 115200, .base_baud = 115200,
}, },
[pbn_brcm_trumanage] = {
.flags = FL_BASE0,
.num_ports = 1,
.reg_shift = 2,
.base_baud = 115200,
},
}; };
static const struct pci_device_id blacklist[] = { static const struct pci_device_id blacklist[] = {
...@@ -4470,6 +4501,13 @@ static struct pci_device_id serial_pci_tbl[] = { ...@@ -4470,6 +4501,13 @@ static struct pci_device_id serial_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_omegapci }, pbn_omegapci },
/*
* Broadcom TruManage
*/
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BROADCOM_TRUMANAGE,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_brcm_trumanage },
/* /*
* AgeStar as-prs2-009 * AgeStar as-prs2-009
*/ */
......
...@@ -50,7 +50,8 @@ ...@@ -50,7 +50,8 @@
#define PORT_LPC3220 22 /* NXP LPC32xx SoC "Standard" UART */ #define PORT_LPC3220 22 /* NXP LPC32xx SoC "Standard" UART */
#define PORT_8250_CIR 23 /* CIR infrared port, has its own driver */ #define PORT_8250_CIR 23 /* CIR infrared port, has its own driver */
#define PORT_XR17V35X 24 /* Exar XR17V35x UARTs */ #define PORT_XR17V35X 24 /* Exar XR17V35x UARTs */
#define PORT_MAX_8250 24 /* max port ID */ #define PORT_BRCM_TRUMANAGE 24
#define PORT_MAX_8250 25 /* max port ID */
/* /*
* ARM specific type numbers. These are not currently guaranteed * ARM specific type numbers. These are not currently guaranteed
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment