Commit 6521d673 authored by Stephen Hurd's avatar Stephen Hurd Committed by Ben Hutchings

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

commit ebebd49a upstream.

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>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
[bwh: Backported to 3.2:
 - Adjust filenames
 - Adjust context
 - First available port type number is 22 not 24
 - s/uart_8250_port/uart_port/
 - Use serial_in() not serial_port_in()]
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
parent 01b7106d
...@@ -316,6 +316,12 @@ static const struct serial8250_config uart_config[] = { ...@@ -316,6 +316,12 @@ static const struct serial8250_config uart_config[] = {
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
.flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR, .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR,
}, },
[PORT_BRCM_TRUMANAGE] = {
.name = "TruManage",
.fifo_size = 1,
.tx_loadsz = 1024,
.flags = UART_CAP_HFIFO,
},
}; };
#if defined(CONFIG_MIPS_ALCHEMY) #if defined(CONFIG_MIPS_ALCHEMY)
...@@ -1511,6 +1517,11 @@ static void transmit_chars(struct uart_8250_port *up) ...@@ -1511,6 +1517,11 @@ static void transmit_chars(struct uart_8250_port *up)
up->port.icount.tx++; up->port.icount.tx++;
if (uart_circ_empty(xmit)) if (uart_circ_empty(xmit))
break; break;
if (up->capabilities & UART_CAP_HFIFO) {
if ((serial_in(up, 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)
......
...@@ -43,6 +43,7 @@ struct serial8250_config { ...@@ -43,6 +43,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 */
......
...@@ -1077,6 +1077,18 @@ pci_omegapci_setup(struct serial_private *priv, ...@@ -1077,6 +1077,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_port *port, int idx)
{
int ret = pci_default_setup(priv, board, port, idx);
port->type = PORT_BRCM_TRUMANAGE;
port->flags = (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_port *port, int idx) struct uart_port *port, int idx)
...@@ -1138,6 +1150,7 @@ pci_xr17c154_setup(struct serial_private *priv, ...@@ -1138,6 +1150,7 @@ pci_xr17c154_setup(struct serial_private *priv,
#define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538 #define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538
#define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6 #define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6
#define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 #define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001
#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 */
#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584
...@@ -1671,6 +1684,17 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { ...@@ -1671,6 +1684,17 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID, .subdevice = PCI_ANY_ID,
.setup = pci_omegapci_setup, .setup = pci_omegapci_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
*/ */
...@@ -1860,6 +1884,7 @@ enum pci_board_num_t { ...@@ -1860,6 +1884,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,
}; };
/* /*
...@@ -2566,6 +2591,12 @@ static struct pciserial_board pci_boards[] __devinitdata = { ...@@ -2566,6 +2591,12 @@ static struct pciserial_board pci_boards[] __devinitdata = {
.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 softmodem_blacklist[] = { static const struct pci_device_id softmodem_blacklist[] = {
...@@ -4107,6 +4138,13 @@ static struct pci_device_id serial_pci_tbl[] = { ...@@ -4107,6 +4138,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 },
/* /*
* These entries match devices with class COMMUNICATION_SERIAL, * These entries match devices with class COMMUNICATION_SERIAL,
* COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL
......
...@@ -47,7 +47,8 @@ ...@@ -47,7 +47,8 @@
#define PORT_U6_16550A 19 /* ST-Ericsson U6xxx internal UART */ #define PORT_U6_16550A 19 /* ST-Ericsson U6xxx internal UART */
#define PORT_TEGRA 20 /* NVIDIA Tegra internal UART */ #define PORT_TEGRA 20 /* NVIDIA Tegra internal UART */
#define PORT_XR17D15X 21 /* Exar XR17D15x UART */ #define PORT_XR17D15X 21 /* Exar XR17D15x UART */
#define PORT_MAX_8250 21 /* max port ID */ #define PORT_BRCM_TRUMANAGE 22
#define PORT_MAX_8250 22 /* 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