Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pwr.c
Go to the documentation of this file.
1 /*
2  * pwr.c
3  *
4  * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5  *
6  * PWR API for controlling DSP power states.
7  *
8  * Copyright (C) 2005-2006 Texas Instruments, Inc.
9  *
10  * This package is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17  */
18 
19 /* ----------------------------------- Host OS */
20 #include <dspbridge/host_os.h>
21 
22 /* ----------------------------------- This */
23 #include <dspbridge/pwr.h>
24 
25 /* ----------------------------------- Resource Manager */
26 #include <dspbridge/devdefs.h>
27 #include <dspbridge/drv.h>
28 
29 /* ----------------------------------- Platform Manager */
30 #include <dspbridge/dev.h>
31 
32 /* ----------------------------------- Link Driver */
33 #include <dspbridge/dspioctl.h>
34 
35 /*
36  * ======== pwr_sleep_dsp ========
37  * Send command to DSP to enter sleep state.
38  */
39 int pwr_sleep_dsp(const u32 sleep_code, const u32 timeout)
40 {
41  struct bridge_drv_interface *intf_fxns;
42  struct bridge_dev_context *dw_context;
43  int status = -EPERM;
44  struct dev_object *hdev_obj = NULL;
45  u32 ioctlcode = 0;
46  u32 arg = timeout;
47 
48  for (hdev_obj = (struct dev_object *)drv_get_first_dev_object();
49  hdev_obj != NULL;
50  hdev_obj =
51  (struct dev_object *)drv_get_next_dev_object((u32) hdev_obj)) {
52  if (dev_get_bridge_context(hdev_obj,
53  (struct bridge_dev_context **)
54  &dw_context)) {
55  continue;
56  }
57  if (dev_get_intf_fxns(hdev_obj,
58  (struct bridge_drv_interface **)
59  &intf_fxns)) {
60  continue;
61  }
62  if (sleep_code == PWR_DEEPSLEEP)
63  ioctlcode = BRDIOCTL_DEEPSLEEP;
64  else if (sleep_code == PWR_EMERGENCYDEEPSLEEP)
65  ioctlcode = BRDIOCTL_EMERGENCYSLEEP;
66  else
67  status = -EINVAL;
68 
69  if (status != -EINVAL) {
70  status = (*intf_fxns->dev_cntrl) (dw_context,
71  ioctlcode,
72  (void *)&arg);
73  }
74  }
75  return status;
76 }
77 
78 /*
79  * ======== pwr_wake_dsp ========
80  * Send command to DSP to wake it from sleep.
81  */
82 int pwr_wake_dsp(const u32 timeout)
83 {
84  struct bridge_drv_interface *intf_fxns;
85  struct bridge_dev_context *dw_context;
86  int status = -EPERM;
87  struct dev_object *hdev_obj = NULL;
88  u32 arg = timeout;
89 
90  for (hdev_obj = (struct dev_object *)drv_get_first_dev_object();
91  hdev_obj != NULL;
92  hdev_obj = (struct dev_object *)drv_get_next_dev_object
93  ((u32) hdev_obj)) {
94  if (!(dev_get_bridge_context(hdev_obj,
95  (struct bridge_dev_context
96  **)&dw_context))) {
97  if (!(dev_get_intf_fxns(hdev_obj,
98  (struct bridge_drv_interface **)&intf_fxns))) {
99  status =
100  (*intf_fxns->dev_cntrl) (dw_context,
102  (void *)&arg);
103  }
104  }
105  }
106  return status;
107 }
108 
109 /*
110  * ======== pwr_pm_pre_scale========
111  * Sends pre-notification message to DSP.
112  */
113 int pwr_pm_pre_scale(u16 voltage_domain, u32 level)
114 {
115  struct bridge_drv_interface *intf_fxns;
116  struct bridge_dev_context *dw_context;
117  int status = -EPERM;
118  struct dev_object *hdev_obj = NULL;
119  u32 arg[2];
120 
121  arg[0] = voltage_domain;
122  arg[1] = level;
123 
124  for (hdev_obj = (struct dev_object *)drv_get_first_dev_object();
125  hdev_obj != NULL;
126  hdev_obj = (struct dev_object *)drv_get_next_dev_object
127  ((u32) hdev_obj)) {
128  if (!(dev_get_bridge_context(hdev_obj,
129  (struct bridge_dev_context
130  **)&dw_context))) {
131  if (!(dev_get_intf_fxns(hdev_obj,
132  (struct bridge_drv_interface **)&intf_fxns))) {
133  status =
134  (*intf_fxns->dev_cntrl) (dw_context,
136  (void *)&arg);
137  }
138  }
139  }
140  return status;
141 }
142 
143 /*
144  * ======== pwr_pm_post_scale========
145  * Sends post-notification message to DSP.
146  */
147 int pwr_pm_post_scale(u16 voltage_domain, u32 level)
148 {
149  struct bridge_drv_interface *intf_fxns;
150  struct bridge_dev_context *dw_context;
151  int status = -EPERM;
152  struct dev_object *hdev_obj = NULL;
153  u32 arg[2];
154 
155  arg[0] = voltage_domain;
156  arg[1] = level;
157 
158  for (hdev_obj = (struct dev_object *)drv_get_first_dev_object();
159  hdev_obj != NULL;
160  hdev_obj = (struct dev_object *)drv_get_next_dev_object
161  ((u32) hdev_obj)) {
162  if (!(dev_get_bridge_context(hdev_obj,
163  (struct bridge_dev_context
164  **)&dw_context))) {
165  if (!(dev_get_intf_fxns(hdev_obj,
166  (struct bridge_drv_interface **)&intf_fxns))) {
167  status =
168  (*intf_fxns->dev_cntrl) (dw_context,
170  (void *)&arg);
171  }
172  }
173  }
174  return status;
175 
176 }