int enter_idle_state(struct kona_idle_state *state)
{
	struct pi* pi = NULL;

#if defined(CONFIG_RHEA_WA_HWJIRA_2301) || defined(CONFIG_RHEA_WA_HWJIRA_2877)
	u32 lpddr2_temp_period = 0;
#endif

	BUG_ON(!state);

	pwr_mgr_event_clear_events(LCDTE_EVENT,BRIDGE_TO_MODEM_EVENT);
	pwr_mgr_event_clear_events(USBOTG_EVENT,MODEMBUS_ACTIVE_EVENT);

	/*Turn off XTAL only for deep sleep state*/
	if (state->flags & CPUIDLE_FLAG_XTAL_ON || keep_xtl_on)
		clk_set_crystal_pwr_on_idle(false);

	clear_wakeup_interrupts();
	config_wakeup_interrupts();

	pi = pi_mgr_get(PI_MGR_PI_ID_ARM_CORE);
	BUG_ON(pi == NULL);
	pi_enable(pi, 0);
#if defined(CONFIG_RHEA_WA_HWJIRA_2301) || defined(CONFIG_RHEA_WA_HWJIRA_2877)
	if (JIRA_WA_ENABLED(2301) || JIRA_WA_ENABLED(2877)) {
		/*
		Workaround for JIRA CRMEMC-919/2301(Periodic device temp.
		polling will prevent entering deep sleep in Rhea B0)
		 Workaround  : Disable temp. polling when A9 enters LPM &
		re-enable on exit from LPM
		*/
		lpddr2_temp_period = readl(KONA_MEMC0_NS_VA +
				CSR_LPDDR2_DEV_TEMP_PERIOD_OFFSET);
		/*Disable temperature polling, 0xC3500 -> 0x350080c0
		Disables periodic reading of the device temperature
		the period field contains the device temperature period.
		The timer operates in the XTAL clock domain. 0cC3500 is the
		default value, write it back. */
		 writel_relaxed(0xC3500,
			KONA_MEMC0_NS_VA + CSR_LPDDR2_DEV_TEMP_PERIOD_OFFSET);
	}
#endif /* CONFIG_RHEA_WA_HWJIRA_2301 || CONFIG_RHEA_WA_HWJIRA_2877 */

#ifdef CONFIG_RHEA_WA_HWJIRA_2221
	if (JIRA_WA_ENABLED(2221)) {

		u32 count;
		u32 temp_val;
		char *noncache_buf_tmp_va;

		/*JIRA HWRHEA_2221 VAR_312M is_idle from MEMC unexpectedly stays
		 * asserted for long periods of time - preventing deepsleep entry */

		 /* reset all MEMC demesh entries */
		 noncache_buf_tmp_va = noncache_buf_va;
		 for (count = 0; count < 16; count++, noncache_buf_tmp_va += 64)
			temp_val = *(volatile u32 *)noncache_buf_tmp_va;
		memc_freq_map = readl(KONA_MEMC0_NS_VA +
						CSR_MEMC_FREQ_STATE_MAPPING_OFFSET);
		writel_relaxed(1, KONA_MEMC0_NS_VA +
				CSR_MEMC_FREQ_STATE_MAPPING_OFFSET);
	}
#endif /*CONFIG_RHEA_WA_HWJIRA_2221*/
	if (dbg_dsm_suspend)
		if (state->flags & CPUIDLE_ENTER_SUSPEND) {
			rhea_clock_print_act_clks();
			rhea_pi_mgr_print_act_pis();
		}

	switch (state->state) {
	case RHEA_STATE_C2:
	case RHEA_STATE_C3:
		enter_retention_state(state);
		break;
	case RHEA_STATE_C4:
	case RHEA_STATE_C5:
		enter_dormant_state(state);
		break;
	}

#if defined(CONFIG_RHEA_WA_HWJIRA_2301) || defined(CONFIG_RHEA_WA_HWJIRA_2877)
 /*
	Workaround for JIRA CRMEMC-919/2301(Periodic device temperature polling
	will prevent entering deep sleep in Rhea B0)
	- Disable temp. polling when A9 enters LPM & re-enable on exit from LPM
 */
	if (JIRA_WA_ENABLED(2301) || JIRA_WA_ENABLED(2877))
		writel_relaxed(lpddr2_temp_period, KONA_MEMC0_NS_VA +
                        CSR_LPDDR2_DEV_TEMP_PERIOD_OFFSET);
#endif /*CONFIG_RHEA_WA_HWJIRA_2301 || CONFIG_RHEA_WA_HWJIRA_2877*/

#ifdef CONFIG_RHEA_WA_HWJIRA_2221
	if (JIRA_WA_ENABLED(2221))
		writel_relaxed(memc_freq_map, KONA_MEMC0_NS_VA +
				CSR_MEMC_FREQ_STATE_MAPPING_OFFSET);
#endif


#ifdef CONFIG_RHEA_WA_HWJIRA_2045
/*
	Workaround for JIRA 2045:
	HUB timer counter value is synchronized to apb register only on next
	32KHz falling edge after WFI wakeup - worst case this could be close to
	one 32KHz cycle (~30us). To avoid reading invalid counter value by timer
	driver, idle handler, on exit from WFI, should wait till timer counter
	is updated.
*/
	if (JIRA_WA_ENABLED(2045)) {
		u32	tmr_lsw = readl(KONA_TMR_HUB_VA + KONA_GPTIMER_STCLO_OFFSET);
		while(tmr_lsw == readl(KONA_TMR_HUB_VA + KONA_GPTIMER_STCLO_OFFSET));
	}
#endif /*CONFIG_RHEA_WA_HWJIRA_2045*/

	pm_dbg(LOG_SW2_STATUS,
		"SW2 state: %d\n", pwr_mgr_is_event_active(SOFTWARE_2_EVENT));
	pwr_mgr_event_set(SOFTWARE_2_EVENT,1);

	pi_enable(pi,1);
	scu_set_power_mode(SCU_STATUS_NORMAL);
#ifdef PM_DEBUG
	if(pwr_mgr_is_event_active(COMMON_INT_TO_AC_EVENT))
	{
		pm_dbg(LOG_INTR_STATUS, "%s:GIC act status1 = %x\n",
			__func__,
			readl(KONA_GICDIST_VA+GICDIST_ACTIVE_STATUS1_OFFSET));
		pm_dbg(LOG_INTR_STATUS, "%s:GIC act status2 = %x\n",
			__func__,
			readl(KONA_GICDIST_VA+GICDIST_ACTIVE_STATUS2_OFFSET));

		pm_dbg(LOG_INTR_STATUS, "%s:GIC act status3 = %x\n",
			__func__,
			readl(KONA_GICDIST_VA+GICDIST_ACTIVE_STATUS3_OFFSET));

		pm_dbg(LOG_INTR_STATUS, "%s:GIC act status4 = %x\n",
			__func__,
			readl(KONA_GICDIST_VA+GICDIST_ACTIVE_STATUS4_OFFSET));

		pm_dbg(LOG_INTR_STATUS, "%s:GIC act status5 = %x\n",
			__func__,
			readl(KONA_GICDIST_VA+GICDIST_ACTIVE_STATUS5_OFFSET));

		pm_dbg(LOG_INTR_STATUS, "%s:GIC act status6 = %x\n",
			__func__,
			readl(KONA_GICDIST_VA+GICDIST_ACTIVE_STATUS6_OFFSET));

		pm_dbg(LOG_INTR_STATUS, "%s:GIC act status7 = %x\n",
			__func__,
			readl(KONA_GICDIST_VA+GICDIST_ACTIVE_STATUS7_OFFSET));

		pm_dbg(LOG_INTR_STATUS, "%s:GIC pending status1 = %x\n",
			__func__,
			readl(KONA_GICDIST_VA+GICDIST_PENDING_SET1_OFFSET));
		pm_dbg(LOG_INTR_STATUS, "%s:GIC pending status2 = %x\n",
			__func__,
			readl(KONA_GICDIST_VA+GICDIST_PENDING_SET2_OFFSET));

		pm_dbg(LOG_INTR_STATUS, "%s:GIC pending status3 = %x\n",
			__func__,
			readl(KONA_GICDIST_VA+GICDIST_PENDING_SET4_OFFSET));

		pm_dbg(LOG_INTR_STATUS, "%s:GIC pending status4 = %x\n",
			__func__,
			readl(KONA_GICDIST_VA+GICDIST_PENDING_SET4_OFFSET));

		pm_dbg(LOG_INTR_STATUS, "%s:GIC pending status5 = %x\n",
			__func__,
			readl(KONA_GICDIST_VA+GICDIST_PENDING_SET5_OFFSET));

		pm_dbg(LOG_INTR_STATUS, "%s:GIC pending status6 = %x\n",
			__func__,
			readl(KONA_GICDIST_VA+GICDIST_PENDING_SET6_OFFSET));

		pm_dbg(LOG_INTR_STATUS, "%s:GIC pending status7 = %x\n",
			__func__,
			readl(KONA_GICDIST_VA+GICDIST_PENDING_SET7_OFFSET));

	}
#endif

	clear_wakeup_interrupts();
	pwr_mgr_process_events(LCDTE_EVENT,BRIDGE_TO_MODEM_EVENT,false);
	pwr_mgr_process_events(USBOTG_EVENT,PHY_RESUME_EVENT,false);

	if (state->flags & CPUIDLE_ENTER_SUSPEND)
		log_wakeup_interrupts();

	if (state->flags & CPUIDLE_FLAG_XTAL_ON || keep_xtl_on)
		clk_set_crystal_pwr_on_idle(true);
	return -1;
}
int __init island_pwr_mgr_init()
{

    struct v0x_spec_i2c_cmd_ptr v_ptr;
    int i;
    struct pi* pi;
    struct pm_policy_cfg cfg;
    cfg.ac = 1;
    cfg.atl = 0;

    v_ptr.other_ptr = 1;
    v_ptr.set2_val = 1; /*Retention voltage inx*/
    v_ptr.set2_ptr = 45;
    v_ptr.set1_val = 2;/*Should be 8 ????Wakeup override*/
    v_ptr.set1_ptr = 49;
    v_ptr.zerov_ptr = 45; /*Not used for island*/
#if 0
    /*disable jtag clock instrusive during debug*/
    pwr_mgr_ignore_dap_powerup_request(true);
#endif
    pwr_mgr_init(&island_pwr_mgr_info);
    island_pi_mgr_init();

    /*MM override is not set by default*/
    //pwr_mgr_pi_set_wakeup_override(PI_MGR_PI_ID_MM,false/*clear*/);

    /*clear all the event */
    pwr_mgr_event_clear_events(LCDTE_EVENT, EVENT_ID_ALL);

    pwr_mgr_event_set(SOFTWARE_2_EVENT,1);
    pwr_mgr_event_set(SOFTWARE_0_EVENT,1);

    /*Init I2c seq*/
    pwr_mgr_pm_i2c_enable(false);
    /*Program I2C sequencer*/
    island_pm_i2c_cmd_init();
    //pwr_mgr_pm_i2c_cmd_write(i2c_cmd,ARRAY_SIZE(i2c_cmd));
    /*Program voltage lookup table
    AVS driver may chnage this later*/
    //pwr_mgr_pm_i2c_var_data_write(pwrmgr_default_volt_lut,VLT_LUT_SIZE);
    /*populate the jump voltage table */
    //pwr_mgr_set_v0x_specific_i2c_cmd_ptr(VOLT0,&v_ptr);

    pwr_mgr_pm_i2c_enable(true);

    /*Init event table*/
    for(i = 0; i < ARRAY_SIZE(event_table); i++)
    {
        u32 event_id;

        event_id = event_table[i].event_id;

        if (event_id >= GPIO29_A_EVENT && event_id <= SPARE10_A_EVENT)
            event_id = GPIO29_A_EVENT;

        if (event_id >= GPIO29_B_EVENT && event_id <= SPARE10_B_EVENT)
            event_id = GPIO29_B_EVENT;


        pwr_mgr_event_trg_enable(event_table[i].event_id,event_table[i].trig_type);

        cfg.policy = event_table[i].policy_modem;
        pwr_mgr_event_set_pi_policy(event_id, PI_MGR_PI_ID_MODEM, &cfg);

        cfg.policy = event_table[i].policy_arm_core;
        pwr_mgr_event_set_pi_policy(event_id, PI_MGR_PI_ID_ARM_CORE, &cfg);

        cfg.policy = event_table[i].policy_arm_sub;
        pwr_mgr_event_set_pi_policy(event_id, PI_MGR_PI_ID_ARM_SUB_SYSTEM, &cfg);

        cfg.policy = event_table[i].policy_hub_aon;
        pwr_mgr_event_set_pi_policy(event_id, PI_MGR_PI_ID_HUB_AON, &cfg);

        cfg.policy = event_table[i].policy_hub_switchable;
        pwr_mgr_event_set_pi_policy(event_id, PI_MGR_PI_ID_HUB_SWITCHABLE, &cfg);

    }
    /*Init all PIs*/
    /*Init all PIs*/
    for(i = 0; i < PI_MGR_PI_ID_MODEM; i++)
    {
        pi = pi_mgr_get(i);
        BUG_ON(pi == NULL);
        pi_init(pi);
    }

    island_clock_init();

    /*All the initializations are done. Clear override bit here so that
     * appropriate policies take effect*/
#if 1
    for (i = 0; i < PI_MGR_PI_ID_MODEM; i++) {
        pi = pi_mgr_get(i);
        BUG_ON(pi == NULL);
        pi_init_state(pi);
    }
#endif
    return 0;
}