/* call cpu specific preparation */
pm_cpu_prep();
/* flush cache back to ram */
flush_cache_all();
s3c2410_pm_check_store();
/* send the cpu to sleep... */
__raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */
/* s3c2410_cpu_save will also act as our return point from when
* we resume as it saves its own register state, so use the return
* code to differentiate return from save and return from sleep */
if (s3c2410_cpu_save(regs_save) == 0) {
flush_cache_all();
pm_cpu_sleep();
}
/* restore the cpu state */
cpu_init();
/*unset the return-from-sleep flag, to ensure reset */
tmp = __raw_readl(S3C2410_GSTATUS2);
tmp |= S3C2410_GSTATUS2_OFFRESET;
__raw_writel(tmp, S3C2410_GSTATUS2);
/* restore the system state */
s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
s3c2410_pm_do_restore(misc_save, ARRAY_SIZE(misc_save));//
s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save));
s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save));
s3c2410_pm_debug_init();
/* check what irq (if any) restored the system */
DBG("post sleep: IRQs 0x%08x, 0x%08x\n",
__raw_readl(S3C2410_SRCPND),
__raw_readl(S3C2410_EINTPEND));
s3c2410_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND),
s3c_irqwake_intmask);
s3c2410_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
s3c_irqwake_eintmask);
DBG("post sleep, preparing to return\n");
s3c2410_pm_check_restore();
/* ok, let's return from sleep */
dump_irq_reg();
DBG("S3C2410 PM Resume (post-restore)\n");
return 0;
}
2、在调试的过程中,出现过系统无法进入睡眠的情况。情况大概是串口终端已经进入睡眠了,系统停止了,但是用精密电源去测,发现电流还是没有下降,通过跟踪,才知道系统逐个调用各个驱动的suspend,按照s3c2410-ts.c原来提供的驱动结构:
static struct platform_driver s3c2410ts_driver = {
.name = "s3c2410-ts",
.bus = &platform_bus_type,
.probe = s3c2410ts_probe,
.remove = s3c2410ts_remove,
};