diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-omap2/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm44xx.c | 135 |
2 files changed, 136 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 0efcc94fad2..3cb1b510ee4 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -49,6 +49,7 @@ ifeq ($(CONFIG_PM),y) obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o cpuidle34xx.o +obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o obj-$(CONFIG_PM_DEBUG) += pm-debug.o AFLAGS_sleep24xx.o :=-Wa,-march=armv6 diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c new file mode 100644 index 00000000000..54544b4fc76 --- /dev/null +++ b/arch/arm/mach-omap2/pm44xx.c @@ -0,0 +1,135 @@ +/* + * OMAP4 Power Management Routines + * + * Copyright (C) 2010 Texas Instruments, Inc. + * Rajendra Nayak <rnayak@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/pm.h> +#include <linux/suspend.h> +#include <linux/module.h> +#include <linux/list.h> +#include <linux/err.h> +#include <linux/slab.h> + +#include <plat/powerdomain.h> +#include <mach/omap4-common.h> + +struct power_state { + struct powerdomain *pwrdm; + u32 next_state; +#ifdef CONFIG_SUSPEND + u32 saved_state; +#endif + struct list_head node; +}; + +static LIST_HEAD(pwrst_list); + +#ifdef CONFIG_SUSPEND +static int omap4_pm_prepare(void) +{ + disable_hlt(); + return 0; +} + +static int omap4_pm_suspend(void) +{ + do_wfi(); + return 0; +} + +static int omap4_pm_enter(suspend_state_t suspend_state) +{ + int ret = 0; + + switch (suspend_state) { + case PM_SUSPEND_STANDBY: + case PM_SUSPEND_MEM: + ret = omap4_pm_suspend(); + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static void omap4_pm_finish(void) +{ + enable_hlt(); + return; +} + +static int omap4_pm_begin(suspend_state_t state) +{ + return 0; +} + +static void omap4_pm_end(void) +{ + return; +} + +static struct platform_suspend_ops omap_pm_ops = { + .begin = omap4_pm_begin, + .end = omap4_pm_end, + .prepare = omap4_pm_prepare, + .enter = omap4_pm_enter, + .finish = omap4_pm_finish, + .valid = suspend_valid_only_mem, +}; +#endif /* CONFIG_SUSPEND */ + +static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) +{ + struct power_state *pwrst; + + if (!pwrdm->pwrsts) + return 0; + + pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC); + if (!pwrst) + return -ENOMEM; + pwrst->pwrdm = pwrdm; + pwrst->next_state = PWRDM_POWER_ON; + list_add(&pwrst->node, &pwrst_list); + + return pwrdm_set_next_pwrst(pwrst->pwrdm, pwrst->next_state); +} + +/** + * omap4_pm_init - Init routine for OMAP4 PM + * + * Initializes all powerdomain and clockdomain target states + * and all PRCM settings. + */ +static int __init omap4_pm_init(void) +{ + int ret; + + if (!cpu_is_omap44xx()) + return -ENODEV; + + pr_err("Power Management for TI OMAP4.\n"); + +#ifdef CONFIG_PM + ret = pwrdm_for_each(pwrdms_setup, NULL); + if (ret) { + pr_err("Failed to setup powerdomains\n"); + goto err2; + } +#endif + +#ifdef CONFIG_SUSPEND + suspend_set_ops(&omap_pm_ops); +#endif /* CONFIG_SUSPEND */ + +err2: + return ret; +} +late_initcall(omap4_pm_init); |