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; }
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; }
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); }
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); }