On Mon, 1 Sep 2008, Rajendra Nayak wrote: > This patch updates omap_sram_idle with CORE OFF support > > Signed-off-by: Rajendra Nayak <rnayak@xxxxxx> > --- > arch/arm/mach-omap2/cpuidle34xx.c | 37 ++++++++++++++++++++++++++++++++ > arch/arm/mach-omap2/pm.h | 2 + > arch/arm/mach-omap2/pm34xx.c | 43 ++++++++++++++++++++++++++++++++++++++ > 3 files changed, 82 insertions(+) > > Index: linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.c > =================================================================== > --- linux-omap-2.6.orig/arch/arm/mach-omap2/cpuidle34xx.c 2008-09-01 > 18:12:35.000000000 +0530 > +++ linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.c 2008-09-01 > 18:25:25.000000000 +0530 > @@ -26,11 +26,48 @@ > #include <mach/pm.h> > #include <mach/prcm.h> > #include <mach/powerdomain.h> > +#include <mach/gpmc.h> > #include <mach/control.h> > +#include <mach/irqs.h> > #include <linux/sched.h> > > #include "cpuidle34xx.h" > > +static int padconf_saved; > +void omap3_save_core_ctx(void) > +{ > + u32 control_padconf_off; > + if (!padconf_saved) { > + /* Save the padconf registers */ > + control_padconf_off = > + omap_ctrl_readl(OMAP343X_CONTROL_PADCONF_OFF); > + control_padconf_off |= START_PADCONF_SAVE; > + omap_ctrl_writel(control_padconf_off, > + OMAP343X_CONTROL_PADCONF_OFF); > + /* wait for the save to complete */ > + while (!omap_ctrl_readl(OMAP343X_CONTROL_GENERAL_PURPOSE_STATUS) > + & PADCONF_SAVE_DONE); This while() should call cpu_relax(). > + padconf_saved = 1; > + } > + /* Save the Interrupt controller context */ > + omap3_save_intc_ctx(); > + /* Save the GPMC context */ > + omap3_save_gpmc_ctx(); > + /* Save the system control module context, padconf already save above*/ > + omap3_save_control_ctx(); > +} > + > +void omap3_restore_core_ctx(void) > +{ > + /* Restore the control module context, padconf restored by h/w */ > + omap3_restore_control_ctx(); > + /* Restore the GPMC context */ > + omap3_restore_gpmc_ctx(); > + /* Restore the interrupt controller context */ > + omap3_restore_intc_ctx(); > + padconf_saved = 0; > +} > + > #ifdef CONFIG_CPU_IDLE > > struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES]; > Index: linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c > =================================================================== > --- linux-omap-2.6.orig/arch/arm/mach-omap2/pm34xx.c 2008-09-01 > 18:23:19.000000000 +0530 > +++ linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c 2008-09-01 18:24:02.000000000 > +0530 > @@ -27,10 +27,13 @@ > #include <mach/gpio.h> > #include <mach/sram.h> > #include <mach/pm.h> > +#include <mach/prcm.h> > #include <mach/clockdomain.h> > #include <mach/powerdomain.h> > #include <mach/common.h> > #include <mach/control.h> > +#include <mach/serial.h> > +#include <mach/gpio.h> > #include <asm/tlbflush.h> > > #include "cm.h" > @@ -58,6 +61,7 @@ static struct powerdomain *mpu_pwrdm, *n > static struct powerdomain *core_pwrdm, *per_pwrdm; > > int set_pwrdm_state(struct powerdomain *pwrdm, u32 state); > +void omap3_restore_sram_ctx(void); > > u32 context_mem[128]; > > @@ -91,6 +95,16 @@ static void gpio_fclk_mask(u32 *fclk) > *fclk &= ~(0x1f << 13); > } > > +void omap3_save_per_ctx(void) > +{ > + omap3_gpio_save(); > +} > + > +void omap3_restore_per_ctx(void) > +{ > + omap3_gpio_restore(); > +} > + > /* PRCM Interrupt Handler for wakeups */ > static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) > { > @@ -225,6 +239,7 @@ void omap_sram_idle(void) > int mpu_next_state = PWRDM_POWER_ON; > int per_next_state = PWRDM_POWER_ON; > int core_next_state = PWRDM_POWER_ON; > + int core_prev_state, per_prev_state; > > if (!_omap_sram_idle) > return; > @@ -261,15 +276,27 @@ void omap_sram_idle(void) > /* PER changes only with core */ > per_next_state = pwrdm_read_next_pwrst(per_pwrdm); > if (per_next_state < PWRDM_POWER_ON) { > + if (per_next_state == PWRDM_POWER_OFF) { > + omap3_save_per_ctx(); > + omap3_save_uart_ctx(2); > + } > if (clocks_off_while_idle) { > per_gpio_clk_disable(); > omap_serial_enable_clocks(0, 2); > } > } > + if (core_next_state == PWRDM_POWER_OFF) { > + omap3_save_core_ctx(); > + omap3_save_prcm_ctx(); > + omap3_save_uart_ctx(0); > + omap3_save_uart_ctx(1); > + } > if (clocks_off_while_idle) { > omap_serial_enable_clocks(0, 0); > omap_serial_enable_clocks(0, 1); > } > + if (core_next_state == PWRDM_POWER_OFF) > + omap3_save_prcm_ctx(); > /* Enable IO-PAD wakeup */ > prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN); > } > @@ -284,16 +311,31 @@ void omap_sram_idle(void) > if (core_next_state < PWRDM_POWER_ON) { > /* Disable IO-PAD wakeup */ > prm_clear_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN); > + core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm); > + if (core_prev_state == PWRDM_POWER_OFF) > + omap3_restore_prcm_ctx(); > if (clocks_off_while_idle) { > omap_serial_enable_clocks(1, 0); > omap_serial_enable_clocks(1, 1); > } > + if (core_prev_state == PWRDM_POWER_OFF) { > + omap3_restore_core_ctx(); > + omap3_restore_sram_ctx(); > + omap3_restore_uart_ctx(0); > + omap3_restore_uart_ctx(1); > + } > if (per_next_state < PWRDM_POWER_ON) { > if (clocks_off_while_idle) { > per_gpio_clk_enable(); > /* This would be actually more effective */ > omap_serial_enable_clocks(1, 2); > } > + per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm); > + if (per_prev_state == PWRDM_POWER_OFF) { > + omap3_restore_per_ctx(); > + /* This would be actually more effective */ > + omap3_restore_uart_ctx(2); > + } > } > omap2_gpio_resume_after_retention(); > } > @@ -815,6 +857,7 @@ int __init omap3_pm_init(void) > /* XXX prcm_setup_regs needs to be before enabling hw > * supervised mode for powerdomains */ > prcm_setup_regs(); > + omap3_save_scratchpad_contents(); > > ret = request_irq(INT_34XX_PRCM_MPU_IRQ, > (irq_handler_t)prcm_interrupt_handler, > Index: linux-omap-2.6/arch/arm/mach-omap2/pm.h > =================================================================== > --- linux-omap-2.6.orig/arch/arm/mach-omap2/pm.h 2008-09-01 18:12:35.000000000 > +0530 > +++ linux-omap-2.6/arch/arm/mach-omap2/pm.h 2008-09-01 18:24:02.000000000 +0530 > @@ -22,6 +22,8 @@ extern atomic_t sleep_block; > > extern void omap2_block_sleep(void); > extern void omap2_allow_sleep(void); > +extern void omap3_save_core_ctx(void); > +extern void omap3_restore_core_ctx(void); > > #define OMAP343X_TABLE_ADDRESS_OFFSET 0x31 > #define OMAP343X_TABLE_VALUE_OFFSET 0x30 > > > -- > To unsubscribe from this list: send the line "unsubscribe linux-omap" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html > - Paul -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html