Received: by 2002:ad5:4acb:0:0:0:0:0 with SMTP id n11csp1240393imw; Fri, 8 Jul 2022 23:29:20 -0700 (PDT) X-Google-Smtp-Source: AGRyM1v00KOJKGEJBqazwbQcgexe5ydRJpgvi9UIK0eASeEHKE6TBOFeGoyhl8rA7O3vX07MDWOP X-Received: by 2002:a05:6402:50c7:b0:435:923b:9b23 with SMTP id h7-20020a05640250c700b00435923b9b23mr9855581edb.336.1657348160802; Fri, 08 Jul 2022 23:29:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657348160; cv=none; d=google.com; s=arc-20160816; b=l5fDYrqQfFr9zT1EPvOyYmbY6Ux0/Z2vLxMRB77khv4R5IX5CxabVOckgbCa9TvMau HaIAn8YKU+/ZrZRg4WU7BJmhtmld8+yBhspWCwGDBW0+lZXL+4KG6MZ1tpaMWiv8WNcE KtTNT+Uz0qmCsS02yhJn0dnqnPapdYXfEsYRmrprtWLYj8YXZ0DGpRBZoEUN46bjdh7b ZAY0g4ubjTibAaI5bzyRzu/1psEEy7+h0aucOn171Uhw478YeauZGQFqJ8e3UW+yG04K bqNIyk+6OH1XW5RVBYni4si3NAeby8LULOdT3i/VPRjibLjrfUNT9tDSEgyONPr95CCu 3lwA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:in-reply-to:from :references:cc:to:content-language:subject:user-agent:mime-version :date:message-id:dkim-signature; bh=ZbV3gRfMak1R7V+ity233CxXUMLrgqK2UNyhVz9OqoU=; b=Rc+8l96kSghZ48i8GBfxvSRKRo0fbeb9ZIdYl+onfDN2w6x1OZv6+UQXpFYSt6HLEm sAvqwYPXXKzvqT8Iy13FJJ1ryCXtFmWDhYH6jn04Mn6vbU1O8wCnaDrb9aXvRNTgBoYp +WjQgLNgF34USTPBzsXpPkIuMrFHxksQ2RKWIY9n8knaIfeArWSgUCmC5ltHV6CBhlHt avW5m0Ib1jUOhyy0o1/yJ3qbjXfIkSZqoWPvWrheGDa57UcVctn6l/JPu5uAcoFc1AkU V2x2eydC0/rOVuRIovJVUt7LyXHGrHaSOLVnOqXKuNleTmupWvO1rsW/OONVvOU0Npd+ pz7Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcdkim header.b="l/7quTRZ"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id z9-20020a50eb49000000b0043a76c17f47si1059954edp.495.2022.07.08.23.28.54; Fri, 08 Jul 2022 23:29:20 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcdkim header.b="l/7quTRZ"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229555AbiGIFkv (ORCPT + 99 others); Sat, 9 Jul 2022 01:40:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40192 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229448AbiGIFku (ORCPT ); Sat, 9 Jul 2022 01:40:50 -0400 Received: from alexa-out-sd-02.qualcomm.com (alexa-out-sd-02.qualcomm.com [199.106.114.39]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5B4A164E1E; Fri, 8 Jul 2022 22:40:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1657345249; x=1688881249; h=message-id:date:mime-version:subject:to:cc:references: from:in-reply-to:content-transfer-encoding; bh=ZbV3gRfMak1R7V+ity233CxXUMLrgqK2UNyhVz9OqoU=; b=l/7quTRZxZ9eCcn/q7NXxAEgyG2gnkAFts8jrCC7q4+0XntfpA8qXOTF mrlauD9kL8FkKFk2wlY+pqe4AqMns/UXPxNpSy2Aoc5J+tN1TkL2hZPxi yvwe7x+Piw0H47QxoRJC3ziOJoMwyHbYZdVtno7uL4cThT/2B47Pn8srN o=; Received: from unknown (HELO ironmsg04-sd.qualcomm.com) ([10.53.140.144]) by alexa-out-sd-02.qualcomm.com with ESMTP; 08 Jul 2022 22:40:48 -0700 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg04-sd.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Jul 2022 22:40:48 -0700 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.22; Fri, 8 Jul 2022 22:40:48 -0700 Received: from [10.216.50.27] (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.22; Fri, 8 Jul 2022 22:40:44 -0700 Message-ID: <1b81980c-c32c-438d-4f08-c7481a955d18@quicinc.com> Date: Sat, 9 Jul 2022 11:10:40 +0530 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.3.2 Subject: Re: [PATCHv3] iommu/arm-smmu-qcom: Add debug support for TLB sync timeouts Content-Language: en-US To: Sai Prakash Ranjan , Will Deacon , Robin Murphy , Joerg Roedel CC: , , , , Bjorn Andersson References: <20220708094230.4349-1-quic_saipraka@quicinc.com> From: Akhil P Oommen In-Reply-To: <20220708094230.4349-1-quic_saipraka@quicinc.com> Content-Type: text/plain; charset="UTF-8"; format=flowed Content-Transfer-Encoding: 7bit X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,NICE_REPLY_A,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 7/8/2022 3:12 PM, Sai Prakash Ranjan wrote: > TLB sync timeouts can be due to various reasons such as TBU power down > or pending TCU/TBU invalidation/sync and so on. Debugging these often > require dumping of some implementation defined registers to know the > status of TBU/TCU operations and some of these registers are not > accessible in non-secure world such as from kernel and requires SMC > calls to read them in the secure world. So, add this debug support > to dump implementation defined registers for TLB sync timeout issues. > > Signed-off-by: Sai Prakash Ranjan > --- > > Changes in v3: > * Move this debug feature to arm-smmu-qcom-debug.c (Will Deacon). > * Keep single ratelimit state and remove local variable (Robin). > > Changes in v2: > * Use scm call consistently so that it works on older chipsets where > some of these regs are secure registers. > * Add device specific data to get the implementation defined register > offsets. > > --- > drivers/iommu/Kconfig | 10 ++ > drivers/iommu/arm/arm-smmu/Makefile | 1 + > .../iommu/arm/arm-smmu/arm-smmu-qcom-debug.c | 142 ++++++++++++++++++ > drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 32 +++- > drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h | 28 ++++ > drivers/iommu/arm/arm-smmu/arm-smmu.c | 6 +- > drivers/iommu/arm/arm-smmu/arm-smmu.h | 1 + > 7 files changed, 211 insertions(+), 9 deletions(-) > create mode 100644 drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c > create mode 100644 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h > > diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig > index c79a0df090c0..5c5cb5bee8b6 100644 > --- a/drivers/iommu/Kconfig > +++ b/drivers/iommu/Kconfig > @@ -363,6 +363,16 @@ config ARM_SMMU_QCOM > When running on a Qualcomm platform that has the custom variant > of the ARM SMMU, this needs to be built into the SMMU driver. > > +config ARM_SMMU_QCOM_DEBUG > + bool "ARM SMMU QCOM implementation defined debug support" > + depends on ARM_SMMU_QCOM > + help > + Support for implementation specific debug features in ARM SMMU > + hardware found in QTI platforms. > + > + Say Y here to enable debug for issues such as TLB sync timeouts > + which requires implementation defined register dumps. > + > config ARM_SMMU_V3 > tristate "ARM Ltd. System MMU Version 3 (SMMUv3) Support" > depends on ARM64 > diff --git a/drivers/iommu/arm/arm-smmu/Makefile b/drivers/iommu/arm/arm-smmu/Makefile > index b0cc01aa20c9..2a5a95e8e3f9 100644 > --- a/drivers/iommu/arm/arm-smmu/Makefile > +++ b/drivers/iommu/arm/arm-smmu/Makefile > @@ -3,3 +3,4 @@ obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o > obj-$(CONFIG_ARM_SMMU) += arm_smmu.o > arm_smmu-objs += arm-smmu.o arm-smmu-impl.o arm-smmu-nvidia.o > arm_smmu-$(CONFIG_ARM_SMMU_QCOM) += arm-smmu-qcom.o > +arm_smmu-$(CONFIG_ARM_SMMU_QCOM_DEBUG) += arm-smmu-qcom-debug.o > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c > new file mode 100644 > index 000000000000..6eed8e67a0ca > --- /dev/null > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c > @@ -0,0 +1,142 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. > + */ > + > +#include > +#include > +#include > + > +#include "arm-smmu.h" > +#include "arm-smmu-qcom.h" > + > +enum qcom_smmu_impl_reg_offset { > + QCOM_SMMU_TBU_PWR_STATUS, > + QCOM_SMMU_STATS_SYNC_INV_TBU_ACK, > + QCOM_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR, > +}; > + > +struct qcom_smmu_config { > + const u32 *reg_offset; > +}; > + > +void qcom_smmu_tlb_sync_debug(struct arm_smmu_device *smmu) > +{ > + int ret; > + u32 tbu_pwr_status, sync_inv_ack, sync_inv_progress; > + struct qcom_smmu *qsmmu = container_of(smmu, struct qcom_smmu, smmu); > + const struct qcom_smmu_config *cfg; > + static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL, > + DEFAULT_RATELIMIT_BURST); > + > + if (__ratelimit(&rs)) { > + dev_err(smmu->dev, "TLB sync timed out -- SMMU may be deadlocked\n"); > + > + cfg = qsmmu->cfg; > + if (!cfg) > + return; > + > + ret = qcom_scm_io_readl(smmu->ioaddr + cfg->reg_offset[QCOM_SMMU_TBU_PWR_STATUS], > + &tbu_pwr_status); > + if (ret) > + dev_err(smmu->dev, > + "Failed to read TBU power status: %d\n", ret); > + > + ret = qcom_scm_io_readl(smmu->ioaddr + cfg->reg_offset[QCOM_SMMU_STATS_SYNC_INV_TBU_ACK], > + &sync_inv_ack); > + if (ret) > + dev_err(smmu->dev, > + "Failed to read TBU sync/inv ack status: %d\n", ret); > + > + ret = qcom_scm_io_readl(smmu->ioaddr + cfg->reg_offset[QCOM_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR], > + &sync_inv_progress); > + if (ret) > + dev_err(smmu->dev, > + "Failed to read TCU syn/inv progress: %d\n", ret); > + > + dev_err(smmu->dev, > + "TBU: power_status %#x sync_inv_ack %#x sync_inv_progress %#x\n", > + tbu_pwr_status, sync_inv_ack, sync_inv_progress); > + } > +} > + > +/* Implementation Defined Register Space 0 register offsets */ > +static const u32 qcom_smmu_impl0_reg_offset[] = { > + [QCOM_SMMU_TBU_PWR_STATUS] = 0x2204, > + [QCOM_SMMU_STATS_SYNC_INV_TBU_ACK] = 0x25dc, > + [QCOM_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR] = 0x2670, > +}; > + > +static const struct qcom_smmu_config qcm2290_smmu_cfg = { > + .reg_offset = qcom_smmu_impl0_reg_offset, > +}; > + > +static const struct qcom_smmu_config sc7180_smmu_cfg = { > + .reg_offset = qcom_smmu_impl0_reg_offset, > +}; > + > +static const struct qcom_smmu_config sc7280_smmu_cfg = { > + .reg_offset = qcom_smmu_impl0_reg_offset, > +}; > + > +static const struct qcom_smmu_config sc8180x_smmu_cfg = { > + .reg_offset = qcom_smmu_impl0_reg_offset, > +}; > + > +static const struct qcom_smmu_config sc8280xp_smmu_cfg = { > + .reg_offset = qcom_smmu_impl0_reg_offset, > +}; > + > +static const struct qcom_smmu_config sm6125_smmu_cfg = { > + .reg_offset = qcom_smmu_impl0_reg_offset, > +}; > + > +static const struct qcom_smmu_config sm6350_smmu_cfg = { > + .reg_offset = qcom_smmu_impl0_reg_offset, > +}; > + > +static const struct qcom_smmu_config sm8150_smmu_cfg = { > + .reg_offset = qcom_smmu_impl0_reg_offset, > +}; > + > +static const struct qcom_smmu_config sm8250_smmu_cfg = { > + .reg_offset = qcom_smmu_impl0_reg_offset, > +}; > + > +static const struct qcom_smmu_config sm8350_smmu_cfg = { > + .reg_offset = qcom_smmu_impl0_reg_offset, > +}; > + > +static const struct qcom_smmu_config sm8450_smmu_cfg = { > + .reg_offset = qcom_smmu_impl0_reg_offset, > +}; > + Can we avoid these duplications? -Akhil. > +static const struct of_device_id __maybe_unused qcom_smmu_impl_debug_match[] = { > + { .compatible = "qcom,msm8998-smmu-v2" }, > + { .compatible = "qcom,qcm2290-smmu-500", .data = &qcm2290_smmu_cfg }, > + { .compatible = "qcom,sc7180-smmu-500", .data = &sc7180_smmu_cfg }, > + { .compatible = "qcom,sc7280-smmu-500", .data = &sc7280_smmu_cfg}, > + { .compatible = "qcom,sc8180x-smmu-500", .data = &sc8180x_smmu_cfg }, > + { .compatible = "qcom,sc8280xp-smmu-500", .data = &sc8280xp_smmu_cfg }, > + { .compatible = "qcom,sdm630-smmu-v2" }, > + { .compatible = "qcom,sdm845-smmu-500" }, > + { .compatible = "qcom,sm6125-smmu-500", .data = &sm6125_smmu_cfg}, > + { .compatible = "qcom,sm6350-smmu-500", .data = &sm6350_smmu_cfg}, > + { .compatible = "qcom,sm8150-smmu-500", .data = &sm8150_smmu_cfg }, > + { .compatible = "qcom,sm8250-smmu-500", .data = &sm8250_smmu_cfg }, > + { .compatible = "qcom,sm8350-smmu-500", .data = &sm8350_smmu_cfg }, > + { .compatible = "qcom,sm8450-smmu-500", .data = &sm8450_smmu_cfg }, > + { } > +}; > + > +const void *qcom_smmu_impl_data(struct arm_smmu_device *smmu) > +{ > + const struct of_device_id *match; > + const struct device_node *np = smmu->dev->of_node; > + > + match = of_match_node(qcom_smmu_impl_debug_match, np); > + if (!match) > + return NULL; > + > + return match->data; > +} > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c > index 2d470d867887..de25071e33ab 100644 > --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c > @@ -5,23 +5,40 @@ > > #include > #include > +#include > #include > #include > > #include "arm-smmu.h" > +#include "arm-smmu-qcom.h" > > -struct qcom_smmu { > - struct arm_smmu_device smmu; > - bool bypass_quirk; > - u8 bypass_cbndx; > - u32 stall_enabled; > -}; > +#define QCOM_DUMMY_VAL -1 > > static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu) > { > return container_of(smmu, struct qcom_smmu, smmu); > } > > +static void qcom_smmu_tlb_sync(struct arm_smmu_device *smmu, int page, > + int sync, int status) > +{ > + unsigned int spin_cnt, delay; > + u32 reg; > + > + arm_smmu_writel(smmu, page, sync, QCOM_DUMMY_VAL); > + for (delay = 1; delay < TLB_LOOP_TIMEOUT; delay *= 2) { > + for (spin_cnt = TLB_SPIN_COUNT; spin_cnt > 0; spin_cnt--) { > + reg = arm_smmu_readl(smmu, page, status); > + if (!(reg & ARM_SMMU_sTLBGSTATUS_GSACTIVE)) > + return; > + cpu_relax(); > + } > + udelay(delay); > + } > + > + qcom_smmu_tlb_sync_debug(smmu); > +} > + > static void qcom_adreno_smmu_write_sctlr(struct arm_smmu_device *smmu, int idx, > u32 reg) > { > @@ -375,6 +392,7 @@ static const struct arm_smmu_impl qcom_smmu_impl = { > .def_domain_type = qcom_smmu_def_domain_type, > .reset = qcom_smmu500_reset, > .write_s2cr = qcom_smmu_write_s2cr, > + .tlb_sync = qcom_smmu_tlb_sync, > }; > > static const struct arm_smmu_impl qcom_adreno_smmu_impl = { > @@ -383,6 +401,7 @@ static const struct arm_smmu_impl qcom_adreno_smmu_impl = { > .reset = qcom_smmu500_reset, > .alloc_context_bank = qcom_adreno_smmu_alloc_context_bank, > .write_sctlr = qcom_adreno_smmu_write_sctlr, > + .tlb_sync = qcom_smmu_tlb_sync, > }; > > static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu, > @@ -399,6 +418,7 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu, > return ERR_PTR(-ENOMEM); > > qsmmu->smmu.impl = impl; > + qsmmu->cfg = qcom_smmu_impl_data(smmu); > > return &qsmmu->smmu; > } > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h > new file mode 100644 > index 000000000000..99ec8f8629a0 > --- /dev/null > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h > @@ -0,0 +1,28 @@ > +/* SPDX-License-Identifier: GPL-2.0-only */ > +/* > + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. > + */ > + > +#ifndef _ARM_SMMU_QCOM_H > +#define _ARM_SMMU_QCOM_H > + > +struct qcom_smmu { > + struct arm_smmu_device smmu; > + const struct qcom_smmu_config *cfg; > + bool bypass_quirk; > + u8 bypass_cbndx; > + u32 stall_enabled; > +}; > + > +#ifdef CONFIG_ARM_SMMU_QCOM_DEBUG > +void qcom_smmu_tlb_sync_debug(struct arm_smmu_device *smmu); > +const void *qcom_smmu_impl_data(struct arm_smmu_device *smmu); > +#else > +static inline void qcom_smmu_tlb_sync_debug(struct arm_smmu_device *smmu) { } > +static inline const void *qcom_smmu_impl_data(struct arm_smmu_device *smmu) > +{ > + return NULL; > +} > +#endif > + > +#endif /* _ARM_SMMU_QCOM_H */ > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c > index 2ed3594f384e..41633e5484f8 100644 > --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c > @@ -2074,7 +2074,6 @@ err_reset_platform_ops: __maybe_unused; > static int arm_smmu_device_probe(struct platform_device *pdev) > { > struct resource *res; > - resource_size_t ioaddr; > struct arm_smmu_device *smmu; > struct device *dev = &pdev->dev; > int num_irqs, i, err; > @@ -2098,7 +2097,8 @@ static int arm_smmu_device_probe(struct platform_device *pdev) > smmu->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); > if (IS_ERR(smmu->base)) > return PTR_ERR(smmu->base); > - ioaddr = res->start; > + smmu->ioaddr = res->start; > + > /* > * The resource size should effectively match the value of SMMU_TOP; > * stash that temporarily until we know PAGESIZE to validate it with. > @@ -2178,7 +2178,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev) > } > > err = iommu_device_sysfs_add(&smmu->iommu, smmu->dev, NULL, > - "smmu.%pa", &ioaddr); > + "smmu.%pa", &smmu->ioaddr); > if (err) { > dev_err(dev, "Failed to register iommu in sysfs\n"); > return err; > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h > index 2b9b42fb6f30..703fd5817ec1 100644 > --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h > @@ -278,6 +278,7 @@ struct arm_smmu_device { > struct device *dev; > > void __iomem *base; > + phys_addr_t ioaddr; > unsigned int numpage; > unsigned int pgshift; >