diff options
Diffstat (limited to 'drivers/tty/serial/8250')
-rw-r--r-- | drivers/tty/serial/8250/8250_bcm7271.c | 4 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_dw.c | 5 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_early.c | 1 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_ingenic.c | 1 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_men_mcb.c | 212 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_omap.c | 1 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_pci.c | 10 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_port.c | 11 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_pxa.c | 1 |
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"); |