From patchwork Wed Nov 16 15:29:32 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Pieralisi X-Patchwork-Id: 9431959 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 85D4560471 for ; Wed, 16 Nov 2016 15:42:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7591628F3F for ; Wed, 16 Nov 2016 15:42:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6A33928F60; Wed, 16 Nov 2016 15:42:17 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0BD3428F3F for ; Wed, 16 Nov 2016 15:42:17 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1c72KH-0000WJ-AK; Wed, 16 Nov 2016 15:40:41 +0000 Received: from foss.arm.com ([217.140.101.70]) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1c729W-0003s8-GP for linux-arm-kernel@lists.infradead.org; Wed, 16 Nov 2016 15:29:40 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4EA9615AD; Wed, 16 Nov 2016 07:29:16 -0800 (PST) Received: from red-moon.cambridge.arm.com (red-moon.cambridge.arm.com [10.1.206.55]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 7BC1A3F220; Wed, 16 Nov 2016 07:29:13 -0800 (PST) From: Lorenzo Pieralisi To: iommu@lists.linux-foundation.org Subject: [PATCH v8 12/16] drivers: iommu: arm-smmu: split probe functions into DT/generic portions Date: Wed, 16 Nov 2016 15:29:32 +0000 Message-Id: <20161116152936.22955-13-lorenzo.pieralisi@arm.com> X-Mailer: git-send-email 2.10.0 In-Reply-To: <20161116152936.22955-1-lorenzo.pieralisi@arm.com> References: <20161116152936.22955-1-lorenzo.pieralisi@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20161116_072934_967310_F0DE181A X-CRM114-Status: GOOD ( 14.89 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-arm-kernel@lists.infradead.org, Lorenzo Pieralisi , linux-acpi@vger.kernel.org, Marc Zyngier , "Rafael J. Wysocki" , Joerg Roedel , Will Deacon , linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, Sinan Kaya , Eric Auger , Dennis Chen , Hanjun Guo , Tomasz Nowicki , Nate Watterson , Prem Mallappa , Robin Murphy , Jon Masters MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Current ARM SMMU probe functions intermingle HW and DT probing in the initialization functions to detect and programme the ARM SMMU driver features. In order to allow probing the ARM SMMU with other firmwares than DT, this patch splits the ARM SMMU init functions into DT and HW specific portions so that other FW interfaces (ie ACPI) can reuse the HW probing functions and skip the DT portion accordingly. This patch implements no functional change, only code reshuffling. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Tomasz Nowicki Tested-by: Hanjun Guo Tested-by: Tomasz Nowicki Cc: Will Deacon Cc: Hanjun Guo Cc: Robin Murphy Reviewed-by: Will Deacon Reviewed-by: Robin Murphy --- drivers/iommu/arm-smmu.c | 62 +++++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 339a8d3..573b2b6 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1668,7 +1668,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) unsigned long size; void __iomem *gr0_base = ARM_SMMU_GR0(smmu); u32 id; - bool cttw_dt, cttw_reg; + bool cttw_reg, cttw_fw = smmu->features & ARM_SMMU_FEAT_COHERENT_WALK; int i; dev_notice(smmu->dev, "probing hardware configuration...\n"); @@ -1713,20 +1713,17 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) /* * In order for DMA API calls to work properly, we must defer to what - * the DT says about coherency, regardless of what the hardware claims. + * the FW says about coherency, regardless of what the hardware claims. * Fortunately, this also opens up a workaround for systems where the * ID register value has ended up configured incorrectly. */ - cttw_dt = of_dma_is_coherent(smmu->dev->of_node); cttw_reg = !!(id & ID0_CTTW); - if (cttw_dt) - smmu->features |= ARM_SMMU_FEAT_COHERENT_WALK; - if (cttw_dt || cttw_reg) + if (cttw_fw || cttw_reg) dev_notice(smmu->dev, "\t%scoherent table walk\n", - cttw_dt ? "" : "non-"); - if (cttw_dt != cttw_reg) + cttw_fw ? "" : "non-"); + if (cttw_fw != cttw_reg) dev_notice(smmu->dev, - "\t(IDR0.CTTW overridden by dma-coherent property)\n"); + "\t(IDR0.CTTW overridden by FW configuration)\n"); /* Max. number of entries we have for stream matching/indexing */ size = 1 << ((id >> ID0_NUMSIDB_SHIFT) & ID0_NUMSIDB_MASK); @@ -1907,15 +1904,25 @@ static const struct of_device_id arm_smmu_of_match[] = { }; MODULE_DEVICE_TABLE(of, arm_smmu_of_match); -static int arm_smmu_device_dt_probe(struct platform_device *pdev) +static int arm_smmu_device_dt_probe(struct platform_device *pdev, + struct arm_smmu_device *smmu) { const struct arm_smmu_match_data *data; - struct resource *res; - struct arm_smmu_device *smmu; struct device *dev = &pdev->dev; - int num_irqs, i, err; bool legacy_binding; + if (of_property_read_u32(dev->of_node, "#global-interrupts", + &smmu->num_global_irqs)) { + dev_err(dev, "missing #global-interrupts property\n"); + return -ENODEV; + } + + data = of_device_get_match_data(dev); + smmu->version = data->version; + smmu->model = data->model; + + parse_driver_options(smmu); + legacy_binding = of_find_property(dev->of_node, "mmu-masters", NULL); if (legacy_binding && !using_generic_binding) { if (!using_legacy_binding) @@ -1928,6 +1935,19 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev) return -ENODEV; } + if (of_dma_is_coherent(dev->of_node)) + smmu->features |= ARM_SMMU_FEAT_COHERENT_WALK; + + return 0; +} + +static int arm_smmu_device_probe(struct platform_device *pdev) +{ + struct resource *res; + struct arm_smmu_device *smmu; + struct device *dev = &pdev->dev; + int num_irqs, i, err; + smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL); if (!smmu) { dev_err(dev, "failed to allocate arm_smmu_device\n"); @@ -1935,9 +1955,9 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev) } smmu->dev = dev; - data = of_device_get_match_data(dev); - smmu->version = data->version; - smmu->model = data->model; + err = arm_smmu_device_dt_probe(pdev, smmu); + if (err) + return err; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); smmu->base = devm_ioremap_resource(dev, res); @@ -1945,12 +1965,6 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev) return PTR_ERR(smmu->base); smmu->size = resource_size(res); - if (of_property_read_u32(dev->of_node, "#global-interrupts", - &smmu->num_global_irqs)) { - dev_err(dev, "missing #global-interrupts property\n"); - return -ENODEV; - } - num_irqs = 0; while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, num_irqs))) { num_irqs++; @@ -1985,8 +1999,6 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev) if (err) return err; - parse_driver_options(smmu); - if (smmu->version == ARM_SMMU_V2 && smmu->num_context_banks != smmu->num_context_irqs) { dev_err(dev, @@ -2048,7 +2060,7 @@ static struct platform_driver arm_smmu_driver = { .name = "arm-smmu", .of_match_table = of_match_ptr(arm_smmu_of_match), }, - .probe = arm_smmu_device_dt_probe, + .probe = arm_smmu_device_probe, .remove = arm_smmu_device_remove, };