From patchwork Thu Feb 17 14:24:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robin Murphy X-Patchwork-Id: 12750278 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 C711AC433EF for ; Thu, 17 Feb 2022 14:35:44 +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:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id: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=gPIoxHAEMCdebb42M+hcLRv7Lo9sG3MTTRyLFw7Yi/c=; b=Xmzi3TH3iH843f 4taw0c9YeuMUoBWJ2facTQRdH2ZaeqZFIM2huycZnBYeGP0XVMKqg8E5h2yCfbWEdmzc8wB8XB0XC JLXaYy6sHFlekoevm5f5kaNWnVbTANgDCot6ZG9DJtxqDWousqVDVAbgL0Bj6uSvWQYoAYbUf6bva 6pJqtnmurJnsVnXF2oQJcdscys3wcvJwfCnemtBJjiCTY9LHbbjllf3hgBT/lMxiJ0EdIwEhspJBO 0W3o9ZycXHqEgkqrrOqMNmilgDFzwtFhhokGG2wRDy2Y7Y6VuOhmi4vkGhFiE6PbtK3dq/fN9tGrj 9fSWmk+NNOCIiNH7r/Lw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nKhrO-00B36k-Mw; Thu, 17 Feb 2022 14:34:19 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nKhhy-00AzS2-48 for linux-arm-kernel@lists.infradead.org; Thu, 17 Feb 2022 14:24:35 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id BAB251480; Thu, 17 Feb 2022 06:24:33 -0800 (PST) Received: from e121345-lin.cambridge.arm.com (e121345-lin.cambridge.arm.com [10.1.196.40]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 9DCC43F718; Thu, 17 Feb 2022 06:24:32 -0800 (PST) From: Robin Murphy To: will@kernel.org, mark.rutland@arm.com Cc: lorenzo.pieralisi@arm.com, sudeep.holla@arm.com, linux-arm-kernel@lists.infradead.org, jean-philippe@linaro.org, leo.yan@linaro.org, noda.akio@socionext.com Subject: [PATCH 4/6] iommu/smmu: Create child devices for PMUs Date: Thu, 17 Feb 2022 14:24:18 +0000 Message-Id: X-Mailer: git-send-email 2.28.0.dirty In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220217_062434_279962_D944A36E X-CRM114-Status: GOOD ( 14.26 ) 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 Whilst SMMUv3 PMCGs are somewhat free-form, the SMMUv1/v2 PMU has a well-defined and closely-coupled relationship with the main SMMU interface. This makes it logical for the SMMU driver to be in charge of consuming the firmware description and instantiating an abstract PMU device directly, obviating the need for independent detection methods. Signed-off-by: Robin Murphy --- drivers/iommu/arm/arm-smmu/arm-smmu.c | 46 +++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index 8d6c8106fc1d..58daf81adae7 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -2070,6 +2070,45 @@ err_reset_platform_ops: __maybe_unused; return err; } +static int arm_smmu_pmu_init(struct arm_smmu_device *smmu, + int irq_offset, int num_irqs) +{ + struct platform_device *pmu, *smmu_pdev; + int i, ret = -ENOMEM; + + pmu = platform_device_alloc("arm-smmu-pmu", PLATFORM_DEVID_AUTO); + if (!pmu) + return -ENOMEM; + + pmu->dev.parent = smmu->dev; + pmu->dev.platform_data = (__force void *)smmu->base + (3 << smmu->pgshift); + pmu->num_resources = num_irqs; + pmu->resource = kcalloc(num_irqs, sizeof(*pmu->resource), GFP_KERNEL); + if (!pmu->resource) + goto error; + + smmu_pdev = to_platform_device(smmu->dev); + for (i = 0; i < num_irqs; i++) { + ret = platform_get_irq(smmu_pdev, irq_offset + i); + if (ret < 0) + goto error; + + pmu->resource[i].start = ret; + pmu->resource[i].end = ret; + pmu->resource[i].flags = IORESOURCE_IRQ; + } + + ret = platform_device_add(pmu); + if (ret) + goto error; + + return 0; +error: + pmu->dev.platform_data = NULL; + platform_device_put(pmu); + return ret; +} + static int arm_smmu_device_probe(struct platform_device *pdev) { struct resource *res; @@ -2216,6 +2255,13 @@ static int arm_smmu_device_probe(struct platform_device *pdev) goto err_unregister_device; } + /* Try the PMU last so we don't have to worry about cleaning it up */ + if (pmu_irqs) { + err = arm_smmu_pmu_init(smmu, global_irqs, pmu_irqs); + if (err) + dev_warn(dev, "Failed to create PMU device: %d", err); + } + return 0; err_unregister_device: