summaryrefslogtreecommitdiff
path: root/drivers/tty/serial/8250
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial/8250')
-rw-r--r--drivers/tty/serial/8250/8250_bcm7271.c4
-rw-r--r--drivers/tty/serial/8250/8250_dw.c5
-rw-r--r--drivers/tty/serial/8250/8250_early.c1
-rw-r--r--drivers/tty/serial/8250/8250_ingenic.c1
-rw-r--r--drivers/tty/serial/8250/8250_men_mcb.c212
-rw-r--r--drivers/tty/serial/8250/8250_omap.c1
-rw-r--r--drivers/tty/serial/8250/8250_pci.c10
-rw-r--r--drivers/tty/serial/8250/8250_port.c11
-rw-r--r--drivers/tty/serial/8250/8250_pxa.c1
9 files changed, 180 insertions, 66 deletions
diff --git a/drivers/tty/serial/8250/8250_bcm7271.c b/drivers/tty/serial/8250/8250_bcm7271.c
index d4b05d7ad9e8..aa5aff046756 100644
--- a/drivers/tty/serial/8250/8250_bcm7271.c
+++ b/drivers/tty/serial/8250/8250_bcm7271.c
@@ -1042,7 +1042,7 @@ static int brcmuart_probe(struct platform_device *pdev)
dev_dbg(dev, "DMA is %senabled\n", priv->dma_enabled ? "" : "not ");
memset(&up, 0, sizeof(up));
- up.port.type = PORT_16550A;
+ up.port.type = PORT_BCM7271;
up.port.uartclk = clk_rate;
up.port.dev = dev;
up.port.mapbase = mapbase;
@@ -1056,8 +1056,6 @@ static int brcmuart_probe(struct platform_device *pdev)
| UPF_FIXED_PORT | UPF_FIXED_TYPE;
up.port.dev = dev;
up.port.private_data = priv;
- up.capabilities = UART_CAP_FIFO | UART_CAP_AFE;
- up.port.fifosize = 32;
/* Check for a fixed line number */
ret = of_alias_get_id(np, "serial");
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 7db51781289e..f4cafca1a7da 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -523,7 +523,10 @@ static int dw8250_probe(struct platform_device *pdev)
if (!regs)
return dev_err_probe(dev, -EINVAL, "no registers defined\n");
- irq = platform_get_irq(pdev, 0);
+ irq = platform_get_irq_optional(pdev, 0);
+ /* no interrupt -> fall back to polling */
+ if (irq == -ENXIO)
+ irq = 0;
if (irq < 0)
return irq;
diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c
index 4299a8bd83d9..9837a27739fd 100644
--- a/drivers/tty/serial/8250/8250_early.c
+++ b/drivers/tty/serial/8250/8250_early.c
@@ -27,7 +27,6 @@
#include <linux/init.h>
#include <linux/console.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/serial_reg.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c
index 617b8ce60d6b..4c4c4da73ad0 100644
--- a/drivers/tty/serial/8250/8250_ingenic.c
+++ b/drivers/tty/serial/8250/8250_ingenic.c
@@ -13,7 +13,6 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
-#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
#include <linux/serial_core.h>
diff --git a/drivers/tty/serial/8250/8250_men_mcb.c b/drivers/tty/serial/8250/8250_men_mcb.c
index f46ca13ff4aa..dc9e093b1cb3 100644
--- a/drivers/tty/serial/8250/8250_men_mcb.c
+++ b/drivers/tty/serial/8250/8250_men_mcb.c
@@ -12,11 +12,42 @@
#define MEN_UART_ID_Z057 0x39
#define MEN_UART_ID_Z125 0x7d
-#define MEN_UART_MEM_SIZE 0x10
+/*
+ * IP Cores Z025 and Z057 can have up to 4 UART
+ * The UARTs available are stored in a global
+ * register saved in physical address + 0x40
+ * Is saved as follows:
+ *
+ * 7 0
+ * +------+-------+-------+-------+-------+-------+-------+-------+
+ * |UART4 | UART3 | UART2 | UART1 | U4irq | U3irq | U2irq | U1irq |
+ * +------+-------+-------+-------+-------+-------+-------+-------+
+ */
+#define MEN_UART1_MASK 0x01
+#define MEN_UART2_MASK 0x02
+#define MEN_UART3_MASK 0x04
+#define MEN_UART4_MASK 0x08
+
+#define MEN_Z125_UARTS_AVAILABLE 0x01
+
+#define MEN_Z025_MAX_UARTS 4
+#define MEN_UART_MEM_SIZE 0x10
+#define MEM_UART_REGISTER_SIZE 0x01
+#define MEN_Z025_REGISTER_OFFSET 0x40
+
+#define MEN_UART1_OFFSET 0
+#define MEN_UART2_OFFSET (MEN_UART1_OFFSET + MEN_UART_MEM_SIZE)
+#define MEN_UART3_OFFSET (MEN_UART2_OFFSET + MEN_UART_MEM_SIZE)
+#define MEN_UART4_OFFSET (MEN_UART3_OFFSET + MEN_UART_MEM_SIZE)
+
+#define MEN_READ_REGISTER(addr) readb(addr)
+
+#define MAX_PORTS 4
struct serial_8250_men_mcb_data {
- struct uart_8250_port uart;
- int line;
+ int num_ports;
+ int line[MAX_PORTS];
+ unsigned int offset[MAX_PORTS];
};
/*
@@ -37,10 +68,10 @@ static u32 men_lookup_uartclk(struct mcb_device *mdev)
clkval = 1041666;
else if (strncmp(mdev->bus->name, "F216", 4) == 0)
clkval = 1843200;
- else if (strncmp(mdev->bus->name, "G215", 4) == 0)
- clkval = 1843200;
else if (strncmp(mdev->bus->name, "F210", 4) == 0)
clkval = 115200;
+ else if (strstr(mdev->bus->name, "215"))
+ clkval = 1843200;
else
dev_info(&mdev->dev,
"board not detected, using default uartclk\n");
@@ -50,16 +81,98 @@ static u32 men_lookup_uartclk(struct mcb_device *mdev)
return clkval;
}
-static int get_num_ports(struct mcb_device *mdev,
- void __iomem *membase)
+static int read_uarts_available_from_register(struct resource *mem_res,
+ u8 *uarts_available)
+{
+ void __iomem *mem;
+ int reg_value;
+
+ if (!request_mem_region(mem_res->start + MEN_Z025_REGISTER_OFFSET,
+ MEM_UART_REGISTER_SIZE, KBUILD_MODNAME)) {
+ return -EBUSY;
+ }
+
+ mem = ioremap(mem_res->start + MEN_Z025_REGISTER_OFFSET,
+ MEM_UART_REGISTER_SIZE);
+ if (!mem) {
+ release_mem_region(mem_res->start + MEN_Z025_REGISTER_OFFSET,
+ MEM_UART_REGISTER_SIZE);
+ return -ENOMEM;
+ }
+
+ reg_value = MEN_READ_REGISTER(mem);
+
+ iounmap(mem);
+
+ release_mem_region(mem_res->start + MEN_Z025_REGISTER_OFFSET,
+ MEM_UART_REGISTER_SIZE);
+
+ *uarts_available = reg_value >> 4;
+
+ return 0;
+}
+
+static int read_serial_data(struct mcb_device *mdev,
+ struct resource *mem_res,
+ struct serial_8250_men_mcb_data *serial_data)
+{
+ u8 uarts_available;
+ int count = 0;
+ int mask;
+ int res;
+ int i;
+
+ res = read_uarts_available_from_register(mem_res, &uarts_available);
+ if (res < 0)
+ return res;
+
+ for (i = 0; i < MAX_PORTS; i++) {
+ mask = 0x1 << i;
+ switch (uarts_available & mask) {
+ case MEN_UART1_MASK:
+ serial_data->offset[count] = MEN_UART1_OFFSET;
+ count++;
+ break;
+ case MEN_UART2_MASK:
+ serial_data->offset[count] = MEN_UART2_OFFSET;
+ count++;
+ break;
+ case MEN_UART3_MASK:
+ serial_data->offset[count] = MEN_UART3_OFFSET;
+ count++;
+ break;
+ case MEN_UART4_MASK:
+ serial_data->offset[count] = MEN_UART4_OFFSET;
+ count++;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ if (count <= 0 || count > MAX_PORTS) {
+ dev_err(&mdev->dev, "unexpected number of ports: %u\n",
+ count);
+ return -ENODEV;
+ }
+
+ serial_data->num_ports = count;
+
+ return 0;
+}
+
+static int init_serial_data(struct mcb_device *mdev,
+ struct resource *mem_res,
+ struct serial_8250_men_mcb_data *serial_data)
{
switch (mdev->id) {
case MEN_UART_ID_Z125:
- return 1U;
+ serial_data->num_ports = 1;
+ serial_data->offset[0] = 0;
+ return 0;
case MEN_UART_ID_Z025:
- return readb(membase) >> 4;
case MEN_UART_ID_Z057:
- return 4U;
+ return read_serial_data(mdev, mem_res, serial_data);
default:
dev_err(&mdev->dev, "no supported device!\n");
return -ENODEV;
@@ -69,62 +182,54 @@ static int get_num_ports(struct mcb_device *mdev,
static int serial_8250_men_mcb_probe(struct mcb_device *mdev,
const struct mcb_device_id *id)
{
+ struct uart_8250_port uart;
struct serial_8250_men_mcb_data *data;
struct resource *mem;
- int num_ports;
int i;
- void __iomem *membase;
+ int res;
mem = mcb_get_resource(mdev, IORESOURCE_MEM);
if (mem == NULL)
return -ENXIO;
- membase = devm_ioremap_resource(&mdev->dev, mem);
- if (IS_ERR(membase))
- return PTR_ERR_OR_ZERO(membase);
-
- num_ports = get_num_ports(mdev, membase);
- dev_dbg(&mdev->dev, "found a 16z%03u with %u ports\n",
- mdev->id, num_ports);
-
- if (num_ports <= 0 || num_ports > 4) {
- dev_err(&mdev->dev, "unexpected number of ports: %u\n",
- num_ports);
- return -ENODEV;
- }
-
- data = devm_kcalloc(&mdev->dev, num_ports,
+ data = devm_kzalloc(&mdev->dev,
sizeof(struct serial_8250_men_mcb_data),
GFP_KERNEL);
if (!data)
return -ENOMEM;
+ res = init_serial_data(mdev, mem, data);
+ if (res < 0)
+ return res;
+
+ dev_dbg(&mdev->dev, "found a 16z%03u with %u ports\n",
+ mdev->id, data->num_ports);
+
mcb_set_drvdata(mdev, data);
- for (i = 0; i < num_ports; i++) {
- data[i].uart.port.dev = mdev->dma_dev;
- spin_lock_init(&data[i].uart.port.lock);
-
- data[i].uart.port.type = PORT_16550;
- data[i].uart.port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ
- | UPF_FIXED_TYPE;
- data[i].uart.port.iotype = UPIO_MEM;
- data[i].uart.port.uartclk = men_lookup_uartclk(mdev);
- data[i].uart.port.regshift = 0;
- data[i].uart.port.irq = mcb_get_irq(mdev);
- data[i].uart.port.membase = membase;
- data[i].uart.port.fifosize = 60;
- data[i].uart.port.mapbase = (unsigned long) mem->start
- + i * MEN_UART_MEM_SIZE;
- data[i].uart.port.iobase = data[i].uart.port.mapbase;
+ for (i = 0; i < data->num_ports; i++) {
+ memset(&uart, 0, sizeof(struct uart_8250_port));
+ spin_lock_init(&uart.port.lock);
+
+ uart.port.flags = UPF_SKIP_TEST |
+ UPF_SHARE_IRQ |
+ UPF_BOOT_AUTOCONF |
+ UPF_IOREMAP;
+ uart.port.iotype = UPIO_MEM;
+ uart.port.uartclk = men_lookup_uartclk(mdev);
+ uart.port.irq = mcb_get_irq(mdev);
+ uart.port.mapbase = (unsigned long) mem->start
+ + data->offset[i];
/* ok, register the port */
- data[i].line = serial8250_register_8250_port(&data[i].uart);
- if (data[i].line < 0) {
+ res = serial8250_register_8250_port(&uart);
+ if (res < 0) {
dev_err(&mdev->dev, "unable to register UART port\n");
- return data[i].line;
+ return res;
}
- dev_info(&mdev->dev, "found MCB UART: ttyS%d\n", data[i].line);
+
+ data->line[i] = res;
+ dev_info(&mdev->dev, "found MCB UART: ttyS%d\n", data->line[i]);
}
return 0;
@@ -132,20 +237,14 @@ static int serial_8250_men_mcb_probe(struct mcb_device *mdev,
static void serial_8250_men_mcb_remove(struct mcb_device *mdev)
{
- int num_ports, i;
+ int i;
struct serial_8250_men_mcb_data *data = mcb_get_drvdata(mdev);
if (!data)
return;
- num_ports = get_num_ports(mdev, data[0].uart.port.membase);
- if (num_ports <= 0 || num_ports > 4) {
- dev_err(&mdev->dev, "error retrieving number of ports!\n");
- return;
- }
-
- for (i = 0; i < num_ports; i++)
- serial8250_unregister_port(data[i].line);
+ for (i = 0; i < data->num_ports; i++)
+ serial8250_unregister_port(data->line[i]);
}
static const struct mcb_device_id serial_8250_men_mcb_ids[] = {
@@ -159,7 +258,6 @@ MODULE_DEVICE_TABLE(mcb, serial_8250_men_mcb_ids);
static struct mcb_driver mcb_driver = {
.driver = {
.name = "8250_men_mcb",
- .owner = THIS_MODULE,
},
.probe = serial_8250_men_mcb_probe,
.remove = serial_8250_men_mcb_remove,
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
index d48a82f1634e..26dd089d8e82 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -18,7 +18,6 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/delay.h>
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
index d2d547b5da95..62a9bd30b4db 100644
--- a/drivers/tty/serial/8250/8250_pci.c
+++ b/drivers/tty/serial/8250/8250_pci.c
@@ -67,6 +67,8 @@ static const struct pci_device_id pci_use_msi[] = {
0xA000, 0x1000) },
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9922,
0xA000, 0x1000) },
+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ASIX, PCI_DEVICE_ID_ASIX_AX99100,
+ 0xA000, 0x1000) },
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_HP_3PAR, PCI_DEVICE_ID_HPE_PCI_SERIAL,
PCI_ANY_ID, PCI_ANY_ID) },
{ }
@@ -5557,6 +5559,14 @@ static const struct pci_device_id serial_pci_tbl[] = {
{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865,
0xA000, 0x3004,
0, 0, pbn_b0_bt_4_115200 },
+
+ /*
+ * ASIX AX99100 PCIe to Multi I/O Controller
+ */
+ { PCI_VENDOR_ID_ASIX, PCI_DEVICE_ID_ASIX_AX99100,
+ 0xA000, 0x1000,
+ 0, 0, pbn_b0_1_115200 },
+
/* Intel CE4100 */
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CE4100_UART,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index 483bb552cdc4..fb891b67968f 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -322,6 +322,14 @@ static const struct serial8250_config uart_config[] = {
.rxtrig_bytes = {2, 66, 130, 194},
.flags = UART_CAP_FIFO,
},
+ [PORT_BCM7271] = {
+ .name = "Broadcom BCM7271 UART",
+ .fifo_size = 32,
+ .tx_loadsz = 32,
+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01,
+ .rxtrig_bytes = {1, 8, 16, 30},
+ .flags = UART_CAP_FIFO | UART_CAP_AFE,
+ },
};
/* Uart divisor latch read */
@@ -1703,8 +1711,7 @@ static void serial8250_enable_ms(struct uart_port *port)
void serial8250_read_char(struct uart_8250_port *up, u16 lsr)
{
struct uart_port *port = &up->port;
- unsigned char ch;
- char flag = TTY_NORMAL;
+ u8 ch, flag = TTY_NORMAL;
if (likely(lsr & UART_LSR_DR))
ch = serial_in(up, UART_RX);
diff --git a/drivers/tty/serial/8250/8250_pxa.c b/drivers/tty/serial/8250/8250_pxa.c
index 28b341f602c6..a5b3ea27fc90 100644
--- a/drivers/tty/serial/8250/8250_pxa.c
+++ b/drivers/tty/serial/8250/8250_pxa.c
@@ -183,6 +183,7 @@ static int __init early_serial_pxa_setup(struct earlycon_device *device,
return early_serial8250_setup(device, NULL);
}
OF_EARLYCON_DECLARE(early_pxa, "mrvl,pxa-uart", early_serial_pxa_setup);
+OF_EARLYCON_DECLARE(mmp, "mrvl,mmp-uart", early_serial_pxa_setup);
#endif
MODULE_AUTHOR("Sergei Ianovich");