diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-01 16:55:57 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-01 16:55:57 -0700 |
commit | cb1595563880a81dab6eab9a5ecb4520d2e76077 (patch) | |
tree | 042907fc859287a40a454d57c034015742e38cbf | |
parent | c12e69c6aaf785fd307d05cb6f36ca0e7577ead7 (diff) | |
parent | 3a13884abea08a5043b98d9374486ec859d1e03a (diff) |
Merge tag 'tty-3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial driver update from Greg KH:
"Here's the big tty/serial driver update for 3.15-rc1.
Nothing major, a number of serial driver updates and a few tty core
fixes as well.
All have been in linux-next for a while"
* tag 'tty-3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (71 commits)
tty/serial: omap: empty the RX FIFO at the end of half-duplex TX
tty/serial: omap: fix RX interrupt enable/disable in half-duplex TX
serial: sh-sci: Neaten dev_<level> uses
serial: sh-sci: Replace hardcoded 3 by UART_PM_STATE_OFF
serial: sh-sci: Add more register documentation
serial: sh-sci: Remove useless casts
serial: sh-sci: Replace printk() by pr_*()
serial_core: Avoid NULL pointer dereference in uart_close()
serial_core: Get a reference for port->tty in uart_remove_one_port()
serial: clps711x: Give a chance to perform useful tasks during wait loop
serial_core: Grammar s/ports/port's/
serial_core: Spelling s/contro/control/
serial: efm32: properly namespace location property
serial: max310x: Add missing #include <linux/uaccess.h>
synclink: fix info leak in ioctl
serial: 8250: Clean up the locking for -rt
serial: 8250_pci: change BayTrail default uartclk
serial: 8250_pci: more BayTrail error-free bauds
serial: sh-sci: Add missing call to uart_remove_one_port() in failure path
serial_core: Unregister console in uart_remove_one_port()
...
43 files changed, 1233 insertions, 847 deletions
diff --git a/Documentation/devicetree/bindings/serial/efm32-uart.txt b/Documentation/devicetree/bindings/serial/efm32-uart.txt index 8e080b893b49..1984bdfbd545 100644 --- a/Documentation/devicetree/bindings/serial/efm32-uart.txt +++ b/Documentation/devicetree/bindings/serial/efm32-uart.txt @@ -6,7 +6,7 @@ Required properties: - interrupts : Should contain uart interrupt Optional properties: -- location : Decides the location of the USART I/O pins. +- efm32,location : Decides the location of the USART I/O pins. Allowed range : [0 .. 5] Default: 0 @@ -16,5 +16,5 @@ uart@0x4000c400 { compatible = "efm32,uart"; reg = <0x4000c400 0x400>; interrupts = <15>; - location = <0>; + efm32,location = <0>; }; diff --git a/Documentation/devicetree/bindings/serial/fsl-lpuart.txt b/Documentation/devicetree/bindings/serial/fsl-lpuart.txt index 6fd1dd1638dd..a1d1205d8185 100644 --- a/Documentation/devicetree/bindings/serial/fsl-lpuart.txt +++ b/Documentation/devicetree/bindings/serial/fsl-lpuart.txt @@ -4,11 +4,24 @@ Required properties: - compatible : Should be "fsl,<soc>-lpuart" - reg : Address and length of the register set for the device - interrupts : Should contain uart interrupt +- clocks : phandle + clock specifier pairs, one for each entry in clock-names +- clock-names : should contain: "ipg" - the uart clock + +Optional properties: +- dmas: A list of two dma specifiers, one for each entry in dma-names. +- dma-names: should contain "tx" and "rx". + +Note: Optional properties for DMA support. Write them both or both not. Example: uart0: serial@40027000 { - compatible = "fsl,vf610-lpuart"; - reg = <0x40027000 0x1000>; - interrupts = <0 61 0x00>; - }; + compatible = "fsl,vf610-lpuart"; + reg = <0x40027000 0x1000>; + interrupts = <0 61 0x00>; + clocks = <&clks VF610_CLK_UART0>; + clock-names = "ipg"; + dmas = <&edma0 0 2>, + <&edma0 0 3>; + dma-names = "rx","tx"; + }; diff --git a/Documentation/devicetree/bindings/serial/maxim,max310x.txt b/Documentation/devicetree/bindings/serial/maxim,max310x.txt new file mode 100644 index 000000000000..83a919c241b0 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/maxim,max310x.txt @@ -0,0 +1,36 @@ +* Maxim MAX310X advanced Universal Asynchronous Receiver-Transmitter (UART) + +Required properties: +- compatible: Should be one of the following: + - "maxim,max3107" for Maxim MAX3107, + - "maxim,max3108" for Maxim MAX3108, + - "maxim,max3109" for Maxim MAX3109, + - "maxim,max14830" for Maxim MAX14830. +- reg: SPI chip select number. +- interrupt-parent: The phandle for the interrupt controller that + services interrupts for this IC. +- interrupts: Specifies the interrupt source of the parent interrupt + controller. The format of the interrupt specifier depends on the + parent interrupt controller. +- clocks: phandle to the IC source clock. +- clock-names: Should be "xtal" if clock is an external crystal or + "osc" if an external clock source is used. + +Optional properties: +- gpio-controller: Marks the device node as a GPIO controller. +- #gpio-cells: Should be two. The first cell is the GPIO number and + the second cell is used to specify the GPIO polarity: + 0 = active high, + 1 = active low. + +Example: + max14830: max14830@0 { + compatible = "maxim,max14830"; + reg = <0>; + clocks = <&clk20m>; + clock-names = "osc"; + interrupt-parent = <&gpio3>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + gpio-controller; + #gpio-cells = <2>; + }; diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt index f372cf29068d..53e6c175db6c 100644 --- a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt @@ -37,7 +37,7 @@ Example: }; scifa0: serial@e6c40000 { - compatible = "renesas,scifa-r8a7790", "renesas,scifa-generic"; + compatible = "renesas,scifa-r8a7790", "renesas,scifa"; reg = <0 0xe6c40000 0 64>; interrupt-parent = <&gic>; interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; diff --git a/arch/arm/boot/dts/atlas6.dtsi b/arch/arm/boot/dts/atlas6.dtsi index f8674bcc4489..0c81dc945aed 100644 --- a/arch/arm/boot/dts/atlas6.dtsi +++ b/arch/arm/boot/dts/atlas6.dtsi @@ -217,8 +217,8 @@ interrupts = <17>; fifosize = <128>; clocks = <&clks 13>; - sirf,uart-dma-rx-channel = <21>; - sirf,uart-dma-tx-channel = <2>; + dmas = <&dmac1 5>, <&dmac0 2>; + dma-names = "rx", "tx"; }; uart1: uart@b0060000 { @@ -228,6 +228,7 @@ interrupts = <18>; fifosize = <32>; clocks = <&clks 14>; + dma-names = "no-rx", "no-tx"; }; uart2: uart@b0070000 { @@ -237,8 +238,8 @@ interrupts = <19>; fifosize = <128>; clocks = <&clks 15>; - sirf,uart-dma-rx-channel = <6>; - sirf,uart-dma-tx-channel = <7>; + dmas = <&dmac0 6>, <&dmac0 7>; + dma-names = "rx", "tx"; }; usp0: usp@b0080000 { @@ -248,8 +249,8 @@ interrupts = <20>; fifosize = <128>; clocks = <&clks 28>; - sirf,usp-dma-rx-channel = <17>; - sirf,usp-dma-tx-channel = <18>; + dmas = <&dmac1 1>, <&dmac1 2>; + dma-names = "rx", "tx"; }; usp1: usp@b0090000 { @@ -259,8 +260,8 @@ interrupts = <21>; fifosize = <128>; clocks = <&clks 29>; - sirf,usp-dma-rx-channel = <14>; - sirf,usp-dma-tx-channel = <15>; + dmas = <&dmac0 14>, <&dmac0 15>; + dma-names = "rx", "tx"; }; dmac0: dma-controller@b00b0000 { diff --git a/arch/arm/boot/dts/prima2.dtsi b/arch/arm/boot/dts/prima2.dtsi index 0e219932d7cc..8582ae41a583 100644 --- a/arch/arm/boot/dts/prima2.dtsi +++ b/arch/arm/boot/dts/prima2.dtsi @@ -223,8 +223,8 @@ interrupts = <17>; fifosize = <128>; clocks = <&clks 13>; - sirf,uart-dma-rx-channel = <21>; - sirf,uart-dma-tx-channel = <2>; + dmas = <&dmac1 5>, <&dmac0 2>; + dma-names = "rx", "tx"; }; uart1: uart@b0060000 { @@ -243,8 +243,8 @@ interrupts = <19>; fifosize = <128>; clocks = <&clks 15>; - sirf,uart-dma-rx-channel = <6>; - sirf,uart-dma-tx-channel = <7>; + dmas = <&dmac0 6>, <&dmac0 7>; + dma-names = "rx", "tx"; }; usp0: usp@b0080000 { @@ -254,8 +254,8 @@ interrupts = <20>; fifosize = <128>; clocks = <&clks 28>; - sirf,usp-dma-rx-channel = <17>; - sirf,usp-dma-tx-channel = <18>; + dmas = <&dmac1 1>, <&dmac1 2>; + dma-names = "rx", "tx"; }; usp1: usp@b0090000 { @@ -265,8 +265,8 @@ interrupts = <21>; fifosize = <128>; clocks = <&clks 29>; - sirf,usp-dma-rx-channel = <14>; - sirf,usp-dma-tx-channel = <15>; + dmas = <&dmac0 14>, <&dmac0 15>; + dma-names = "rx", "tx"; }; usp2: usp@b00a0000 { @@ -276,8 +276,8 @@ interrupts = <22>; fifosize = <128>; clocks = <&clks 30>; - sirf,usp-dma-rx-channel = <10>; - sirf,usp-dma-tx-channel = <11>; + dmas = <&dmac0 10>, <&dmac0 11>; + dma-names = "rx", "tx"; }; dmac0: dma-controller@b00b0000 { diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c index b3738e616f19..8f45afe785f8 100644 --- a/arch/arm/mach-imx/mach-mx31moboard.c +++ b/arch/arm/mach-imx/mach-mx31moboard.c @@ -128,27 +128,15 @@ static struct platform_device mx31moboard_flash = { .num_resources = 1, }; -static int moboard_uart0_init(struct platform_device *pdev) +static void __init moboard_uart0_init(void) { - int ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_CTS1), "uart0-cts-hack"); - if (ret) - return ret; - - ret = gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CTS1), 0); - if (ret) + if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_CTS1), "uart0-cts-hack")) { + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CTS1), 0); gpio_free(IOMUX_TO_GPIO(MX31_PIN_CTS1)); - - return ret; -} - -static void moboard_uart0_exit(struct platform_device *pdev) -{ - gpio_free(IOMUX_TO_GPIO(MX31_PIN_CTS1)); + } } static const struct imxuart_platform_data uart0_pdata __initconst = { - .init = moboard_uart0_init, - .exit = moboard_uart0_exit, }; static const struct imxuart_platform_data uart4_pdata __initconst = { @@ -543,6 +531,7 @@ static void __init mx31moboard_init(void) imx31_add_imx2_wdt(); + moboard_uart0_init(); imx31_add_imx_uart0(&uart0_pdata); imx31_add_imx_uart4(&uart4_pdata); diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index 50b46881b6ca..94f9e3a38412 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -31,6 +31,7 @@ #include <linux/list.h> #include <linux/module.h> #include <linux/major.h> +#include <linux/atomic.h> #include <linux/sysrq.h> #include <linux/tty.h> #include <linux/tty_flip.h> @@ -70,6 +71,9 @@ static struct task_struct *hvc_task; /* Picks up late kicks after list walk but before schedule() */ static int hvc_kicked; +/* hvc_init is triggered from hvc_alloc, i.e. only when actually used */ +static atomic_t hvc_needs_init __read_mostly = ATOMIC_INIT(-1); + static int hvc_init(void); #ifdef CONFIG_MAGIC_SYSRQ @@ -851,7 +855,7 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data, int i; /* We wait until a driver actually comes along */ - if (!hvc_driver) { + if (atomic_inc_not_zero(&hvc_needs_init)) { int err = hvc_init(); if (err) return ERR_PTR(err); diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index ebd5bff0f5c1..17ee3bf0926b 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c @@ -176,9 +176,6 @@ void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data, ": %d chars not inserted to flip buffer!\n", length - work); - /* - * This may sleep if ->low_latency is set - */ if (work) tty_flip_buffer_push(&tty->port); } diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index d15624c1b751..41fe8a047d37 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1900,13 +1900,10 @@ static inline int input_available_p(struct tty_struct *tty, int poll) struct n_tty_data *ldata = tty->disc_data; int amt = poll && !TIME_CHAR(tty) && MIN_CHAR(tty) ? MIN_CHAR(tty) : 1; - if (ldata->icanon && !L_EXTPROC(tty)) { - if (ldata->canon_head != ldata->read_tail) - return 1; - } else if (read_cnt(ldata) >= amt) - return 1; - - return 0; + if (ldata->icanon && !L_EXTPROC(tty)) + return ldata->canon_head != ldata->read_tail; + else + return read_cnt(ldata) >= amt; } /** diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 69932b7556cf..81f909c2101f 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -1694,6 +1694,10 @@ static int serial_link_irq_chain(struct uart_8250_port *up) static void serial_unlink_irq_chain(struct uart_8250_port *up) { + /* + * yes, some broken gcc emit "warning: 'i' may be used uninitialized" + * but no, we are not going to take a patch that assigns NULL below. + */ struct irq_info *i; struct hlist_node *n; struct hlist_head *h; @@ -2882,14 +2886,10 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) touch_nmi_watchdog(); - local_irq_save(flags); - if (port->sysrq) { - /* serial8250_handle_irq() already took the lock */ - locked = 0; - } else if (oops_in_progress) { - locked = spin_trylock(&port->lock); - } else - spin_lock(&port->lock); + if (port->sysrq || oops_in_progress) + locked = spin_trylock_irqsave(&port->lock, flags); + else + spin_lock_irqsave(&port->lock, flags); /* * First save the IER then disable the interrupts @@ -2921,8 +2921,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) serial8250_modem_status(up); if (locked) - spin_unlock(&port->lock); - local_irq_restore(flags); + spin_unlock_irqrestore(&port->lock, flags); } static int __init serial8250_console_setup(struct console *co, char *options) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 0ff3e3624d4c..b14bcba96c25 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1366,23 +1366,44 @@ byt_set_termios(struct uart_port *p, struct ktermios *termios, struct ktermios *old) { unsigned int baud = tty_termios_baud_rate(termios); - unsigned int m = 6912; - unsigned int n = 15625; + unsigned int m, n; u32 reg; - /* For baud rates 1M, 2M, 3M and 4M the dividers must be adjusted. */ - if (baud == 1000000 || baud == 2000000 || baud == 4000000) { + /* + * For baud rates 0.5M, 1M, 1.5M, 2M, 2.5M, 3M, 3.5M and 4M the + * dividers must be adjusted. + * + * uartclk = (m / n) * 100 MHz, where m <= n + */ + switch (baud) { + case 500000: + case 1000000: + case 2000000: + case 4000000: m = 64; n = 100; - p->uartclk = 64000000; - } else if (baud == 3000000) { + break; + case 3500000: + m = 56; + n = 100; + p->uartclk = 56000000; + break; + case 1500000: + case 3000000: m = 48; n = 100; - p->uartclk = 48000000; - } else { - p->uartclk = 44236800; + break; + case 2500000: + m = 40; + n = 100; + p->uartclk = 40000000; + break; + default: + m = 2304; + n = 3125; + p->uartclk = 73728000; } /* Reset the clock */ @@ -3449,6 +3470,10 @@ static struct pciserial_board pci_boards[] = { .base_baud = 921600, .reg_shift = 2, }, + /* + * Intel BayTrail HSUART reference clock is 44.2368 MHz at power-on, + * but is overridden by byt_set_termios. + */ [pbn_byt] = { .flags = FL_BASE0, .num_ports = 1, diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index a3815eaed421..2577d67bacb2 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -289,7 +289,7 @@ config SERIAL_MAX3100 MAX3100 chip support config SERIAL_MAX310X - bool "MAX310X support" + tristate "MAX310X support" depends on SPI_MASTER select SERIAL_CORE select REGMAP_SPI if SPI_MASTER @@ -708,7 +708,7 @@ config SERIAL_IP22_ZILOG_CONSOLE config SERIAL_SH_SCI tristate "SuperH SCI(F) serial port support" - depends on HAVE_CLK && (SUPERH || ARM || COMPILE_TEST) + depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST select SERIAL_CORE config SERIAL_SH_SCI_NR_UARTS diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index d58783d364e3..d4eda24aa68b 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -2154,9 +2154,19 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) amba_ports[i] = uap; amba_set_drvdata(dev, uap); + + if (!amba_reg.state) { + ret = uart_register_driver(&amba_reg); + if (ret < 0) { + pr_err("Failed to register AMBA-PL011 driver\n"); + return ret; + } + } + ret = uart_add_one_port(&amba_reg, &uap->port); if (ret) { amba_ports[i] = NULL; + uart_unregister_driver(&amba_reg); pl011_dma_remove(uap); } out: @@ -2175,6 +2185,7 @@ static int pl011_remove(struct amba_device *dev) amba_ports[i] = NULL; pl011_dma_remove(uap); + uart_unregister_driver(&amba_reg); return 0; } @@ -2230,22 +2241,14 @@ static struct amba_driver pl011_driver = { static int __init pl011_init(void) { - int ret; printk(KERN_INFO "Serial: AMBA PL011 UART driver\n"); - ret = uart_register_driver(&amba_reg); - if (ret == 0) { - ret = amba_driver_register(&pl011_driver); - if (ret) - uart_unregister_driver(&amba_reg); - } - return ret; + return amba_driver_register(&pl011_driver); } static void __exit pl011_exit(void) { amba_driver_unregister(&pl011_driver); - uart_unregister_driver(&amba_reg); } /* diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index a49f10d269b2..b0603e1f7d82 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -115,9 +115,6 @@ static void atmel_stop_rx(struct uart_port *port); #define UART_PUT_TCR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_TCR) #define UART_GET_TCR(port) __raw_readl((port)->membase + ATMEL_PDC_TCR) -static int (*atmel_open_hook)(struct uart_port *); -static void (*atmel_close_hook)(struct uart_port *); - struct atmel_dma_buffer { unsigned char *buf; dma_addr_t dma_addr; @@ -1555,7 +1552,7 @@ static int atmel_startup(struct uart_port *port) retval = request_irq(port->irq, atmel_interrupt, IRQF_SHARED, tty ? tty->name : "atmel_serial", port); if (retval) { - printk("atmel_serial: atmel_startup - Can't get irq\n"); + dev_err(port->dev, "atmel_startup - Can't get irq\n"); return retval; } @@ -1575,17 +1572,6 @@ static int atmel_startup(struct uart_port *port) if (retval < 0) atmel_set_ops(port); } - /* - * If there is a specific "open" function (to register - * control line interrupts) - */ - if (atmel_open_hook) { - retval = atmel_open_hook(port); - if (retval) { - free_irq(port->irq, port); - return retval; - } - } /* Save current CSR for comparison in atmel_tasklet_func() */ atmel_port->irq_status_prev = UART_GET_CSR(port); @@ -1684,13 +1670,6 @@ static void atmel_shutdown(struct uart_port *port) * Free the interrupt */ free_irq(port->irq, port); - - /* - * If there is a specific "close" function (to unregister - * control line interrupts) - */ - if (atmel_close_hook) - atmel_close_hook(port); } /* @@ -1738,7 +1717,7 @@ static void atmel_serial_pm(struct uart_port *port, unsigned int state, clk_disable_unprepare(atmel_port->clk); break; default: - printk(KERN_ERR "atmel_serial: unknown pm %d\n", state); + dev_err(port->dev, "atmel_serial: unknown pm %d\n", state); } } @@ -1853,13 +1832,10 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, mode &= ~ATMEL_US_USMODE; if (atmel_port->rs485.flags & SER_RS485_ENABLED) { - dev_dbg(port->dev, "Setting UART to RS485\n"); if ((atmel_port->rs485.delay_rts_after_send) > 0) UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_after_send); mode |= ATMEL_US_USMODE_RS485; - } else { - dev_dbg(port->dev, "Setting UART to RS232\n"); } /* set the parity, stop bits and data size */ diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index 78e82b017b92..a47421e4627c 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c @@ -30,6 +30,8 @@ #include <linux/serial.h> #include <linux/serial_core.h> #include <linux/serial_bcm63xx.h> +#include <linux/io.h> +#include <linux/of.h> #define BCM63XX_NR_UARTS 2 @@ -588,7 +590,7 @@ static int bcm_uart_request_port(struct uart_port *port) { unsigned int size; - size = RSET_UART_SIZE; + size = UART_REG_SIZE; if (!request_mem_region(port->mapbase, size, "bcm63xx")) { dev_err(port->dev, "Memory region busy\n"); return -EBUSY; @@ -608,7 +610,7 @@ static int bcm_uart_request_port(struct uart_port *port) */ static void bcm_uart_release_port(struct uart_port *port) { - release_mem_region(port->mapbase, RSET_UART_SIZE); + release_mem_region(port->mapbase, UART_REG_SIZE); iounmap(port->membase); } @@ -805,6 +807,9 @@ static int bcm_uart_probe(struct platform_device *pdev) struct clk *clk; int ret; + if (pdev->dev.of_node) + pdev->id = of_alias_get_id(pdev->dev.of_node, "uart"); + if (pdev->id < 0 || pdev->id >= BCM63XX_NR_UARTS) return -EINVAL; @@ -856,6 +861,12 @@ static int bcm_uart_remove(struct platform_device *pdev) return 0; } +static const struct of_device_id bcm63xx_of_match[] = { + { .compatible = "brcm,bcm6345-uart" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, bcm63xx_of_match); + /* * platform driver stuff */ @@ -865,6 +876,7 @@ static struct platform_driver bcm_uart_platform_driver = { .driver = { .owner = THIS_MODULE, .name = "bcm63xx_uart", + .of_match_table = bcm63xx_of_match, }, }; diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index b0eacb83f831..5e6fdb1ea73b 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -368,11 +368,16 @@ static const struct uart_ops uart_clps711x_ops = { static void uart_clps711x_console_putchar(struct uart_port *port, int ch) { struct clps711x_port *s = dev_get_drvdata(port->dev); - u32 sysflg = 0; - do { + /* Wait for FIFO is not full */ + while (1) { + u32 sysflg = 0; + regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg); - } while (sysflg & SYSFLG_UTXFF); + if (!(sysflg & SYSFLG_UTXFF)) + break; + cond_resched(); + } writew(ch, port->membase + UARTDR_OFFSET); } @@ -382,14 +387,18 @@ static void uart_clps711x_console_write(struct console *co, const char *c, { struct uart_port *port = clps711x_uart.state[co->index].uart_port; struct clps711x_port *s = dev_get_drvdata(port->dev); - u32 sysflg = 0; uart_console_write(port, c, n, uart_clps711x_console_putchar); /* Wait for transmitter to become empty */ - do { + while (1) { + u32 sysflg = 0; + regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg); |