1 /* 2 * OMAP4 Power Management Routines 3 * 4 * Copyright (C) 2010 Texas Instruments, Inc. 5 * Rajendra Nayak <rnayak@ti.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 */ 11 12 #include <linux/pm.h> 13 #include <linux/suspend.h> 14 #include <linux/module.h> 15 #include <linux/list.h> 16 #include <linux/err.h> 17 #include <linux/slab.h> 18 19 #include <plat/powerdomain.h> 20 #include <mach/omap4-common.h> 21 22 struct power_state { 23 struct powerdomain *pwrdm; 24 u32 next_state; 25 #ifdef CONFIG_SUSPEND 26 u32 saved_state; 27 #endif 28 struct list_head node; 29 }; 30 31 static LIST_HEAD(pwrst_list); 32 33 #ifdef CONFIG_SUSPEND 34 static int omap4_pm_prepare(void) 35 { 36 disable_hlt(); 37 return 0; 38 } 39 40 static int omap4_pm_suspend(void) 41 { 42 do_wfi(); 43 return 0; 44 } 45 46 static int omap4_pm_enter(suspend_state_t suspend_state) 47 { 48 int ret = 0; 49 50 switch (suspend_state) { 51 case PM_SUSPEND_STANDBY: 52 case PM_SUSPEND_MEM: 53 ret = omap4_pm_suspend(); 54 break; 55 default: 56 ret = -EINVAL; 57 } 58 59 return ret; 60 } 61 62 static void omap4_pm_finish(void) 63 { 64 enable_hlt(); 65 return; 66 } 67 68 static int omap4_pm_begin(suspend_state_t state) 69 { 70 return 0; 71 } 72 73 static void omap4_pm_end(void) 74 { 75 return; 76 } 77 78 static struct platform_suspend_ops omap_pm_ops = { 79 .begin = omap4_pm_begin, 80 .end = omap4_pm_end, 81 .prepare = omap4_pm_prepare, 82 .enter = omap4_pm_enter, 83 .finish = omap4_pm_finish, 84 .valid = suspend_valid_only_mem, 85 }; 86 #endif /* CONFIG_SUSPEND */ 87 88 static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) 89 { 90 struct power_state *pwrst; 91 92 if (!pwrdm->pwrsts) 93 return 0; 94 95 pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC); 96 if (!pwrst) 97 return -ENOMEM; 98 pwrst->pwrdm = pwrdm; 99 pwrst->next_state = PWRDM_POWER_ON; 100 list_add(&pwrst->node, &pwrst_list); 101 102 return pwrdm_set_next_pwrst(pwrst->pwrdm, pwrst->next_state); 103 } 104 105 /** 106 * omap4_pm_init - Init routine for OMAP4 PM 107 * 108 * Initializes all powerdomain and clockdomain target states 109 * and all PRCM settings. 110 */ 111 static int __init omap4_pm_init(void) 112 { 113 int ret; 114 115 if (!cpu_is_omap44xx()) 116 return -ENODEV; 117 118 pr_err("Power Management for TI OMAP4.\n"); 119 120 #ifdef CONFIG_PM 121 ret = pwrdm_for_each(pwrdms_setup, NULL); 122 if (ret) { 123 pr_err("Failed to setup powerdomains\n"); 124 goto err2; 125 } 126 #endif 127 128 #ifdef CONFIG_SUSPEND 129 suspend_set_ops(&omap_pm_ops); 130 #endif /* CONFIG_SUSPEND */ 131 132 err2: 133 return ret; 134 } 135 late_initcall(omap4_pm_init); 136