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 22struct 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 31static LIST_HEAD(pwrst_list); 32 33#ifdef CONFIG_SUSPEND 34static int omap4_pm_prepare(void) 35{ 36 disable_hlt(); 37 return 0; 38} 39 40static int omap4_pm_suspend(void) 41{ 42 do_wfi(); 43 return 0; 44} 45 46static 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 62static void omap4_pm_finish(void) 63{ 64 enable_hlt(); 65 return; 66} 67 68static int omap4_pm_begin(suspend_state_t state) 69{ 70 return 0; 71} 72 73static void omap4_pm_end(void) 74{ 75 return; 76} 77 78static 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 88static 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 */ 111static 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 132err2: 133 return ret; 134} 135late_initcall(omap4_pm_init); 136