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

Stephen Hurd
2012-12-12T00:32:43Z

[-- Attachment #1: Type: text/plain, Size: 782 bytes --]

From: Stephen Hurd <shurd@broadcom.com>

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: Stephen Hurd <shurd@broadcom.com>

---

Patch against linux-2.7 from ftp.kernel.org downloaded Dec-11-2012.

Sorry about the attachment, I'm required to use Outlook.

Stephen Hurd
Senior Staff Engineer - Software Development
Broadcom Corporation
949-926-8039
shurd@broadcom.com

[-- Attachment #2: brcm-trumanage-uart.patch --]
[-- Type: application/octet-stream, Size: 4143 bytes --]

diff -uprN -X linux-3.7/Documentation/dontdiff linux-3.7.orig/drivers/tty/serial/8250/8250.c linux-3.7/drivers/tty/serial/8250/8250.c
--- linux-3.7.orig/drivers/tty/serial/8250/8250.c 2012-12-10 19:30:57.000000000 -0800
+++ linux-3.7/drivers/tty/serial/8250/8250.c 2012-12-11 15:56:40.686343959 -0800
@@ -290,6 +290,12 @@ static const struct serial8250_config ua
UART_FCR_R_TRIG_00 | UART_FCR_T_TRIG_00,
.flags = UART_CAP_FIFO,
},
+ [PORT_BRCM_TRUMANAGE] = {
+ .name = "TruManage",
+ .fifo_size = 1,
+ .tx_loadsz = 1024,
+ .flags = UART_CAP_HFIFO,
+ },
[PORT_8250_CIR] = {
.name = "CIR port"
}
@@ -1441,6 +1447,11 @@ void serial8250_tx_chars(struct uart_825
port->icount.tx++;
if (uart_circ_empty(xmit))
break;
+ if (up->capabilities & UART_CAP_HFIFO) {
+ if ((serial_port_in(port, UART_LSR) & BOTH_EMPTY)
+ != BOTH_EMPTY)
+ break;
+ }
} while (--count > 0);

if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
diff -uprN -X linux-3.7/Documentation/dontdiff linux-3.7.orig/drivers/tty/serial/8250/8250.h linux-3.7/drivers/tty/serial/8250/8250.h
--- linux-3.7.orig/drivers/tty/serial/8250/8250.h 2012-12-10 19:30:57.000000000 -0800
+++ linux-3.7/drivers/tty/serial/8250/8250.h 2012-12-11 14:57:48.641613676 -0800
@@ -40,6 +40,7 @@ struct serial8250_config {
#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_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_TXEN (1 << 1) /* UART has buggy TX IIR status */
diff -uprN -X linux-3.7/Documentation/dontdiff linux-3.7.orig/drivers/tty/serial/8250/8250_pci.c linux-3.7/drivers/tty/serial/8250/8250_pci.c
--- linux-3.7.orig/drivers/tty/serial/8250/8250_pci.c 2012-12-10 19:30:57.000000000 -0800
+++ linux-3.7/drivers/tty/serial/8250/8250_pci.c 2012-12-11 15:58:10.958340077 -0800
@@ -1085,6 +1085,17 @@ pci_omegapci_setup(struct serial_private
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,
const struct pciserial_board *board,
struct uart_8250_port *port, int idx)
@@ -1213,6 +1224,7 @@ pci_wch_ch353_setup(struct serial_privat
#define PCI_VENDOR_ID_AGESTAR 0x5372
#define PCI_DEVICE_ID_AGESTAR_9375 0x6872
#define PCI_VENDOR_ID_ASIX 0x9710
+#define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a

/* Unknown vendors/cards - this should not be in linux/pci_ids.h */
#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584
@@ -1788,6 +1800,17 @@ static struct pci_serial_quirk pci_seria
.setup = pci_asix_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
*/
{
@@ -1975,6 +1998,7 @@ enum pci_board_num_t {
pbn_ce4100_1_115200,
pbn_omegapci,
pbn_NETMOS9900_2s_115200,
+ pbn_brcm_trumanage,
};

/*
@@ -2674,6 +2698,12 @@ static struct pciserial_board pci_boards
.num_ports = 2,
.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[] = {
@@ -4238,6 +4268,13 @@ static struct pci_device_id serial_pci_t
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
*/
{ PCI_VENDOR_ID_AGESTAR, PCI_DEVICE_ID_AGESTAR_9375,