| From bb0b197aadd928f52ce6f01f0ee977f0a08cf1be Mon Sep 17 00:00:00 2001 |
| From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> |
| Date: Wed, 27 Apr 2022 15:23:26 +0200 |
| Subject: serial: 8250_mtk: Fix UART_EFR register address |
| |
| From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> |
| |
| commit bb0b197aadd928f52ce6f01f0ee977f0a08cf1be upstream. |
| |
| On MediaTek SoCs, the UART IP is 16550A compatible, but there are some |
| specific quirks: we are declaring a register shift of 2, but this is |
| only valid for the majority of the registers, as there are some that |
| are out of the standard layout. |
| |
| Specifically, this driver is using definitions from serial_reg.h, where |
| we have a UART_EFR register defined as 2: this results in a 0x8 offset, |
| but there we have the FCR register instead. |
| |
| The right offset for the EFR register on MediaTek UART is at 0x98, |
| so, following the decimal definition convention in serial_reg.h and |
| accounting for the register left shift of two, add and use the correct |
| register address for this IP, defined as decimal 38, so that the final |
| calculation results in (0x26 << 2) = 0x98. |
| |
| Fixes: bdbd0a7f8f03 ("serial: 8250-mtk: modify baudrate setting") |
| Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> |
| Cc: stable <stable@vger.kernel.org> |
| Link: https://lore.kernel.org/r/20220427132328.228297-2-angelogioacchino.delregno@collabora.com |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/tty/serial/8250/8250_mtk.c | 15 ++++++++------- |
| 1 file changed, 8 insertions(+), 7 deletions(-) |
| |
| --- a/drivers/tty/serial/8250/8250_mtk.c |
| +++ b/drivers/tty/serial/8250/8250_mtk.c |
| @@ -36,6 +36,7 @@ |
| #define MTK_UART_IER_RTSI 0x40 /* Enable RTS Modem status interrupt */ |
| #define MTK_UART_IER_CTSI 0x80 /* Enable CTS Modem status interrupt */ |
| |
| +#define MTK_UART_EFR 38 /* I/O: Extended Features Register */ |
| #define MTK_UART_EFR_EN 0x10 /* Enable enhancement feature */ |
| #define MTK_UART_EFR_RTS 0x40 /* Enable hardware rx flow control */ |
| #define MTK_UART_EFR_CTS 0x80 /* Enable hardware tx flow control */ |
| @@ -168,7 +169,7 @@ static void mtk8250_dma_enable(struct ua |
| MTK_UART_DMA_EN_RX | MTK_UART_DMA_EN_TX); |
| |
| serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
| - serial_out(up, UART_EFR, UART_EFR_ECB); |
| + serial_out(up, MTK_UART_EFR, UART_EFR_ECB); |
| serial_out(up, UART_LCR, lcr); |
| |
| if (dmaengine_slave_config(dma->rxchan, &dma->rxconf) != 0) |
| @@ -231,7 +232,7 @@ static void mtk8250_set_flow_ctrl(struct |
| int lcr = serial_in(up, UART_LCR); |
| |
| serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
| - serial_out(up, UART_EFR, UART_EFR_ECB); |
| + serial_out(up, MTK_UART_EFR, UART_EFR_ECB); |
| serial_out(up, UART_LCR, lcr); |
| lcr = serial_in(up, UART_LCR); |
| |
| @@ -240,7 +241,7 @@ static void mtk8250_set_flow_ctrl(struct |
| serial_out(up, MTK_UART_ESCAPE_DAT, MTK_UART_ESCAPE_CHAR); |
| serial_out(up, MTK_UART_ESCAPE_EN, 0x00); |
| serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
| - serial_out(up, UART_EFR, serial_in(up, UART_EFR) & |
| + serial_out(up, MTK_UART_EFR, serial_in(up, MTK_UART_EFR) & |
| (~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK))); |
| serial_out(up, UART_LCR, lcr); |
| mtk8250_disable_intrs(up, MTK_UART_IER_XOFFI | |
| @@ -254,8 +255,8 @@ static void mtk8250_set_flow_ctrl(struct |
| serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
| |
| /*enable hw flow control*/ |
| - serial_out(up, UART_EFR, MTK_UART_EFR_HW_FC | |
| - (serial_in(up, UART_EFR) & |
| + serial_out(up, MTK_UART_EFR, MTK_UART_EFR_HW_FC | |
| + (serial_in(up, MTK_UART_EFR) & |
| (~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK)))); |
| |
| serial_out(up, UART_LCR, lcr); |
| @@ -269,8 +270,8 @@ static void mtk8250_set_flow_ctrl(struct |
| serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
| |
| /*enable sw flow control */ |
| - serial_out(up, UART_EFR, MTK_UART_EFR_XON1_XOFF1 | |
| - (serial_in(up, UART_EFR) & |
| + serial_out(up, MTK_UART_EFR, MTK_UART_EFR_XON1_XOFF1 | |
| + (serial_in(up, MTK_UART_EFR) & |
| (~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK)))); |
| |
| serial_out(up, UART_XON1, START_CHAR(port->state->port.tty)); |