diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 13:41:04 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 13:41:04 -0800 |
commit | 21eaab6d19ed43e82ed39c8deb7f192134fb4a0e (patch) | |
tree | d995205afdcb7f47462bcd28067dc0c4ab0b7b02 /drivers/tty/serial/efm32-uart.c | |
parent | 74e1a2a39355b2d3ae8c60c78d8add162c6d7183 (diff) | |
parent | 9e17df37d710f8998e9cb10a548304fe33d4a5c2 (diff) |
Merge tag 'tty-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial patches from Greg Kroah-Hartman:
"Here's the big tty/serial driver patches for 3.9-rc1.
More tty port rework and fixes from Jiri here, as well as lots of
individual serial driver updates and fixes.
All of these have been in the linux-next tree for a while."
* tag 'tty-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (140 commits)
tty: mxser: improve error handling in mxser_probe() and mxser_module_init()
serial: imx: fix uninitialized variable warning
serial: tegra: assume CONFIG_OF
TTY: do not update atime/mtime on read/write
lguest: select CONFIG_TTY to build properly.
ARM defconfigs: add missing inclusions of linux/platform_device.h
fb/exynos: include platform_device.h
ARM: sa1100/assabet: include platform_device.h directly
serial: imx: Fix recursive locking bug
pps: Fix build breakage from decoupling pps from tty
tty: Remove ancient hardpps()
pps: Additional cleanups in uart_handle_dcd_change
pps: Move timestamp read into PPS code proper
pps: Don't crash the machine when exiting will do
pps: Fix a use-after free bug when unregistering a source.
pps: Use pps_lookup_dev to reduce ldisc coupling
pps: Add pps_lookup_dev() function
tty: serial: uartlite: Support uartlite on big and little endian systems
tty: serial: uartlite: Fix sparse and checkpatch warnings
serial/arc-uart: Miscll DT related updates (Grant's review comments)
...
Fix up trivial conflicts, mostly just due to the TTY config option
clashing with the EXPERIMENTAL removal.
Diffstat (limited to 'drivers/tty/serial/efm32-uart.c')
-rw-r--r-- | drivers/tty/serial/efm32-uart.c | 52 |
1 files changed, 31 insertions, 21 deletions
diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c index a8cbb2670521..7d199c8e1a75 100644 --- a/drivers/tty/serial/efm32-uart.c +++ b/drivers/tty/serial/efm32-uart.c @@ -81,6 +81,7 @@ struct efm32_uart_port { struct uart_port port; unsigned int txirq; struct clk *clk; + struct efm32_uart_pdata pdata; }; #define to_efm_port(_port) container_of(_port, struct efm32_uart_port, port) #define efm_debug(efm_port, format, arg...) \ @@ -194,8 +195,7 @@ static void efm32_uart_break_ctl(struct uart_port *port, int ctl) /* not possible without fiddling with gpios */ } -static void efm32_uart_rx_chars(struct efm32_uart_port *efm_port, - struct tty_struct *tty) +static void efm32_uart_rx_chars(struct efm32_uart_port *efm_port) { struct uart_port *port = &efm_port->port; @@ -237,8 +237,8 @@ static void efm32_uart_rx_chars(struct efm32_uart_port *efm_port, rxdata & UARTn_RXDATAX_RXDATA__MASK)) continue; - if (tty && (rxdata & port->ignore_status_mask) == 0) - tty_insert_flip_char(tty, + if ((rxdata & port->ignore_status_mask) == 0) + tty_insert_flip_char(&port->state->port, rxdata & UARTn_RXDATAX_RXDATA__MASK, flag); } } @@ -249,15 +249,13 @@ static irqreturn_t efm32_uart_rxirq(int irq, void *data) u32 irqflag = efm32_uart_read32(efm_port, UARTn_IF); int handled = IRQ_NONE; struct uart_port *port = &efm_port->port; - struct tty_struct *tty; + struct tty_port *tport = &port->state->port; spin_lock(&port->lock); - tty = tty_kref_get(port->state->port.tty); - if (irqflag & UARTn_IF_RXDATAV) { efm32_uart_write32(efm_port, UARTn_IF_RXDATAV, UARTn_IFC); - efm32_uart_rx_chars(efm_port, tty); + efm32_uart_rx_chars(efm_port); handled = IRQ_HANDLED; } @@ -265,16 +263,12 @@ static irqreturn_t efm32_uart_rxirq(int irq, void *data) if (irqflag & UARTn_IF_RXOF) { efm32_uart_write32(efm_port, UARTn_IF_RXOF, UARTn_IFC); port->icount.overrun++; - if (tty) - tty_insert_flip_char(tty, 0, TTY_OVERRUN); + tty_insert_flip_char(tport, 0, TTY_OVERRUN); handled = IRQ_HANDLED; } - if (tty) { - tty_flip_buffer_push(tty); - tty_kref_put(tty); - } + tty_flip_buffer_push(tport); spin_unlock(&port->lock); @@ -300,13 +294,8 @@ static irqreturn_t efm32_uart_txirq(int irq, void *data) static int efm32_uart_startup(struct uart_port *port) { struct efm32_uart_port *efm_port = to_efm_port(port); - u32 location = 0; - struct efm32_uart_pdata *pdata = dev_get_platdata(port->dev); int ret; - if (pdata) - location = UARTn_ROUTE_LOCATION(pdata->location); - ret = clk_enable(efm_port->clk); if (ret) { efm_debug(efm_port, "failed to enable clk\n"); @@ -315,7 +304,9 @@ static int efm32_uart_startup(struct uart_port *port) port->uartclk = clk_get_rate(efm_port->clk); /* Enable pins at configured location */ - efm32_uart_write32(efm_port, location | UARTn_ROUTE_RXPEN | UARTn_ROUTE_TXPEN, + efm32_uart_write32(efm_port, + UARTn_ROUTE_LOCATION(efm_port->pdata.location) | + UARTn_ROUTE_RXPEN | UARTn_ROUTE_TXPEN, UARTn_ROUTE); ret = request_irq(port->irq, efm32_uart_rxirq, 0, @@ -674,11 +665,24 @@ static int efm32_uart_probe_dt(struct platform_device *pdev, struct efm32_uart_port *efm_port) { struct device_node *np = pdev->dev.of_node; + u32 location; int ret; if (!np) return 1; + ret = of_property_read_u32(np, "location", &location); + if (!ret) { + if (location > 5) { + dev_err(&pdev->dev, "invalid location\n"); + return -EINVAL; + } + efm_debug(efm_port, "using location %u\n", location); + efm_port->pdata.location = location; + } else { + efm_debug(efm_port, "fall back to location 0\n"); + } + ret = of_alias_get_id(np, "serial"); if (ret < 0) { dev_err(&pdev->dev, "failed to get alias id: %d\n", ret); @@ -738,10 +742,16 @@ static int efm32_uart_probe(struct platform_device *pdev) efm_port->port.flags = UPF_BOOT_AUTOCONF; ret = efm32_uart_probe_dt(pdev, efm_port); - if (ret > 0) + if (ret > 0) { /* not created by device tree */ + const struct efm32_uart_pdata *pdata = dev_get_platdata(&pdev->dev); + efm_port->port.line = pdev->id; + if (pdata) + efm_port->pdata = *pdata; + } + if (efm_port->port.line >= 0 && efm_port->port.line < ARRAY_SIZE(efm32_uart_ports)) efm32_uart_ports[efm_port->port.line] = efm_port; |