0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/kernel.h>
0010 #include <linux/suspend.h>
0011 #include <linux/io.h>
0012 #include "kirkwood.h"
0013 #include "kirkwood-pm.h"
0014
0015 static void __iomem *ddr_operation_base;
0016 static void __iomem *memory_pm_ctrl;
0017
0018 static void kirkwood_low_power(void)
0019 {
0020 u32 mem_pm_ctrl;
0021
0022 mem_pm_ctrl = readl(memory_pm_ctrl);
0023
0024
0025 writel_relaxed(~0, memory_pm_ctrl);
0026
0027
0028 writel_relaxed(0x7, ddr_operation_base);
0029
0030
0031
0032
0033
0034
0035 cpu_do_idle();
0036
0037 writel_relaxed(mem_pm_ctrl, memory_pm_ctrl);
0038 }
0039
0040 static int kirkwood_suspend_enter(suspend_state_t state)
0041 {
0042 switch (state) {
0043 case PM_SUSPEND_STANDBY:
0044 kirkwood_low_power();
0045 break;
0046 default:
0047 return -EINVAL;
0048 }
0049 return 0;
0050 }
0051
0052 static int kirkwood_pm_valid_standby(suspend_state_t state)
0053 {
0054 return state == PM_SUSPEND_STANDBY;
0055 }
0056
0057 static const struct platform_suspend_ops kirkwood_suspend_ops = {
0058 .enter = kirkwood_suspend_enter,
0059 .valid = kirkwood_pm_valid_standby,
0060 };
0061
0062 void __init kirkwood_pm_init(void)
0063 {
0064 ddr_operation_base = ioremap(DDR_OPERATION_BASE, 4);
0065 memory_pm_ctrl = ioremap(MEMORY_PM_CTRL_PHYS, 4);
0066
0067 suspend_set_ops(&kirkwood_suspend_ops);
0068 }