RE: [PATCH] 8250/16?50: Add support for Broadcom TruManageredirected serial port
From: Stephen Hurd
Date: Wed Dec 12 2012 - 00:28:31 EST
From: Stephen Hurd <shurd@xxxxxxxxxxxx>
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@xxxxxxxxxxxx>
---
Patch against linux-2.7 from ftp.kernel.org downloaded Dec-11-2012.
I don't know anybody here off hand who does Linux work nor am I in a position to configure the Exchange server. If this still isn't acceptable, I guess I could try emailing this patch around internally and hope it lands with someone has the appropriate magic available.
-- Stephen Hurd
diff -uprN 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 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 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,
diff -uprN linux-3.7.orig/include/uapi/linux/serial_core.h linux-3.7/include/uapi/linux/serial_core.h
--- linux-3.7.orig/include/uapi/linux/serial_core.h 2012-12-10 19:30:57.000000000 -0800
+++ linux-3.7/include/uapi/linux/serial_core.h 2012-12-11 15:00:07.005618440 -0800
@@ -49,7 +49,8 @@
#define PORT_XR17D15X 21 /* Exar XR17D15x UART */
#define PORT_LPC3220 22 /* NXP LPC32xx SoC "Standard" UART */
#define PORT_8250_CIR 23 /* CIR infrared port, has its own driver */
-#define PORT_MAX_8250 23 /* max port ID */
+#define PORT_BRCM_TRUMANAGE 24
+#define PORT_MAX_8250 24 /* max port ID */
/*
* ARM specific type numbers. These are not currently guaranteed