diff options
Diffstat (limited to 'arch/arm/mach-omap2/pm.c')
| -rw-r--r-- | arch/arm/mach-omap2/pm.c | 75 |
1 files changed, 69 insertions, 6 deletions
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 68f9f2e95891..59ca03b0e691 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c | |||
| @@ -18,11 +18,15 @@ | |||
| 18 | #include <plat/omap_device.h> | 18 | #include <plat/omap_device.h> |
| 19 | #include <plat/common.h> | 19 | #include <plat/common.h> |
| 20 | 20 | ||
| 21 | #include <plat/powerdomain.h> | ||
| 22 | #include <plat/clockdomain.h> | ||
| 23 | |||
| 21 | static struct omap_device_pm_latency *pm_lats; | 24 | static struct omap_device_pm_latency *pm_lats; |
| 22 | 25 | ||
| 23 | static struct device *mpu_dev; | 26 | static struct device *mpu_dev; |
| 24 | static struct device *dsp_dev; | 27 | static struct device *iva_dev; |
| 25 | static struct device *l3_dev; | 28 | static struct device *l3_dev; |
| 29 | static struct device *dsp_dev; | ||
| 26 | 30 | ||
| 27 | struct device *omap2_get_mpuss_device(void) | 31 | struct device *omap2_get_mpuss_device(void) |
| 28 | { | 32 | { |
| @@ -30,10 +34,10 @@ struct device *omap2_get_mpuss_device(void) | |||
| 30 | return mpu_dev; | 34 | return mpu_dev; |
| 31 | } | 35 | } |
| 32 | 36 | ||
| 33 | struct device *omap2_get_dsp_device(void) | 37 | struct device *omap2_get_iva_device(void) |
| 34 | { | 38 | { |
| 35 | WARN_ON_ONCE(!dsp_dev); | 39 | WARN_ON_ONCE(!iva_dev); |
| 36 | return dsp_dev; | 40 | return iva_dev; |
| 37 | } | 41 | } |
| 38 | 42 | ||
| 39 | struct device *omap2_get_l3_device(void) | 43 | struct device *omap2_get_l3_device(void) |
| @@ -42,6 +46,13 @@ struct device *omap2_get_l3_device(void) | |||
| 42 | return l3_dev; | 46 | return l3_dev; |
| 43 | } | 47 | } |
| 44 | 48 | ||
| 49 | struct device *omap4_get_dsp_device(void) | ||
| 50 | { | ||
| 51 | WARN_ON_ONCE(!dsp_dev); | ||
| 52 | return dsp_dev; | ||
| 53 | } | ||
| 54 | EXPORT_SYMBOL(omap4_get_dsp_device); | ||
| 55 | |||
| 45 | /* static int _init_omap_device(struct omap_hwmod *oh, void *user) */ | 56 | /* static int _init_omap_device(struct omap_hwmod *oh, void *user) */ |
| 46 | static int _init_omap_device(char *name, struct device **new_dev) | 57 | static int _init_omap_device(char *name, struct device **new_dev) |
| 47 | { | 58 | { |
| @@ -69,8 +80,60 @@ static int _init_omap_device(char *name, struct device **new_dev) | |||
| 69 | static void omap2_init_processor_devices(void) | 80 | static void omap2_init_processor_devices(void) |
| 70 | { | 81 | { |
| 71 | _init_omap_device("mpu", &mpu_dev); | 82 | _init_omap_device("mpu", &mpu_dev); |
| 72 | _init_omap_device("iva", &dsp_dev); | 83 | _init_omap_device("iva", &iva_dev); |
| 73 | _init_omap_device("l3_main", &l3_dev); | 84 | if (cpu_is_omap44xx()) { |
| 85 | _init_omap_device("l3_main_1", &l3_dev); | ||
| 86 | _init_omap_device("dsp", &dsp_dev); | ||
| 87 | } else { | ||
| 88 | _init_omap_device("l3_main", &l3_dev); | ||
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 92 | /* | ||
| 93 | * This sets pwrdm state (other than mpu & core. Currently only ON & | ||
| 94 | * RET are supported. Function is assuming that clkdm doesn't have | ||
| 95 | * hw_sup mode enabled. | ||
| 96 | */ | ||
| 97 | int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state) | ||
| 98 | { | ||
| 99 | u32 cur_state; | ||
| 100 | int sleep_switch = 0; | ||
| 101 | int ret = 0; | ||
| 102 | |||
| 103 | if (pwrdm == NULL || IS_ERR(pwrdm)) | ||
| 104 | return -EINVAL; | ||
| 105 | |||
| 106 | while (!(pwrdm->pwrsts & (1 << state))) { | ||
| 107 | if (state == PWRDM_POWER_OFF) | ||
| 108 | return ret; | ||
| 109 | state--; | ||
| 110 | } | ||
| 111 | |||
| 112 | cur_state = pwrdm_read_next_pwrst(pwrdm); | ||
| 113 | if (cur_state == state) | ||
| 114 | return ret; | ||
| 115 | |||
| 116 | if (pwrdm_read_pwrst(pwrdm) < PWRDM_POWER_ON) { | ||
| 117 | omap2_clkdm_wakeup(pwrdm->pwrdm_clkdms[0]); | ||
| 118 | sleep_switch = 1; | ||
| 119 | pwrdm_wait_transition(pwrdm); | ||
| 120 | } | ||
| 121 | |||
| 122 | ret = pwrdm_set_next_pwrst(pwrdm, state); | ||
| 123 | if (ret) { | ||
| 124 | printk(KERN_ERR "Unable to set state of powerdomain: %s\n", | ||
| 125 | pwrdm->name); | ||
| 126 | goto err; | ||
| 127 | } | ||
| 128 | |||
| 129 | if (sleep_switch) { | ||
| 130 | omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]); | ||
| 131 | pwrdm_wait_transition(pwrdm); | ||
| 132 | pwrdm_state_switch(pwrdm); | ||
| 133 | } | ||
| 134 | |||
| 135 | err: | ||
| 136 | return ret; | ||
| 74 | } | 137 | } |
| 75 | 138 | ||
| 76 | static int __init omap2_common_pm_init(void) | 139 | static int __init omap2_common_pm_init(void) |
