예제 #1
0
static ssize_t idle_store(struct kobject *kobj, struct kobj_attribute *attr,
			  const char *buf, size_t n)
{
	unsigned short value;

	if (sscanf(buf, "%hu", &value) != 1 ||
	    (value != 0 && value != 1)) {
		printk(KERN_ERR "idle_store: Invalid value\n");
		return -EINVAL;
	}

	if (attr == &sleep_while_idle_attr) {
		enable_dyn_sleep = value;
	} else if (attr == &clocks_off_while_idle_attr) {
		clocks_off_while_idle = value;
	} else if (attr == &enable_off_mode_attr) {
		enable_off_mode = value;
		omap3_pm_off_mode_enable(enable_off_mode);
	} else if (attr == &voltage_off_while_idle_attr) {
		voltage_off_while_idle = value;
		if (voltage_off_while_idle)
			prm_set_mod_reg_bits(OMAP3430_SEL_OFF, OMAP3430_GR_MOD,
					OMAP3_PRM_VOLTCTRL_OFFSET);
		else
			prm_clear_mod_reg_bits(OMAP3430_SEL_OFF,
					OMAP3430_GR_MOD,
					OMAP3_PRM_VOLTCTRL_OFFSET);
	} else {
		return -EINVAL;
	}
	return n;
}
예제 #2
0
static int _prcm_int_handle_wakeup(void)
{
	int c;

	/* By OMAP3630ES1.x and OMAP3430ES3.1 TRM, S/W must clear
	 * the EN_IO and EN_IO_CHAIN bits of WKEN_WKUP. Those bits
	 * would be set again by S/W in sleep sequences.
	 */
	if (omap_rev() >= OMAP3430_REV_ES3_1)
		prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK |
				       OMAP3430_EN_IO_CHAIN_MASK,
				       WKUP_MOD, PM_WKEN);

	c = prcm_clear_mod_irqs(WKUP_MOD, 1);
	c += prcm_clear_mod_irqs(CORE_MOD, 1);
	c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1);
	if (omap_rev() > OMAP3430_REV_ES1_0) {
		c += prcm_clear_mod_irqs(CORE_MOD, 3);
		c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1);
	}

	return c;
}
예제 #3
0
static void omap2_enter_full_retention(void)
{
	u32 l;
	struct timespec ts_preidle, ts_postidle, ts_idle;

	/* There is 1 reference hold for all children of the oscillator
	 * clock, the following will remove it. If no one else uses the
	 * oscillator itself it will be disabled if/when we enter retention
	 * mode.
	 */
	clk_disable(osc_ck);

	/* Clear old wake-up events */
	/* REVISIT: These write to reserved bits? */
	prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1);
	prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2);
	prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST);

	/*
	 * Set MPU powerdomain's next power state to RETENTION;
	 * preserve logic state during retention
	 */
	pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET);
	pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET);

	/* Workaround to kill USB */
	l = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0) | OMAP24XX_USBSTANDBYCTRL;
	omap_ctrl_writel(l, OMAP2_CONTROL_DEVCONF0);

	omap2_gpio_prepare_for_idle(PWRDM_POWER_RET);

	if (omap2_pm_debug) {
		omap2_pm_dump(0, 0, 0);
		getnstimeofday(&ts_preidle);
	}

	/* One last check for pending IRQs to avoid extra latency due
	 * to sleeping unnecessarily. */
	if (omap_irq_pending())
		goto no_sleep;

	omap_uart_prepare_idle(0);
	omap_uart_prepare_idle(1);
	omap_uart_prepare_idle(2);

	/* Jump to SRAM suspend code */
	omap2_sram_suspend(sdrc_read_reg(SDRC_DLLA_CTRL),
				OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL),
				OMAP_SDRC_REGADDR(SDRC_POWER));
no_sleep:
	omap_uart_resume_idle(2);
	omap_uart_resume_idle(1);
	omap_uart_resume_idle(0);

	if (omap2_pm_debug) {
		unsigned long long tmp;

		getnstimeofday(&ts_postidle);
		ts_idle = timespec_sub(ts_postidle, ts_preidle);
		tmp = timespec_to_ns(&ts_idle) * NSEC_PER_USEC;
		omap2_pm_dump(0, 1, tmp);
	}
	omap2_gpio_resume_after_idle();

	clk_enable(osc_ck);

	/* clear CORE wake-up events */
	prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1);
	prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2);

	/* wakeup domain events - bit 1: GPT1, bit5 GPIO */
	prm_clear_mod_reg_bits(0x4 | 0x1, WKUP_MOD, PM_WKST);

	/* MPU domain wake events */
	l = prm_read_mod_reg(OCP_MOD, OMAP2_PRM_IRQSTATUS_MPU_OFFSET);
	if (l & 0x01)
		prm_write_mod_reg(0x01, OCP_MOD,
				OMAP2_PRM_IRQSTATUS_MPU_OFFSET);
	if (l & 0x20)
		prm_write_mod_reg(0x20, OCP_MOD,
				OMAP2_PRM_IRQSTATUS_MPU_OFFSET);

	/* Mask future PRCM-to-MPU interrupts */
	prm_write_mod_reg(0x0, OCP_MOD, OMAP2_PRM_IRQSTATUS_MPU_OFFSET);
}
예제 #4
0
static void omap3_disable_io_chain(void)
{
	if (omap_rev() >= OMAP3430_REV_ES3_1)
		prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
				       PM_WKEN);
}