Received: by 2002:a05:6a10:5bc5:0:0:0:0 with SMTP id os5csp1596434pxb; Wed, 20 Oct 2021 08:09:58 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy8us98y1vCjQ4kpBppAr51/XJDzFqIkSo1MrCENqbM5/EkUevkjZB5zrUTgxmUKKu4Yw0i X-Received: by 2002:a1c:a5d6:: with SMTP id o205mr14167044wme.90.1634742598145; Wed, 20 Oct 2021 08:09:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1634742598; cv=none; d=google.com; s=arc-20160816; b=Ybj/ylkWPUU6yYPQQ8KpwM5I0Z9vTJBD/2vqfAywYjC4ZFype6JCeP+md4Q6PZUU2+ 8P6DAqs78J+hJ822dQzJZisRbVX0UlZ1og+595wlEWtUwO8HbHSRpMJRKPCcDPvkvEjh OAZPv1CYHZXmI74jF28OinFVJJmbrqL7SZ+Xl9nZcm7Wn6gNAgMFLvzH+rF/om8phI06 lylHBvb9OgTDTTmwZyNw53EwqHfggPZBJjieemO11jeR7wq268jnnB+XrDHpD5XQUSZd 52q7P9IupVUYmWlJhwlGIYsZ99UYuf6v/3DeugZ2IV6MgKJWx6nTtR8BATAmiqCr9nfR 3ZwA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=JtIR+oBYy0unpZqp/ZI74GRw2a+uR2l8SS7NVOH8cVc=; b=doD4lwzXgpZt1UVN1jtIJ5CoPpzRon2aIjcoFo8q34kElsEl7qq/k5Ql/67adCJy8B /ds5ITc1PHWAiRYuX2OL3cF1vuwA149AqrEF5iK3hfCvo8UcjInyTCN0ymVLJ7Afvm3m XP6TmZDDgHFRs0PnglzJFJX1PowD1q17Uv2Cv9kYQK8IC6fsDvvGptBtyTO2eOf4WPz0 wMx+2enL582P2g5CNnhLcDepg6QY1sjp0nk/oXJcKSQHWZDfHpVJfyWm4doPszXs2DZ3 QJgeN18MuXSUPM3uMScmVIydm9n+vuoulR/Y3y/RlC3gqkVZRDtvHYpNRkDZ+EYsJDgw Z1Rw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@foss.st.com header.s=selector1 header.b=IxwvK7uU; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=foss.st.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id z2si2841129eju.533.2021.10.20.08.09.33; Wed, 20 Oct 2021 08:09:58 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@foss.st.com header.s=selector1 header.b=IxwvK7uU; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=foss.st.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230449AbhJTPGZ (ORCPT + 99 others); Wed, 20 Oct 2021 11:06:25 -0400 Received: from mx07-00178001.pphosted.com ([185.132.182.106]:57610 "EHLO mx07-00178001.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230372AbhJTPGQ (ORCPT ); Wed, 20 Oct 2021 11:06:16 -0400 Received: from pps.filterd (m0046668.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 19KD3Twi008021; Wed, 20 Oct 2021 17:03:53 +0200 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=JtIR+oBYy0unpZqp/ZI74GRw2a+uR2l8SS7NVOH8cVc=; b=IxwvK7uUj8PkF/HN9XCVbCmtKWgCfa77G5Ns2PEc15wjWiDWnedZ17u5fENhgd9MILrc 7oTBCllYkxhT5IMoqGfQP9ON9RSSo0MXu8ZRQ+gBEcGwDy8NyHNaPxcQvKUY8pZWhbyw tumioTgIyjR8rGGWGR0yD0ld+WjuIGK46NBrFQ/lUksgkLkZG4wFVHvuzDjNTyoUTEb2 YUUBG6apHsqmhXgqODtx8hKvFZmAzqVq23asT4SM/KZ1pqZh1aumyy3oSHiZAWxs/jcR yjqyHsts++jTuPKQuuNLBAUdq9Tku2fv5P62yzVpVcEAHqtWfUmDGSXBKDSORZvatncF eA== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com with ESMTP id 3btknp8psb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 20 Oct 2021 17:03:53 +0200 Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id D66AB100034; Wed, 20 Oct 2021 17:03:52 +0200 (CEST) Received: from Webmail-eu.st.com (sfhdag2node2.st.com [10.75.127.5]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id CE3B222A6E8; Wed, 20 Oct 2021 17:03:52 +0200 (CEST) Received: from localhost (10.75.127.46) by SFHDAG2NODE2.st.com (10.75.127.5) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Wed, 20 Oct 2021 17:03:52 +0200 From: Erwan Le Ray To: Greg Kroah-Hartman , Jiri Slaby , Maxime Coquelin , Alexandre Torgue CC: , , , , Erwan Le Ray , Fabrice Gasnier , Valentin Caron , Amelie Delaunay Subject: [PATCH 3/3] serial: stm32: update throttle and unthrottle ops for dma mode Date: Wed, 20 Oct 2021 17:03:32 +0200 Message-ID: <20211020150332.10214-4-erwan.leray@foss.st.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211020150332.10214-1-erwan.leray@foss.st.com> References: <20211020150332.10214-1-erwan.leray@foss.st.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.75.127.46] X-ClientProxiedBy: SFHDAG1NODE3.st.com (10.75.127.3) To SFHDAG2NODE2.st.com (10.75.127.5) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.182.1,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.0.607.475 definitions=2021-10-20_05,2021-10-20_02,2020-04-07_01 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Disable DMA request line (if enabled) to switch in PIO mode in throttle ops, so the RX data gets queues into the FIFO. The hardware flow control is triggered when the RX FIFO is full. Switch back to DMA mode (re-enable DMA request line) in unthrottle ops. Hardware flow control is stopped when FIFO is not full anymore. Signed-off-by: Valentin Caron Signed-off-by: Erwan Le Ray diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index cfdda35499e6..7fd192e1e15d 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -577,9 +577,12 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr) * rx errors in dma mode has to be handled ASAP to avoid overrun as the DMA request * line has been masked by HW and rx data are stacking in FIFO. */ - if (((sr & USART_SR_RXNE) && !stm32_usart_rx_dma_enabled(port)) || - ((sr & USART_SR_ERR_MASK) && stm32_usart_rx_dma_enabled(port))) - stm32_usart_receive_chars(port, false); + if (!stm32_port->throttled) { + if (((sr & USART_SR_RXNE) && !stm32_usart_rx_dma_enabled(port)) || + ((sr & USART_SR_ERR_MASK) && stm32_usart_rx_dma_enabled(port))) { + stm32_usart_receive_chars(port, false); + } + } if ((sr & USART_SR_TXE) && !(stm32_port->tx_ch)) { spin_lock(&port->lock); @@ -596,9 +599,11 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr) static irqreturn_t stm32_usart_threaded_interrupt(int irq, void *ptr) { struct uart_port *port = ptr; + struct stm32_port *stm32_port = to_stm32_port(port); /* Receiver timeout irq for DMA RX */ - stm32_usart_receive_chars(port, false); + if (!stm32_port->throttled) + stm32_usart_receive_chars(port, false); return IRQ_HANDLED; } @@ -711,10 +716,19 @@ static void stm32_usart_throttle(struct uart_port *port) unsigned long flags; spin_lock_irqsave(&port->lock, flags); + + /* + * Disable DMA request line if enabled, so the RX data gets queued into the FIFO. + * Hardware flow control is triggered when RX FIFO is full. + */ + if (stm32_usart_rx_dma_enabled(port)) + stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAR); + stm32_usart_clr_bits(port, ofs->cr1, stm32_port->cr1_irq); if (stm32_port->cr3_irq) stm32_usart_clr_bits(port, ofs->cr3, stm32_port->cr3_irq); + stm32_port->throttled = true; spin_unlock_irqrestore(&port->lock, flags); } @@ -730,6 +744,14 @@ static void stm32_usart_unthrottle(struct uart_port *port) if (stm32_port->cr3_irq) stm32_usart_set_bits(port, ofs->cr3, stm32_port->cr3_irq); + /* + * Switch back to DMA mode (re-enable DMA request line). + * Hardware flow control is stopped when FIFO is not full any more. + */ + if (stm32_port->rx_ch) + stm32_usart_set_bits(port, ofs->cr3, USART_CR3_DMAR); + + stm32_port->throttled = false; spin_unlock_irqrestore(&port->lock, flags); } @@ -775,6 +797,13 @@ static int stm32_usart_startup(struct uart_port *port) if (ofs->rqr != UNDEF_REG) writel_relaxed(USART_RQR_RXFRQ, port->membase + ofs->rqr); + /* + * DMA request line not re-enabled at resume when port is throttled. + * It will be re-enabled by unthrottle ops. + */ + if (!stm32_port->throttled) + stm32_usart_set_bits(port, ofs->cr3, USART_CR3_DMAR); + /* RX enabling */ val = stm32_port->cr1_irq | USART_CR1_RE | BIT(cfg->uart_enable_bit); stm32_usart_set_bits(port, ofs->cr1, val); diff --git a/drivers/tty/serial/stm32-usart.h b/drivers/tty/serial/stm32-usart.h index 53bcd032fce7..e23916bfbb60 100644 --- a/drivers/tty/serial/stm32-usart.h +++ b/drivers/tty/serial/stm32-usart.h @@ -265,6 +265,7 @@ struct stm32_port { u32 cr3_irq; /* USART_CR3_RXFTIE */ int last_res; bool tx_dma_busy; /* dma tx busy */ + bool throttled; /* port throttled */ bool hw_flow_control; bool swap; /* swap RX & TX pins */ bool fifoen; -- 2.17.1