Received: by 2002:a05:7412:419a:b0:f3:1519:9f41 with SMTP id i26csp4555821rdh; Wed, 29 Nov 2023 05:00:53 -0800 (PST) X-Google-Smtp-Source: AGHT+IHc/gyrXK89vHnVyGfd2ikSUoyveNRd/bV0KL024IKrtD+DZX56QsBqK4f9Hxk5U3SyCfEI X-Received: by 2002:a05:6a00:3a04:b0:6cb:ccea:e2fd with SMTP id fj4-20020a056a003a0400b006cbcceae2fdmr20121390pfb.5.1701262853156; Wed, 29 Nov 2023 05:00:53 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701262853; cv=none; d=google.com; s=arc-20160816; b=ub+hYku9THuM4xlyrK3zvJC4KOtO/jB3czTaaAafxqi3XaYazQ91We+57upb968fQA mrekZ1fvBoiequMqtzBfu0JWjMMaZhBwwOlm0yNqWJ5hQJ0/9D9KBqdPVJFa4+UbHeo5 XB0CS75KllsU22vxOKbAqnC82tD1MhOOmqD3tmr95pkjYdUHvUO58Q+8ktbE9zX4elp5 o6Kh2FsjGzYbE0LJCe2v/bW7oQMecuwblpuDWrWZjpJfawbvm5jmBeHTQKSQk6348P9Y Z2hF3H4TaASwFxITfkTBuw3Izfj9Eg/PxFhDKGY9ltFqUPckbkOkN2P+79XNi7arQWnb rO6w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=JtOvQS+6evVSFOg4x1qpS4jVWP7j9KTB9w21qfsiDm4=; fh=1acBYjOFNp/b0CzagNI7fHUsuwsPw8XtOHZDlioLM5o=; b=VLUKWsFLIISYmnzWzyp6K6+eEVn8ZvWuo+9qW+2+jrbrXqL3BEU9gAQ991L47lN1S1 CMLAOJC+aM12qbzO2mdN47SG5oqUp28uP4Bgu4WT243bgStAc6Ic7QlNNw2wSbD9sONE 3/0FCIyWolWmpYAEx/H7Iw9SjrxEoJ1LVZFZdIj7zVSFMeTFAFIY4td7FRbw/+vm+uyq 6JivuM2Rw4ZFM4OsadCHSy96bMhKR9qWiwlkC7bYo65HtOWAfXWp5JB5Fglic/rDeUPN 8IqOSS4VKTW72qlepL+Uk+JAezjq8SMxItGr/5smPyQne+a4Qv/9TolExiwaFbrGFIij 0moA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@foss.st.com header.s=selector1 header.b="TU4Mz5M/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.31 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 morse.vger.email (morse.vger.email. [23.128.96.31]) by mx.google.com with ESMTPS id v4-20020a056a00148400b006c9bf737482si14374391pfu.295.2023.11.29.05.00.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Nov 2023 05:00:53 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.31 as permitted sender) client-ip=23.128.96.31; Authentication-Results: mx.google.com; dkim=pass header.i=@foss.st.com header.s=selector1 header.b="TU4Mz5M/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.31 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: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by morse.vger.email (Postfix) with ESMTP id 26B5F8074E0D; Wed, 29 Nov 2023 05:00:23 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at morse.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233595AbjK2NAE (ORCPT + 99 others); Wed, 29 Nov 2023 08:00:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50896 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233590AbjK2NAA (ORCPT ); Wed, 29 Nov 2023 08:00:00 -0500 Received: from mx07-00178001.pphosted.com (mx07-00178001.pphosted.com [185.132.182.106]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 31DAF10E2; Wed, 29 Nov 2023 05:00:05 -0800 (PST) Received: from pps.filterd (m0369458.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.22/8.17.1.22) with ESMTP id 3ATAIMa5005577; Wed, 29 Nov 2023 13:59:54 +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-transfer-encoding:content-type; s= selector1; bh=JtOvQS+6evVSFOg4x1qpS4jVWP7j9KTB9w21qfsiDm4=; b=TU 4Mz5M/sTLIEttQjLy5O0ouAEcuT+oCpyMws6WaQ0VpNKhdETN1RL1awOVG/LXcl7 3NJQ/eFMe0BuSfBgxG9FYAGBvhqy1pHjHrfACWaHBLjXBRbTq/JJBpXe5k/SCWHc cpdHPtzDSSyLNIWCLSUm3iYxg0NDjBxKFl8Hsseqeqh/jLSMfmM2XPUDMtcB3vbi MCLOrROa+OW006PRdHUYZb20rZJFsueeG3dV+kPHqZOeAxY8vQGns0NwOb2hgDu+ N40J2y9JisM+4AKLs56ydAmjhYH2T7Dz/tKaF24RWrITldpf1mC1H9zyoM+AQcNK yEmkZ0uj9+Cev7A8WpPw== 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 3unxcj22e2-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 29 Nov 2023 13:59:54 +0100 (CET) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 6AB3A10002A; Wed, 29 Nov 2023 13:59:53 +0100 (CET) Received: from Webmail-eu.st.com (shfdag1node1.st.com [10.75.129.69]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id E7C6221BF62; Wed, 29 Nov 2023 13:59:53 +0100 (CET) Received: from localhost (10.129.178.213) by SHFDAG1NODE1.st.com (10.75.129.69) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Wed, 29 Nov 2023 13:59:53 +0100 From: Alain Volmat To: Andi Shyti , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Maxime Coquelin , Alexandre Torgue , Pierre-Yves MORDRET , Alain Volmat CC: , , , , Subject: [PATCH 1/7] i2c: stm32f7: perform most of irq job in threaded handler Date: Wed, 29 Nov 2023 13:59:10 +0100 Message-ID: <20231129125920.1702497-2-alain.volmat@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231129125920.1702497-1-alain.volmat@foss.st.com> References: <20231129125920.1702497-1-alain.volmat@foss.st.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Originating-IP: [10.129.178.213] X-ClientProxiedBy: SHFCAS1NODE2.st.com (10.75.129.73) To SHFDAG1NODE1.st.com (10.75.129.69) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.997,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-11-29_09,2023-11-29_01,2023-05-22_02 X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on morse.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (morse.vger.email [0.0.0.0]); Wed, 29 Nov 2023 05:00:23 -0800 (PST) The irq handling is currently split between the irq handler and the threaded irq handler. Some of the handling (such as dma related stuffs) done within the irq handler might sleep or take some time leading to issues if the kernel is built with realtime constraints. In order to fix that, perform an overall rework to perform most of the job within the threaded handler and only keep fifo access in the non threaded handler. Signed-off-by: Alain Volmat --- drivers/i2c/busses/i2c-stm32f7.c | 126 ++++++++++++++----------------- 1 file changed, 56 insertions(+), 70 deletions(-) diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index 983509936727..34dcc370e615 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -1497,17 +1497,11 @@ static irqreturn_t stm32f7_i2c_slave_isr_event(struct stm32f7_i2c_dev *i2c_dev) static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data) { struct stm32f7_i2c_dev *i2c_dev = data; - struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; - struct stm32_i2c_dma *dma = i2c_dev->dma; - void __iomem *base = i2c_dev->base; - u32 status, mask; - int ret = IRQ_HANDLED; + u32 status; - /* Check if the interrupt if for a slave device */ - if (!i2c_dev->master_mode) { - ret = stm32f7_i2c_slave_isr_event(i2c_dev); - return ret; - } + /* Check if the interrupt is for a slave device */ + if (!i2c_dev->master_mode) + return IRQ_WAKE_THREAD; status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR); @@ -1519,6 +1513,29 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data) if (status & STM32F7_I2C_ISR_RXNE) stm32f7_i2c_read_rx_data(i2c_dev); + /* Wake up the thread if other flags are raised */ + if (status & + (STM32F7_I2C_ISR_NACKF | STM32F7_I2C_ISR_STOPF | + STM32F7_I2C_ISR_TC | STM32F7_I2C_ISR_TCR)) + return IRQ_WAKE_THREAD; + + return IRQ_HANDLED; +} + +static irqreturn_t stm32f7_i2c_isr_event_thread(int irq, void *data) +{ + struct stm32f7_i2c_dev *i2c_dev = data; + struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; + struct stm32_i2c_dma *dma = i2c_dev->dma; + void __iomem *base = i2c_dev->base; + u32 status, mask; + int ret; + + if (!i2c_dev->master_mode) + return stm32f7_i2c_slave_isr_event(i2c_dev); + + status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR); + /* NACK received */ if (status & STM32F7_I2C_ISR_NACKF) { dev_dbg(i2c_dev->dev, "<%s>: Receive NACK (addr %x)\n", @@ -1531,33 +1548,28 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data) f7_msg->result = -ENXIO; } - /* STOP detection flag */ - if (status & STM32F7_I2C_ISR_STOPF) { - /* Disable interrupts */ - if (stm32f7_i2c_is_slave_registered(i2c_dev)) - mask = STM32F7_I2C_XFER_IRQ_MASK; + if (status & STM32F7_I2C_ISR_TCR) { + if (f7_msg->smbus) + stm32f7_i2c_smbus_reload(i2c_dev); else - mask = STM32F7_I2C_ALL_IRQ_MASK; - stm32f7_i2c_disable_irq(i2c_dev, mask); - - /* Clear STOP flag */ - writel_relaxed(STM32F7_I2C_ICR_STOPCF, base + STM32F7_I2C_ICR); - - if (i2c_dev->use_dma && !f7_msg->result) { - ret = IRQ_WAKE_THREAD; - } else { - i2c_dev->master_mode = false; - complete(&i2c_dev->complete); - } + stm32f7_i2c_reload(i2c_dev); } /* Transfer complete */ if (status & STM32F7_I2C_ISR_TC) { + /* Wait for dma transfer completion before sending next message */ + if (i2c_dev->use_dma && !f7_msg->result) { + ret = wait_for_completion_timeout(&i2c_dev->dma->dma_complete, HZ); + if (!ret) { + dev_dbg(i2c_dev->dev, "<%s>: Timed out\n", __func__); + stm32f7_i2c_disable_dma_req(i2c_dev); + dmaengine_terminate_async(dma->chan_using); + f7_msg->result = -ETIMEDOUT; + } + } if (f7_msg->stop) { mask = STM32F7_I2C_CR2_STOP; stm32f7_i2c_set_bits(base + STM32F7_I2C_CR2, mask); - } else if (i2c_dev->use_dma && !f7_msg->result) { - ret = IRQ_WAKE_THREAD; } else if (f7_msg->smbus) { stm32f7_i2c_smbus_rep_start(i2c_dev); } else { @@ -1567,47 +1579,18 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data) } } - if (status & STM32F7_I2C_ISR_TCR) { - if (f7_msg->smbus) - stm32f7_i2c_smbus_reload(i2c_dev); + /* STOP detection flag */ + if (status & STM32F7_I2C_ISR_STOPF) { + /* Disable interrupts */ + if (stm32f7_i2c_is_slave_registered(i2c_dev)) + mask = STM32F7_I2C_XFER_IRQ_MASK; else - stm32f7_i2c_reload(i2c_dev); - } - - return ret; -} - -static irqreturn_t stm32f7_i2c_isr_event_thread(int irq, void *data) -{ - struct stm32f7_i2c_dev *i2c_dev = data; - struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; - struct stm32_i2c_dma *dma = i2c_dev->dma; - u32 status; - int ret; - - /* - * Wait for dma transfer completion before sending next message or - * notity the end of xfer to the client - */ - ret = wait_for_completion_timeout(&i2c_dev->dma->dma_complete, HZ); - if (!ret) { - dev_dbg(i2c_dev->dev, "<%s>: Timed out\n", __func__); - stm32f7_i2c_disable_dma_req(i2c_dev); - dmaengine_terminate_async(dma->chan_using); - f7_msg->result = -ETIMEDOUT; - } + mask = STM32F7_I2C_ALL_IRQ_MASK; + stm32f7_i2c_disable_irq(i2c_dev, mask); - status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR); + /* Clear STOP flag */ + writel_relaxed(STM32F7_I2C_ICR_STOPCF, base + STM32F7_I2C_ICR); - if (status & STM32F7_I2C_ISR_TC) { - if (f7_msg->smbus) { - stm32f7_i2c_smbus_rep_start(i2c_dev); - } else { - i2c_dev->msg_id++; - i2c_dev->msg++; - stm32f7_i2c_xfer_msg(i2c_dev, i2c_dev->msg); - } - } else { i2c_dev->master_mode = false; complete(&i2c_dev->complete); } @@ -1615,7 +1598,7 @@ static irqreturn_t stm32f7_i2c_isr_event_thread(int irq, void *data) return IRQ_HANDLED; } -static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data) +static irqreturn_t stm32f7_i2c_isr_error_thread(int irq, void *data) { struct stm32f7_i2c_dev *i2c_dev = data; struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; @@ -2205,8 +2188,11 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) return ret; } - ret = devm_request_irq(&pdev->dev, irq_error, stm32f7_i2c_isr_error, 0, - pdev->name, i2c_dev); + ret = devm_request_threaded_irq(&pdev->dev, irq_error, + NULL, + stm32f7_i2c_isr_error_thread, + IRQF_ONESHOT, + pdev->name, i2c_dev); if (ret) { dev_err(&pdev->dev, "Failed to request irq error %i\n", irq_error); -- 2.25.1