Merge back earlier suspend/hibernation changes for v4.8.
[cascardo/linux.git] / drivers / iommu / arm-smmu-v3.c
index 4ff73ff..5f6b3bc 100644 (file)
@@ -590,6 +590,7 @@ struct arm_smmu_device {
 
        unsigned long                   ias; /* IPA */
        unsigned long                   oas; /* PA */
+       unsigned long                   pgsize_bitmap;
 
 #define ARM_SMMU_MAX_ASIDS             (1 << 16)
        unsigned int                    asid_bits;
@@ -1476,7 +1477,7 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
        struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg;
 
        asid = arm_smmu_bitmap_alloc(smmu->asid_map, smmu->asid_bits);
-       if (IS_ERR_VALUE(asid))
+       if (asid < 0)
                return asid;
 
        cfg->cdptr = dmam_alloc_coherent(smmu->dev, CTXDESC_CD_DWORDS << 3,
@@ -1507,7 +1508,7 @@ static int arm_smmu_domain_finalise_s2(struct arm_smmu_domain *smmu_domain,
        struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg;
 
        vmid = arm_smmu_bitmap_alloc(smmu->vmid_map, smmu->vmid_bits);
-       if (IS_ERR_VALUE(vmid))
+       if (vmid < 0)
                return vmid;
 
        cfg->vmid       = (u16)vmid;
@@ -1516,8 +1517,6 @@ static int arm_smmu_domain_finalise_s2(struct arm_smmu_domain *smmu_domain,
        return 0;
 }
 
-static struct iommu_ops arm_smmu_ops;
-
 static int arm_smmu_domain_finalise(struct iommu_domain *domain)
 {
        int ret;
@@ -1555,7 +1554,7 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain)
        }
 
        pgtbl_cfg = (struct io_pgtable_cfg) {
-               .pgsize_bitmap  = arm_smmu_ops.pgsize_bitmap,
+               .pgsize_bitmap  = smmu->pgsize_bitmap,
                .ias            = ias,
                .oas            = oas,
                .tlb            = &arm_smmu_gather_ops,
@@ -1566,11 +1565,11 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain)
        if (!pgtbl_ops)
                return -ENOMEM;
 
-       arm_smmu_ops.pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
+       domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
        smmu_domain->pgtbl_ops = pgtbl_ops;
 
        ret = finalise_stage_fn(smmu_domain, &pgtbl_cfg);
-       if (IS_ERR_VALUE(ret))
+       if (ret < 0)
                free_io_pgtable_ops(pgtbl_ops);
 
        return ret;
@@ -1643,7 +1642,7 @@ static void arm_smmu_detach_dev(struct device *dev)
        struct arm_smmu_group *smmu_group = arm_smmu_group_get(dev);
 
        smmu_group->ste.bypass = true;
-       if (IS_ERR_VALUE(arm_smmu_install_ste_for_group(smmu_group)))
+       if (arm_smmu_install_ste_for_group(smmu_group) < 0)
                dev_warn(dev, "failed to install bypass STE\n");
 
        smmu_group->domain = NULL;
@@ -1695,7 +1694,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
        smmu_group->ste.bypass  = domain->type == IOMMU_DOMAIN_DMA;
 
        ret = arm_smmu_install_ste_for_group(smmu_group);
-       if (IS_ERR_VALUE(ret))
+       if (ret < 0)
                smmu_group->domain = NULL;
 
 out_unlock:
@@ -1942,6 +1941,7 @@ static struct iommu_ops arm_smmu_ops = {
        .attach_dev             = arm_smmu_attach_dev,
        .map                    = arm_smmu_map,
        .unmap                  = arm_smmu_unmap,
+       .map_sg                 = default_iommu_map_sg,
        .iova_to_phys           = arm_smmu_iova_to_phys,
        .add_device             = arm_smmu_add_device,
        .remove_device          = arm_smmu_remove_device,
@@ -2236,7 +2236,7 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
                                                arm_smmu_evtq_handler,
                                                arm_smmu_evtq_thread,
                                                0, "arm-smmu-v3-evtq", smmu);
-               if (IS_ERR_VALUE(ret))
+               if (ret < 0)
                        dev_warn(smmu->dev, "failed to enable evtq irq\n");
        }
 
@@ -2245,7 +2245,7 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
                ret = devm_request_irq(smmu->dev, irq,
                                       arm_smmu_cmdq_sync_handler, 0,
                                       "arm-smmu-v3-cmdq-sync", smmu);
-               if (IS_ERR_VALUE(ret))
+               if (ret < 0)
                        dev_warn(smmu->dev, "failed to enable cmdq-sync irq\n");
        }
 
@@ -2253,7 +2253,7 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
        if (irq) {
                ret = devm_request_irq(smmu->dev, irq, arm_smmu_gerror_handler,
                                       0, "arm-smmu-v3-gerror", smmu);
-               if (IS_ERR_VALUE(ret))
+               if (ret < 0)
                        dev_warn(smmu->dev, "failed to enable gerror irq\n");
        }
 
@@ -2265,7 +2265,7 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
                                                        arm_smmu_priq_thread,
                                                        0, "arm-smmu-v3-priq",
                                                        smmu);
-                       if (IS_ERR_VALUE(ret))
+                       if (ret < 0)
                                dev_warn(smmu->dev,
                                         "failed to enable priq irq\n");
                        else
@@ -2410,7 +2410,6 @@ static int arm_smmu_device_probe(struct arm_smmu_device *smmu)
 {
        u32 reg;
        bool coherent;
-       unsigned long pgsize_bitmap = 0;
 
        /* IDR0 */
        reg = readl_relaxed(smmu->base + ARM_SMMU_IDR0);
@@ -2541,13 +2540,16 @@ static int arm_smmu_device_probe(struct arm_smmu_device *smmu)
 
        /* Page sizes */
        if (reg & IDR5_GRAN64K)
-               pgsize_bitmap |= SZ_64K | SZ_512M;
+               smmu->pgsize_bitmap |= SZ_64K | SZ_512M;
        if (reg & IDR5_GRAN16K)
-               pgsize_bitmap |= SZ_16K | SZ_32M;
+               smmu->pgsize_bitmap |= SZ_16K | SZ_32M;
        if (reg & IDR5_GRAN4K)
-               pgsize_bitmap |= SZ_4K | SZ_2M | SZ_1G;
+               smmu->pgsize_bitmap |= SZ_4K | SZ_2M | SZ_1G;
 
-       arm_smmu_ops.pgsize_bitmap &= pgsize_bitmap;
+       if (arm_smmu_ops.pgsize_bitmap == -1UL)
+               arm_smmu_ops.pgsize_bitmap = smmu->pgsize_bitmap;
+       else
+               arm_smmu_ops.pgsize_bitmap |= smmu->pgsize_bitmap;
 
        /* Output address size */
        switch (reg & IDR5_OAS_MASK << IDR5_OAS_SHIFT) {