When the user initializes the uart port, and waits for the transmit
engine to complete in lpuart32_set_termios(), if the UART TX fifo has
dirty data and the UARTMODIR enable the flow control, the TX fifo may
never be empty. So here we should disable the flow control first to make
sure the transmit engin can complete.
Fixes: 380c966c09 ("tty: serial: fsl_lpuart: add 32-bit register interface support")
Cc: stable <stable@kernel.org>
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
Link: https://lore.kernel.org/r/20220821101527.10066-1-sherry.sun@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The LPUART hardware doesn't zero out the parity bit on the received
characters. This behavior won't impact the use cases of CS8 because
the parity bit is the 9th bit which is not currently used by software.
But the parity bit for CS7 must be zeroed out by software in order to
get the correct raw data.
Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com>
Link: https://lore.kernel.org/r/20220714185858.615373-1-shenwei.wang@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Serial core handles serial_rs485 sanitization. Remove custom
sanitization from lpuart_config_rs485.
This change loses dev_err when SER_RS485_RX_DURING_TX is set due to
incorrect configuration. Other drivers do not do similar prinout for
full-duplex case and it should be done in serial core if it is
desirable to notify on this condition. Personally, I doesn't see it
important because the kernel gracefully downgrades to half-duplex.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Link: https://lore.kernel.org/r/20220606100433.13793-31-ilpo.jarvinen@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
A few serial drivers make a call to rs485_config() themselves (all
these seem to relate to init). Convert them all to use a common helper
which makes it easy to make adjustments on tasks related to it as
serial_rs485 struct sanitization is going to be added.
In pci_fintek_setup() (in 8250_pci.c), the rs485_config() call was made
with NULL, however, it can be changed to pass uart_port's rs485 struct.
No other callers should pass NULL into rs485_config() so the NULL check
can now be eliminated.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Link: https://lore.kernel.org/r/20220606100433.13793-2-ilpo.jarvinen@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Now fsl_lpuart driver use both of_alias_get_id() and ida_simple_get() in
.probe(), which has the potential bug. For example, when remove the
lpuart7 alias in dts, of_alias_get_id() will return error, then call
ida_simple_get() to allocate the id 0 for lpuart7, this may confilct
with the lpuart4 which has alias 0.
aliases {
...
serial0 = &lpuart4;
serial1 = &lpuart5;
serial2 = &lpuart6;
serial3 = &lpuart7;
}
So remove the ida_simple_get() in .probe(), return an error directly
when calling of_alias_get_id() fails, which is consistent with other
uart drivers behavior.
Fixes: 3bc3206e1c ("serial: fsl_lpuart: Remove the alias node dependence")
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
Link: https://lore.kernel.org/r/20220321112211.8895-1-sherry.sun@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
In uart_set_rs485_config() the serial core already ensures that only one of
both options RTS on send or RTS after send is set. It also assigns the
passed serial_rs485 struct to the uart port.
So remove the check and the assignment from the drivers rs485_config()
function to avoid redundancy.
Signed-off-by: Lino Sanfilippo <LinoSanfilippo@gmx.de>
Link: https://lore.kernel.org/r/20220410104642.32195-9-LinoSanfilippo@gmx.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Use wait_event_interruptible in lpuart_dma_shutdown isn't a reasonable
behavior, since it may cause the system hang here if the condition
!sport->dma_tx_in_progress never to be true in some corner case, such as
when enable the flow control, the dma tx request may never be completed
due to the peer's CTS setting when run .shutdown().
So here change to use wait_event_interruptible_timeout instead of
wait_event_interruptible, the tx dma will be forcibly terminated if the
tx dma request cannot be completed within 300ms.
Considering the worst tx dma case is to have a 4K bytes tx buffer, which
would require about 300ms to complete when the baudrate is 115200.
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
Link: https://lore.kernel.org/r/20211203030441.22873-1-sherry.sun@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Revert commit b4b844930f ("tty: serial: fsl_lpuart: drop earlycon entry
for i.MX8QXP"), because this breaks earlycon support on imx8qm/imx8qxp.
While it is true that for earlycon there is no difference between
i.MX8QXP and i.MX7ULP (for now at least), there are differences
regarding clocks and fixups for wakeup support. For that reason it was
deemed unacceptable to add the imx7ulp compatible to device tree in
order to get earlycon working again.
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
Link: https://lore.kernel.org/r/20211124073109.805088-1-alexander.stein@ew.tq-group.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Do software reset for communication port on imx7ulp and imx8qxp after
the port is registered if the UART controller support the feature.
Do partition reset with LPUART's power on, LPUART registers will
keep the previous status, like on i.MX8QXP platform, which is not
expected action, so need to set the RST bit of GLOBAL register to reset
all uart internal logic and registers.
Currently, only i.MX7ULP and i.MX8QXP LPUART controllers include
global register that support the software reset.
Signed-off-by: Fugang Duan <fugang.duan@nxp.com>
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
Link: https://lore.kernel.org/r/20210823091801.17447-1-sherry.sun@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Patch e60c2991f1 make the lpuart32_get_mctrl always return 0, actually
this will break the functions of device which use flow control such as
Bluetooth.
For lpuart32 plaform, the hardware can handle the CTS automatically.
So we should set TIOCM_CTS active. Also need to set CAR and DSR active.
Patch has been tested on lpuart32 platforms such as imx8qm and imx8ulp.
Fixes: e60c2991f1 ("serial: fsl_lpuart: remove RTSCTS handling from get_mctrl()")
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
Link: https://lore.kernel.org/r/20210729083109.31541-1-sherry.sun@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
SYSRQ doesn't work with DMA. This is because there is no error
indication whether a symbol had a framing error or not. Actually,
this is not completely correct, there is a bit in the data register
which is set in this case, but we'd have to read change the DMA access
to 16 bit and we'd need to post process the data, thus make the DMA
pointless in the first place.
Signed-off-by: Michael Walle <michael@walle.cc>
Link: https://lore.kernel.org/r/20210512141255.18277-10-michael@walle.cc
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The LPUART doesn't have the ability to control the RTS or CTS line
manually. Instead it will set it automatically when data is send or
handle it when data is received. Thus drop the wrong code in set_mctrl.
For the 32 bit version this was already done in the commit 2b30efe2e8
("tty: serial: lpuart: Remove unnecessary code from set_mctrl"). Keep
the 8-bit version in sync and remove it there, too.
Signed-off-by: Michael Walle <michael@walle.cc>
Link: https://lore.kernel.org/r/20210512141255.18277-8-michael@walle.cc
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The wrong code in set_mctrl() was already removed in commit 2b30efe2e8
("tty: serial: lpuart: Remove unnecessary code from set_mctrl"), but the
code in get_mctrl() wasn't removed. It will not return the state of the
RTS or CTS line but whether automatic flow control is enabled, which is
wrong for the get_mctrl(). Thus remove it.
Fixes: 2b30efe2e8 ("tty: serial: lpuart: Remove unnecessary code from set_mctrl")
Signed-off-by: Michael Walle <michael@walle.cc>
Link: https://lore.kernel.org/r/20210512141255.18277-7-michael@walle.cc
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>From commit 75f4e830fa ("serial: do not restore interrupt state in
sysrq helper"):
Since commit 81e2073c17 ("genirq: Disable interrupts for force
threaded handlers") interrupt handlers that are not explicitly
requested as threaded are always called with interrupts disabled and
there is no need to save the interrupt state when taking the port
lock.
Apply this also to fsl_lpuart in prepartion for sysrq handling with
uart_unlock_and_check_sysrq().
Signed-off-by: Michael Walle <michael@walle.cc>
Link: https://lore.kernel.org/r/20210512141255.18277-4-michael@walle.cc
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
We should be very careful about the register values that will be used
for division or modulo operations, althrough the possibility that the
UARTBAUD register value is zero is very low, but we had better to deal
with the "bad data" of hardware in advance to avoid division or modulo
by zero leading to undefined kernel behavior.
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
Link: https://lore.kernel.org/r/20210427021226.27468-1-sherry.sun@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Prior to the commit that this one fixes, the FIFO size was derived from
the read-only register LPUARTx_FIFO[TXFIFOSIZE] using the following
formula:
TX FIFO size = 2 ^ (LPUARTx_FIFO[TXFIFOSIZE] - 1)
The documentation for LS1021A is a mess. Under chapter 26.1.3 LS1021A
LPUART module special consideration, it mentions TXFIFO_SZ and RXFIFO_SZ
being equal to 4, and in the register description for LPUARTx_FIFO, it
shows the out-of-reset value of TXFIFOSIZE and RXFIFOSIZE fields as "011",
even though these registers read as "101" in reality.
And when LPUART on LS1021A was working, the "101" value did correspond
to "16 datawords", by applying the formula above, even though the
documentation is wrong again (!!!!) and says that "101" means 64 datawords
(hint: it doesn't).
So the "new" formula created by commit f77ebb241c has all the premises
of being wrong for LS1021A, because it relied only on false data and no
actual experimentation.
Interestingly, in commit c2f448cff2 ("tty: serial: fsl_lpuart: add
LS1028A support"), Michael Walle applied a workaround to this by manually
setting the FIFO widths for LS1028A. It looks like the same values are
used by LS1021A as well, in fact.
When the driver thinks that it has a deeper FIFO than it really has,
getty (user space) output gets truncated.
Many thanks to Michael for pointing out where to look.
Fixes: f77ebb241c ("tty: serial: fsl_lpuart: correct the FIFO depth size")
Suggested-by: Michael Walle <michael@walle.cc>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://lore.kernel.org/r/20201023013429.3551026-1-vladimir.oltean@nxp.com
Reviewed-by:Fugang Duan <fugang.duan@nxp.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
We're about to amend uart_get_rs485_mode() to support a GPIO pin for
rs485 bus termination. Retrieving the GPIO descriptor may fail, so
allow uart_get_rs485_mode() to return an errno and change all callers
to check for failure.
The GPIO descriptor is going to be stored in struct uart_port. Pass
that struct to uart_get_rs485_mode() in lieu of a struct device and
struct serial_rs485, both of which are directly accessible from struct
uart_port.
A few drivers call uart_get_rs485_mode() before setting the struct
device pointer in struct uart_port. Shuffle those calls around where
necessary.
[Heiko Stuebner did the ar933x_uart.c portion, hence his Signed-off-by.]
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Link: https://lore.kernel.org/r/271e814af4b0db3bffbbb74abf2b46b75add4516.1589285873.git.lukas@wunner.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Currently the following messages are seen when booting i.MX8QXP:
fsl-lpuart 5a060000.serial: DMA tx channel request failed, operating without tx DMA (-19)
fsl-lpuart 5a060000.serial: DMA rx channel request failed, operating without rx DMA (-19)
It is not really useful to have such messages on every boot, so change
them to debug level instead.
Signed-off-by: Fabio Estevam <festevam@gmail.com>
Link: https://lore.kernel.org/r/20200416153453.18825-1-festevam@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Coverity reports the following:
var_compare_op: Comparing chan to null implies that chan might be null.
1234 if (chan)
1235 dmaengine_terminate_all(chan);
1236
Dereference after null check (FORWARD_NULL)
var_deref_op: Dereferencing null pointer chan.
1237 dma_unmap_sg(chan->device->dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE);
Technically, this is correct. But lpuart_dma_rx_free() is guarded by
lpuart_dma_rx_use which is only true if there is a dma channel, see
lpuart_rx_dma_startup(). In any way, this looks bogus. So remove
the superfluous "if (chan)" check and make coverity happy.
Fixes: a092ab25fd ("tty: serial: fsl_lpuart: fix DMA mapping")
Signed-off-by: Michael Walle <michael@walle.cc>
Reported-by: Colin Ian King <colin.king@canonical.com>
Acked-by: Jiri Slaby <jslaby@suse.cz>
Reviewed-by: Fabio Estevam <festevam@gmail.com>
Link: https://lore.kernel.org/r/20200403174942.9594-1-michael@walle.cc
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>