| 
					
				 | 
			
			
				@@ -153,3 +153,143 @@ static int prcm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	int c = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	wkst = omap2_prm_read_mod_reg(module, wkst_off); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	wkst &= omap2_prm_read_mod_reg(module, grpsel_off); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	wkst &= ~ignore_bits; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (wkst) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		iclk = omap2_cm_read_mod_reg(module, iclk_off); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		fclk = omap2_cm_read_mod_reg(module, fclk_off); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		while (wkst) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			clken = wkst; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			omap2_cm_set_mod_reg_bits(clken, module, iclk_off); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			 * For USBHOST, we don't know whether HOST1 or 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			 * HOST2 woke us up, so enable both f-clocks 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (module == OMAP3430ES2_USBHOST_MOD) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				clken |= 1 << OMAP3430ES2_EN_USBHOST2_SHIFT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			omap2_cm_set_mod_reg_bits(clken, module, fclk_off); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			omap2_prm_write_mod_reg(wkst, module, wkst_off); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			wkst = omap2_prm_read_mod_reg(module, wkst_off); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			wkst &= ~ignore_bits; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			c++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		omap2_cm_write_mod_reg(iclk, module, iclk_off); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		omap2_cm_write_mod_reg(fclk, module, fclk_off); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static irqreturn_t _prcm_int_handle_io(int irq, void *unused) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	c = prcm_clear_mod_irqs(WKUP_MOD, 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		~(OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return c ? IRQ_HANDLED : IRQ_NONE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static irqreturn_t _prcm_int_handle_wakeup(int irq, void *unused) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * Clear all except ST_IO and ST_IO_CHAIN for wkup module, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * these are handled in a separate handler to avoid acking 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * IO events before parsing in mux code 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	c = prcm_clear_mod_irqs(WKUP_MOD, 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	c += prcm_clear_mod_irqs(CORE_MOD, 1, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (omap_rev() > OMAP3430_REV_ES1_0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		c += prcm_clear_mod_irqs(CORE_MOD, 3, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return c ? IRQ_HANDLED : IRQ_NONE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void omap34xx_save_context(u32 *save) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u32 val; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* Read Auxiliary Control Register */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	asm("mrc p15, 0, %0, c1, c0, 1" : "=r" (val)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	*save++ = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	*save++ = val; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* Read L2 AUX ctrl register */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	asm("mrc p15, 1, %0, c9, c0, 2" : "=r" (val)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	*save++ = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	*save++ = val; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static int omap34xx_do_sram_idle(unsigned long save_state) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	omap34xx_cpu_suspend(save_state); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void omap_sram_idle(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* Variable to tell what needs to be saved and restored 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * in omap_sram_idle*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* save_state = 0 => Nothing to save and restored */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* save_state = 1 => Only L1 and logic lost */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* save_state = 2 => Only L2 lost */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* save_state = 3 => L1, L2 and logic lost */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int save_state = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int mpu_next_state = PWRDM_POWER_ON; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int per_next_state = PWRDM_POWER_ON; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int core_next_state = PWRDM_POWER_ON; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int per_going_off; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int core_prev_state; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u32 sdrc_pwr = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	switch (mpu_next_state) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case PWRDM_POWER_ON: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case PWRDM_POWER_RET: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		/* No need to save context */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		save_state = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case PWRDM_POWER_OFF: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		save_state = 3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		/* Invalid state */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		pr_err("Invalid mpu state in sram_idle\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* NEON control */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (pwrdm_read_pwrst(neon_pwrdm) == PWRDM_POWER_ON) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		pwrdm_set_next_pwrst(neon_pwrdm, mpu_next_state); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* Enable IO-PAD and IO-CHAIN wakeups */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	per_next_state = pwrdm_read_next_pwrst(per_pwrdm); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	core_next_state = pwrdm_read_next_pwrst(core_pwrdm); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	pwrdm_pre_transition(NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* PER */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (per_next_state < PWRDM_POWER_ON) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		omap2_gpio_prepare_for_idle(per_going_off); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* CORE */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (core_next_state < PWRDM_POWER_ON) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (core_next_state == PWRDM_POWER_OFF) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			omap3_core_save_context(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			omap3_cm_save_context(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	omap3_intc_prepare_idle(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * On EMU/HS devices ROM code restores a SRDC value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * from scratchpad which has automatic self refresh on timeout 
			 |