|
@@ -281,6 +281,9 @@ enum arm_smmu_s2cr_privcfg {
|
|
|
|
|
|
#define FSYNR0_WNR (1 << 4)
|
|
|
|
|
|
+#define MSI_IOVA_BASE 0x8000000
|
|
|
+#define MSI_IOVA_LENGTH 0x100000
|
|
|
+
|
|
|
static int force_stage;
|
|
|
module_param(force_stage, int, S_IRUGO);
|
|
|
MODULE_PARM_DESC(force_stage,
|
|
@@ -1549,6 +1552,29 @@ static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
|
|
|
return iommu_fwspec_add_ids(dev, &fwid, 1);
|
|
|
}
|
|
|
|
|
|
+static void arm_smmu_get_resv_regions(struct device *dev,
|
|
|
+ struct list_head *head)
|
|
|
+{
|
|
|
+ struct iommu_resv_region *region;
|
|
|
+ int prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO;
|
|
|
+
|
|
|
+ region = iommu_alloc_resv_region(MSI_IOVA_BASE, MSI_IOVA_LENGTH,
|
|
|
+ prot, IOMMU_RESV_MSI);
|
|
|
+ if (!region)
|
|
|
+ return;
|
|
|
+
|
|
|
+ list_add_tail(®ion->list, head);
|
|
|
+}
|
|
|
+
|
|
|
+static void arm_smmu_put_resv_regions(struct device *dev,
|
|
|
+ struct list_head *head)
|
|
|
+{
|
|
|
+ struct iommu_resv_region *entry, *next;
|
|
|
+
|
|
|
+ list_for_each_entry_safe(entry, next, head, list)
|
|
|
+ kfree(entry);
|
|
|
+}
|
|
|
+
|
|
|
static struct iommu_ops arm_smmu_ops = {
|
|
|
.capable = arm_smmu_capable,
|
|
|
.domain_alloc = arm_smmu_domain_alloc,
|
|
@@ -1564,6 +1590,8 @@ static struct iommu_ops arm_smmu_ops = {
|
|
|
.domain_get_attr = arm_smmu_domain_get_attr,
|
|
|
.domain_set_attr = arm_smmu_domain_set_attr,
|
|
|
.of_xlate = arm_smmu_of_xlate,
|
|
|
+ .get_resv_regions = arm_smmu_get_resv_regions,
|
|
|
+ .put_resv_regions = arm_smmu_put_resv_regions,
|
|
|
.pgsize_bitmap = -1UL, /* Restricted during device attach */
|
|
|
};
|
|
|
|