From patchwork Tue Jan 11 16:44:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valentin Caron X-Patchwork-Id: 531734 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 650FFC433FE for ; Tue, 11 Jan 2022 16:45:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343828AbiAKQps (ORCPT ); Tue, 11 Jan 2022 11:45:48 -0500 Received: from mx08-00178001.pphosted.com ([91.207.212.93]:58178 "EHLO mx07-00178001.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S240793AbiAKQpq (ORCPT ); Tue, 11 Jan 2022 11:45:46 -0500 Received: from pps.filterd (m0046660.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 20BGCfWb022160; Tue, 11 Jan 2022 17:45:26 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=selector1; bh=DUFh1SKt2sWCGI0makXOoBN/QEWeJJpABfJYD6qhEeA=; b=RunS487M0nGsePY944EKUzlt0hPZcCSlcyeUFE75ZRIcmwUrCKVhJ2ZYpeF0rgmtQZ7T fG2ow+YI+lWSfPpKjaYO3nr5/Q9406Zbhcx6tA7cHOkeOEsIOmPNI3wUSI3sqzhgKT2n mOUEm/7ol5dVeBa7boYn7P9I2aKSxaoRaoxHkGMFQob9/VcSCIG69elFlHZjWc5fZYc5 +IlxludzNtaurwf3P34BQtgTGYYwJD7UHWVfnBRVYTZayfspcXyg4nomiMW/m7CuRqD1 cS15Q5hNSmcXVK66uekf/wXjoALxkabNOqFHcqEhfCftqLk+oQhZkad/yyJamg0Oq/kl fw== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 3dh2m5uyub-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Jan 2022 17:45:25 +0100 Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 3DDDC10002A; Tue, 11 Jan 2022 17:45:25 +0100 (CET) Received: from Webmail-eu.st.com (sfhdag2node2.st.com [10.75.127.5]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 353E1245FC8; Tue, 11 Jan 2022 17:45:25 +0100 (CET) Received: from localhost (10.75.127.46) by SFHDAG2NODE2.st.com (10.75.127.5) with Microsoft SMTP Server (TLS) id 15.0.1497.26; Tue, 11 Jan 2022 17:45:24 +0100 From: Valentin Caron To: Greg Kroah-Hartman CC: Jiri Slaby , Maxime Coquelin , Alexandre Torgue , Erwan Le Ray , Valentin Caron , , , , Subject: [PATCH 1/2] serial: stm32: prevent TDR register overwrite when sending x_char Date: Tue, 11 Jan 2022 17:44:40 +0100 Message-ID: <20220111164441.6178-2-valentin.caron@foss.st.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220111164441.6178-1-valentin.caron@foss.st.com> References: <20220111164441.6178-1-valentin.caron@foss.st.com> MIME-Version: 1.0 X-Originating-IP: [10.75.127.46] X-ClientProxiedBy: SFHDAG2NODE2.st.com (10.75.127.5) To SFHDAG2NODE2.st.com (10.75.127.5) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-11_04,2022-01-11_01,2021-12-02_01 Precedence: bulk List-ID: X-Mailing-List: linux-serial@vger.kernel.org When sending x_char in stm32_usart_transmit_chars(), driver can overwrite the value of TDR register by the value of x_char. If this happens, the previous value that was present in TDR register will not be sent through uart. This code checks if the previous value in TDR register is sent before writing the x_char value into register. Fixes: 48a6092fb41f ("serial: stm32-usart: Add STM32 USART Driver") Signed-off-by: Valentin Caron --- drivers/tty/serial/stm32-usart.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index 1f89ab0e49ac..c1b8828451c8 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -550,11 +550,23 @@ static void stm32_usart_transmit_chars(struct uart_port *port) struct stm32_port *stm32_port = to_stm32_port(port); const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; struct circ_buf *xmit = &port->state->xmit; + u32 isr; + int ret; if (port->x_char) { if (stm32_usart_tx_dma_started(stm32_port) && stm32_usart_tx_dma_enabled(stm32_port)) stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT); + + /* Check that TDR is empty before filling FIFO */ + ret = + readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr, + isr, + (isr & USART_SR_TXE), + 10, 1000); + if (ret) + dev_warn(port->dev, "1 character may be erased\n"); + writel_relaxed(port->x_char, port->membase + ofs->tdr); port->x_char = 0; port->icount.tx++;