mfd: Base interrupt for twl4030-irq must be one-shot
[pandora-kernel.git] / drivers / mfd / db8500-prcmu.c
index dcc690e..a25ab9c 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/uaccess.h>
 #include <linux/mfd/core.h>
-#include <linux/mfd/db8500-prcmu.h>
+#include <linux/mfd/dbx500-prcmu.h>
 #include <linux/regulator/db8500-prcmu.h>
 #include <linux/regulator/machine.h>
 #include <mach/hardware.h>
 #include <mach/irqs.h>
 #include <mach/db8500-regs.h>
 #include <mach/id.h>
-#include "db8500-prcmu-regs.h"
+#include "dbx500-prcmu-regs.h"
 
 /* Offset for the firmware version within the TCPM */
 #define PRCMU_FW_VERSION_OFFSET 0xA4
@@ -459,6 +459,35 @@ struct clk_mgt clk_mgt[PRCMU_NUM_REG_CLOCKS] = {
        CLK_MGT_ENTRY(UICCCLK),
 };
 
+static struct regulator *hwacc_regulator[NUM_HW_ACC];
+static struct regulator *hwacc_ret_regulator[NUM_HW_ACC];
+
+static bool hwacc_enabled[NUM_HW_ACC];
+static bool hwacc_ret_enabled[NUM_HW_ACC];
+
+static const char *hwacc_regulator_name[NUM_HW_ACC] = {
+       [HW_ACC_SVAMMDSP]       = "hwacc-sva-mmdsp",
+       [HW_ACC_SVAPIPE]        = "hwacc-sva-pipe",
+       [HW_ACC_SIAMMDSP]       = "hwacc-sia-mmdsp",
+       [HW_ACC_SIAPIPE]        = "hwacc-sia-pipe",
+       [HW_ACC_SGA]            = "hwacc-sga",
+       [HW_ACC_B2R2]           = "hwacc-b2r2",
+       [HW_ACC_MCDE]           = "hwacc-mcde",
+       [HW_ACC_ESRAM1]         = "hwacc-esram1",
+       [HW_ACC_ESRAM2]         = "hwacc-esram2",
+       [HW_ACC_ESRAM3]         = "hwacc-esram3",
+       [HW_ACC_ESRAM4]         = "hwacc-esram4",
+};
+
+static const char *hwacc_ret_regulator_name[NUM_HW_ACC] = {
+       [HW_ACC_SVAMMDSP]       = "hwacc-sva-mmdsp-ret",
+       [HW_ACC_SIAMMDSP]       = "hwacc-sia-mmdsp-ret",
+       [HW_ACC_ESRAM1]         = "hwacc-esram1-ret",
+       [HW_ACC_ESRAM2]         = "hwacc-esram2-ret",
+       [HW_ACC_ESRAM3]         = "hwacc-esram3-ret",
+       [HW_ACC_ESRAM4]         = "hwacc-esram4-ret",
+};
+
 /*
 * Used by MCDE to setup all necessary PRCMU registers
 */
@@ -507,7 +536,7 @@ static struct {
 } prcmu_version;
 
 
-int prcmu_enable_dsipll(void)
+int db8500_prcmu_enable_dsipll(void)
 {
        int i;
        unsigned int plldsifreq;
@@ -542,7 +571,7 @@ int prcmu_enable_dsipll(void)
        return 0;
 }
 
-int prcmu_disable_dsipll(void)
+int db8500_prcmu_disable_dsipll(void)
 {
        /* Disable dsi pll */
        writel(PRCMU_DISABLE_PLLDSI, PRCM_PLLDSI_ENABLE);
@@ -551,7 +580,7 @@ int prcmu_disable_dsipll(void)
        return 0;
 }
 
-int prcmu_set_display_clocks(void)
+int db8500_prcmu_set_display_clocks(void)
 {
        unsigned long flags;
        unsigned int dsiclk;
@@ -734,7 +763,7 @@ unlock_and_return:
        return r;
 }
 
-int prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll)
+int db8500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll)
 {
        unsigned long flags;
 
@@ -791,7 +820,7 @@ static void config_wakeups(void)
        last_abb_events = abb_events;
 }
 
-void prcmu_enable_wakeups(u32 wakeups)
+void db8500_prcmu_enable_wakeups(u32 wakeups)
 {
        unsigned long flags;
        u32 bits;
@@ -812,7 +841,7 @@ void prcmu_enable_wakeups(u32 wakeups)
        spin_unlock_irqrestore(&mb0_transfer.lock, flags);
 }
 
-void prcmu_config_abb_event_readout(u32 abb_events)
+void db8500_prcmu_config_abb_event_readout(u32 abb_events)
 {
        unsigned long flags;
 
@@ -824,7 +853,7 @@ void prcmu_config_abb_event_readout(u32 abb_events)
        spin_unlock_irqrestore(&mb0_transfer.lock, flags);
 }
 
-void prcmu_get_abb_event_buffer(void __iomem **buf)
+void db8500_prcmu_get_abb_event_buffer(void __iomem **buf)
 {
        if (readb(tcdm_base + PRCM_ACK_MB0_READ_POINTER) & 1)
                *buf = (tcdm_base + PRCM_ACK_MB0_WAKEUP_1_4500);
@@ -833,13 +862,13 @@ void prcmu_get_abb_event_buffer(void __iomem **buf)
 }
 
 /**
- * prcmu_set_arm_opp - set the appropriate ARM OPP
+ * db8500_prcmu_set_arm_opp - set the appropriate ARM OPP
  * @opp: The new ARM operating point to which transition is to be made
  * Returns: 0 on success, non-zero on failure
  *
  * This function sets the the operating point of the ARM.
  */
-int prcmu_set_arm_opp(u8 opp)
+int db8500_prcmu_set_arm_opp(u8 opp)
 {
        int r;
 
@@ -870,11 +899,11 @@ int prcmu_set_arm_opp(u8 opp)
 }
 
 /**
- * prcmu_get_arm_opp - get the current ARM OPP
+ * db8500_prcmu_get_arm_opp - get the current ARM OPP
  *
  * Returns: the current ARM OPP
  */
-int prcmu_get_arm_opp(void)
+int db8500_prcmu_get_arm_opp(void)
 {
        return readb(tcdm_base + PRCM_ACK_MB1_CURRENT_ARM_OPP);
 }
@@ -1023,15 +1052,169 @@ int prcmu_release_usb_wakeup_state(void)
        return r;
 }
 
+static int request_pll(u8 clock, bool enable)
+{
+       int r = 0;
+
+       if (clock == PRCMU_PLLSOC1)
+               clock = (enable ? PLL_SOC1_ON : PLL_SOC1_OFF);
+       else
+               return -EINVAL;
+
+       mutex_lock(&mb1_transfer.lock);
+
+       while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1))
+               cpu_relax();
+
+       writeb(MB1H_PLL_ON_OFF, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1));
+       writeb(clock, (tcdm_base + PRCM_REQ_MB1_PLL_ON_OFF));
+
+       writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET);
+       wait_for_completion(&mb1_transfer.work);
+
+       if (mb1_transfer.ack.header != MB1H_PLL_ON_OFF)
+               r = -EIO;
+
+       mutex_unlock(&mb1_transfer.lock);
+
+       return r;
+}
+
 /**
- * prcmu_set_epod - set the state of a EPOD (power domain)
+ * prcmu_set_hwacc - set the power state of a h/w accelerator
+ * @hwacc_dev: The hardware accelerator (enum hw_acc_dev).
+ * @state: The new power state (enum hw_acc_state).
+ *
+ * This function sets the power state of a hardware accelerator.
+ * This function should not be called from interrupt context.
+ *
+ * NOTE! Deprecated, to be removed when all users switched over to use the
+ * regulator framework API.
+ */
+int prcmu_set_hwacc(u16 hwacc_dev, u8 state)
+{
+       int r = 0;
+       bool ram_retention = false;
+       bool enable, enable_ret;
+
+       /* check argument */
+       BUG_ON(hwacc_dev >= NUM_HW_ACC);
+
+       /* get state of switches */
+       enable = hwacc_enabled[hwacc_dev];
+       enable_ret = hwacc_ret_enabled[hwacc_dev];
+
+       /* set flag if retention is possible */
+       switch (hwacc_dev) {
+       case HW_ACC_SVAMMDSP:
+       case HW_ACC_SIAMMDSP:
+       case HW_ACC_ESRAM1:
+       case HW_ACC_ESRAM2:
+       case HW_ACC_ESRAM3:
+       case HW_ACC_ESRAM4:
+               ram_retention = true;
+               break;
+       }
+
+       /* check argument */
+       BUG_ON(state > HW_ON);
+       BUG_ON(state == HW_OFF_RAMRET && !ram_retention);
+
+       /* modify enable flags */
+       switch (state) {
+       case HW_OFF:
+               enable_ret = false;
+               enable = false;
+               break;
+       case HW_ON:
+               enable = true;
+               break;
+       case HW_OFF_RAMRET:
+               enable_ret = true;
+               enable = false;
+               break;
+       }
+
+       /* get regulator (lazy) */
+       if (hwacc_regulator[hwacc_dev] == NULL) {
+               hwacc_regulator[hwacc_dev] = regulator_get(NULL,
+                       hwacc_regulator_name[hwacc_dev]);
+               if (IS_ERR(hwacc_regulator[hwacc_dev])) {
+                       pr_err("prcmu: failed to get supply %s\n",
+                               hwacc_regulator_name[hwacc_dev]);
+                       r = PTR_ERR(hwacc_regulator[hwacc_dev]);
+                       goto out;
+               }
+       }
+
+       if (ram_retention) {
+               if (hwacc_ret_regulator[hwacc_dev] == NULL) {
+                       hwacc_ret_regulator[hwacc_dev] = regulator_get(NULL,
+                               hwacc_ret_regulator_name[hwacc_dev]);
+                       if (IS_ERR(hwacc_ret_regulator[hwacc_dev])) {
+                               pr_err("prcmu: failed to get supply %s\n",
+                                       hwacc_ret_regulator_name[hwacc_dev]);
+                               r = PTR_ERR(hwacc_ret_regulator[hwacc_dev]);
+                               goto out;
+                       }
+               }
+       }
+
+       /* set regulators */
+       if (ram_retention) {
+               if (enable_ret && !hwacc_ret_enabled[hwacc_dev]) {
+                       r = regulator_enable(hwacc_ret_regulator[hwacc_dev]);
+                       if (r < 0) {
+                               pr_err("prcmu_set_hwacc: ret enable failed\n");
+                               goto out;
+                       }
+                       hwacc_ret_enabled[hwacc_dev] = true;
+               }
+       }
+
+       if (enable && !hwacc_enabled[hwacc_dev]) {
+               r = regulator_enable(hwacc_regulator[hwacc_dev]);
+               if (r < 0) {
+                       pr_err("prcmu_set_hwacc: enable failed\n");
+                       goto out;
+               }
+               hwacc_enabled[hwacc_dev] = true;
+       }
+
+       if (!enable && hwacc_enabled[hwacc_dev]) {
+               r = regulator_disable(hwacc_regulator[hwacc_dev]);
+               if (r < 0) {
+                       pr_err("prcmu_set_hwacc: disable failed\n");
+                       goto out;
+               }
+               hwacc_enabled[hwacc_dev] = false;
+       }
+
+       if (ram_retention) {
+               if (!enable_ret && hwacc_ret_enabled[hwacc_dev]) {
+                       r = regulator_disable(hwacc_ret_regulator[hwacc_dev]);
+                       if (r < 0) {
+                               pr_err("prcmu_set_hwacc: ret disable failed\n");
+                               goto out;
+                       }
+                       hwacc_ret_enabled[hwacc_dev] = false;
+               }
+       }
+
+out:
+       return r;
+}
+EXPORT_SYMBOL(prcmu_set_hwacc);
+
+/**
+ * db8500_prcmu_set_epod - set the state of a EPOD (power domain)
  * @epod_id: The EPOD to set
  * @epod_state: The new EPOD state
  *
  * This function sets the state of a EPOD (power domain). It may not be called
  * from interrupt context.
  */
-int prcmu_set_epod(u16 epod_id, u8 epod_state)
+int db8500_prcmu_set_epod(u16 epod_id, u8 epod_state)
 {
        int r = 0;
        bool ram_retention = false;
@@ -1220,27 +1403,54 @@ static int request_reg_clock(u8 clock, bool enable)
        return 0;
 }
 
+static int request_sga_clock(u8 clock, bool enable)
+{
+       u32 val;
+       int ret;
+
+       if (enable) {
+               val = readl(PRCM_CGATING_BYPASS);
+               writel(val | PRCM_CGATING_BYPASS_ICN2, PRCM_CGATING_BYPASS);
+       }
+
+       ret = request_reg_clock(clock, enable);
+
+       if (!ret && !enable) {
+               val = readl(PRCM_CGATING_BYPASS);
+               writel(val & ~PRCM_CGATING_BYPASS_ICN2, PRCM_CGATING_BYPASS);
+       }
+
+       return ret;
+}
+
 /**
- * prcmu_request_clock() - Request for a clock to be enabled or disabled.
+ * db8500_prcmu_request_clock() - Request for a clock to be enabled or disabled.
  * @clock:      The clock for which the request is made.
  * @enable:     Whether the clock should be enabled (true) or disabled (false).
  *
  * This function should only be used by the clock implementation.
  * Do not use it from any other place!
  */
-int prcmu_request_clock(u8 clock, bool enable)
+int db8500_prcmu_request_clock(u8 clock, bool enable)
 {
-       if (clock < PRCMU_NUM_REG_CLOCKS)
-               return request_reg_clock(clock, enable);
-       else if (clock == PRCMU_TIMCLK)
+       switch(clock) {
+       case PRCMU_SGACLK:
+               return request_sga_clock(clock, enable);
+       case PRCMU_TIMCLK:
                return request_timclk(enable);
-       else if (clock == PRCMU_SYSCLK)
+       case PRCMU_SYSCLK:
                return request_sysclk(enable);
-       else
-               return -EINVAL;
+       case PRCMU_PLLSOC1:
+               return request_pll(clock, enable);
+       default:
+               break;
+       }
+       if (clock < PRCMU_NUM_REG_CLOCKS)
+               return request_reg_clock(clock, enable);
+       return -EINVAL;
 }
 
-int prcmu_config_esram0_deep_sleep(u8 state)
+int db8500_prcmu_config_esram0_deep_sleep(u8 state)
 {
        if ((state > ESRAM0_DEEP_SLEEP_STATE_RET) ||
            (state < ESRAM0_DEEP_SLEEP_STATE_OFF))
@@ -1336,6 +1546,78 @@ int prcmu_stop_temp_sense(void)
        return config_hot_period(0xFFFF);
 }
 
+static int prcmu_a9wdog(u8 cmd, u8 d0, u8 d1, u8 d2, u8 d3)
+{
+
+       mutex_lock(&mb4_transfer.lock);
+
+       while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(4))
+               cpu_relax();
+
+       writeb(d0, (tcdm_base + PRCM_REQ_MB4_A9WDOG_0));
+       writeb(d1, (tcdm_base + PRCM_REQ_MB4_A9WDOG_1));
+       writeb(d2, (tcdm_base + PRCM_REQ_MB4_A9WDOG_2));
+       writeb(d3, (tcdm_base + PRCM_REQ_MB4_A9WDOG_3));
+
+       writeb(cmd, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4));
+
+       writel(MBOX_BIT(4), PRCM_MBOX_CPU_SET);
+       wait_for_completion(&mb4_transfer.work);
+
+       mutex_unlock(&mb4_transfer.lock);
+
+       return 0;
+
+}
+
+int prcmu_config_a9wdog(u8 num, bool sleep_auto_off)
+{
+       BUG_ON(num == 0 || num > 0xf);
+       return prcmu_a9wdog(MB4H_A9WDOG_CONF, num, 0, 0,
+                           sleep_auto_off ? A9WDOG_AUTO_OFF_EN :
+                           A9WDOG_AUTO_OFF_DIS);
+}
+
+int prcmu_enable_a9wdog(u8 id)
+{
+       return prcmu_a9wdog(MB4H_A9WDOG_EN, id, 0, 0, 0);
+}
+
+int prcmu_disable_a9wdog(u8 id)
+{
+       return prcmu_a9wdog(MB4H_A9WDOG_DIS, id, 0, 0, 0);
+}
+
+int prcmu_kick_a9wdog(u8 id)
+{
+       return prcmu_a9wdog(MB4H_A9WDOG_KICK, id, 0, 0, 0);
+}
+
+/*
+ * timeout is 28 bit, in ms.
+ */
+#define MAX_WATCHDOG_TIMEOUT 131000
+int prcmu_load_a9wdog(u8 id, u32 timeout)
+{
+       if (timeout > MAX_WATCHDOG_TIMEOUT)
+               /*
+                * Due to calculation bug in prcmu fw, timeouts
+                * can't be bigger than 131 seconds.
+                */
+               return -EINVAL;
+
+       return prcmu_a9wdog(MB4H_A9WDOG_LOAD,
+                           (id & A9WDOG_ID_MASK) |
+                           /*
+                            * Put the lowest 28 bits of timeout at
+                            * offset 4. Four first bits are used for id.
+                            */
+                           (u8)((timeout << 4) & 0xf0),
+                           (u8)((timeout >> 4) & 0xff),
+                           (u8)((timeout >> 12) & 0xff),
+                           (u8)((timeout >> 20) & 0xff));
+}
+
 /**
  * prcmu_set_clock_divider() - Configure the clock divider.
  * @clock:     The clock for which the request is made.
@@ -1466,6 +1748,7 @@ int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
 void prcmu_ac_wake_req(void)
 {
        u32 val;
+       u32 status;
 
        mutex_lock(&mb0_transfer.ac_wake_lock);
 
@@ -1475,11 +1758,34 @@ void prcmu_ac_wake_req(void)
 
        atomic_set(&ac_wake_req_state, 1);
 
+retry:
        writel((val | PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ), PRCM_HOSTACCESS_REQ);
 
        if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work,
-                       msecs_to_jiffies(20000))) {
-               pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n",
+                       msecs_to_jiffies(5000))) {
+               pr_crit("prcmu: %s timed out (5 s) waiting for a reply.\n",
+                       __func__);
+               goto unlock_and_return;
+       }
+
+       /*
+        * The modem can generate an AC_WAKE_ACK, and then still go to sleep.
+        * As a workaround, we wait, and then check that the modem is indeed
+        * awake (in terms of the value of the PRCM_MOD_AWAKE_STATUS
+        * register, which may not be the whole truth).
+        */
+       udelay(400);
+       status = (readl(PRCM_MOD_AWAKE_STATUS) & BITS(0, 2));
+       if (status != (PRCM_MOD_AWAKE_STATUS_PRCM_MOD_AAPD_AWAKE |
+                       PRCM_MOD_AWAKE_STATUS_PRCM_MOD_COREPD_AWAKE)) {
+               pr_err("prcmu: %s received ack, but modem not awake (0x%X).\n",
+                       __func__, status);
+               udelay(1200);
+               writel(val, PRCM_HOSTACCESS_REQ);
+               if (wait_for_completion_timeout(&mb0_transfer.ac_wake_work,
+                               msecs_to_jiffies(5000)))
+                       goto retry;
+               pr_crit("prcmu: %s timed out (5 s) waiting for AC_SLEEP_ACK.\n",
                        __func__);
        }
 
@@ -1504,8 +1810,8 @@ void prcmu_ac_sleep_req()
                PRCM_HOSTACCESS_REQ);
 
        if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work,
-                       msecs_to_jiffies(20000))) {
-               pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n",
+                       msecs_to_jiffies(5000))) {
+               pr_crit("prcmu: %s timed out (5 s) waiting for a reply.\n",
                        __func__);
        }
 
@@ -1515,23 +1821,34 @@ unlock_and_return:
        mutex_unlock(&mb0_transfer.ac_wake_lock);
 }
 
-bool prcmu_is_ac_wake_requested(void)
+bool db8500_prcmu_is_ac_wake_requested(void)
 {
        return (atomic_read(&ac_wake_req_state) != 0);
 }
 
 /**
- * prcmu_system_reset - System reset
+ * db8500_prcmu_system_reset - System reset
  *
- * Saves the reset reason code and then sets the APE_SOFRST register which
+ * Saves the reset reason code and then sets the APE_SOFTRST register which
  * fires interrupt to fw
  */
-void prcmu_system_reset(u16 reset_code)
+void db8500_prcmu_system_reset(u16 reset_code)
 {
        writew(reset_code, (tcdm_base + PRCM_SW_RST_REASON));
        writel(1, PRCM_APE_SOFTRST);
 }
 
+/**
+ * db8500_prcmu_get_reset_code - Retrieve SW reset reason code
+ *
+ * Retrieves the reset reason code stored by prcmu_system_reset() before
+ * last restart.
+ */
+u16 db8500_prcmu_get_reset_code(void)
+{
+       return readw(tcdm_base + PRCM_SW_RST_REASON);
+}
+
 /**
  * prcmu_reset_modem - ask the PRCMU to reset modem
  */
@@ -1782,7 +2099,7 @@ static struct irq_chip prcmu_irq_chip = {
        .irq_unmask     = prcmu_irq_unmask,
 };
 
-void __init prcmu_early_init(void)
+void __init db8500_prcmu_early_init(void)
 {
        unsigned int i;
 
@@ -1840,6 +2157,16 @@ void __init prcmu_early_init(void)
        }
 }
 
+static void __init db8500_prcmu_init_clkforce(void)
+{
+       u32 val;
+
+       val = readl(PRCM_A9PL_FORCE_CLKEN);
+       val &= ~(PRCM_A9PL_FORCE_CLKEN_PRCM_A9PL_FORCE_CLKEN |
+               PRCM_A9PL_FORCE_CLKEN_PRCM_A9AXI_FORCE_CLKEN);
+       writel(val, (PRCM_A9PL_FORCE_CLKEN));
+}
+
 /*
  * Power domain switches (ePODs) modeled as regulators for the DB8500 SoC
  */
@@ -1875,7 +2202,42 @@ static struct regulator_consumer_supply db8500_vsmps2_consumers[] = {
 
 static struct regulator_consumer_supply db8500_b2r2_mcde_consumers[] = {
        REGULATOR_SUPPLY("vsupply", "b2r2.0"),
-       REGULATOR_SUPPLY("vsupply", "mcde.0"),
+       REGULATOR_SUPPLY("vsupply", "mcde"),
+};
+
+/* SVA MMDSP regulator switch */
+static struct regulator_consumer_supply db8500_svammdsp_consumers[] = {
+       REGULATOR_SUPPLY("sva-mmdsp", "cm_control"),
+};
+
+/* SVA pipe regulator switch */
+static struct regulator_consumer_supply db8500_svapipe_consumers[] = {
+       REGULATOR_SUPPLY("sva-pipe", "cm_control"),
+};
+
+/* SIA MMDSP regulator switch */
+static struct regulator_consumer_supply db8500_siammdsp_consumers[] = {
+       REGULATOR_SUPPLY("sia-mmdsp", "cm_control"),
+};
+
+/* SIA pipe regulator switch */
+static struct regulator_consumer_supply db8500_siapipe_consumers[] = {
+       REGULATOR_SUPPLY("sia-pipe", "cm_control"),
+};
+
+static struct regulator_consumer_supply db8500_sga_consumers[] = {
+       REGULATOR_SUPPLY("v-mali", NULL),
+};
+
+/* ESRAM1 and 2 regulator switch */
+static struct regulator_consumer_supply db8500_esram12_consumers[] = {
+       REGULATOR_SUPPLY("esram12", "cm_control"),
+};
+
+/* ESRAM3 and 4 regulator switch */
+static struct regulator_consumer_supply db8500_esram34_consumers[] = {
+       REGULATOR_SUPPLY("v-esram34", "mcde"),
+       REGULATOR_SUPPLY("esram34", "cm_control"),
 };
 
 static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = {
@@ -1937,6 +2299,8 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = {
                        .name = "db8500-sva-mmdsp",
                        .valid_ops_mask = REGULATOR_CHANGE_STATUS,
                },
+               .consumer_supplies = db8500_svammdsp_consumers,
+               .num_consumer_supplies = ARRAY_SIZE(db8500_svammdsp_consumers),
        },
        [DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = {
                .constraints = {
@@ -1951,6 +2315,8 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = {
                        .name = "db8500-sva-pipe",
                        .valid_ops_mask = REGULATOR_CHANGE_STATUS,
                },
+               .consumer_supplies = db8500_svapipe_consumers,
+               .num_consumer_supplies = ARRAY_SIZE(db8500_svapipe_consumers),
        },
        [DB8500_REGULATOR_SWITCH_SIAMMDSP] = {
                .supply_regulator = "db8500-vape",
@@ -1958,6 +2324,8 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = {
                        .name = "db8500-sia-mmdsp",
                        .valid_ops_mask = REGULATOR_CHANGE_STATUS,
                },
+               .consumer_supplies = db8500_siammdsp_consumers,
+               .num_consumer_supplies = ARRAY_SIZE(db8500_siammdsp_consumers),
        },
        [DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = {
                .constraints = {
@@ -1971,6 +2339,8 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = {
                        .name = "db8500-sia-pipe",
                        .valid_ops_mask = REGULATOR_CHANGE_STATUS,
                },
+               .consumer_supplies = db8500_siapipe_consumers,
+               .num_consumer_supplies = ARRAY_SIZE(db8500_siapipe_consumers),
        },
        [DB8500_REGULATOR_SWITCH_SGA] = {
                .supply_regulator = "db8500-vape",
@@ -1978,6 +2348,9 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = {
                        .name = "db8500-sga",
                        .valid_ops_mask = REGULATOR_CHANGE_STATUS,
                },
+               .consumer_supplies = db8500_sga_consumers,
+               .num_consumer_supplies = ARRAY_SIZE(db8500_sga_consumers),
+
        },
        [DB8500_REGULATOR_SWITCH_B2R2_MCDE] = {
                .supply_regulator = "db8500-vape",
@@ -1994,6 +2367,8 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = {
                        .name = "db8500-esram12",
                        .valid_ops_mask = REGULATOR_CHANGE_STATUS,
                },
+               .consumer_supplies = db8500_esram12_consumers,
+               .num_consumer_supplies = ARRAY_SIZE(db8500_esram12_consumers),
        },
        [DB8500_REGULATOR_SWITCH_ESRAM12RET] = {
                .constraints = {
@@ -2007,6 +2382,8 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = {
                        .name = "db8500-esram34",
                        .valid_ops_mask = REGULATOR_CHANGE_STATUS,
                },
+               .consumer_supplies = db8500_esram34_consumers,
+               .num_consumer_supplies = ARRAY_SIZE(db8500_esram34_consumers),
        },
        [DB8500_REGULATOR_SWITCH_ESRAM34RET] = {
                .constraints = {
@@ -2038,6 +2415,8 @@ static int __init db8500_prcmu_probe(struct platform_device *pdev)
        if (ux500_is_svp())
                return -ENODEV;
 
+       db8500_prcmu_init_clkforce();
+
        /* Clean up the mailbox interrupts after pre-kernel code. */
        writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR);