linux-stable/arch/arm/include/debug/zynq.S
Linus Walleij 2c50a570e9 ARM: 9004/1: debug: Split waituart to CTS and TXRDY
This patch was triggered by a remark from Russell that
introducing a call to the waituart (needed to fix debug prints
on the Qualcomm platforms) was dangerous because in some cases
this will involve waiting for a modem CTS (clear to send)
signal, and debug messages would maybe not work on platforms
with no modem connected to the UART port: they will just
hang waiting for the modem to assert CTS and this might never
happen.

Looking through all UART debug drivers implementing the waituart
macro I discovered that all users except two actually use this
macro to check if the UART is ready for TX, let's call this
TXRDY.

Only two debug UART drivers actually check for CTS:
- arch/arm/include/debug/8250.S
- arch/arm/include/debug/tegra.S

The former is very significant since the 8250 is possibly
the most common UART on the planet.

We have the following problem: the semantics of waituart are
ambiguous making it dangerous to introduce the macro to debug
code fixing debug prints for Qualcomm. To start to pry this
problem apart, this patch does the following:

- Convert all debug UART drivers to define two macros:

  - waituartcts with the clear semantic to wait for CTS
    to be asserted

  - waituarttxrdy with the clear semantic to wait for the TX
    capability of the UART to be ready

- When doing this take care to assign the right function to
  each drivers macro, so they now do exactly the above.

- Update the three sites in the kernel invoking the waituart
  macro to call waituartcts/waituarttxrdy in sequence, so that
  the functional impact on the kernel should be zero.

After this we can start to change the code sites using this
code to do the right thing.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
2020-09-15 14:35:27 +01:00

51 lines
1.2 KiB
ArmAsm

/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Debugging macro include header
*
* Copyright (C) 2011 Xilinx
*/
#define UART_CR_OFFSET 0x00 /* Control Register [8:0] */
#define UART_SR_OFFSET 0x2C /* Channel Status [11:0] */
#define UART_FIFO_OFFSET 0x30 /* FIFO [15:0] or [7:0] */
#define UART_SR_TXFULL 0x00000010 /* TX FIFO full */
#define UART_SR_TXEMPTY 0x00000008 /* TX FIFO empty */
#define UART0_PHYS 0xE0000000
#define UART0_VIRT 0xF0800000
#define UART1_PHYS 0xE0001000
#define UART1_VIRT 0xF0801000
#if IS_ENABLED(CONFIG_DEBUG_ZYNQ_UART1)
# define LL_UART_PADDR UART1_PHYS
# define LL_UART_VADDR UART1_VIRT
#else
# define LL_UART_PADDR UART0_PHYS
# define LL_UART_VADDR UART0_VIRT
#endif
.macro addruart, rp, rv, tmp
ldr \rp, =LL_UART_PADDR @ physical
ldr \rv, =LL_UART_VADDR @ virtual
.endm
.macro senduart,rd,rx
strb \rd, [\rx, #UART_FIFO_OFFSET] @ TXDATA
.endm
.macro waituartcts,rd,rx
.endm
.macro waituarttxrdy,rd,rx
1001: ldr \rd, [\rx, #UART_SR_OFFSET]
ARM_BE8( rev \rd, \rd )
tst \rd, #UART_SR_TXEMPTY
beq 1001b
.endm
.macro busyuart,rd,rx
1002: ldr \rd, [\rx, #UART_SR_OFFSET] @ get status register
ARM_BE8( rev \rd, \rd )
tst \rd, #UART_SR_TXFULL @
bne 1002b @ wait if FIFO is full
.endm