iommu: arm-smmu: Vote for power in add_device and remove_device

These functions access iommu registers, so ensure the device is in
the proper state first.

Change-Id: I66df2c25a0eb072dc9c69604fbe32d0af2828303
Signed-off-by: Patrick Daly <pdaly@codeaurora.org>
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index d714e27..4d6ee1b 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -2374,6 +2374,10 @@
 		return -ENODEV;
 	}
 
+	ret = arm_smmu_power_on(smmu->pwr);
+	if (ret)
+		goto out_free;
+
 	ret = -EINVAL;
 	for (i = 0; i < fwspec->num_ids; i++) {
 		u16 sid = fwspec->ids[i];
@@ -2382,12 +2386,12 @@
 		if (sid & ~smmu->streamid_mask) {
 			dev_err(dev, "stream ID 0x%x out of range for SMMU (0x%x)\n",
 				sid, smmu->streamid_mask);
-			goto out_free;
+			goto out_pwr_off;
 		}
 		if (mask & ~smmu->smr_mask_mask) {
 			dev_err(dev, "SMR mask 0x%x out of range for SMMU (0x%x)\n",
 				sid, smmu->smr_mask_mask);
-			goto out_free;
+			goto out_pwr_off;
 		}
 	}
 
@@ -2395,7 +2399,7 @@
 	cfg = kzalloc(offsetof(struct arm_smmu_master_cfg, smendx[i]),
 		      GFP_KERNEL);
 	if (!cfg)
-		goto out_free;
+		goto out_pwr_off;
 
 	cfg->smmu = smmu;
 	fwspec->iommu_priv = cfg;
@@ -2404,10 +2408,13 @@
 
 	ret = arm_smmu_master_alloc_smes(dev);
 	if (ret)
-		goto out_free;
+		goto out_pwr_off;
 
+	arm_smmu_power_off(smmu->pwr);
 	return 0;
 
+out_pwr_off:
+	arm_smmu_power_off(smmu->pwr);
 out_free:
 	if (fwspec)
 		kfree(fwspec->iommu_priv);
@@ -2418,14 +2425,22 @@
 static void arm_smmu_remove_device(struct device *dev)
 {
 	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
+	struct arm_smmu_device *smmu;
 
 	if (!fwspec || fwspec->ops != &arm_smmu_ops)
 		return;
 
+	smmu = fwspec_smmu(fwspec);
+	if (arm_smmu_power_on(smmu->pwr)) {
+		WARN_ON(1);
+		return;
+	}
+
 	arm_smmu_master_free_smes(fwspec);
 	iommu_group_remove_device(dev);
 	kfree(fwspec->iommu_priv);
 	iommu_fwspec_free(dev);
+	arm_smmu_power_off(smmu->pwr);
 }
 
 static struct iommu_group *arm_smmu_device_group(struct device *dev)