From patchwork Thu Mar 23 16:10:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jing Zhang X-Patchwork-Id: 13185815 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 408BBC6FD1C for ; Thu, 23 Mar 2023 16:12:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id: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:In-Reply-To:References: List-Owner; bh=gM3gYjabLWhpRAS1ffcrBEXTP+Zf8WPoDEq6M5EVdIE=; b=i3pXVg6Km1D7vv dsC4tEjwhIykgZf6xwCmvO30krx99pFIlVidGgLYyzFJXjyx74SYT4ZbNk/234wAjvydBxufaOe8X mHS0dMomqU6clbbA//iPezBYYmlsD2llCRab4s8L7K5/8RjZdCG2shRZhXI9zAk7B059ZKV55k7vE CLU4FhWkcFiqFKuOMLGeS3wiIK1OqHvXkV6eoqgEB6Yl1fLHeYJN2HiHXBuLzJ+cXkdhgUDOzhCfl ajqfWgfRW+eXv1/CsLrt4ALIipGLt579vFwD32u7/KOPhGqFzkWyFwwXqkqBdZxllyHwfnI5oVM3x xRZYyycAWQo5SVGNDwNg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1pfNWv-002R4D-0E; Thu, 23 Mar 2023 16:11:09 +0000 Received: from out30-131.freemail.mail.aliyun.com ([115.124.30.131]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1pfNWo-002R2o-3C for linux-arm-kernel@lists.infradead.org; Thu, 23 Mar 2023 16:11:07 +0000 X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R141e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018046056;MF=renyu.zj@linux.alibaba.com;NM=1;PH=DS;RN=9;SR=0;TI=SMTPD_---0VeUu73m_1679587840; Received: from srmbuffer011165236051.sqa.net(mailfrom:renyu.zj@linux.alibaba.com fp:SMTPD_---0VeUu73m_1679587840) by smtp.aliyun-inc.com; Fri, 24 Mar 2023 00:10:53 +0800 From: Jing Zhang To: Will Deacon , Mark Rutland Cc: linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org, Shuai Xue , Zhuo Song , Jing Zhang Subject: [RESEND PATCH] driver/perf: arm-cmn: support ACPI probe Date: Fri, 24 Mar 2023 00:10:38 +0800 Message-Id: <1679587838-80000-1-git-send-email-renyu.zj@linux.alibaba.com> X-Mailer: git-send-email 1.8.3.1 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230323_091103_223894_370D0411 X-CRM114-Status: GOOD ( 18.42 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org ACPI companion devices call insert_resource() in platform_device_add() to claim the device resources. If the resources are claimed again before ioremap(), and the addresses of multiple resources overlap, it will return -BUSY, causing the driver to fail to load. For example, the CMN700 on my machine is set with two resources similar to CMN600, and the overlap of resource addresses makes the CMN driver unable to match my CMN700. The error log: [ 12.016837] arm-cmn ARMHC700:00: can't request region for resource [mem 0x40000000-0x4fffffff] [ 12.028230] arm-cmn: probe of ARMHC700:00 failed with error -16 [ 12.036832] arm-cmn ARMHC700:01: can't request region for resource [mem 0x40040000000-0x4004fffffff] [ 12.051289] arm-cmn: probe of ARMHC700:01 failed with error -16 So let ACPI companion devices call arm_cmn_acpi_probe() and not claim resource again. In addition, the arm_cmn_acpi_probe() and arm_cmn_of_probe() functions are refactored to make them compatible with both CMN600 and CMN-ANY. Fixes: 61ec1d875812 ("perf/arm-cmn: Demarcate CMN-600 specifics") Signed-off-by: Jing Zhang --- drivers/perf/arm-cmn.c | 57 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c index 1deb61b..beb3b37 100644 --- a/drivers/perf/arm-cmn.c +++ b/drivers/perf/arm-cmn.c @@ -2206,7 +2206,7 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset) return 0; } -static int arm_cmn600_acpi_probe(struct platform_device *pdev, struct arm_cmn *cmn) +static int arm_cmn_acpi_probe(struct platform_device *pdev, struct arm_cmn *cmn) { struct resource *cfg, *root; @@ -2214,12 +2214,21 @@ static int arm_cmn600_acpi_probe(struct platform_device *pdev, struct arm_cmn *c if (!cfg) return -EINVAL; - root = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (!root) - return -EINVAL; + /* If ACPI defines more than one resource, such as cmn-600, then there may be + * a deviation between ROOTNODEBASE and PERIPHBASE, and ROOTNODEBASE can + * be obtained from the second resource. Otherwise, it can be considered that + * ROOT NODE BASE is PERIPHBASE. This is compatible with cmn-600 and cmn-any. + */ + if (pdev->num_resources > 1) { + root = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!root) + return -EINVAL; - if (!resource_contains(cfg, root)) - swap(cfg, root); + if (!resource_contains(cfg, root)) + swap(cfg, root); + } else { + root = cfg; + } /* * Note that devm_ioremap_resource() is dumb and won't let the platform * device claim cfg when the ACPI companion device has already claimed @@ -2227,17 +2236,30 @@ static int arm_cmn600_acpi_probe(struct platform_device *pdev, struct arm_cmn *c * appropriate name, we don't really need to do it again here anyway. */ cmn->base = devm_ioremap(cmn->dev, cfg->start, resource_size(cfg)); - if (!cmn->base) - return -ENOMEM; + if (IS_ERR(cmn->base)) + return PTR_ERR(cmn->base); return root->start - cfg->start; } -static int arm_cmn600_of_probe(struct device_node *np) +static int arm_cmn_of_probe(struct platform_device *pdev, struct arm_cmn *cmn) { u32 rootnode; + int ret; + + cmn->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(cmn->base)) + return PTR_ERR(cmn->base); - return of_property_read_u32(np, "arm,root-node", &rootnode) ?: rootnode; + /* If of_property_read_u32() return -EINVAL, it means that device tree has + * not define root-node, and root-node will return 0, which is compatible + * with cmn-600 and cmn-any. + */ + ret = of_property_read_u32(pdev->dev.of_node, "arm,root-node", &rootnode); + if (ret == -EINVAL) + return 0; + + return rootnode; } static int arm_cmn_probe(struct platform_device *pdev) @@ -2255,16 +2277,11 @@ static int arm_cmn_probe(struct platform_device *pdev) cmn->model = (unsigned long)device_get_match_data(cmn->dev); platform_set_drvdata(pdev, cmn); - if (cmn->model == CMN600 && has_acpi_companion(cmn->dev)) { - rootnode = arm_cmn600_acpi_probe(pdev, cmn); - } else { - rootnode = 0; - cmn->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(cmn->base)) - return PTR_ERR(cmn->base); - if (cmn->model == CMN600) - rootnode = arm_cmn600_of_probe(pdev->dev.of_node); - } + if (has_acpi_companion(cmn->dev)) + rootnode = arm_cmn_acpi_probe(pdev, cmn); + else + rootnode = arm_cmn_of_probe(pdev, cmn); + if (rootnode < 0) return rootnode;