Commit 7725cb81 authored by Russell King's avatar Russell King

[ARM] Power management updates

This provides an element of core PM support to ARM, providing an APM
like user space interface, and separating the core PM support from
the SA1100 PM implementation.
parent 016e1577
......@@ -16,6 +16,7 @@ obj-n :=
obj- :=
obj-$(CONFIG_APM) += apm.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_ARCH_ACORN) += ecard.o time-acorn.o
obj-$(CONFIG_ARCH_CLPS7500) += time-acorn.o
obj-$(CONFIG_FOOTBRIDGE) += isa.o
......
This diff is collapsed.
/*
* linux/arch/arm/kernel/suspend.c
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License.
*
* This is the common support code for suspending an ARM machine.
* pm_do_suspend() is responsible for actually putting the CPU to
* sleep.
*/
#include <linux/config.h>
#include <linux/pm.h>
#include <linux/device.h>
#include <linux/cpufreq.h>
#include <asm/leds.h>
#include <asm/system.h>
int suspend(void)
{
int ret;
/*
* Suspend "legacy" devices.
*/
ret = pm_send_all(PM_SUSPEND, (void *)3);
if (ret != 0)
goto out;
/*
* Tell LDM devices we're going to suspend.
*/
ret = device_suspend(4, SUSPEND_NOTIFY);
if (ret != 0)
goto resume_legacy;
/*
* Disable, devices, and save state.
*/
device_suspend(4, SUSPEND_DISABLE);
device_suspend(4, SUSPEND_SAVE_STATE);
/*
* Tell devices that they're going to be powered off.
*/
device_suspend(4, SUSPEND_POWER_DOWN);
local_irq_disable();
leds_event(led_stop);
ret = pm_do_suspend();
leds_event(led_start);
local_irq_enable();
/*
* Tell devices that they now have power.
*/
device_resume(RESUME_POWER_ON);
/*
* Restore the CPU frequency settings.
*/
#ifdef CONFIG_CPU_FREQ
cpufreq_restore();
#endif
/*
* Resume LDM devices.
*/
device_resume(RESUME_RESTORE_STATE);
device_resume(RESUME_ENABLE);
resume_legacy:
/*
* Resume "legacy" devices.
*/
pm_send_all(PM_RESUME, (void *)0);
out:
return ret;
}
#ifdef CONFIG_SYSCTL
#include <linux/init.h>
#include <linux/sysctl.h>
/*
* This came from arch/arm/mach-sa1100/pm.c:
* Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
* with modifications by Nicolas Pitre and Russell King.
*
* ARGH! ACPI people defined CTL_ACPI in linux/acpi.h rather than
* linux/sysctl.h.
*
* This means our interface here won't survive long - it needs a new
* interface. Quick hack to get this working - use sysctl id 9999.
*/
#warning ACPI broke the kernel, this interface needs to be fixed up.
#define CTL_ACPI 9999
#define ACPI_S1_SLP_TYP 19
static struct ctl_table pm_table[] =
{
{ACPI_S1_SLP_TYP, "suspend", NULL, 0, 0600, NULL, (proc_handler *)&suspend},
{0}
};
static struct ctl_table pm_dir_table[] =
{
{CTL_ACPI, "pm", NULL, 0, 0555, pm_table},
{0}
};
/*
* Initialize power interface
*/
static int __init pm_init(void)
{
register_sysctl_table(pm_dir_table, 1);
return 0;
}
fs_initcall(pm_init);
#endif
......@@ -22,25 +22,12 @@
* 2002-05-27: Nicolas Pitre Killed sleep.h and the kmalloced save array.
* Storage is local on the stack now.
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pm.h>
#include <linux/sysctl.h>
#include <linux/errno.h>
#include <linux/device.h>
#include <linux/cpufreq.h>
#include <linux/time.h>
#include <asm/hardware.h>
#include <asm/memory.h>
#include <asm/system.h>
#include <asm/leds.h>
/*
* Debug macros
*/
#undef DEBUG
extern void sa1100_cpu_suspend(void);
extern void sa1100_cpu_resume(void);
......@@ -72,10 +59,6 @@ int pm_do_suspend(void)
{
unsigned long sleep_save[SLEEP_SAVE_SIZE];
local_irq_disable();
leds_event(led_stop);
/* preserve current time */
RCNR = xtime.tv_sec;
......@@ -154,17 +137,6 @@ int pm_do_suspend(void)
/* restore current time */
xtime.tv_sec = RCNR;
leds_event(led_start);
local_irq_enable();
/*
* Restore the CPU frequency settings.
*/
#ifdef CONFIG_CPU_FREQ
cpufreq_restore();
#endif
return 0;
}
......@@ -172,78 +144,3 @@ unsigned long sleep_phys_sp(void *sp)
{
return virt_to_phys(sp);
}
#ifdef CONFIG_SYSCTL
/*
* ARGH! ACPI people defined CTL_ACPI in linux/acpi.h rather than
* linux/sysctl.h.
*
* This means our interface here won't survive long - it needs a new
* interface. Quick hack to get this working - use sysctl id 9999.
*/
#warning ACPI broke the kernel, this interface needs to be fixed up.
#define CTL_ACPI 9999
#define ACPI_S1_SLP_TYP 19
/*
* Send us to sleep.
*/
static int sysctl_pm_do_suspend(void)
{
int retval;
/*
* Suspend "legacy" devices.
*/
retval = pm_send_all(PM_SUSPEND, (void *)3);
if (retval == 0) {
/*
* Suspend LDM devices.
*/
device_suspend(4, SUSPEND_NOTIFY);
device_suspend(4, SUSPEND_SAVE_STATE);
device_suspend(4, SUSPEND_DISABLE);
retval = pm_do_suspend();
/*
* Resume LDM devices.
*/
device_resume(RESUME_RESTORE_STATE);
device_resume(RESUME_ENABLE);
/*
* Resume "legacy" devices.
*/
pm_send_all(PM_RESUME, (void *)0);
}
return retval;
}
static struct ctl_table pm_table[] =
{
{ACPI_S1_SLP_TYP, "suspend", NULL, 0, 0600, NULL, (proc_handler *)&sysctl_pm_do_suspend},
{0}
};
static struct ctl_table pm_dir_table[] =
{
{CTL_ACPI, "pm", NULL, 0, 0555, pm_table},
{0}
};
/*
* Initialize power interface
*/
static int __init pm_init(void)
{
register_sysctl_table(pm_dir_table, 1);
return 0;
}
fs_initcall(pm_init);
#endif
EXPORT_SYMBOL(pm_do_suspend);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment