blob: 6b24a020df1f477b43a4d6b9169d118f5417574f [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* arch/arm/mach-msm/pm2.c
2 *
3 * MSM Power Management Routines
4 *
5 * Copyright (C) 2007 Google, Inc.
6 * Copyright (c) 2008-2011 Code Aurora Forum. All rights reserved.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <linux/module.h>
20#include <linux/kernel.h>
21#include <linux/clk.h>
22#include <linux/delay.h>
23#include <linux/init.h>
24#include <linux/pm.h>
25#include <linux/pm_qos_params.h>
26#include <linux/proc_fs.h>
27#include <linux/suspend.h>
28#include <linux/reboot.h>
29#include <linux/uaccess.h>
30#include <linux/io.h>
31#include <linux/memory.h>
32#ifdef CONFIG_HAS_WAKELOCK
33#include <linux/wakelock.h>
34#endif
35#include <mach/msm_iomap.h>
36#include <mach/system.h>
37#ifdef CONFIG_CPU_V7
38#include <asm/pgtable.h>
39#include <asm/pgalloc.h>
40#endif
41#ifdef CONFIG_CACHE_L2X0
42#include <asm/hardware/cache-l2x0.h>
43#endif
44#ifdef CONFIG_VFP
45#include <asm/vfp.h>
46#endif
47
48#ifdef CONFIG_MSM_MEMORY_LOW_POWER_MODE_SUSPEND_DEEP_POWER_DOWN
49#include <mach/msm_migrate_pages.h>
50#endif
51
52#include "smd_private.h"
53#include "smd_rpcrouter.h"
54#include "acpuclock.h"
55#include "clock.h"
56#include "proc_comm.h"
57#include "idle.h"
58#include "irq.h"
59#include "gpio.h"
60#include "timer.h"
61#include "pm.h"
62#include "spm.h"
63#include "sirc.h"
64
65/******************************************************************************
66 * Debug Definitions
67 *****************************************************************************/
68
69enum {
70 MSM_PM_DEBUG_SUSPEND = 1U << 0,
71 MSM_PM_DEBUG_POWER_COLLAPSE = 1U << 1,
72 MSM_PM_DEBUG_STATE = 1U << 2,
73 MSM_PM_DEBUG_CLOCK = 1U << 3,
74 MSM_PM_DEBUG_RESET_VECTOR = 1U << 4,
75 MSM_PM_DEBUG_SMSM_STATE = 1U << 5,
76 MSM_PM_DEBUG_IDLE = 1U << 6,
77};
78
79static int msm_pm_debug_mask;
80module_param_named(
81 debug_mask, msm_pm_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP
82);
83
84#define MSM_PM_DPRINTK(mask, level, message, ...) \
85 do { \
86 if ((mask) & msm_pm_debug_mask) \
87 printk(level message, ## __VA_ARGS__); \
88 } while (0)
89
90#define MSM_PM_DEBUG_PRINT_STATE(tag) \
91 do { \
92 MSM_PM_DPRINTK(MSM_PM_DEBUG_STATE, \
93 KERN_INFO, "%s: " \
94 "APPS_CLK_SLEEP_EN %x, APPS_PWRDOWN %x, " \
95 "SMSM_POWER_MASTER_DEM %x, SMSM_MODEM_STATE %x, " \
96 "SMSM_APPS_DEM %x\n", \
97 tag, \
98 __raw_readl(APPS_CLK_SLEEP_EN), \
99 __raw_readl(APPS_PWRDOWN), \
100 smsm_get_state(SMSM_POWER_MASTER_DEM), \
101 smsm_get_state(SMSM_MODEM_STATE), \
102 smsm_get_state(SMSM_APPS_DEM)); \
103 } while (0)
104
105#define MSM_PM_DEBUG_PRINT_SLEEP_INFO() \
106 do { \
107 if (msm_pm_debug_mask & MSM_PM_DEBUG_SMSM_STATE) \
108 smsm_print_sleep_info(msm_pm_smem_data->sleep_time, \
109 msm_pm_smem_data->resources_used, \
110 msm_pm_smem_data->irq_mask, \
111 msm_pm_smem_data->wakeup_reason, \
112 msm_pm_smem_data->pending_irqs); \
113 } while (0)
114
115
116/******************************************************************************
117 * Sleep Modes and Parameters
118 *****************************************************************************/
119
120static int msm_pm_sleep_mode = CONFIG_MSM7X00A_SLEEP_MODE;
121module_param_named(
122 sleep_mode, msm_pm_sleep_mode,
123 int, S_IRUGO | S_IWUSR | S_IWGRP
124);
125
126static int msm_pm_idle_sleep_mode = CONFIG_MSM7X00A_IDLE_SLEEP_MODE;
127module_param_named(
128 idle_sleep_mode, msm_pm_idle_sleep_mode,
129 int, S_IRUGO | S_IWUSR | S_IWGRP
130);
131
132static int msm_pm_idle_sleep_min_time = CONFIG_MSM7X00A_IDLE_SLEEP_MIN_TIME;
133module_param_named(
134 idle_sleep_min_time, msm_pm_idle_sleep_min_time,
135 int, S_IRUGO | S_IWUSR | S_IWGRP
136);
137
138enum {
139 MSM_PM_MODE_ATTR_SUSPEND,
140 MSM_PM_MODE_ATTR_IDLE,
141 MSM_PM_MODE_ATTR_LATENCY,
142 MSM_PM_MODE_ATTR_RESIDENCY,
143 MSM_PM_MODE_ATTR_NR,
144};
145
146static char *msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_NR] = {
147 [MSM_PM_MODE_ATTR_SUSPEND] = "suspend_enabled",
148 [MSM_PM_MODE_ATTR_IDLE] = "idle_enabled",
149 [MSM_PM_MODE_ATTR_LATENCY] = "latency",
150 [MSM_PM_MODE_ATTR_RESIDENCY] = "residency",
151};
152
153static char *msm_pm_sleep_mode_labels[MSM_PM_SLEEP_MODE_NR] = {
154 [MSM_PM_SLEEP_MODE_POWER_COLLAPSE_SUSPEND] = " ",
155 [MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = "power_collapse",
156 [MSM_PM_SLEEP_MODE_APPS_SLEEP] = "apps_sleep",
157 [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT] =
158 "ramp_down_and_wfi",
159 [MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT] = "wfi",
160 [MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN] =
161 "power_collapse_no_xo_shutdown",
162 [MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE] =
163 "standalone_power_collapse",
164};
165
166static struct msm_pm_platform_data *msm_pm_modes;
167
168static struct kobject *msm_pm_mode_kobjs[MSM_PM_SLEEP_MODE_NR];
169static struct attribute_group *msm_pm_mode_attr_group[MSM_PM_SLEEP_MODE_NR];
170static struct attribute **msm_pm_mode_attrs[MSM_PM_SLEEP_MODE_NR];
171static struct kobj_attribute *msm_pm_mode_kobj_attrs[MSM_PM_SLEEP_MODE_NR];
172
173/*
174 * Write out the attribute.
175 */
176static ssize_t msm_pm_mode_attr_show(
177 struct kobject *kobj, struct kobj_attribute *attr, char *buf)
178{
179 int ret = -EINVAL;
180 int i;
181
182 for (i = 0; i < MSM_PM_SLEEP_MODE_NR; i++) {
183 struct kernel_param kp;
184
185 if (msm_pm_sleep_mode_labels[i] == NULL)
186 continue;
187
188 if (strcmp(kobj->name, msm_pm_sleep_mode_labels[i]))
189 continue;
190
191 if (!strcmp(attr->attr.name,
192 msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_SUSPEND])) {
193 u32 arg = msm_pm_modes[i].suspend_enabled;
194 kp.arg = &arg;
195 ret = param_get_ulong(buf, &kp);
196 } else if (!strcmp(attr->attr.name,
197 msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_IDLE])) {
198 u32 arg = msm_pm_modes[i].idle_enabled;
199 kp.arg = &arg;
200 ret = param_get_ulong(buf, &kp);
201 } else if (!strcmp(attr->attr.name,
202 msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_LATENCY])) {
203 kp.arg = &msm_pm_modes[i].latency;
204 ret = param_get_ulong(buf, &kp);
205 } else if (!strcmp(attr->attr.name,
206 msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_RESIDENCY])) {
207 kp.arg = &msm_pm_modes[i].residency;
208 ret = param_get_ulong(buf, &kp);
209 }
210
211 break;
212 }
213
214 if (ret > 0) {
215 strcat(buf, "\n");
216 ret++;
217 }
218
219 return ret;
220}
221
222/*
223 * Read in the new attribute value.
224 */
225static ssize_t msm_pm_mode_attr_store(struct kobject *kobj,
226 struct kobj_attribute *attr, const char *buf, size_t count)
227{
228 int ret = -EINVAL;
229 int i;
230
231 for (i = 0; i < MSM_PM_SLEEP_MODE_NR; i++) {
232 struct kernel_param kp;
233
234 if (msm_pm_sleep_mode_labels[i] == NULL)
235 continue;
236
237 if (strcmp(kobj->name, msm_pm_sleep_mode_labels[i]))
238 continue;
239
240 if (!strcmp(attr->attr.name,
241 msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_SUSPEND])) {
242 kp.arg = &msm_pm_modes[i].suspend_enabled;
243 ret = param_set_byte(buf, &kp);
244 } else if (!strcmp(attr->attr.name,
245 msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_IDLE])) {
246 kp.arg = &msm_pm_modes[i].idle_enabled;
247 ret = param_set_byte(buf, &kp);
248 } else if (!strcmp(attr->attr.name,
249 msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_LATENCY])) {
250 kp.arg = &msm_pm_modes[i].latency;
251 ret = param_set_ulong(buf, &kp);
252 } else if (!strcmp(attr->attr.name,
253 msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_RESIDENCY])) {
254 kp.arg = &msm_pm_modes[i].residency;
255 ret = param_set_ulong(buf, &kp);
256 }
257
258 break;
259 }
260
261 return ret ? ret : count;
262}
263
264/*
265 * Add sysfs entries for the sleep modes.
266 */
267static int __init msm_pm_mode_sysfs_add(void)
268{
269 struct kobject *module_kobj = NULL;
270 struct kobject *modes_kobj = NULL;
271
272 struct kobject *kobj;
273 struct attribute_group *attr_group;
274 struct attribute **attrs;
275 struct kobj_attribute *kobj_attrs;
276
277 int i, j, k;
278 int ret;
279
280 module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME);
281 if (!module_kobj) {
282 printk(KERN_ERR "%s: cannot find kobject for module %s\n",
283 __func__, KBUILD_MODNAME);
284 ret = -ENOENT;
285 goto mode_sysfs_add_cleanup;
286 }
287
288 modes_kobj = kobject_create_and_add("modes", module_kobj);
289 if (!modes_kobj) {
290 printk(KERN_ERR "%s: cannot create modes kobject\n", __func__);
291 ret = -ENOMEM;
292 goto mode_sysfs_add_cleanup;
293 }
294
295 for (i = 0; i < ARRAY_SIZE(msm_pm_mode_kobjs); i++) {
296 if (!msm_pm_modes[i].suspend_supported &&
297 !msm_pm_modes[i].idle_supported)
298 continue;
299
300 kobj = kobject_create_and_add(
301 msm_pm_sleep_mode_labels[i], modes_kobj);
302 attr_group = kzalloc(sizeof(*attr_group), GFP_KERNEL);
303 attrs = kzalloc(sizeof(*attrs) * (MSM_PM_MODE_ATTR_NR + 1),
304 GFP_KERNEL);
305 kobj_attrs = kzalloc(sizeof(*kobj_attrs) * MSM_PM_MODE_ATTR_NR,
306 GFP_KERNEL);
307
308 if (!kobj || !attr_group || !attrs || !kobj_attrs) {
309 printk(KERN_ERR
310 "%s: cannot create kobject or attributes\n",
311 __func__);
312 ret = -ENOMEM;
313 goto mode_sysfs_add_abort;
314 }
315
316 for (k = 0, j = 0; k < MSM_PM_MODE_ATTR_NR; k++) {
317 if ((k == MSM_PM_MODE_ATTR_SUSPEND) &&
318 (!msm_pm_modes[i].suspend_supported))
319 continue;
320 if ((k == MSM_PM_MODE_ATTR_IDLE) &&
321 (!msm_pm_modes[i].idle_supported))
322 continue;
323
324 kobj_attrs[j].attr.mode = 0644;
325 kobj_attrs[j].show = msm_pm_mode_attr_show;
326 kobj_attrs[j].store = msm_pm_mode_attr_store;
327 kobj_attrs[j].attr.name = msm_pm_mode_attr_labels[k];
328 attrs[j] = &kobj_attrs[j].attr;
329 j++;
330 }
331 attrs[j] = NULL;
332
333 attr_group->attrs = attrs;
334 ret = sysfs_create_group(kobj, attr_group);
335 if (ret) {
336 printk(KERN_ERR
337 "%s: cannot create kobject attribute group\n",
338 __func__);
339 goto mode_sysfs_add_abort;
340 }
341
342 msm_pm_mode_kobjs[i] = kobj;
343 msm_pm_mode_attr_group[i] = attr_group;
344 msm_pm_mode_attrs[i] = attrs;
345 msm_pm_mode_kobj_attrs[i] = kobj_attrs;
346 }
347
348 return 0;
349
350mode_sysfs_add_abort:
351 kfree(kobj_attrs);
352 kfree(attrs);
353 kfree(attr_group);
354 kobject_put(kobj);
355
356mode_sysfs_add_cleanup:
357 for (i = ARRAY_SIZE(msm_pm_mode_kobjs) - 1; i >= 0; i--) {
358 if (!msm_pm_mode_kobjs[i])
359 continue;
360
361 sysfs_remove_group(
362 msm_pm_mode_kobjs[i], msm_pm_mode_attr_group[i]);
363
364 kfree(msm_pm_mode_kobj_attrs[i]);
365 kfree(msm_pm_mode_attrs[i]);
366 kfree(msm_pm_mode_attr_group[i]);
367 kobject_put(msm_pm_mode_kobjs[i]);
368 }
369
370 return ret;
371}
372
373void __init msm_pm_set_platform_data(
374 struct msm_pm_platform_data *data, int count)
375{
376 BUG_ON(MSM_PM_SLEEP_MODE_NR != count);
377 msm_pm_modes = data;
378}
379
380
381/******************************************************************************
382 * Sleep Limitations
383 *****************************************************************************/
384enum {
385 SLEEP_LIMIT_NONE = 0,
386 SLEEP_LIMIT_NO_TCXO_SHUTDOWN = 2,
387 SLEEP_LIMIT_MASK = 0x03,
388};
389
390#ifdef CONFIG_MSM_MEMORY_LOW_POWER_MODE
391enum {
392 SLEEP_RESOURCE_MEMORY_BIT0 = 0x0200,
393 SLEEP_RESOURCE_MEMORY_BIT1 = 0x0010,
394};
395#endif
396
397
398/******************************************************************************
399 * Configure Hardware for Power Down/Up
400 *****************************************************************************/
401
402#if defined(CONFIG_ARCH_MSM7X30)
403#define APPS_CLK_SLEEP_EN (MSM_GCC_BASE + 0x020)
404#define APPS_PWRDOWN (MSM_ACC_BASE + 0x01c)
405#define APPS_SECOP (MSM_TCSR_BASE + 0x038)
406#else /* defined(CONFIG_ARCH_MSM7X30) */
407#define APPS_CLK_SLEEP_EN (MSM_CSR_BASE + 0x11c)
408#define APPS_PWRDOWN (MSM_CSR_BASE + 0x440)
409#define APPS_STANDBY_CTL (MSM_CSR_BASE + 0x108)
410#endif /* defined(CONFIG_ARCH_MSM7X30) */
411
412/*
413 * Configure hardware registers in preparation for Apps power down.
414 */
415static void msm_pm_config_hw_before_power_down(void)
416{
417#if defined(CONFIG_ARCH_MSM7X30)
418 __raw_writel(1, APPS_PWRDOWN);
419 mb();
420 __raw_writel(4, APPS_SECOP);
421 mb();
422#elif defined(CONFIG_ARCH_MSM7X27)
423 __raw_writel(0x1f, APPS_CLK_SLEEP_EN);
424 mb();
425 __raw_writel(1, APPS_PWRDOWN);
426 mb();
427#elif defined(CONFIG_ARCH_MSM7x27A)
428 __raw_writel(0x7, APPS_CLK_SLEEP_EN);
429 mb();
430 __raw_writel(1, APPS_PWRDOWN);
431 mb();
432#else
433 __raw_writel(0x1f, APPS_CLK_SLEEP_EN);
434 mb();
435 __raw_writel(1, APPS_PWRDOWN);
436 mb();
437 __raw_writel(0, APPS_STANDBY_CTL);
438 mb();
439#endif
440}
441
442/*
443 * Clear hardware registers after Apps powers up.
444 */
445static void msm_pm_config_hw_after_power_up(void)
446{
447#if defined(CONFIG_ARCH_MSM7X30)
448 __raw_writel(0, APPS_SECOP);
449 mb();
450 __raw_writel(0, APPS_PWRDOWN);
451 mb();
452 msm_spm_reinit();
453#elif defined(CONFIG_ARCH_MSM7x27A)
454 __raw_writel(0, APPS_PWRDOWN);
455 mb();
456 __raw_writel(0, APPS_CLK_SLEEP_EN);
457 mb();
458#else
459 __raw_writel(0, APPS_PWRDOWN);
460 mb();
461 __raw_writel(0, APPS_CLK_SLEEP_EN);
462 mb();
463#endif
464}
465
466/*
467 * Configure hardware registers in preparation for SWFI.
468 */
469static void msm_pm_config_hw_before_swfi(void)
470{
471#if defined(CONFIG_ARCH_QSD8X50)
472 __raw_writel(0x1f, APPS_CLK_SLEEP_EN);
473 mb();
474#elif defined(CONFIG_ARCH_MSM7X27)
475 __raw_writel(0x0f, APPS_CLK_SLEEP_EN);
476 mb();
477#elif defined(CONFIG_ARCH_MSM7X27A)
478 __raw_writel(0x7, APPS_CLK_SLEEP_EN);
479 mb();
480#endif
481}
482
483/*
484 * Respond to timing out waiting for Modem
485 *
486 * NOTE: The function never returns.
487 */
488static void msm_pm_timeout(void)
489{
490#if defined(CONFIG_MSM_PM_TIMEOUT_RESET_CHIP)
491 printk(KERN_EMERG "%s(): resetting chip\n", __func__);
492 msm_proc_comm(PCOM_RESET_CHIP_IMM, NULL, NULL);
493#elif defined(CONFIG_MSM_PM_TIMEOUT_RESET_MODEM)
494 printk(KERN_EMERG "%s(): resetting modem\n", __func__);
495 msm_proc_comm_reset_modem_now();
496#elif defined(CONFIG_MSM_PM_TIMEOUT_HALT)
497 printk(KERN_EMERG "%s(): halting\n", __func__);
498#endif
499 for (;;)
500 ;
501}
502
503
504/******************************************************************************
505 * State Polling Definitions
506 *****************************************************************************/
507
508struct msm_pm_polled_group {
509 uint32_t group_id;
510
511 uint32_t bits_all_set;
512 uint32_t bits_all_clear;
513 uint32_t bits_any_set;
514 uint32_t bits_any_clear;
515
516 uint32_t value_read;
517};
518
519/*
520 * Return true if all bits indicated by flag are set in source.
521 */
522static inline bool msm_pm_all_set(uint32_t source, uint32_t flag)
523{
524 return (source & flag) == flag;
525}
526
527/*
528 * Return true if any bit indicated by flag are set in source.
529 */
530static inline bool msm_pm_any_set(uint32_t source, uint32_t flag)
531{
532 return !flag || (source & flag);
533}
534
535/*
536 * Return true if all bits indicated by flag are cleared in source.
537 */
538static inline bool msm_pm_all_clear(uint32_t source, uint32_t flag)
539{
540 return (~source & flag) == flag;
541}
542
543/*
544 * Return true if any bit indicated by flag are cleared in source.
545 */
546static inline bool msm_pm_any_clear(uint32_t source, uint32_t flag)
547{
548 return !flag || (~source & flag);
549}
550
551/*
552 * Poll the shared memory states as indicated by the poll groups.
553 *
554 * nr_grps: number of groups in the array
555 * grps: array of groups
556 *
557 * The function returns when conditions specified by any of the poll
558 * groups become true. The conditions specified by a poll group are
559 * deemed true when 1) at least one bit from bits_any_set is set OR one
560 * bit from bits_any_clear is cleared; and 2) all bits in bits_all_set
561 * are set; and 3) all bits in bits_all_clear are cleared.
562 *
563 * Return value:
564 * >=0: index of the poll group whose conditions have become true
565 * -ETIMEDOUT: timed out
566 */
567static int msm_pm_poll_state(int nr_grps, struct msm_pm_polled_group *grps)
568{
569 int i, k;
570
571 for (i = 0; i < 50000; i++) {
572 for (k = 0; k < nr_grps; k++) {
573 bool all_set, all_clear;
574 bool any_set, any_clear;
575
576 grps[k].value_read = smsm_get_state(grps[k].group_id);
577
578 all_set = msm_pm_all_set(grps[k].value_read,
579 grps[k].bits_all_set);
580 all_clear = msm_pm_all_clear(grps[k].value_read,
581 grps[k].bits_all_clear);
582 any_set = msm_pm_any_set(grps[k].value_read,
583 grps[k].bits_any_set);
584 any_clear = msm_pm_any_clear(grps[k].value_read,
585 grps[k].bits_any_clear);
586
587 if (all_set && all_clear && (any_set || any_clear))
588 return k;
589 }
590 udelay(50);
591 }
592
593 printk(KERN_ERR "%s failed:\n", __func__);
594 for (k = 0; k < nr_grps; k++)
595 printk(KERN_ERR "(%x, %x, %x, %x) %x\n",
596 grps[k].bits_all_set, grps[k].bits_all_clear,
597 grps[k].bits_any_set, grps[k].bits_any_clear,
598 grps[k].value_read);
599
600 return -ETIMEDOUT;
601}
602
603
604/******************************************************************************
605 * Suspend Max Sleep Time
606 *****************************************************************************/
607
608#define SCLK_HZ (32768)
609#define MSM_PM_SLEEP_TICK_LIMIT (0x6DDD000)
610
611#ifdef CONFIG_MSM_SLEEP_TIME_OVERRIDE
612static int msm_pm_sleep_time_override;
613module_param_named(sleep_time_override,
614 msm_pm_sleep_time_override, int, S_IRUGO | S_IWUSR | S_IWGRP);
615#endif
616
617static uint32_t msm_pm_max_sleep_time;
618
619/*
620 * Convert time from nanoseconds to slow clock ticks, then cap it to the
621 * specified limit
622 */
623static int64_t msm_pm_convert_and_cap_time(int64_t time_ns, int64_t limit)
624{
625 do_div(time_ns, NSEC_PER_SEC / SCLK_HZ);
626 return (time_ns > limit) ? limit : time_ns;
627}
628
629/*
630 * Set the sleep time for suspend. 0 means infinite sleep time.
631 */
632void msm_pm_set_max_sleep_time(int64_t max_sleep_time_ns)
633{
634 unsigned long flags;
635
636 local_irq_save(flags);
637 if (max_sleep_time_ns == 0) {
638 msm_pm_max_sleep_time = 0;
639 } else {
640 msm_pm_max_sleep_time = (uint32_t)msm_pm_convert_and_cap_time(
641 max_sleep_time_ns, MSM_PM_SLEEP_TICK_LIMIT);
642
643 if (msm_pm_max_sleep_time == 0)
644 msm_pm_max_sleep_time = 1;
645 }
646
647 MSM_PM_DPRINTK(MSM_PM_DEBUG_SUSPEND, KERN_INFO,
648 "%s(): Requested %lld ns Giving %u sclk ticks\n", __func__,
649 max_sleep_time_ns, msm_pm_max_sleep_time);
650 local_irq_restore(flags);
651}
652EXPORT_SYMBOL(msm_pm_set_max_sleep_time);
653
654
655/******************************************************************************
656 * CONFIG_MSM_IDLE_STATS
657 *****************************************************************************/
658
659#ifdef CONFIG_MSM_IDLE_STATS
660enum msm_pm_time_stats_id {
661 MSM_PM_STAT_REQUESTED_IDLE,
662 MSM_PM_STAT_IDLE_SPIN,
663 MSM_PM_STAT_IDLE_WFI,
664 MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE,
665 MSM_PM_STAT_IDLE_FAILED_STANDALONE_POWER_COLLAPSE,
666 MSM_PM_STAT_IDLE_SLEEP,
667 MSM_PM_STAT_IDLE_FAILED_SLEEP,
668 MSM_PM_STAT_IDLE_POWER_COLLAPSE,
669 MSM_PM_STAT_IDLE_FAILED_POWER_COLLAPSE,
670 MSM_PM_STAT_SUSPEND,
671 MSM_PM_STAT_FAILED_SUSPEND,
672 MSM_PM_STAT_NOT_IDLE,
673 MSM_PM_STAT_COUNT
674};
675
676static struct msm_pm_time_stats {
677 const char *name;
678 int64_t first_bucket_time;
679 int bucket[CONFIG_MSM_IDLE_STATS_BUCKET_COUNT];
680 int64_t min_time[CONFIG_MSM_IDLE_STATS_BUCKET_COUNT];
681 int64_t max_time[CONFIG_MSM_IDLE_STATS_BUCKET_COUNT];
682 int count;
683 int64_t total_time;
684} msm_pm_stats[MSM_PM_STAT_COUNT] = {
685 [MSM_PM_STAT_REQUESTED_IDLE].name = "idle-request",
686 [MSM_PM_STAT_REQUESTED_IDLE].first_bucket_time =
687 CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
688
689 [MSM_PM_STAT_IDLE_SPIN].name = "idle-spin",
690 [MSM_PM_STAT_IDLE_SPIN].first_bucket_time =
691 CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
692
693 [MSM_PM_STAT_IDLE_WFI].name = "idle-wfi",
694 [MSM_PM_STAT_IDLE_WFI].first_bucket_time =
695 CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
696
697 [MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE].name =
698 "idle-standalone-power-collapse",
699 [MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE].first_bucket_time =
700 CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
701
702 [MSM_PM_STAT_IDLE_FAILED_STANDALONE_POWER_COLLAPSE].name =
703 "idle-failed-standalone-power-collapse",
704 [MSM_PM_STAT_IDLE_FAILED_STANDALONE_POWER_COLLAPSE].first_bucket_time =
705 CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
706
707 [MSM_PM_STAT_IDLE_SLEEP].name = "idle-sleep",
708 [MSM_PM_STAT_IDLE_SLEEP].first_bucket_time =
709 CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
710
711 [MSM_PM_STAT_IDLE_FAILED_SLEEP].name = "idle-failed-sleep",
712 [MSM_PM_STAT_IDLE_FAILED_SLEEP].first_bucket_time =
713 CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
714
715 [MSM_PM_STAT_IDLE_POWER_COLLAPSE].name = "idle-power-collapse",
716 [MSM_PM_STAT_IDLE_POWER_COLLAPSE].first_bucket_time =
717 CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
718
719 [MSM_PM_STAT_IDLE_FAILED_POWER_COLLAPSE].name =
720 "idle-failed-power-collapse",
721 [MSM_PM_STAT_IDLE_FAILED_POWER_COLLAPSE].first_bucket_time =
722 CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
723
724 [MSM_PM_STAT_SUSPEND].name = "suspend",
725 [MSM_PM_STAT_SUSPEND].first_bucket_time =
726 CONFIG_MSM_SUSPEND_STATS_FIRST_BUCKET,
727
728 [MSM_PM_STAT_FAILED_SUSPEND].name = "failed-suspend",
729 [MSM_PM_STAT_FAILED_SUSPEND].first_bucket_time =
730 CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
731
732 [MSM_PM_STAT_NOT_IDLE].name = "not-idle",
733 [MSM_PM_STAT_NOT_IDLE].first_bucket_time =
734 CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
735};
736
737static uint32_t msm_pm_sleep_limit = SLEEP_LIMIT_NONE;
738
739/*
740 * Add the given time data to the statistics collection.
741 */
742static void msm_pm_add_stat(enum msm_pm_time_stats_id id, int64_t t)
743{
744 int i;
745 int64_t bt;
746
747 msm_pm_stats[id].total_time += t;
748 msm_pm_stats[id].count++;
749
750 bt = t;
751 do_div(bt, msm_pm_stats[id].first_bucket_time);
752
753 if (bt < 1ULL << (CONFIG_MSM_IDLE_STATS_BUCKET_SHIFT *
754 (CONFIG_MSM_IDLE_STATS_BUCKET_COUNT - 1)))
755 i = DIV_ROUND_UP(fls((uint32_t)bt),
756 CONFIG_MSM_IDLE_STATS_BUCKET_SHIFT);
757 else
758 i = CONFIG_MSM_IDLE_STATS_BUCKET_COUNT - 1;
759
760 msm_pm_stats[id].bucket[i]++;
761
762 if (t < msm_pm_stats[id].min_time[i] || !msm_pm_stats[id].max_time[i])
763 msm_pm_stats[id].min_time[i] = t;
764 if (t > msm_pm_stats[id].max_time[i])
765 msm_pm_stats[id].max_time[i] = t;
766}
767
768/*
769 * Helper function of snprintf where buf is auto-incremented, size is auto-
770 * decremented, and there is no return value.
771 *
772 * NOTE: buf and size must be l-values (e.g. variables)
773 */
774#define SNPRINTF(buf, size, format, ...) \
775 do { \
776 if (size > 0) { \
777 int ret; \
778 ret = snprintf(buf, size, format, ## __VA_ARGS__); \
779 if (ret > size) { \
780 buf += size; \
781 size = 0; \
782 } else { \
783 buf += ret; \
784 size -= ret; \
785 } \
786 } \
787 } while (0)
788
789/*
790 * Write out the power management statistics.
791 */
792static int msm_pm_read_proc
793 (char *page, char **start, off_t off, int count, int *eof, void *data)
794{
795 int i;
796 char *p = page;
797
798 if (count < 1024) {
799 *start = (char *) 0;
800 *eof = 0;
801 return 0;
802 }
803
804 if (!off) {
805 SNPRINTF(p, count, "Last power collapse voted ");
806 if ((msm_pm_sleep_limit & SLEEP_LIMIT_MASK) ==
807 SLEEP_LIMIT_NONE)
808 SNPRINTF(p, count, "for TCXO shutdown\n\n");
809 else
810 SNPRINTF(p, count, "against TCXO shutdown\n\n");
811
812 *start = (char *) 1;
813 *eof = 0;
814 } else if (--off < ARRAY_SIZE(msm_pm_stats)) {
815 int64_t bucket_time;
816 int64_t s;
817 uint32_t ns;
818
819 s = msm_pm_stats[off].total_time;
820 ns = do_div(s, NSEC_PER_SEC);
821 SNPRINTF(p, count,
822 "%s:\n"
823 " count: %7d\n"
824 " total_time: %lld.%09u\n",
825 msm_pm_stats[off].name,
826 msm_pm_stats[off].count,
827 s, ns);
828
829 bucket_time = msm_pm_stats[off].first_bucket_time;
830 for (i = 0; i < CONFIG_MSM_IDLE_STATS_BUCKET_COUNT - 1; i++) {
831 s = bucket_time;
832 ns = do_div(s, NSEC_PER_SEC);
833 SNPRINTF(p, count,
834 " <%6lld.%09u: %7d (%lld-%lld)\n",
835 s, ns, msm_pm_stats[off].bucket[i],
836 msm_pm_stats[off].min_time[i],
837 msm_pm_stats[off].max_time[i]);
838
839 bucket_time <<= CONFIG_MSM_IDLE_STATS_BUCKET_SHIFT;
840 }
841
842 SNPRINTF(p, count, " >=%6lld.%09u: %7d (%lld-%lld)\n",
843 s, ns, msm_pm_stats[off].bucket[i],
844 msm_pm_stats[off].min_time[i],
845 msm_pm_stats[off].max_time[i]);
846
847 *start = (char *) 1;
848 *eof = (off + 1 >= ARRAY_SIZE(msm_pm_stats));
849 }
850
851 return p - page;
852}
853#undef SNPRINTF
854
855#define MSM_PM_STATS_RESET "reset"
856
857/*
858 * Reset the power management statistics values.
859 */
860static int msm_pm_write_proc(struct file *file, const char __user *buffer,
861 unsigned long count, void *data)
862{
863 char buf[sizeof(MSM_PM_STATS_RESET)];
864 int ret;
865 unsigned long flags;
866 int i;
867
868 if (count < strlen(MSM_PM_STATS_RESET)) {
869 ret = -EINVAL;
870 goto write_proc_failed;
871 }
872
873 if (copy_from_user(buf, buffer, strlen(MSM_PM_STATS_RESET))) {
874 ret = -EFAULT;
875 goto write_proc_failed;
876 }
877
878 if (memcmp(buf, MSM_PM_STATS_RESET, strlen(MSM_PM_STATS_RESET))) {
879 ret = -EINVAL;
880 goto write_proc_failed;
881 }
882
883 local_irq_save(flags);
884 for (i = 0; i < ARRAY_SIZE(msm_pm_stats); i++) {
885 memset(msm_pm_stats[i].bucket,
886 0, sizeof(msm_pm_stats[i].bucket));
887 memset(msm_pm_stats[i].min_time,
888 0, sizeof(msm_pm_stats[i].min_time));
889 memset(msm_pm_stats[i].max_time,
890 0, sizeof(msm_pm_stats[i].max_time));
891 msm_pm_stats[i].count = 0;
892 msm_pm_stats[i].total_time = 0;
893 }
894
895 msm_pm_sleep_limit = SLEEP_LIMIT_NONE;
896 local_irq_restore(flags);
897
898 return count;
899
900write_proc_failed:
901 return ret;
902}
903#undef MSM_PM_STATS_RESET
904#endif /* CONFIG_MSM_IDLE_STATS */
905
906
907/******************************************************************************
908 * Shared Memory Bits
909 *****************************************************************************/
910
911#define DEM_MASTER_BITS_PER_CPU 6
912
913/* Power Master State Bits - Per CPU */
914#define DEM_MASTER_SMSM_RUN \
915 (0x01UL << (DEM_MASTER_BITS_PER_CPU * SMSM_APPS_STATE))
916#define DEM_MASTER_SMSM_RSA \
917 (0x02UL << (DEM_MASTER_BITS_PER_CPU * SMSM_APPS_STATE))
918#define DEM_MASTER_SMSM_PWRC_EARLY_EXIT \
919 (0x04UL << (DEM_MASTER_BITS_PER_CPU * SMSM_APPS_STATE))
920#define DEM_MASTER_SMSM_SLEEP_EXIT \
921 (0x08UL << (DEM_MASTER_BITS_PER_CPU * SMSM_APPS_STATE))
922#define DEM_MASTER_SMSM_READY \
923 (0x10UL << (DEM_MASTER_BITS_PER_CPU * SMSM_APPS_STATE))
924#define DEM_MASTER_SMSM_SLEEP \
925 (0x20UL << (DEM_MASTER_BITS_PER_CPU * SMSM_APPS_STATE))
926
927/* Power Slave State Bits */
928#define DEM_SLAVE_SMSM_RUN (0x0001)
929#define DEM_SLAVE_SMSM_PWRC (0x0002)
930#define DEM_SLAVE_SMSM_PWRC_DELAY (0x0004)
931#define DEM_SLAVE_SMSM_PWRC_EARLY_EXIT (0x0008)
932#define DEM_SLAVE_SMSM_WFPI (0x0010)
933#define DEM_SLAVE_SMSM_SLEEP (0x0020)
934#define DEM_SLAVE_SMSM_SLEEP_EXIT (0x0040)
935#define DEM_SLAVE_SMSM_MSGS_REDUCED (0x0080)
936#define DEM_SLAVE_SMSM_RESET (0x0100)
937#define DEM_SLAVE_SMSM_PWRC_SUSPEND (0x0200)
938
939
940/******************************************************************************
941 * Shared Memory Data
942 *****************************************************************************/
943
944#define DEM_MAX_PORT_NAME_LEN (20)
945
946struct msm_pm_smem_t {
947 uint32_t sleep_time;
948 uint32_t irq_mask;
949 uint32_t resources_used;
950 uint32_t reserved1;
951
952 uint32_t wakeup_reason;
953 uint32_t pending_irqs;
954 uint32_t rpc_prog;
955 uint32_t rpc_proc;
956 char smd_port_name[DEM_MAX_PORT_NAME_LEN];
957 uint32_t reserved2;
958};
959
960
961/******************************************************************************
962 *
963 *****************************************************************************/
964static struct msm_pm_smem_t *msm_pm_smem_data;
965static uint32_t *msm_pm_reset_vector;
966static atomic_t msm_pm_init_done = ATOMIC_INIT(0);
967
968static int msm_pm_modem_busy(void)
969{
970 if (!(smsm_get_state(SMSM_POWER_MASTER_DEM) & DEM_MASTER_SMSM_READY)) {
971 MSM_PM_DPRINTK(MSM_PM_DEBUG_POWER_COLLAPSE,
972 KERN_INFO, "%s(): master not ready\n", __func__);
973 return -EBUSY;
974 }
975
976 return 0;
977}
978
979/*
980 * Power collapse the Apps processor. This function executes the handshake
981 * protocol with Modem.
982 *
983 * Return value:
984 * -EAGAIN: modem reset occurred or early exit from power collapse
985 * -EBUSY: modem not ready for our power collapse -- no power loss
986 * -ETIMEDOUT: timed out waiting for modem's handshake -- no power loss
987 * 0: success
988 */
989static int msm_pm_power_collapse
990 (bool from_idle, uint32_t sleep_delay, uint32_t sleep_limit)
991{
992 struct msm_pm_polled_group state_grps[2];
993 unsigned long saved_acpuclk_rate;
994 uint32_t saved_vector[2];
995 int collapsed = 0;
996 int ret;
997
998 MSM_PM_DPRINTK(MSM_PM_DEBUG_SUSPEND|MSM_PM_DEBUG_POWER_COLLAPSE,
999 KERN_INFO, "%s(): idle %d, delay %u, limit %u\n", __func__,
1000 (int)from_idle, sleep_delay, sleep_limit);
1001
1002 if (!(smsm_get_state(SMSM_POWER_MASTER_DEM) & DEM_MASTER_SMSM_READY)) {
1003 MSM_PM_DPRINTK(
1004 MSM_PM_DEBUG_SUSPEND | MSM_PM_DEBUG_POWER_COLLAPSE,
1005 KERN_INFO, "%s(): master not ready\n", __func__);
1006 ret = -EBUSY;
1007 goto power_collapse_bail;
1008 }
1009
1010 memset(msm_pm_smem_data, 0, sizeof(*msm_pm_smem_data));
1011
1012 msm_irq_enter_sleep1(true, from_idle, &msm_pm_smem_data->irq_mask);
1013 msm_sirc_enter_sleep();
1014 msm_gpio_enter_sleep(from_idle);
1015
1016 msm_pm_smem_data->sleep_time = sleep_delay;
1017 msm_pm_smem_data->resources_used = sleep_limit;
1018
1019 /* Enter PWRC/PWRC_SUSPEND */
1020
1021 if (from_idle)
1022 smsm_change_state(SMSM_APPS_DEM, DEM_SLAVE_SMSM_RUN,
1023 DEM_SLAVE_SMSM_PWRC);
1024 else
1025 smsm_change_state(SMSM_APPS_DEM, DEM_SLAVE_SMSM_RUN,
1026 DEM_SLAVE_SMSM_PWRC | DEM_SLAVE_SMSM_PWRC_SUSPEND);
1027
1028 MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): PWRC");
1029 MSM_PM_DEBUG_PRINT_SLEEP_INFO();
1030
1031 memset(state_grps, 0, sizeof(state_grps));
1032 state_grps[0].group_id = SMSM_POWER_MASTER_DEM;
1033 state_grps[0].bits_all_set = DEM_MASTER_SMSM_RSA;
1034 state_grps[1].group_id = SMSM_MODEM_STATE;
1035 state_grps[1].bits_all_set = SMSM_RESET;
1036
1037 ret = msm_pm_poll_state(ARRAY_SIZE(state_grps), state_grps);
1038
1039 if (ret < 0) {
1040 printk(KERN_EMERG "%s(): power collapse entry "
1041 "timed out waiting for Modem's response\n", __func__);
1042 msm_pm_timeout();
1043 }
1044
1045 if (ret == 1) {
1046 MSM_PM_DPRINTK(
1047 MSM_PM_DEBUG_SUSPEND|MSM_PM_DEBUG_POWER_COLLAPSE,
1048 KERN_INFO,
1049 "%s(): msm_pm_poll_state detected Modem reset\n",
1050 __func__);
1051 goto power_collapse_early_exit;
1052 }
1053
1054 /* DEM Master in RSA */
1055
1056 MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): PWRC RSA");
1057
1058 ret = msm_irq_enter_sleep2(true, from_idle);
1059 if (ret < 0) {
1060 MSM_PM_DPRINTK(
1061 MSM_PM_DEBUG_SUSPEND|MSM_PM_DEBUG_POWER_COLLAPSE,
1062 KERN_INFO,
1063 "%s(): msm_irq_enter_sleep2 aborted, %d\n", __func__,
1064 ret);
1065 goto power_collapse_early_exit;
1066 }
1067
1068 msm_pm_config_hw_before_power_down();
1069 MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): pre power down");
1070
1071 saved_acpuclk_rate = acpuclk_power_collapse();
1072 MSM_PM_DPRINTK(MSM_PM_DEBUG_CLOCK, KERN_INFO,
1073 "%s(): change clock rate (old rate = %lu)\n", __func__,
1074 saved_acpuclk_rate);
1075
1076 if (saved_acpuclk_rate == 0) {
1077 msm_pm_config_hw_after_power_up();
1078 goto power_collapse_early_exit;
1079 }
1080
1081 saved_vector[0] = msm_pm_reset_vector[0];
1082 saved_vector[1] = msm_pm_reset_vector[1];
1083 msm_pm_reset_vector[0] = 0xE51FF004; /* ldr pc, 4 */
1084 msm_pm_reset_vector[1] = virt_to_phys(msm_pm_collapse_exit);
1085
1086 MSM_PM_DPRINTK(MSM_PM_DEBUG_RESET_VECTOR, KERN_INFO,
1087 "%s(): vector %x %x -> %x %x\n", __func__,
1088 saved_vector[0], saved_vector[1],
1089 msm_pm_reset_vector[0], msm_pm_reset_vector[1]);
1090
1091#ifdef CONFIG_VFP
1092 if (from_idle)
1093 vfp_flush_context();
1094#endif
1095
1096#ifdef CONFIG_CACHE_L2X0
1097 l2x0_suspend();
1098#endif
1099
1100 collapsed = msm_pm_collapse();
1101
1102#ifdef CONFIG_CACHE_L2X0
1103 l2x0_resume(collapsed);
1104#endif
1105
1106 msm_pm_reset_vector[0] = saved_vector[0];
1107 msm_pm_reset_vector[1] = saved_vector[1];
1108
1109 if (collapsed) {
1110#ifdef CONFIG_VFP
1111 if (from_idle)
1112 vfp_reinit();
1113#endif
1114 cpu_init();
1115 local_fiq_enable();
1116 }
1117
1118 MSM_PM_DPRINTK(MSM_PM_DEBUG_SUSPEND | MSM_PM_DEBUG_POWER_COLLAPSE,
1119 KERN_INFO,
1120 "%s(): msm_pm_collapse returned %d\n", __func__, collapsed);
1121
1122 MSM_PM_DPRINTK(MSM_PM_DEBUG_CLOCK, KERN_INFO,
1123 "%s(): restore clock rate to %lu\n", __func__,
1124 saved_acpuclk_rate);
1125 if (acpuclk_set_rate(smp_processor_id(), saved_acpuclk_rate,
1126 SETRATE_PC) < 0)
1127 printk(KERN_ERR "%s(): failed to restore clock rate(%lu)\n",
1128 __func__, saved_acpuclk_rate);
1129
1130 msm_irq_exit_sleep1(msm_pm_smem_data->irq_mask,
1131 msm_pm_smem_data->wakeup_reason,
1132 msm_pm_smem_data->pending_irqs);
1133
1134 msm_pm_config_hw_after_power_up();
1135 MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): post power up");
1136
1137 memset(state_grps, 0, sizeof(state_grps));
1138 state_grps[0].group_id = SMSM_POWER_MASTER_DEM;
1139 state_grps[0].bits_any_set =
1140 DEM_MASTER_SMSM_RSA | DEM_MASTER_SMSM_PWRC_EARLY_EXIT;
1141 state_grps[1].group_id = SMSM_MODEM_STATE;
1142 state_grps[1].bits_all_set = SMSM_RESET;
1143
1144 ret = msm_pm_poll_state(ARRAY_SIZE(state_grps), state_grps);
1145
1146 if (ret < 0) {
1147 printk(KERN_EMERG "%s(): power collapse exit "
1148 "timed out waiting for Modem's response\n", __func__);
1149 msm_pm_timeout();
1150 }
1151
1152 if (ret == 1) {
1153 MSM_PM_DPRINTK(
1154 MSM_PM_DEBUG_SUSPEND|MSM_PM_DEBUG_POWER_COLLAPSE,
1155 KERN_INFO,
1156 "%s(): msm_pm_poll_state detected Modem reset\n",
1157 __func__);
1158 goto power_collapse_early_exit;
1159 }
1160
1161 /* Sanity check */
1162 if (collapsed) {
1163 BUG_ON(!(state_grps[0].value_read & DEM_MASTER_SMSM_RSA));
1164 } else {
1165 BUG_ON(!(state_grps[0].value_read &
1166 DEM_MASTER_SMSM_PWRC_EARLY_EXIT));
1167 goto power_collapse_early_exit;
1168 }
1169
1170 /* Enter WFPI */
1171
1172 smsm_change_state(SMSM_APPS_DEM,
1173 DEM_SLAVE_SMSM_PWRC | DEM_SLAVE_SMSM_PWRC_SUSPEND,
1174 DEM_SLAVE_SMSM_WFPI);
1175
1176 MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): WFPI");
1177
1178 memset(state_grps, 0, sizeof(state_grps));
1179 state_grps[0].group_id = SMSM_POWER_MASTER_DEM;
1180 state_grps[0].bits_all_set = DEM_MASTER_SMSM_RUN;
1181 state_grps[1].group_id = SMSM_MODEM_STATE;
1182 state_grps[1].bits_all_set = SMSM_RESET;
1183
1184 ret = msm_pm_poll_state(ARRAY_SIZE(state_grps), state_grps);
1185
1186 if (ret < 0) {
1187 printk(KERN_EMERG "%s(): power collapse WFPI "
1188 "timed out waiting for Modem's response\n", __func__);
1189 msm_pm_timeout();
1190 }
1191
1192 if (ret == 1) {
1193 MSM_PM_DPRINTK(
1194 MSM_PM_DEBUG_SUSPEND|MSM_PM_DEBUG_POWER_COLLAPSE,
1195 KERN_INFO,
1196 "%s(): msm_pm_poll_state detected Modem reset\n",
1197 __func__);
1198 ret = -EAGAIN;
1199 goto power_collapse_restore_gpio_bail;
1200 }
1201
1202 /* DEM Master == RUN */
1203
1204 MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): WFPI RUN");
1205 MSM_PM_DEBUG_PRINT_SLEEP_INFO();
1206
1207 msm_irq_exit_sleep2(msm_pm_smem_data->irq_mask,
1208 msm_pm_smem_data->wakeup_reason,
1209 msm_pm_smem_data->pending_irqs);
1210 msm_irq_exit_sleep3(msm_pm_smem_data->irq_mask,
1211 msm_pm_smem_data->wakeup_reason,
1212 msm_pm_smem_data->pending_irqs);
1213 msm_gpio_exit_sleep();
1214 msm_sirc_exit_sleep();
1215
1216 smsm_change_state(SMSM_APPS_DEM,
1217 DEM_SLAVE_SMSM_WFPI, DEM_SLAVE_SMSM_RUN);
1218
1219 MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): RUN");
1220
1221 smd_sleep_exit();
1222 return 0;
1223
1224power_collapse_early_exit:
1225 /* Enter PWRC_EARLY_EXIT */
1226
1227 smsm_change_state(SMSM_APPS_DEM,
1228 DEM_SLAVE_SMSM_PWRC | DEM_SLAVE_SMSM_PWRC_SUSPEND,
1229 DEM_SLAVE_SMSM_PWRC_EARLY_EXIT);
1230
1231 MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): EARLY_EXIT");
1232
1233 memset(state_grps, 0, sizeof(state_grps));
1234 state_grps[0].group_id = SMSM_POWER_MASTER_DEM;
1235 state_grps[0].bits_all_set = DEM_MASTER_SMSM_PWRC_EARLY_EXIT;
1236 state_grps[1].group_id = SMSM_MODEM_STATE;
1237 state_grps[1].bits_all_set = SMSM_RESET;
1238
1239 ret = msm_pm_poll_state(ARRAY_SIZE(state_grps), state_grps);
1240 MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): EARLY_EXIT EE");
1241
1242 if (ret < 0) {
1243 printk(KERN_EMERG "%s(): power collapse EARLY_EXIT "
1244 "timed out waiting for Modem's response\n", __func__);
1245 msm_pm_timeout();
1246 }
1247
1248 if (ret == 1) {
1249 MSM_PM_DPRINTK(
1250 MSM_PM_DEBUG_SUSPEND|MSM_PM_DEBUG_POWER_COLLAPSE,
1251 KERN_INFO,
1252 "%s(): msm_pm_poll_state detected Modem reset\n",
1253 __func__);
1254 }
1255
1256 /* DEM Master == RESET or PWRC_EARLY_EXIT */
1257
1258 ret = -EAGAIN;
1259
1260power_collapse_restore_gpio_bail:
1261 msm_gpio_exit_sleep();
1262 msm_sirc_exit_sleep();
1263
1264 /* Enter RUN */
1265 smsm_change_state(SMSM_APPS_DEM,
1266 DEM_SLAVE_SMSM_PWRC | DEM_SLAVE_SMSM_PWRC_SUSPEND |
1267 DEM_SLAVE_SMSM_PWRC_EARLY_EXIT, DEM_SLAVE_SMSM_RUN);
1268
1269 MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): RUN");
1270
1271 if (collapsed)
1272 smd_sleep_exit();
1273
1274power_collapse_bail:
1275 return ret;
1276}
1277
1278/*
1279 * Power collapse the Apps processor without involving Modem.
1280 *
1281 * Return value:
1282 * 0: success
1283 */
1284static int msm_pm_power_collapse_standalone(void)
1285{
1286 uint32_t saved_vector[2];
1287 int collapsed = 0;
1288 int ret;
1289
1290 MSM_PM_DPRINTK(MSM_PM_DEBUG_SUSPEND|MSM_PM_DEBUG_POWER_COLLAPSE,
1291 KERN_INFO, "%s()\n", __func__);
1292
1293 ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_POWER_COLLAPSE, false);
1294 WARN_ON(ret);
1295
1296 saved_vector[0] = msm_pm_reset_vector[0];
1297 saved_vector[1] = msm_pm_reset_vector[1];
1298 msm_pm_reset_vector[0] = 0xE51FF004; /* ldr pc, 4 */
1299 msm_pm_reset_vector[1] = virt_to_phys(msm_pm_collapse_exit);
1300
1301 MSM_PM_DPRINTK(MSM_PM_DEBUG_RESET_VECTOR, KERN_INFO,
1302 "%s(): vector %x %x -> %x %x\n", __func__,
1303 saved_vector[0], saved_vector[1],
1304 msm_pm_reset_vector[0], msm_pm_reset_vector[1]);
1305
1306#ifdef CONFIG_VFP
1307 vfp_flush_context();
1308#endif
1309
1310#ifdef CONFIG_CACHE_L2X0
1311 l2x0_suspend();
1312#endif
1313
1314 collapsed = msm_pm_collapse();
1315
1316#ifdef CONFIG_CACHE_L2X0
1317 l2x0_resume(collapsed);
1318#endif
1319
1320 msm_pm_reset_vector[0] = saved_vector[0];
1321 msm_pm_reset_vector[1] = saved_vector[1];
1322
1323 if (collapsed) {
1324#ifdef CONFIG_VFP
1325 vfp_reinit();
1326#endif
1327 cpu_init();
1328 local_fiq_enable();
1329 }
1330
1331 MSM_PM_DPRINTK(MSM_PM_DEBUG_SUSPEND | MSM_PM_DEBUG_POWER_COLLAPSE,
1332 KERN_INFO,
1333 "%s(): msm_pm_collapse returned %d\n", __func__, collapsed);
1334
1335 ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING, false);
1336 WARN_ON(ret);
1337
1338 return 0;
1339}
1340
1341/*
1342 * Apps-sleep the Apps processor. This function execute the handshake
1343 * protocol with Modem.
1344 *
1345 * Return value:
1346 * -ENOSYS: function not implemented yet
1347 */
1348static int msm_pm_apps_sleep(uint32_t sleep_delay, uint32_t sleep_limit)
1349{
1350 return -ENOSYS;
1351}
1352
1353/*
1354 * Bring the Apps processor to SWFI.
1355 *
1356 * Return value:
1357 * -EIO: could not ramp Apps processor clock
1358 * 0: success
1359 */
1360static int msm_pm_swfi(bool ramp_acpu)
1361{
1362 unsigned long saved_acpuclk_rate = 0;
1363
1364 if (ramp_acpu) {
1365 saved_acpuclk_rate = acpuclk_wait_for_irq();
1366 MSM_PM_DPRINTK(MSM_PM_DEBUG_CLOCK, KERN_INFO,
1367 "%s(): change clock rate (old rate = %lu)\n", __func__,
1368 saved_acpuclk_rate);
1369
1370 if (!saved_acpuclk_rate)
1371 return -EIO;
1372 }
1373
1374 msm_pm_config_hw_before_swfi();
1375 msm_arch_idle();
1376
1377 if (ramp_acpu) {
1378 MSM_PM_DPRINTK(MSM_PM_DEBUG_CLOCK, KERN_INFO,
1379 "%s(): restore clock rate to %lu\n", __func__,
1380 saved_acpuclk_rate);
1381 if (acpuclk_set_rate(smp_processor_id(), saved_acpuclk_rate,
1382 SETRATE_SWFI) < 0)
1383 printk(KERN_ERR
1384 "%s(): failed to restore clock rate(%lu)\n",
1385 __func__, saved_acpuclk_rate);
1386 }
1387
1388 return 0;
1389}
1390
1391
1392/******************************************************************************
1393 * External Idle/Suspend Functions
1394 *****************************************************************************/
1395
1396/*
1397 * Put CPU in low power mode.
1398 */
1399void arch_idle(void)
1400{
1401 bool allow[MSM_PM_SLEEP_MODE_NR];
1402 uint32_t sleep_limit = SLEEP_LIMIT_NONE;
1403
1404 int latency_qos;
1405 int64_t timer_expiration;
1406
1407 int low_power;
1408 int ret;
1409 int i;
1410
1411#ifdef CONFIG_MSM_IDLE_STATS
1412 int64_t t1;
1413 static int64_t t2;
1414 int exit_stat;
1415#endif /* CONFIG_MSM_IDLE_STATS */
1416
1417 if (!atomic_read(&msm_pm_init_done))
1418 return;
1419
1420 latency_qos = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
1421 timer_expiration = msm_timer_enter_idle();
1422
1423#ifdef CONFIG_MSM_IDLE_STATS
1424 t1 = ktime_to_ns(ktime_get());
1425 msm_pm_add_stat(MSM_PM_STAT_NOT_IDLE, t1 - t2);
1426 msm_pm_add_stat(MSM_PM_STAT_REQUESTED_IDLE, timer_expiration);
1427#endif /* CONFIG_MSM_IDLE_STATS */
1428
1429 for (i = 0; i < ARRAY_SIZE(allow); i++)
1430 allow[i] = true;
1431
1432 switch (msm_pm_idle_sleep_mode) {
1433 case MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT:
1434 allow[MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT] =
1435 false;
1436 /* fall through */
1437 case MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT:
1438 allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE] = false;
1439 /* fall through */
1440 case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE:
1441 allow[MSM_PM_SLEEP_MODE_APPS_SLEEP] = false;
1442 /* fall through */
1443 case MSM_PM_SLEEP_MODE_APPS_SLEEP:
1444 allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN] = false;
1445 allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = false;
1446 /* fall through */
1447 case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_SUSPEND:
1448 case MSM_PM_SLEEP_MODE_POWER_COLLAPSE:
1449 break;
1450 default:
1451 printk(KERN_ERR "idle sleep mode is invalid: %d\n",
1452 msm_pm_idle_sleep_mode);
1453#ifdef CONFIG_MSM_IDLE_STATS
1454 exit_stat = MSM_PM_STAT_IDLE_SPIN;
1455#endif /* CONFIG_MSM_IDLE_STATS */
1456 low_power = 0;
1457 goto arch_idle_exit;
1458 }
1459
1460 if ((timer_expiration < msm_pm_idle_sleep_min_time) ||
1461#ifdef CONFIG_HAS_WAKELOCK
1462 has_wake_lock(WAKE_LOCK_IDLE) ||
1463#endif
1464 !msm_irq_idle_sleep_allowed()) {
1465 allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = false;
1466 allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN] = false;
1467 allow[MSM_PM_SLEEP_MODE_APPS_SLEEP] = false;
1468 }
1469
1470 for (i = 0; i < ARRAY_SIZE(allow); i++) {
1471 struct msm_pm_platform_data *mode = &msm_pm_modes[i];
1472 if (!mode->idle_supported || !mode->idle_enabled ||
1473 mode->latency >= latency_qos ||
1474 mode->residency * 1000ULL >= timer_expiration)
1475 allow[i] = false;
1476 }
1477
1478 if (allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE] ||
1479 allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN]) {
1480 uint32_t wait_us = CONFIG_MSM_IDLE_WAIT_ON_MODEM;
1481 while (msm_pm_modem_busy() && wait_us) {
1482 if (wait_us > 100) {
1483 udelay(100);
1484 wait_us -= 100;
1485 } else {
1486 udelay(wait_us);
1487 wait_us = 0;
1488 }
1489 }
1490
1491 if (msm_pm_modem_busy()) {
1492 allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = false;
1493 allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN]
1494 = false;
1495 }
1496 }
1497
1498 MSM_PM_DPRINTK(MSM_PM_DEBUG_IDLE, KERN_INFO,
1499 "%s(): latency qos %d, next timer %lld, sleep limit %u\n",
1500 __func__, latency_qos, timer_expiration, sleep_limit);
1501
1502 for (i = 0; i < ARRAY_SIZE(allow); i++)
1503 MSM_PM_DPRINTK(MSM_PM_DEBUG_IDLE, KERN_INFO,
1504 "%s(): allow %s: %d\n", __func__,
1505 msm_pm_sleep_mode_labels[i], (int)allow[i]);
1506
1507 if (allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE] ||
1508 allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN]) {
1509 uint32_t sleep_delay;
1510
1511 sleep_delay = (uint32_t) msm_pm_convert_and_cap_time(
1512 timer_expiration, MSM_PM_SLEEP_TICK_LIMIT);
1513 if (sleep_delay == 0) /* 0 would mean infinite time */
1514 sleep_delay = 1;
1515
1516 if (!allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE])
1517 sleep_limit = SLEEP_LIMIT_NO_TCXO_SHUTDOWN;
1518
1519#if defined(CONFIG_MSM_MEMORY_LOW_POWER_MODE_IDLE_ACTIVE)
1520 sleep_limit |= SLEEP_RESOURCE_MEMORY_BIT1;
1521#elif defined(CONFIG_MSM_MEMORY_LOW_POWER_MODE_IDLE_RETENTION)
1522 sleep_limit |= SLEEP_RESOURCE_MEMORY_BIT0;
1523#endif
1524
1525 ret = msm_pm_power_collapse(true, sleep_delay, sleep_limit);
1526 low_power = (ret != -EBUSY && ret != -ETIMEDOUT);
1527
1528#ifdef CONFIG_MSM_IDLE_STATS
1529 if (ret)
1530 exit_stat = MSM_PM_STAT_IDLE_FAILED_POWER_COLLAPSE;
1531 else {
1532 exit_stat = MSM_PM_STAT_IDLE_POWER_COLLAPSE;
1533 msm_pm_sleep_limit = sleep_limit;
1534 }
1535#endif /* CONFIG_MSM_IDLE_STATS */
1536 } else if (allow[MSM_PM_SLEEP_MODE_APPS_SLEEP]) {
1537 uint32_t sleep_delay;
1538
1539 sleep_delay = (uint32_t) msm_pm_convert_and_cap_time(
1540 timer_expiration, MSM_PM_SLEEP_TICK_LIMIT);
1541 if (sleep_delay == 0) /* 0 would mean infinite time */
1542 sleep_delay = 1;
1543
1544 ret = msm_pm_apps_sleep(sleep_delay, sleep_limit);
1545 low_power = 0;
1546
1547#ifdef CONFIG_MSM_IDLE_STATS
1548 if (ret)
1549 exit_stat = MSM_PM_STAT_IDLE_FAILED_SLEEP;
1550 else
1551 exit_stat = MSM_PM_STAT_IDLE_SLEEP;
1552#endif /* CONFIG_MSM_IDLE_STATS */
1553 } else if (allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE]) {
1554 ret = msm_pm_power_collapse_standalone();
1555 low_power = 0;
1556#ifdef CONFIG_MSM_IDLE_STATS
1557 exit_stat = ret ?
1558 MSM_PM_STAT_IDLE_FAILED_STANDALONE_POWER_COLLAPSE :
1559 MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE;
1560#endif /* CONFIG_MSM_IDLE_STATS */
1561 } else if (allow[MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT]) {
1562 ret = msm_pm_swfi(true);
1563 if (ret)
1564 while (!msm_irq_pending())
1565 udelay(1);
1566 low_power = 0;
1567#ifdef CONFIG_MSM_IDLE_STATS
1568 exit_stat = ret ? MSM_PM_STAT_IDLE_SPIN : MSM_PM_STAT_IDLE_WFI;
1569#endif /* CONFIG_MSM_IDLE_STATS */
1570 } else if (allow[MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT]) {
1571 msm_pm_swfi(false);
1572 low_power = 0;
1573#ifdef CONFIG_MSM_IDLE_STATS
1574 exit_stat = MSM_PM_STAT_IDLE_WFI;
1575#endif /* CONFIG_MSM_IDLE_STATS */
1576 } else {
1577 while (!msm_irq_pending())
1578 udelay(1);
1579 low_power = 0;
1580#ifdef CONFIG_MSM_IDLE_STATS
1581 exit_stat = MSM_PM_STAT_IDLE_SPIN;
1582#endif /* CONFIG_MSM_IDLE_STATS */
1583 }
1584
1585arch_idle_exit:
1586 msm_timer_exit_idle(low_power);
1587
1588#ifdef CONFIG_MSM_IDLE_STATS
1589 t2 = ktime_to_ns(ktime_get());
1590 msm_pm_add_stat(exit_stat, t2 - t1);
1591#endif /* CONFIG_MSM_IDLE_STATS */
1592}
1593
1594/*
1595 * Suspend the Apps processor.
1596 *
1597 * Return value:
1598 * -EAGAIN: modem reset occurred or early exit from suspend
1599 * -EBUSY: modem not ready for our suspend
1600 * -EINVAL: invalid sleep mode
1601 * -EIO: could not ramp Apps processor clock
1602 * -ETIMEDOUT: timed out waiting for modem's handshake
1603 * 0: success
1604 */
1605static int msm_pm_enter(suspend_state_t state)
1606{
1607 bool allow[MSM_PM_SLEEP_MODE_NR];
1608 uint32_t sleep_limit = SLEEP_LIMIT_NONE;
1609 int ret;
1610 int i;
1611
1612#ifdef CONFIG_MSM_IDLE_STATS
1613 int64_t period = 0;
1614 int64_t time = 0;
1615
1616 time = msm_timer_get_sclk_time(&period);
1617#endif
1618
1619 MSM_PM_DPRINTK(MSM_PM_DEBUG_SUSPEND, KERN_INFO,
1620 "%s(): sleep limit %u\n", __func__, sleep_limit);
1621
1622 for (i = 0; i < ARRAY_SIZE(allow); i++)
1623 allow[i] = true;
1624
1625 switch (msm_pm_sleep_mode) {
1626 case MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT:
1627 allow[MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT] =
1628 false;
1629 /* fall through */
1630 case MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT:
1631 allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE] = false;
1632 /* fall through */
1633 case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE:
1634 allow[MSM_PM_SLEEP_MODE_APPS_SLEEP] = false;
1635 /* fall through */
1636 case MSM_PM_SLEEP_MODE_APPS_SLEEP:
1637 allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN] = false;
1638 allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = false;
1639 /* fall through */
1640 case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_SUSPEND:
1641 case MSM_PM_SLEEP_MODE_POWER_COLLAPSE:
1642 break;
1643 default:
1644 printk(KERN_ERR "suspend sleep mode is invalid: %d\n",
1645 msm_pm_sleep_mode);
1646 return -EINVAL;
1647 }
1648
1649 for (i = 0; i < ARRAY_SIZE(allow); i++) {
1650 struct msm_pm_platform_data *mode = &msm_pm_modes[i];
1651 if (!mode->suspend_supported || !mode->suspend_enabled)
1652 allow[i] = false;
1653 }
1654
1655 ret = 0;
1656
1657 if (allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE] ||
1658 allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN]) {
1659#ifdef CONFIG_MSM_IDLE_STATS
1660 enum msm_pm_time_stats_id id;
1661 int64_t end_time;
1662#endif
1663
1664 clock_debug_print_enabled();
1665
1666#ifdef CONFIG_MSM_SLEEP_TIME_OVERRIDE
1667 if (msm_pm_sleep_time_override > 0) {
1668 int64_t ns;
1669 ns = NSEC_PER_SEC * (int64_t)msm_pm_sleep_time_override;
1670 msm_pm_set_max_sleep_time(ns);
1671 msm_pm_sleep_time_override = 0;
1672 }
1673#endif
1674 if (!allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE])
1675 sleep_limit = SLEEP_LIMIT_NO_TCXO_SHUTDOWN;
1676
1677#if defined(CONFIG_MSM_MEMORY_LOW_POWER_MODE_SUSPEND_ACTIVE)
1678 sleep_limit |= SLEEP_RESOURCE_MEMORY_BIT1;
1679#elif defined(CONFIG_MSM_MEMORY_LOW_POWER_MODE_SUSPEND_RETENTION)
1680 sleep_limit |= SLEEP_RESOURCE_MEMORY_BIT0;
1681#elif defined(CONFIG_MSM_MEMORY_LOW_POWER_MODE_SUSPEND_DEEP_POWER_DOWN)
1682 if (get_msm_migrate_pages_status() != MEM_OFFLINE)
1683 sleep_limit |= SLEEP_RESOURCE_MEMORY_BIT0;
1684#endif
1685
1686 for (i = 0; i < 30 && msm_pm_modem_busy(); i++)
1687 udelay(500);
1688
1689 ret = msm_pm_power_collapse(
1690 false, msm_pm_max_sleep_time, sleep_limit);
1691
1692#ifdef CONFIG_MSM_IDLE_STATS
1693 if (ret)
1694 id = MSM_PM_STAT_FAILED_SUSPEND;
1695 else {
1696 id = MSM_PM_STAT_SUSPEND;
1697 msm_pm_sleep_limit = sleep_limit;
1698 }
1699
1700 if (time != 0) {
1701 end_time = msm_timer_get_sclk_time(NULL);
1702 if (end_time != 0) {
1703 time = end_time - time;
1704 if (time < 0)
1705 time += period;
1706 } else
1707 time = 0;
1708 }
1709
1710 msm_pm_add_stat(id, time);
1711#endif
1712 } else if (allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE]) {
1713 ret = msm_pm_power_collapse_standalone();
1714 } else if (allow[MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT]) {
1715 ret = msm_pm_swfi(true);
1716 if (ret)
1717 while (!msm_irq_pending())
1718 udelay(1);
1719 } else if (allow[MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT]) {
1720 msm_pm_swfi(false);
1721 }
1722
1723 MSM_PM_DPRINTK(MSM_PM_DEBUG_SUSPEND, KERN_INFO,
1724 "%s(): return %d\n", __func__, ret);
1725
1726 return ret;
1727}
1728
1729static struct platform_suspend_ops msm_pm_ops = {
1730 .enter = msm_pm_enter,
1731 .valid = suspend_valid_only_mem,
1732};
1733
1734
1735/******************************************************************************
1736 * Restart Definitions
1737 *****************************************************************************/
1738
1739static uint32_t restart_reason = 0x776655AA;
1740
1741static void msm_pm_power_off(void)
1742{
1743 msm_rpcrouter_close();
1744 msm_proc_comm(PCOM_POWER_DOWN, 0, 0);
1745 for (;;)
1746 ;
1747}
1748
1749static void msm_pm_restart(char str, const char *cmd)
1750{
1751 msm_rpcrouter_close();
1752 msm_proc_comm(PCOM_RESET_CHIP, &restart_reason, 0);
1753
1754 for (;;)
1755 ;
1756}
1757
1758static int msm_reboot_call
1759 (struct notifier_block *this, unsigned long code, void *_cmd)
1760{
1761 if ((code == SYS_RESTART) && _cmd) {
1762 char *cmd = _cmd;
1763 if (!strcmp(cmd, "bootloader")) {
1764 restart_reason = 0x77665500;
1765 } else if (!strcmp(cmd, "recovery")) {
1766 restart_reason = 0x77665502;
1767 } else if (!strcmp(cmd, "eraseflash")) {
1768 restart_reason = 0x776655EF;
1769 } else if (!strncmp(cmd, "oem-", 4)) {
1770 unsigned code = simple_strtoul(cmd + 4, 0, 16) & 0xff;
1771 restart_reason = 0x6f656d00 | code;
1772 } else {
1773 restart_reason = 0x77665501;
1774 }
1775 }
1776 return NOTIFY_DONE;
1777}
1778
1779static struct notifier_block msm_reboot_notifier = {
1780 .notifier_call = msm_reboot_call,
1781};
1782
1783
1784/******************************************************************************
1785 *
1786 *****************************************************************************/
1787
1788/*
1789 * Initialize the power management subsystem.
1790 *
1791 * Return value:
1792 * -ENODEV: initialization failed
1793 * 0: success
1794 */
1795static int __init msm_pm_init(void)
1796{
1797#ifdef CONFIG_MSM_IDLE_STATS
1798 struct proc_dir_entry *d_entry;
1799#endif
1800 int ret;
1801#ifdef CONFIG_CPU_V7
1802 pgd_t *pc_pgd;
1803 pmd_t *pmd;
1804 unsigned long pmdval;
1805
1806 /* Page table for cores to come back up safely. */
1807 pc_pgd = pgd_alloc(&init_mm);
1808 if (!pc_pgd)
1809 return -ENOMEM;
1810 pmd = pmd_offset(pc_pgd +
1811 pgd_index(virt_to_phys(msm_pm_collapse_exit)),
1812 virt_to_phys(msm_pm_collapse_exit));
1813 pmdval = (virt_to_phys(msm_pm_collapse_exit) & PGDIR_MASK) |
1814 PMD_TYPE_SECT | PMD_SECT_AP_WRITE;
1815 pmd[0] = __pmd(pmdval);
1816 pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1)));
1817
1818 /* It is remotely possible that the code in msm_pm_collapse_exit()
1819 * which turns on the MMU with this mapping is in the
1820 * next even-numbered megabyte beyond the
1821 * start of msm_pm_collapse_exit().
1822 * Map this megabyte in as well.
1823 */
1824 pmd[2] = __pmd(pmdval + (2 << (PGDIR_SHIFT - 1)));
1825 flush_pmd_entry(pmd);
1826 msm_pm_pc_pgd = virt_to_phys(pc_pgd);
1827#endif
1828
1829 pm_power_off = msm_pm_power_off;
1830 arm_pm_restart = msm_pm_restart;
1831 register_reboot_notifier(&msm_reboot_notifier);
1832
1833 msm_pm_smem_data = smem_alloc(SMEM_APPS_DEM_SLAVE_DATA,
1834 sizeof(*msm_pm_smem_data));
1835 if (msm_pm_smem_data == NULL) {
1836 printk(KERN_ERR "%s: failed to get smsm_data\n", __func__);
1837 return -ENODEV;
1838 }
1839#if defined(CONFIG_ARCH_MSM_SCORPION) && !defined(CONFIG_MSM_SMP)
1840 /* The bootloader is responsible for initializing many of Scorpion's
1841 * coprocessor registers for things like cache timing. The state of
1842 * these coprocessor registers is lost on reset, so part of the
1843 * bootloader must be re-executed. Do not overwrite the reset vector
1844 * or bootloader area.
1845 */
1846 msm_pm_reset_vector = (uint32_t *) PAGE_OFFSET;
1847#else
1848 msm_pm_reset_vector = ioremap(0, PAGE_SIZE);
1849 if (msm_pm_reset_vector == NULL) {
1850 printk(KERN_ERR "%s: failed to map reset vector\n", __func__);
1851 return -ENODEV;
1852 }
1853#endif /* CONFIG_ARCH_MSM_SCORPION */
1854
1855 ret = msm_timer_init_time_sync(msm_pm_timeout);
1856 if (ret)
1857 return ret;
1858
1859 ret = smsm_change_intr_mask(SMSM_POWER_MASTER_DEM, 0xFFFFFFFF, 0);
1860 if (ret) {
1861 printk(KERN_ERR "%s: failed to clear interrupt mask, %d\n",
1862 __func__, ret);
1863 return ret;
1864 }
1865
1866#ifdef CONFIG_MSM_MEMORY_LOW_POWER_MODE
1867 /* The wakeup_reason field is overloaded during initialization time
1868 to signal Modem that Apps will control the low power modes of
1869 the memory.
1870 */
1871 msm_pm_smem_data->wakeup_reason = 1;
1872 smsm_change_state(SMSM_APPS_DEM, 0, DEM_SLAVE_SMSM_RUN);
1873#endif
1874
1875 BUG_ON(msm_pm_modes == NULL);
1876
1877 atomic_set(&msm_pm_init_done, 1);
1878 suspend_set_ops(&msm_pm_ops);
1879
1880 msm_pm_mode_sysfs_add();
1881#ifdef CONFIG_MSM_IDLE_STATS
1882 d_entry = create_proc_entry("msm_pm_stats",
1883 S_IRUGO | S_IWUSR | S_IWGRP, NULL);
1884 if (d_entry) {
1885 d_entry->read_proc = msm_pm_read_proc;
1886 d_entry->write_proc = msm_pm_write_proc;
1887 d_entry->data = NULL;
1888 }
1889#endif
1890
1891 return 0;
1892}
1893
1894late_initcall_sync(msm_pm_init);