]> Pileus Git - ~andy/linux/blob - drivers/staging/tidspbridge/rmgr/pwr.c
Merge tag 'metag-v3.9-rc1-v4' of git://git.kernel.org/pub/scm/linux/kernel/git/jhogan...
[~andy/linux] / drivers / staging / tidspbridge / rmgr / pwr.c
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,
101                                                         BRDIOCTL_WAKEUP,
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,
135                                                 BRDIOCTL_PRESCALE_NOTIFY,
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,
169                                                 BRDIOCTL_POSTSCALE_NOTIFY,
170                                                 (void *)&arg);
171                         }
172                 }
173         }
174         return status;
175
176 }