Loading arch/arm64/boot/dts/qcom/msm-arm-smmu-8953.dtsi +2 −2 Original line number Diff line number Diff line /* *Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. *Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -47,7 +47,7 @@ }; apps_iommu: qcom,iommu@1e00000 { status = "disabled"; status = "okay"; compatible = "qcom,qsmmu-v500"; reg = <0x1e00000 0x40000>, <0x1ee2000 0x20>; Loading drivers/iommu/arm-smmu.c +34 −2 Original line number Diff line number Diff line Loading @@ -55,11 +55,10 @@ #include <linux/remote_spinlock.h> #include <linux/ktime.h> #include <trace/events/iommu.h> #include <soc/qcom/msm_tz_smmu.h> #include <soc/qcom/scm.h> #include <linux/notifier.h> #include <linux/amba/bus.h> #include <soc/qcom/msm_tz_smmu.h> #include "io-pgtable.h" Loading Loading @@ -2736,6 +2735,39 @@ static bool arm_smmu_capable(enum iommu_cap cap) } } #ifdef CONFIG_MSM_TZ_SMMU static struct arm_smmu_device *arm_smmu_get_by_addr(void __iomem *addr) { struct arm_smmu_device *smmu; unsigned long flags; spin_lock_irqsave(&arm_smmu_devices_lock, flags); list_for_each_entry(smmu, &arm_smmu_devices, list) { unsigned long base = (unsigned long)smmu->base; unsigned long mask = ~(smmu->size - 1); if ((base & mask) == ((unsigned long)addr & mask)) { spin_unlock_irqrestore(&arm_smmu_devices_lock, flags); return smmu; } } spin_unlock_irqrestore(&arm_smmu_devices_lock, flags); return NULL; } bool arm_smmu_skip_write(void __iomem *addr) { struct arm_smmu_device *smmu; smmu = arm_smmu_get_by_addr(addr); if (smmu && ((unsigned long)addr & (smmu->size - 1)) >= (smmu->size >> 1)) return false; else return true; } #endif static struct arm_smmu_device *arm_smmu_get_by_list(struct device_node *np) { struct arm_smmu_device *smmu; Loading include/soc/qcom/msm_tz_smmu.h +9 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,15 @@ enum tz_smmu_device_id msm_dev_to_device_id(struct device *dev); int msm_tz_set_cb_format(enum tz_smmu_device_id sec_id, int cbndx); int msm_iommu_sec_pgtbl_init(void); int register_iommu_sec_ptbl(void); bool arm_smmu_skip_write(void __iomem *addr); /* Donot write to smmu global space with CONFIG_MSM_TZ_SMMU */ #undef writel_relaxed #define writel_relaxed(v, c) do { \ if (!arm_smmu_skip_write(c)) \ ((void)__raw_writel((__force u32)cpu_to_le32(v), (c))); \ } while (0) #else static inline int msm_tz_smmu_atos_start(struct device *dev, int cb_num) Loading Loading
arch/arm64/boot/dts/qcom/msm-arm-smmu-8953.dtsi +2 −2 Original line number Diff line number Diff line /* *Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. *Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -47,7 +47,7 @@ }; apps_iommu: qcom,iommu@1e00000 { status = "disabled"; status = "okay"; compatible = "qcom,qsmmu-v500"; reg = <0x1e00000 0x40000>, <0x1ee2000 0x20>; Loading
drivers/iommu/arm-smmu.c +34 −2 Original line number Diff line number Diff line Loading @@ -55,11 +55,10 @@ #include <linux/remote_spinlock.h> #include <linux/ktime.h> #include <trace/events/iommu.h> #include <soc/qcom/msm_tz_smmu.h> #include <soc/qcom/scm.h> #include <linux/notifier.h> #include <linux/amba/bus.h> #include <soc/qcom/msm_tz_smmu.h> #include "io-pgtable.h" Loading Loading @@ -2736,6 +2735,39 @@ static bool arm_smmu_capable(enum iommu_cap cap) } } #ifdef CONFIG_MSM_TZ_SMMU static struct arm_smmu_device *arm_smmu_get_by_addr(void __iomem *addr) { struct arm_smmu_device *smmu; unsigned long flags; spin_lock_irqsave(&arm_smmu_devices_lock, flags); list_for_each_entry(smmu, &arm_smmu_devices, list) { unsigned long base = (unsigned long)smmu->base; unsigned long mask = ~(smmu->size - 1); if ((base & mask) == ((unsigned long)addr & mask)) { spin_unlock_irqrestore(&arm_smmu_devices_lock, flags); return smmu; } } spin_unlock_irqrestore(&arm_smmu_devices_lock, flags); return NULL; } bool arm_smmu_skip_write(void __iomem *addr) { struct arm_smmu_device *smmu; smmu = arm_smmu_get_by_addr(addr); if (smmu && ((unsigned long)addr & (smmu->size - 1)) >= (smmu->size >> 1)) return false; else return true; } #endif static struct arm_smmu_device *arm_smmu_get_by_list(struct device_node *np) { struct arm_smmu_device *smmu; Loading
include/soc/qcom/msm_tz_smmu.h +9 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,15 @@ enum tz_smmu_device_id msm_dev_to_device_id(struct device *dev); int msm_tz_set_cb_format(enum tz_smmu_device_id sec_id, int cbndx); int msm_iommu_sec_pgtbl_init(void); int register_iommu_sec_ptbl(void); bool arm_smmu_skip_write(void __iomem *addr); /* Donot write to smmu global space with CONFIG_MSM_TZ_SMMU */ #undef writel_relaxed #define writel_relaxed(v, c) do { \ if (!arm_smmu_skip_write(c)) \ ((void)__raw_writel((__force u32)cpu_to_le32(v), (c))); \ } while (0) #else static inline int msm_tz_smmu_atos_start(struct device *dev, int cb_num) Loading