diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt b/Documentation/devicetree/bindings/iommu/arm,smmu.txt index 9e512d1ea763..c16084a89ccf 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt @@ -121,6 +121,12 @@ conditions. supported as we are directly comparing client SID with ID bits of SMR registers. +- qcom,deferred-regulator-disable-delay : The time delay for deferred regulator + disable in ms. In case of unmap call, regulator is + enabled/disabled. This may introduce additional delay. For + clients who do not detach, it's not possible to keep regulator + vote while smmu is attached. Type is . + - clocks : List of clocks to be used during SMMU register access. See Documentation/devicetree/bindings/clock/clock-bindings.txt for information about the format. For each clock specified diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 065379c1397f..f14812fdee6c 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -404,6 +404,7 @@ struct arm_smmu_device { struct msm_bus_scale_pdata *bus_pdata; enum tz_smmu_device_id sec_id; + int regulator_defer; }; struct arm_smmu_cfg { @@ -950,7 +951,8 @@ static int arm_smmu_disable_regulators(struct arm_smmu_device *smmu) arm_smmu_unprepare_clocks(smmu); arm_smmu_unrequest_bus(smmu); if (smmu->gdsc) { - ret = regulator_disable(smmu->gdsc); + ret = regulator_disable_deferred(smmu->gdsc, + smmu->regulator_defer); WARN(ret, "%s: Regulator disable failed\n", dev_name(smmu->dev)); } @@ -3610,6 +3612,12 @@ static int arm_smmu_init_regulators(struct arm_smmu_device *smmu) if (!of_get_property(dev->of_node, "vdd-supply", NULL)) return 0; + if (!of_property_read_u32(dev->of_node, + "qcom,deferred-regulator-disable-delay", + &(smmu->regulator_defer))) + dev_info(dev, "regulator defer delay %d\n", + smmu->regulator_defer); + smmu->gdsc = devm_regulator_get(dev, "vdd"); if (IS_ERR(smmu->gdsc)) return PTR_ERR(smmu->gdsc);