From patchwork Fri Jul 22 16:48:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Zhou Yanjie X-Patchwork-Id: 12926620 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 1CA8FCCA489 for ; Fri, 22 Jul 2022 16:49:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235879AbiGVQtF (ORCPT ); Fri, 22 Jul 2022 12:49:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44158 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235870AbiGVQtE (ORCPT ); Fri, 22 Jul 2022 12:49:04 -0400 Received: from out28-173.mail.aliyun.com (out28-173.mail.aliyun.com [115.124.28.173]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1ACAF93638; Fri, 22 Jul 2022 09:48:53 -0700 (PDT) X-Alimail-AntiSpam: AC=CONTINUE;BC=0.07772149|-1;CH=green;DM=|CONTINUE|false|;DS=CONTINUE|ham_system_inform|0.00248871-9.81933e-05-0.997413;FP=0|0|0|0|0|-1|-1|-1;HT=ay29a033018047204;MF=zhouyanjie@wanyeetech.com;NM=1;PH=DS;RN=23;RT=23;SR=0;TI=SMTPD_---.Ob0cnJp_1658508527; Received: from localhost.localdomain(mailfrom:zhouyanjie@wanyeetech.com fp:SMTPD_---.Ob0cnJp_1658508527) by smtp.aliyun-inc.com; Sat, 23 Jul 2022 00:48:49 +0800 From: =?utf-8?b?5ZGo55Cw5p2wIChaaG91IFlhbmppZSk=?= To: tudor.ambarus@microchip.com, p.yadav@ti.com, michael@walle.cc, miquel.raynal@bootlin.com, richard@nod.at, vigneshr@ti.com, broonie@kernel.org, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org Cc: linux-mtd@lists.infradead.org, linux-spi@vger.kernel.org, linux-mips@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, aidanmacdonald.0x0@gmail.com, tmn505@gmail.com, paul@crapouillou.net, dongsheng.qiu@ingenic.com, aric.pzqi@ingenic.com, rick.tyliu@ingenic.com, jinghui.liu@ingenic.com, sernia.zhou@foxmail.com, reimu@sudomaker.com Subject: [PATCH 1/3] mtd: spi-nor: Use the spi-mem poll status APIs. Date: Sat, 23 Jul 2022 00:48:28 +0800 Message-Id: <1658508510-15400-2-git-send-email-zhouyanjie@wanyeetech.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1658508510-15400-1-git-send-email-zhouyanjie@wanyeetech.com> References: <1658508510-15400-1-git-send-email-zhouyanjie@wanyeetech.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org With advanced controllers (such as Ingenic SFC), it is possible to poll the status register of the device. This could be done to offload the CPU during a erase or write operation. Make use of spi-mem poll status APIs to handle this feature. Previously, when erasing large area (e.g. 32MiB), in non-offload case, CPU load could reach ~90% and would generate ~3.92 million interrupts, now it decrease to ~15% CPU load and 0.15 million interrupts. This should also fix the high CPU usage for system which don't have a dedicated poll status block logic (decrease to ~80% CPU load and ~1.61 million interrupts.). Signed-off-by: 周琰杰 (Zhou Yanjie) --- drivers/mtd/spi-nor/core.c | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 502967c..6a31132 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -617,19 +617,41 @@ static int spi_nor_wait_till_ready_with_timeout(struct spi_nor *nor, unsigned long deadline; int timeout = 0, ret; - deadline = jiffies + timeout_jiffies; + if (nor->spimem && !nor->params->ready) { + struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDSR, 0), + SPI_MEM_OP_NO_ADDR, + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_DATA_IN(1, nor->bouncebuf, 0)); - while (!timeout) { - if (time_after_eq(jiffies, deadline)) - timeout = 1; + if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR) { + op.addr.nbytes = nor->params->rdsr_addr_nbytes; + op.dummy.nbytes = nor->params->rdsr_dummy; + /* + * We don't want to read only one byte in DTR mode. So, + * read 2 and then discard the second byte. + */ + op.data.nbytes = 2; + } - ret = spi_nor_ready(nor); - if (ret < 0) - return ret; - if (ret) - return 0; + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + + return spi_mem_poll_status(nor->spimem, &op, SR_WIP, 0, 0, 10, + jiffies_to_msecs(timeout_jiffies)); + } else { + deadline = jiffies + timeout_jiffies; - cond_resched(); + while (!timeout) { + if (time_after_eq(jiffies, deadline)) + timeout = 1; + + ret = spi_nor_ready(nor); + if (ret < 0) + return ret; + if (ret) + return 0; + + cond_resched(); + } } dev_dbg(nor->dev, "flash operation timed out\n");