#include <linux/clk.h>
 #include <linux/libata.h>
+#include <linux/regulator/consumer.h>
 
 /* Enclosure Management Control */
 #define EM_CTRL_MSG_TYPE              0x000f0000
        u32                     em_buf_sz;      /* EM buffer size in byte */
        u32                     em_msg_type;    /* EM message type */
        struct clk              *clks[AHCI_MAX_CLKS]; /* Optional */
+       struct regulator        *target_pwr;    /* Optional */
        void                    *plat_data;     /* Other platform data */
        /*
         * Optional ahci_start_engine override, if not set this gets set to the
 
                return -ENOMEM;
        }
 
+       hpriv->target_pwr = devm_regulator_get_optional(dev, "target");
+       if (IS_ERR(hpriv->target_pwr)) {
+               rc = PTR_ERR(hpriv->target_pwr);
+               if (rc == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
+               hpriv->target_pwr = NULL;
+       }
+
        for (i = 0; i < AHCI_MAX_CLKS; i++) {
                /*
                 * For now we must use clk_get(dev, NULL) for the first clock,
                hpriv->clks[i] = clk;
        }
 
+       if (hpriv->target_pwr) {
+               rc = regulator_enable(hpriv->target_pwr);
+               if (rc)
+                       goto free_clk;
+       }
+
        rc = ahci_enable_clks(dev, hpriv);
        if (rc)
-               goto free_clk;
+               goto disable_regulator;
 
        /*
         * Some platforms might need to prepare for mmio region access,
                pdata->exit(dev);
 disable_unprepare_clk:
        ahci_disable_clks(hpriv);
+disable_regulator:
+       if (hpriv->target_pwr)
+               regulator_disable(hpriv->target_pwr);
 free_clk:
        ahci_put_clks(hpriv);
        return rc;
 
        ahci_disable_clks(hpriv);
        ahci_put_clks(hpriv);
+
+       if (hpriv->target_pwr)
+               regulator_disable(hpriv->target_pwr);
 }
 
 #ifdef CONFIG_PM_SLEEP
 
        ahci_disable_clks(hpriv);
 
+       if (hpriv->target_pwr)
+               regulator_disable(hpriv->target_pwr);
+
        return 0;
 }
 
        struct ahci_host_priv *hpriv = host->private_data;
        int rc;
 
+       if (hpriv->target_pwr) {
+               rc = regulator_enable(hpriv->target_pwr);
+               if (rc)
+                       return rc;
+       }
+
        rc = ahci_enable_clks(dev, hpriv);
        if (rc)
-               return rc;
+               goto disable_regulator;
 
        if (pdata && pdata->resume) {
                rc = pdata->resume(dev);
 
 disable_unprepare_clk:
        ahci_disable_clks(hpriv);
+disable_regulator:
+       if (hpriv->target_pwr)
+               regulator_disable(hpriv->target_pwr);
 
        return rc;
 }