From mboxrd@z Thu Jan 1 00:00:00 1970 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2261CC624A4 for ; Thu, 3 Sep 2026 08:07:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type: Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date :Subject:CC:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=VUxWm/z7xLtLP5dz8f8UFkQB4ImA8Yg4bPohYdRPwwA=; b=BvblQfUX2Zx3naUBtPw4IXk4ob 7ETfjYPXN9lpeoJ1CM6FQ8zt/8OvyMeJbEsnyhSepBdcARD6kN9tpAgzkilqILL7bbRwz4fJVit+H mVFlHvzWuPgOVRdqYw1UxJj3HrLqSjxVFmA43WjV3d2ZPHUwseuYnlJwyX9rf7lbVnuUbwtKE4ar4 9Swg/mmtRaEhsI8FqhACI1MkNEwzbeB1FQFMaZWPJa28NUPkCrWuReQhqD3UUZb0lXqFoDGT27KJp 6vMap/tWZo7ZDz5tga4rvkngym3YLpkLXtbSSYJePcTnbvOh1MD52kG+v8OKk6ynonmCgEJ649cGk qpx9c/Jw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1x22To-0000000GkLD-43uz; Thu, 03 Sep 2026 08:07:28 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1x22Tm-0000000GkKZ-40zt; Thu, 03 Sep 2026 08:07:28 +0000 X-UUID: 7c3b4ea0a76e11f1acbe4559397dec65-20260903 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=VUxWm/z7xLtLP5dz8f8UFkQB4ImA8Yg4bPohYdRPwwA=; b=Ia38we6LlI+wABzWxX23BxBJppS59a5DnVbxZewmYM6xkGgTPNJjlAP293x7atIzUG3URT+TIrHlE9YqhgPsNkhN/W18fuxmXMvkTaKeMdi2Xl3c2d4Iq8iUTKzCOh2N+b1qYnaOCArPoq/um9UTfJZrBeeaxQFk91AKMvPsnIM=; X-CID-CACHE: Type:Local,Time:202609030057-07,HitQuantity:1 X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.3.19,REQID:359fee17-5616-4df0-a3e8-f72b1c79aaa0,IP:0,U RL:0,TC:0,Content:-25,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTIO N:release,TS:-25 X-CID-META: VersionHash:7db8b62,CLOUDID:d2596df2-6b5d-4016-ba8d-9f799a78b7e4,B ulkID:nil,BulkQuantity:0,SF:81|82|102|836|865|888|898,TC:-5,Content:0|15|5 0|99,EDM:-3,IP:nil,URL:0,File:130,RT:0,Bulk:nil,QS:nil,BEC:-1,COL:0,OSI:0, OSA:0,AV:0,LES:1,SPR:NO,DKR:0,DKP:0,BRR:0,BRE:0,ARC:0 X-CID-BVR: 2,SSN|SDN X-CID-BAS: 2,SSN|SDN,0,_ X-CID-FACTOR: TF_CID_SPAM_SNR X-CID-RHF: D41D8CD98F00B204E9800998ECF8427E X-UUID: 7c3b4ea0a76e11f1acbe4559397dec65-20260903 Received: from mtkmbs13n2.mediatek.inc [(172.21.101.108)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 842416545; Thu, 03 Sep 2026 01:07:19 -0700 Received: from mtkmbs13n2.mediatek.inc (172.21.101.108) by MTKMBS09N2.mediatek.inc (172.21.101.94) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.29; Thu, 3 Sep 2026 16:07:17 +0800 Received: from gcnsap21.gcn.mediatek.inc (10.17.81.22) by mtkmbs13n2.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.2562.29 via Frontend Transport; Thu, 3 Sep 2026 16:07:16 +0800 From: Jingcheng Ji To: Mark Brown CC: Matthias Brugger , AngeloGioacchino Del Regno , , , , , Jingcheng Ji Subject: [PATCH v2] spi: spi-mtk-nor: Get clocks from devicetree in bulk Date: Thu, 3 Sep 2026 16:07:09 +0800 Message-ID: <20260903080709.3049832-1-ot_jingcheng.ji@mediatek.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260821090046.2353986-1-ot_jingcheng.ji@mediatek.com> References: <20260821090046.2353986-1-ot_jingcheng.ji@mediatek.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260903_010727_032891_BE857AAE X-CRM114-Status: GOOD ( 20.54 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The driver currently gets a fixed set of clock inputs by name. This ties the driver to the clock names used by existing devicetrees. It also means that a future binding extension which adds controller clock inputs needs a matching driver change to enable them. Get every clock described by the devicetree with devm_clk_bulk_get_all() and enable the resulting set as a group. Keep looking up the "spi" input to derive the transfer rate, and verify that the required "sf" input is present. Obtain the clock inputs before allocating the SPI controller so a deferred clock probe fails early. For non-DT platform devices, retain the existing named clock lookups so clkdev users continue to work. This prepares the driver for future binding extensions without requiring another driver change. Existing platforms' behavior is unchanged. Signed-off-by: Jingcheng Ji --- v2: - Rebase onto current spi/for-next and reuse its existing IRQ error cleanup path. - Preserve named clock lookup for non-DT platform devices. - Clarify that this prepares for a future binding extension. drivers/spi/spi-mtk-nor.c | 151 +++++++++++++++++++++++--------------- 1 file changed, 91 insertions(+), 60 deletions(-) diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c index 63f5139176c8..c0a47f3a8dbd 100644 --- a/drivers/spi/spi-mtk-nor.c +++ b/drivers/spi/spi-mtk-nor.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -116,10 +117,8 @@ struct mtk_nor { void __iomem *base; u8 *buffer; dma_addr_t buffer_dma; - struct clk *spi_clk; - struct clk *ctlr_clk; - struct clk *axi_clk; - struct clk *axi_s_clk; + struct clk_bulk_data *clks; + int num_clks; unsigned int spi_freq; bool wbuf_en; bool has_irq; @@ -703,42 +702,12 @@ static int mtk_nor_transfer_one_message(struct spi_controller *host, static void mtk_nor_disable_clk(struct mtk_nor *sp) { - clk_disable_unprepare(sp->spi_clk); - clk_disable_unprepare(sp->ctlr_clk); - clk_disable_unprepare(sp->axi_clk); - clk_disable_unprepare(sp->axi_s_clk); + clk_bulk_disable_unprepare(sp->num_clks, sp->clks); } static int mtk_nor_enable_clk(struct mtk_nor *sp) { - int ret; - - ret = clk_prepare_enable(sp->spi_clk); - if (ret) - return ret; - - ret = clk_prepare_enable(sp->ctlr_clk); - if (ret) { - clk_disable_unprepare(sp->spi_clk); - return ret; - } - - ret = clk_prepare_enable(sp->axi_clk); - if (ret) { - clk_disable_unprepare(sp->spi_clk); - clk_disable_unprepare(sp->ctlr_clk); - return ret; - } - - ret = clk_prepare_enable(sp->axi_s_clk); - if (ret) { - clk_disable_unprepare(sp->spi_clk); - clk_disable_unprepare(sp->ctlr_clk); - clk_disable_unprepare(sp->axi_clk); - return ret; - } - - return 0; + return clk_bulk_prepare_enable(sp->num_clks, sp->clks); } static void mtk_nor_init(struct mtk_nor *sp) @@ -807,34 +776,92 @@ static const struct of_device_id mtk_nor_match[] = { }; MODULE_DEVICE_TABLE(of, mtk_nor_match); +static struct clk *mtk_nor_get_clk(struct clk_bulk_data *clks, int num_clks, + const char *id) +{ + int i; + + for (i = 0; i < num_clks; i++) { + if (clks[i].id && !strcmp(clks[i].id, id)) + return clks[i].clk; + } + + return NULL; +} + +static int mtk_nor_get_named_clks(struct device *dev, + struct clk_bulk_data **clks) +{ + struct clk_bulk_data *bulk; + struct clk *clk; + int num_clks = 2; + + bulk = devm_kcalloc(dev, 4, sizeof(*bulk), GFP_KERNEL); + if (!bulk) + return -ENOMEM; + + bulk[0].id = "spi"; + bulk[0].clk = devm_clk_get(dev, bulk[0].id); + if (IS_ERR(bulk[0].clk)) + return PTR_ERR(bulk[0].clk); + + bulk[1].id = "sf"; + bulk[1].clk = devm_clk_get(dev, bulk[1].id); + if (IS_ERR(bulk[1].clk)) + return PTR_ERR(bulk[1].clk); + + clk = devm_clk_get_optional(dev, "axi"); + if (IS_ERR(clk)) + return PTR_ERR(clk); + if (clk) { + bulk[num_clks].id = "axi"; + bulk[num_clks++].clk = clk; + } + + clk = devm_clk_get_optional(dev, "axi_s"); + if (IS_ERR(clk)) + return PTR_ERR(clk); + if (clk) { + bulk[num_clks].id = "axi_s"; + bulk[num_clks++].clk = clk; + } + + *clks = bulk; + + return num_clks; +} + static int mtk_nor_probe(struct platform_device *pdev) { struct spi_controller *ctlr; struct mtk_nor *sp; struct mtk_nor_caps *caps; void __iomem *base; - struct clk *spi_clk, *ctlr_clk, *axi_clk, *axi_s_clk; - int ret, irq; + struct clk_bulk_data *clks; + struct clk *spi_clk; + int num_clks, ret, irq; base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); - spi_clk = devm_clk_get(&pdev->dev, "spi"); - if (IS_ERR(spi_clk)) - return PTR_ERR(spi_clk); - - ctlr_clk = devm_clk_get(&pdev->dev, "sf"); - if (IS_ERR(ctlr_clk)) - return PTR_ERR(ctlr_clk); - - axi_clk = devm_clk_get_optional(&pdev->dev, "axi"); - if (IS_ERR(axi_clk)) - return PTR_ERR(axi_clk); - - axi_s_clk = devm_clk_get_optional(&pdev->dev, "axi_s"); - if (IS_ERR(axi_s_clk)) - return PTR_ERR(axi_s_clk); + if (dev_of_node(&pdev->dev)) + num_clks = devm_clk_bulk_get_all(&pdev->dev, &clks); + else + num_clks = mtk_nor_get_named_clks(&pdev->dev, &clks); + if (num_clks < 0) + return dev_err_probe(&pdev->dev, num_clks, + "failed to get clocks\n"); + if (!num_clks) + return dev_err_probe(&pdev->dev, -EINVAL, "no clocks defined\n"); + + spi_clk = mtk_nor_get_clk(clks, num_clks, "spi"); + if (!spi_clk) + return dev_err_probe(&pdev->dev, -EINVAL, + "missing \"spi\" clock\n"); + if (!mtk_nor_get_clk(clks, num_clks, "sf")) + return dev_err_probe(&pdev->dev, -EINVAL, + "missing \"sf\" clock\n"); caps = (struct mtk_nor_caps *)of_device_get_match_data(&pdev->dev); @@ -867,10 +894,8 @@ static int mtk_nor_probe(struct platform_device *pdev) sp->wbuf_en = false; sp->ctlr = ctlr; sp->dev = &pdev->dev; - sp->spi_clk = spi_clk; - sp->ctlr_clk = ctlr_clk; - sp->axi_clk = axi_clk; - sp->axi_s_clk = axi_s_clk; + sp->clks = clks; + sp->num_clks = num_clks; sp->caps = caps; sp->high_dma = caps->dma_bits > 32; sp->buffer = dmam_alloc_coherent(&pdev->dev, @@ -886,9 +911,15 @@ static int mtk_nor_probe(struct platform_device *pdev) ret = mtk_nor_enable_clk(sp); if (ret < 0) - return ret; - - sp->spi_freq = clk_get_rate(sp->spi_clk); + return dev_err_probe(&pdev->dev, ret, + "failed to enable clocks\n"); + + sp->spi_freq = clk_get_rate(spi_clk); + if (!sp->spi_freq) { + dev_err(&pdev->dev, "invalid spi clock rate\n"); + ret = -EINVAL; + goto err_disable_clk; + } mtk_nor_init(sp); -- 2.45.2