diff options
-rw-r--r-- | drivers/iommu/qcom_iommu.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/drivers/iommu/qcom_iommu.c b/drivers/iommu/qcom_iommu.c index 4a2c4378b3db..e07f02d00c68 100644 --- a/drivers/iommu/qcom_iommu.c +++ b/drivers/iommu/qcom_iommu.c | |||
@@ -66,6 +66,7 @@ struct qcom_iommu_ctx { | |||
66 | void __iomem *base; | 66 | void __iomem *base; |
67 | bool secure_init; | 67 | bool secure_init; |
68 | u8 asid; /* asid and ctx bank # are 1:1 */ | 68 | u8 asid; /* asid and ctx bank # are 1:1 */ |
69 | struct iommu_domain *domain; | ||
69 | }; | 70 | }; |
70 | 71 | ||
71 | struct qcom_iommu_domain { | 72 | struct qcom_iommu_domain { |
@@ -194,12 +195,15 @@ static irqreturn_t qcom_iommu_fault(int irq, void *dev) | |||
194 | fsynr = iommu_readl(ctx, ARM_SMMU_CB_FSYNR0); | 195 | fsynr = iommu_readl(ctx, ARM_SMMU_CB_FSYNR0); |
195 | iova = iommu_readq(ctx, ARM_SMMU_CB_FAR); | 196 | iova = iommu_readq(ctx, ARM_SMMU_CB_FAR); |
196 | 197 | ||
197 | dev_err_ratelimited(ctx->dev, | 198 | if (!report_iommu_fault(ctx->domain, ctx->dev, iova, 0)) { |
198 | "Unhandled context fault: fsr=0x%x, " | 199 | dev_err_ratelimited(ctx->dev, |
199 | "iova=0x%016llx, fsynr=0x%x, cb=%d\n", | 200 | "Unhandled context fault: fsr=0x%x, " |
200 | fsr, iova, fsynr, ctx->asid); | 201 | "iova=0x%016llx, fsynr=0x%x, cb=%d\n", |
202 | fsr, iova, fsynr, ctx->asid); | ||
203 | } | ||
201 | 204 | ||
202 | iommu_writel(ctx, ARM_SMMU_CB_FSR, fsr); | 205 | iommu_writel(ctx, ARM_SMMU_CB_FSR, fsr); |
206 | iommu_writel(ctx, ARM_SMMU_CB_RESUME, RESUME_TERMINATE); | ||
203 | 207 | ||
204 | return IRQ_HANDLED; | 208 | return IRQ_HANDLED; |
205 | } | 209 | } |
@@ -274,12 +278,14 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain, | |||
274 | 278 | ||
275 | /* SCTLR */ | 279 | /* SCTLR */ |
276 | reg = SCTLR_CFIE | SCTLR_CFRE | SCTLR_AFE | SCTLR_TRE | | 280 | reg = SCTLR_CFIE | SCTLR_CFRE | SCTLR_AFE | SCTLR_TRE | |
277 | SCTLR_M | SCTLR_S1_ASIDPNE; | 281 | SCTLR_M | SCTLR_S1_ASIDPNE | SCTLR_CFCFG; |
278 | 282 | ||
279 | if (IS_ENABLED(CONFIG_BIG_ENDIAN)) | 283 | if (IS_ENABLED(CONFIG_BIG_ENDIAN)) |
280 | reg |= SCTLR_E; | 284 | reg |= SCTLR_E; |
281 | 285 | ||
282 | iommu_writel(ctx, ARM_SMMU_CB_SCTLR, reg); | 286 | iommu_writel(ctx, ARM_SMMU_CB_SCTLR, reg); |
287 | |||
288 | ctx->domain = domain; | ||
283 | } | 289 | } |
284 | 290 | ||
285 | mutex_unlock(&qcom_domain->init_mutex); | 291 | mutex_unlock(&qcom_domain->init_mutex); |
@@ -395,6 +401,8 @@ static void qcom_iommu_detach_dev(struct iommu_domain *domain, struct device *de | |||
395 | 401 | ||
396 | /* Disable the context bank: */ | 402 | /* Disable the context bank: */ |
397 | iommu_writel(ctx, ARM_SMMU_CB_SCTLR, 0); | 403 | iommu_writel(ctx, ARM_SMMU_CB_SCTLR, 0); |
404 | |||
405 | ctx->domain = NULL; | ||
398 | } | 406 | } |
399 | pm_runtime_put_sync(qcom_iommu->dev); | 407 | pm_runtime_put_sync(qcom_iommu->dev); |
400 | 408 | ||