ARM: 6467/1: amba: optional PrimeCell core voltage switch
[pandora-kernel.git] / drivers / amba / bus.c
index 2737b97..e7df019 100644 (file)
@@ -147,6 +147,39 @@ static void amba_put_disable_pclk(struct amba_device *pcdev)
        clk_put(pclk);
 }
 
+static int amba_get_enable_vcore(struct amba_device *pcdev)
+{
+       struct regulator *vcore = regulator_get(&pcdev->dev, "vcore");
+       int ret;
+
+       pcdev->vcore = vcore;
+
+       if (IS_ERR(vcore)) {
+               /* It is OK not to supply a vcore regulator */
+               if (PTR_ERR(vcore) == -ENODEV)
+                       return 0;
+               return PTR_ERR(vcore);
+       }
+
+       ret = regulator_enable(vcore);
+       if (ret) {
+               regulator_put(vcore);
+               pcdev->vcore = ERR_PTR(-ENODEV);
+       }
+
+       return ret;
+}
+
+static void amba_put_disable_vcore(struct amba_device *pcdev)
+{
+       struct regulator *vcore = pcdev->vcore;
+
+       if (!IS_ERR(vcore)) {
+               regulator_disable(vcore);
+               regulator_put(vcore);
+       }
+}
+
 /*
  * These are the device model conversion veneers; they convert the
  * device model structures to our more specific structures.
@@ -159,6 +192,10 @@ static int amba_probe(struct device *dev)
        int ret;
 
        do {
+               ret = amba_get_enable_vcore(pcdev);
+               if (ret)
+                       break;
+
                ret = amba_get_enable_pclk(pcdev);
                if (ret)
                        break;
@@ -168,6 +205,7 @@ static int amba_probe(struct device *dev)
                        break;
 
                amba_put_disable_pclk(pcdev);
+               amba_put_disable_vcore(pcdev);
        } while (0);
 
        return ret;
@@ -180,6 +218,7 @@ static int amba_remove(struct device *dev)
        int ret = drv->remove(pcdev);
 
        amba_put_disable_pclk(pcdev);
+       amba_put_disable_vcore(pcdev);
 
        return ret;
 }