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

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>
[xr: Backported to 3.4:
 - Adjust filenames
 - Adjust context
 - PORT_BRCM_TRUMANAGE is 22 not 24]
Cc: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: default avatarRui Xiang <rui.xiang@huawei.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent eb2249dc
...@@ -282,6 +282,12 @@ static const struct serial8250_config uart_config[] = { ...@@ -282,6 +282,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)
...@@ -1470,6 +1476,11 @@ void serial8250_tx_chars(struct uart_8250_port *up) ...@@ -1470,6 +1476,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)
...@@ -2641,7 +2652,7 @@ serial8250_verify_port(struct uart_port *port, struct serial_struct *ser) ...@@ -2641,7 +2652,7 @@ serial8250_verify_port(struct uart_port *port, struct serial_struct *ser)
if (ser->irq >= nr_irqs || ser->irq < 0 || if (ser->irq >= nr_irqs || ser->irq < 0 ||
ser->baud_base < 9600 || ser->type < PORT_UNKNOWN || ser->baud_base < 9600 || ser->type < PORT_UNKNOWN ||
ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS || ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS ||
ser->type == PORT_STARTECH) ser->type == PORT_STARTECH || uart_config[ser->type].name == NULL)
return -EINVAL; return -EINVAL;
return 0; return 0;
} }
...@@ -2651,7 +2662,7 @@ serial8250_type(struct uart_port *port) ...@@ -2651,7 +2662,7 @@ serial8250_type(struct uart_port *port)
{ {
int type = port->type; int type = port->type;
if (type >= ARRAY_SIZE(uart_config)) if (type >= ARRAY_SIZE(uart_config) || uart_config[type].name == NULL)
type = 0; type = 0;
return uart_config[type].name; return uart_config[type].name;
} }
......
...@@ -69,6 +69,7 @@ struct serial8250_config { ...@@ -69,6 +69,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_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_port *port, int idx) struct uart_port *port, int idx)
...@@ -1151,6 +1163,7 @@ pci_xr17c154_setup(struct serial_private *priv, ...@@ -1151,6 +1163,7 @@ pci_xr17c154_setup(struct serial_private *priv,
#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_INTEL_PATSBURG_KT 0x1d3d #define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d
#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
...@@ -1683,6 +1696,17 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { ...@@ -1683,6 +1696,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
*/ */
...@@ -1872,6 +1896,7 @@ enum pci_board_num_t { ...@@ -1872,6 +1896,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,
}; };
/* /*
...@@ -2578,6 +2603,12 @@ static struct pciserial_board pci_boards[] __devinitdata = { ...@@ -2578,6 +2603,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[] = {
...@@ -4139,6 +4170,13 @@ static struct pci_device_id serial_pci_tbl[] = { ...@@ -4139,6 +4170,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 25
#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