mirror of
https://github.com/torvalds/linux.git
synced 2024-11-16 17:12:06 +00:00
6a93dde1e8
This patch is V3 of the SuperH Mobile Runtime PM platform bus implentation matching Rafael's Runtime PM v16. The code gets invoked from the SuperH specific Runtime PM platform bus functions that override the weak symbols for: - platform_pm_runtime_suspend() - platform_pm_runtime_resume() - platform_pm_runtime_idle() This Runtime PM implementation performs two levels of power management. At the time of platform bus runtime suspend the clock to the device is stopped instantly. Later on if all devices within the power domain has their clocks stopped then the device driver ->runtime_suspend() callbacks are used to save hardware register state for each device. Device driver ->runtime_suspend() calls are scheduled from cpuidle context using platform_pm_runtime_suspend_idle(). When all devices have been fully suspended the processor is allowed to enter deep sleep from cpuidle. The runtime resume operation turns on clocks and also restores registers if needed. It is worth noting that the devices start in a suspended state and the device driver is responsible for calling runtime resume before accessing the actual hardware. In this particular platform bus implementation runtime resume is not allowed from interrupt context. Runtime suspend is however allowed from interrupt context as long as the synchronous functions are avoided. [ updated for v17 -- PFM. ] Signed-off-by: Magnus Damm <damm@igel.co.jp> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
73 lines
1.5 KiB
C
73 lines
1.5 KiB
C
#ifndef __ASM_SH_HWBLK_H
|
|
#define __ASM_SH_HWBLK_H
|
|
|
|
#include <asm/clock.h>
|
|
#include <asm/io.h>
|
|
|
|
#define HWBLK_CNT_USAGE 0
|
|
#define HWBLK_CNT_IDLE 1
|
|
#define HWBLK_CNT_DEVICES 2
|
|
#define HWBLK_CNT_NR 3
|
|
|
|
#define HWBLK_AREA_FLAG_PARENT (1 << 0) /* valid parent */
|
|
|
|
#define HWBLK_AREA(_flags, _parent) \
|
|
{ \
|
|
.flags = _flags, \
|
|
.parent = _parent, \
|
|
}
|
|
|
|
struct hwblk_area {
|
|
int cnt[HWBLK_CNT_NR];
|
|
unsigned char parent;
|
|
unsigned char flags;
|
|
};
|
|
|
|
#define HWBLK(_mstp, _bit, _area) \
|
|
{ \
|
|
.mstp = (void __iomem *)_mstp, \
|
|
.bit = _bit, \
|
|
.area = _area, \
|
|
}
|
|
|
|
struct hwblk {
|
|
void __iomem *mstp;
|
|
unsigned char bit;
|
|
unsigned char area;
|
|
int cnt[HWBLK_CNT_NR];
|
|
};
|
|
|
|
struct hwblk_info {
|
|
struct hwblk_area *areas;
|
|
int nr_areas;
|
|
struct hwblk *hwblks;
|
|
int nr_hwblks;
|
|
};
|
|
|
|
/* Should be defined by processor-specific code */
|
|
int arch_hwblk_init(void);
|
|
int arch_hwblk_sleep_mode(void);
|
|
|
|
int hwblk_register(struct hwblk_info *info);
|
|
int hwblk_init(void);
|
|
|
|
void hwblk_enable(struct hwblk_info *info, int hwblk);
|
|
void hwblk_disable(struct hwblk_info *info, int hwblk);
|
|
|
|
void hwblk_cnt_inc(struct hwblk_info *info, int hwblk, int cnt);
|
|
void hwblk_cnt_dec(struct hwblk_info *info, int hwblk, int cnt);
|
|
|
|
/* allow clocks to enable and disable hardware blocks */
|
|
#define SH_HWBLK_CLK(_name, _id, _parent, _hwblk, _flags) \
|
|
{ \
|
|
.name = _name, \
|
|
.id = _id, \
|
|
.parent = _parent, \
|
|
.arch_flags = _hwblk, \
|
|
.flags = _flags, \
|
|
}
|
|
|
|
int sh_hwblk_clk_register(struct clk *clks, int nr);
|
|
|
|
#endif /* __ASM_SH_HWBLK_H */
|