|  | @@ -512,3 +512,161 @@ static void __init prcm_setup_regs(void)
 | 
	
		
			
				|  |  |  				OMAP3430_DSS_MOD, PM_WKEN);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	/* Enable wakeups in PER */
 | 
	
		
			
				|  |  | +	omap2_prm_write_mod_reg(omap3630_en_uart4_mask |
 | 
	
		
			
				|  |  | +			  OMAP3430_EN_GPIO2_MASK | OMAP3430_EN_GPIO3_MASK |
 | 
	
		
			
				|  |  | +			  OMAP3430_EN_GPIO4_MASK | OMAP3430_EN_GPIO5_MASK |
 | 
	
		
			
				|  |  | +			  OMAP3430_EN_GPIO6_MASK | OMAP3430_EN_UART3_MASK |
 | 
	
		
			
				|  |  | +			  OMAP3430_EN_MCBSP2_MASK | OMAP3430_EN_MCBSP3_MASK |
 | 
	
		
			
				|  |  | +			  OMAP3430_EN_MCBSP4_MASK,
 | 
	
		
			
				|  |  | +			  OMAP3430_PER_MOD, PM_WKEN);
 | 
	
		
			
				|  |  | +	/* and allow them to wake up MPU */
 | 
	
		
			
				|  |  | +	omap2_prm_write_mod_reg(omap3630_grpsel_uart4_mask |
 | 
	
		
			
				|  |  | +			  OMAP3430_GRPSEL_GPIO2_MASK |
 | 
	
		
			
				|  |  | +			  OMAP3430_GRPSEL_GPIO3_MASK |
 | 
	
		
			
				|  |  | +			  OMAP3430_GRPSEL_GPIO4_MASK |
 | 
	
		
			
				|  |  | +			  OMAP3430_GRPSEL_GPIO5_MASK |
 | 
	
		
			
				|  |  | +			  OMAP3430_GRPSEL_GPIO6_MASK |
 | 
	
		
			
				|  |  | +			  OMAP3430_GRPSEL_UART3_MASK |
 | 
	
		
			
				|  |  | +			  OMAP3430_GRPSEL_MCBSP2_MASK |
 | 
	
		
			
				|  |  | +			  OMAP3430_GRPSEL_MCBSP3_MASK |
 | 
	
		
			
				|  |  | +			  OMAP3430_GRPSEL_MCBSP4_MASK,
 | 
	
		
			
				|  |  | +			  OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* Don't attach IVA interrupts */
 | 
	
		
			
				|  |  | +	if (omap3_has_iva()) {
 | 
	
		
			
				|  |  | +		omap2_prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
 | 
	
		
			
				|  |  | +		omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1);
 | 
	
		
			
				|  |  | +		omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3);
 | 
	
		
			
				|  |  | +		omap2_prm_write_mod_reg(0, OMAP3430_PER_MOD,
 | 
	
		
			
				|  |  | +					OMAP3430_PM_IVAGRPSEL);
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* Clear any pending 'reset' flags */
 | 
	
		
			
				|  |  | +	omap2_prm_write_mod_reg(0xffffffff, MPU_MOD, OMAP2_RM_RSTST);
 | 
	
		
			
				|  |  | +	omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP2_RM_RSTST);
 | 
	
		
			
				|  |  | +	omap2_prm_write_mod_reg(0xffffffff, OMAP3430_PER_MOD, OMAP2_RM_RSTST);
 | 
	
		
			
				|  |  | +	omap2_prm_write_mod_reg(0xffffffff, OMAP3430_EMU_MOD, OMAP2_RM_RSTST);
 | 
	
		
			
				|  |  | +	omap2_prm_write_mod_reg(0xffffffff, OMAP3430_NEON_MOD, OMAP2_RM_RSTST);
 | 
	
		
			
				|  |  | +	omap2_prm_write_mod_reg(0xffffffff, OMAP3430_DSS_MOD, OMAP2_RM_RSTST);
 | 
	
		
			
				|  |  | +	omap2_prm_write_mod_reg(0xffffffff, OMAP3430ES2_USBHOST_MOD, OMAP2_RM_RSTST);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* Clear any pending PRCM interrupts */
 | 
	
		
			
				|  |  | +	omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (omap3_has_iva())
 | 
	
		
			
				|  |  | +		omap3_iva_idle();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	omap3_d2d_idle();
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void omap3_pm_off_mode_enable(int enable)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	struct power_state *pwrst;
 | 
	
		
			
				|  |  | +	u32 state;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (enable)
 | 
	
		
			
				|  |  | +		state = PWRDM_POWER_OFF;
 | 
	
		
			
				|  |  | +	else
 | 
	
		
			
				|  |  | +		state = PWRDM_POWER_RET;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	list_for_each_entry(pwrst, &pwrst_list, node) {
 | 
	
		
			
				|  |  | +		if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583) &&
 | 
	
		
			
				|  |  | +				pwrst->pwrdm == core_pwrdm &&
 | 
	
		
			
				|  |  | +				state == PWRDM_POWER_OFF) {
 | 
	
		
			
				|  |  | +			pwrst->next_state = PWRDM_POWER_RET;
 | 
	
		
			
				|  |  | +			pr_warn("%s: Core OFF disabled due to errata i583\n",
 | 
	
		
			
				|  |  | +				__func__);
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			pwrst->next_state = state;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +int omap3_pm_get_suspend_state(struct powerdomain *pwrdm)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	struct power_state *pwrst;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	list_for_each_entry(pwrst, &pwrst_list, node) {
 | 
	
		
			
				|  |  | +		if (pwrst->pwrdm == pwrdm)
 | 
	
		
			
				|  |  | +			return pwrst->next_state;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	return -EINVAL;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	struct power_state *pwrst;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	list_for_each_entry(pwrst, &pwrst_list, node) {
 | 
	
		
			
				|  |  | +		if (pwrst->pwrdm == pwrdm) {
 | 
	
		
			
				|  |  | +			pwrst->next_state = state;
 | 
	
		
			
				|  |  | +			return 0;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	return -EINVAL;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	struct power_state *pwrst;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (!pwrdm->pwrsts)
 | 
	
		
			
				|  |  | +		return 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC);
 | 
	
		
			
				|  |  | +	if (!pwrst)
 | 
	
		
			
				|  |  | +		return -ENOMEM;
 | 
	
		
			
				|  |  | +	pwrst->pwrdm = pwrdm;
 | 
	
		
			
				|  |  | +	pwrst->next_state = PWRDM_POWER_RET;
 | 
	
		
			
				|  |  | +	list_add(&pwrst->node, &pwrst_list);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (pwrdm_has_hdwr_sar(pwrdm))
 | 
	
		
			
				|  |  | +		pwrdm_enable_hdwr_sar(pwrdm);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * Push functions to SRAM
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * The minimum set of functions is pushed to SRAM for execution:
 | 
	
		
			
				|  |  | + * - omap3_do_wfi for erratum i581 WA,
 | 
	
		
			
				|  |  | + * - save_secure_ram_context for security extensions.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +void omap_push_sram_idle(void)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	omap3_do_wfi_sram = omap_sram_push(omap3_do_wfi, omap3_do_wfi_sz);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (omap_type() != OMAP2_DEVICE_TYPE_GP)
 | 
	
		
			
				|  |  | +		_omap_save_secure_sram = omap_sram_push(save_secure_ram_context,
 | 
	
		
			
				|  |  | +				save_secure_ram_context_sz);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static void __init pm_errata_configure(void)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	if (cpu_is_omap3630()) {
 | 
	
		
			
				|  |  | +		pm34xx_errata |= PM_RTA_ERRATUM_i608;
 | 
	
		
			
				|  |  | +		/* Enable the l2 cache toggling in sleep logic */
 | 
	
		
			
				|  |  | +		enable_omap3630_toggle_l2_on_restore();
 | 
	
		
			
				|  |  | +		if (omap_rev() < OMAP3630_REV_ES1_2)
 | 
	
		
			
				|  |  | +			pm34xx_errata |= (PM_SDRC_WAKEUP_ERRATUM_i583 |
 | 
	
		
			
				|  |  | +					  PM_PER_MEMORIES_ERRATUM_i582);
 | 
	
		
			
				|  |  | +	} else if (cpu_is_omap34xx()) {
 | 
	
		
			
				|  |  | +		pm34xx_errata |= PM_PER_MEMORIES_ERRATUM_i582;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +int __init omap3_pm_init(void)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	struct power_state *pwrst, *tmp;
 | 
	
		
			
				|  |  | +	struct clockdomain *neon_clkdm, *mpu_clkdm, *per_clkdm, *wkup_clkdm;
 | 
	
		
			
				|  |  | +	int ret;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (!omap3_has_io_chain_ctrl())
 | 
	
		
			
				|  |  | +		pr_warning("PM: no software I/O chain control; some wakeups may be lost\n");
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	pm_errata_configure();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* XXX prcm_setup_regs needs to be before enabling hw
 | 
	
		
			
				|  |  | +	 * supervised mode for powerdomains */
 |