1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker * Copyright © 2013, 2015 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker *
4*d83cc019SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker *
11*d83cc019SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker * Software.
14*d83cc019SAndroid Build Coastguard Worker *
15*d83cc019SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*d83cc019SAndroid Build Coastguard Worker * IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker *
23*d83cc019SAndroid Build Coastguard Worker * Authors:
24*d83cc019SAndroid Build Coastguard Worker * Paulo Zanoni <[email protected]>
25*d83cc019SAndroid Build Coastguard Worker * David Weinehall <[email protected]>
26*d83cc019SAndroid Build Coastguard Worker *
27*d83cc019SAndroid Build Coastguard Worker */
28*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
29*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
30*d83cc019SAndroid Build Coastguard Worker #include <limits.h>
31*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
32*d83cc019SAndroid Build Coastguard Worker #include <string.h>
33*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
34*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
35*d83cc019SAndroid Build Coastguard Worker #include <sys/types.h>
36*d83cc019SAndroid Build Coastguard Worker #include <dirent.h>
37*d83cc019SAndroid Build Coastguard Worker
38*d83cc019SAndroid Build Coastguard Worker #include "drmtest.h"
39*d83cc019SAndroid Build Coastguard Worker #include "igt_pm.h"
40*d83cc019SAndroid Build Coastguard Worker #include "igt_aux.h"
41*d83cc019SAndroid Build Coastguard Worker
42*d83cc019SAndroid Build Coastguard Worker /**
43*d83cc019SAndroid Build Coastguard Worker * SECTION:igt_pm
44*d83cc019SAndroid Build Coastguard Worker * @short_description: Power Management related helpers
45*d83cc019SAndroid Build Coastguard Worker * @title: Power Management
46*d83cc019SAndroid Build Coastguard Worker * @include: igt.h
47*d83cc019SAndroid Build Coastguard Worker *
48*d83cc019SAndroid Build Coastguard Worker * This library provides various helpers to enable power management for,
49*d83cc019SAndroid Build Coastguard Worker * and in some cases subsequently allow restoring the old behaviour of,
50*d83cc019SAndroid Build Coastguard Worker * various external components that by default are set up in a way
51*d83cc019SAndroid Build Coastguard Worker * that interferes with the testing of our power management functionality.
52*d83cc019SAndroid Build Coastguard Worker */
53*d83cc019SAndroid Build Coastguard Worker
54*d83cc019SAndroid Build Coastguard Worker enum {
55*d83cc019SAndroid Build Coastguard Worker POLICY_UNKNOWN = -1,
56*d83cc019SAndroid Build Coastguard Worker POLICY_MAX_PERFORMANCE = 0,
57*d83cc019SAndroid Build Coastguard Worker POLICY_MEDIUM_POWER = 1,
58*d83cc019SAndroid Build Coastguard Worker POLICY_MIN_POWER = 2
59*d83cc019SAndroid Build Coastguard Worker };
60*d83cc019SAndroid Build Coastguard Worker
61*d83cc019SAndroid Build Coastguard Worker #define MAX_PERFORMANCE_STR "max_performance\n"
62*d83cc019SAndroid Build Coastguard Worker #define MEDIUM_POWER_STR "medium_power\n"
63*d83cc019SAndroid Build Coastguard Worker #define MIN_POWER_STR "min_power\n"
64*d83cc019SAndroid Build Coastguard Worker /* Remember to fix this if adding longer strings */
65*d83cc019SAndroid Build Coastguard Worker #define MAX_POLICY_STRLEN strlen(MAX_PERFORMANCE_STR)
66*d83cc019SAndroid Build Coastguard Worker
67*d83cc019SAndroid Build Coastguard Worker static char __igt_pm_audio_runtime_power_save[64];
68*d83cc019SAndroid Build Coastguard Worker static char * __igt_pm_audio_runtime_control_path;
69*d83cc019SAndroid Build Coastguard Worker static char __igt_pm_audio_runtime_control[64];
70*d83cc019SAndroid Build Coastguard Worker
__igt_pm_audio_restore_runtime_pm(void)71*d83cc019SAndroid Build Coastguard Worker static int __igt_pm_audio_restore_runtime_pm(void)
72*d83cc019SAndroid Build Coastguard Worker {
73*d83cc019SAndroid Build Coastguard Worker int fd;
74*d83cc019SAndroid Build Coastguard Worker
75*d83cc019SAndroid Build Coastguard Worker if (!__igt_pm_audio_runtime_power_save[0])
76*d83cc019SAndroid Build Coastguard Worker return 0;
77*d83cc019SAndroid Build Coastguard Worker
78*d83cc019SAndroid Build Coastguard Worker fd = open("/sys/module/snd_hda_intel/parameters/power_save", O_WRONLY);
79*d83cc019SAndroid Build Coastguard Worker if (fd < 0)
80*d83cc019SAndroid Build Coastguard Worker return errno;
81*d83cc019SAndroid Build Coastguard Worker
82*d83cc019SAndroid Build Coastguard Worker if (write(fd, __igt_pm_audio_runtime_power_save,
83*d83cc019SAndroid Build Coastguard Worker strlen(__igt_pm_audio_runtime_power_save)) !=
84*d83cc019SAndroid Build Coastguard Worker strlen(__igt_pm_audio_runtime_power_save)) {
85*d83cc019SAndroid Build Coastguard Worker close(fd);
86*d83cc019SAndroid Build Coastguard Worker return errno;
87*d83cc019SAndroid Build Coastguard Worker }
88*d83cc019SAndroid Build Coastguard Worker
89*d83cc019SAndroid Build Coastguard Worker close(fd);
90*d83cc019SAndroid Build Coastguard Worker
91*d83cc019SAndroid Build Coastguard Worker fd = open(__igt_pm_audio_runtime_control_path, O_WRONLY);
92*d83cc019SAndroid Build Coastguard Worker if (fd < 0)
93*d83cc019SAndroid Build Coastguard Worker return errno;
94*d83cc019SAndroid Build Coastguard Worker
95*d83cc019SAndroid Build Coastguard Worker if (write(fd, __igt_pm_audio_runtime_control,
96*d83cc019SAndroid Build Coastguard Worker strlen(__igt_pm_audio_runtime_control)) !=
97*d83cc019SAndroid Build Coastguard Worker strlen(__igt_pm_audio_runtime_control)) {
98*d83cc019SAndroid Build Coastguard Worker close(fd);
99*d83cc019SAndroid Build Coastguard Worker return errno;
100*d83cc019SAndroid Build Coastguard Worker }
101*d83cc019SAndroid Build Coastguard Worker
102*d83cc019SAndroid Build Coastguard Worker close(fd);
103*d83cc019SAndroid Build Coastguard Worker
104*d83cc019SAndroid Build Coastguard Worker memset(__igt_pm_audio_runtime_power_save, 0,
105*d83cc019SAndroid Build Coastguard Worker sizeof(__igt_pm_audio_runtime_power_save));
106*d83cc019SAndroid Build Coastguard Worker
107*d83cc019SAndroid Build Coastguard Worker memset(__igt_pm_audio_runtime_control, 0,
108*d83cc019SAndroid Build Coastguard Worker sizeof(__igt_pm_audio_runtime_control));
109*d83cc019SAndroid Build Coastguard Worker
110*d83cc019SAndroid Build Coastguard Worker free(__igt_pm_audio_runtime_control_path);
111*d83cc019SAndroid Build Coastguard Worker __igt_pm_audio_runtime_control_path = NULL;
112*d83cc019SAndroid Build Coastguard Worker
113*d83cc019SAndroid Build Coastguard Worker return 0;
114*d83cc019SAndroid Build Coastguard Worker }
115*d83cc019SAndroid Build Coastguard Worker
igt_pm_audio_restore_runtime_pm(void)116*d83cc019SAndroid Build Coastguard Worker static void igt_pm_audio_restore_runtime_pm(void)
117*d83cc019SAndroid Build Coastguard Worker {
118*d83cc019SAndroid Build Coastguard Worker int ret;
119*d83cc019SAndroid Build Coastguard Worker
120*d83cc019SAndroid Build Coastguard Worker if (!__igt_pm_audio_runtime_power_save[0])
121*d83cc019SAndroid Build Coastguard Worker return;
122*d83cc019SAndroid Build Coastguard Worker
123*d83cc019SAndroid Build Coastguard Worker igt_debug("Restoring audio power management to '%s' and '%s'\n",
124*d83cc019SAndroid Build Coastguard Worker __igt_pm_audio_runtime_power_save,
125*d83cc019SAndroid Build Coastguard Worker __igt_pm_audio_runtime_control);
126*d83cc019SAndroid Build Coastguard Worker
127*d83cc019SAndroid Build Coastguard Worker ret = __igt_pm_audio_restore_runtime_pm();
128*d83cc019SAndroid Build Coastguard Worker if (ret)
129*d83cc019SAndroid Build Coastguard Worker igt_warn("Failed to restore runtime audio PM! (errno=%d)\n",
130*d83cc019SAndroid Build Coastguard Worker ret);
131*d83cc019SAndroid Build Coastguard Worker }
132*d83cc019SAndroid Build Coastguard Worker
__igt_pm_audio_runtime_exit_handler(int sig)133*d83cc019SAndroid Build Coastguard Worker static void __igt_pm_audio_runtime_exit_handler(int sig)
134*d83cc019SAndroid Build Coastguard Worker {
135*d83cc019SAndroid Build Coastguard Worker __igt_pm_audio_restore_runtime_pm();
136*d83cc019SAndroid Build Coastguard Worker }
137*d83cc019SAndroid Build Coastguard Worker
strchomp(char * str)138*d83cc019SAndroid Build Coastguard Worker static void strchomp(char *str)
139*d83cc019SAndroid Build Coastguard Worker {
140*d83cc019SAndroid Build Coastguard Worker int len = strlen(str);
141*d83cc019SAndroid Build Coastguard Worker
142*d83cc019SAndroid Build Coastguard Worker if (len && str[len - 1] == '\n')
143*d83cc019SAndroid Build Coastguard Worker str[len - 1] = 0;
144*d83cc019SAndroid Build Coastguard Worker }
145*d83cc019SAndroid Build Coastguard Worker
__igt_pm_enable_audio_runtime_pm(void)146*d83cc019SAndroid Build Coastguard Worker static int __igt_pm_enable_audio_runtime_pm(void)
147*d83cc019SAndroid Build Coastguard Worker {
148*d83cc019SAndroid Build Coastguard Worker char *path = NULL;
149*d83cc019SAndroid Build Coastguard Worker struct dirent *de;
150*d83cc019SAndroid Build Coastguard Worker DIR *dir;
151*d83cc019SAndroid Build Coastguard Worker int err;
152*d83cc019SAndroid Build Coastguard Worker int fd;
153*d83cc019SAndroid Build Coastguard Worker
154*d83cc019SAndroid Build Coastguard Worker dir = opendir("/sys/class/sound");
155*d83cc019SAndroid Build Coastguard Worker if (!dir)
156*d83cc019SAndroid Build Coastguard Worker return 0;
157*d83cc019SAndroid Build Coastguard Worker
158*d83cc019SAndroid Build Coastguard Worker /* Find PCI device claimed by snd_hda_intel and tied to i915. */
159*d83cc019SAndroid Build Coastguard Worker while ((de = readdir(dir))) {
160*d83cc019SAndroid Build Coastguard Worker const char *match = "hwC";
161*d83cc019SAndroid Build Coastguard Worker char buf[32] = { }; /* for Valgrind */
162*d83cc019SAndroid Build Coastguard Worker int loops = 500;
163*d83cc019SAndroid Build Coastguard Worker int base;
164*d83cc019SAndroid Build Coastguard Worker int ret;
165*d83cc019SAndroid Build Coastguard Worker
166*d83cc019SAndroid Build Coastguard Worker if (de->d_type != DT_LNK ||
167*d83cc019SAndroid Build Coastguard Worker strncmp(de->d_name, match, strlen(match)))
168*d83cc019SAndroid Build Coastguard Worker continue;
169*d83cc019SAndroid Build Coastguard Worker
170*d83cc019SAndroid Build Coastguard Worker base = openat(dirfd(dir), de->d_name, O_RDONLY);
171*d83cc019SAndroid Build Coastguard Worker igt_assert_fd(base);
172*d83cc019SAndroid Build Coastguard Worker
173*d83cc019SAndroid Build Coastguard Worker do {
174*d83cc019SAndroid Build Coastguard Worker fd = openat(base, "vendor_name", O_RDONLY);
175*d83cc019SAndroid Build Coastguard Worker if (fd < 0) /* module is still loading? */
176*d83cc019SAndroid Build Coastguard Worker usleep(1000);
177*d83cc019SAndroid Build Coastguard Worker else
178*d83cc019SAndroid Build Coastguard Worker break;
179*d83cc019SAndroid Build Coastguard Worker } while (--loops);
180*d83cc019SAndroid Build Coastguard Worker close(base);
181*d83cc019SAndroid Build Coastguard Worker if (fd < 0)
182*d83cc019SAndroid Build Coastguard Worker continue;
183*d83cc019SAndroid Build Coastguard Worker
184*d83cc019SAndroid Build Coastguard Worker ret = read(fd, buf, sizeof(buf) - 1);
185*d83cc019SAndroid Build Coastguard Worker close(fd);
186*d83cc019SAndroid Build Coastguard Worker igt_assert(ret > 0);
187*d83cc019SAndroid Build Coastguard Worker buf[ret] = '\0';
188*d83cc019SAndroid Build Coastguard Worker strchomp(buf);
189*d83cc019SAndroid Build Coastguard Worker
190*d83cc019SAndroid Build Coastguard Worker /* Realtek and similar devices are not what we are after. */
191*d83cc019SAndroid Build Coastguard Worker if (strcmp(buf, "Intel"))
192*d83cc019SAndroid Build Coastguard Worker continue;
193*d83cc019SAndroid Build Coastguard Worker
194*d83cc019SAndroid Build Coastguard Worker igt_assert(asprintf(&path,
195*d83cc019SAndroid Build Coastguard Worker "/sys/class/sound/%s/device/device/power/control",
196*d83cc019SAndroid Build Coastguard Worker de->d_name));
197*d83cc019SAndroid Build Coastguard Worker
198*d83cc019SAndroid Build Coastguard Worker igt_debug("Audio device path is %s\n", path);
199*d83cc019SAndroid Build Coastguard Worker break;
200*d83cc019SAndroid Build Coastguard Worker }
201*d83cc019SAndroid Build Coastguard Worker closedir(dir);
202*d83cc019SAndroid Build Coastguard Worker
203*d83cc019SAndroid Build Coastguard Worker fd = open("/sys/module/snd_hda_intel/parameters/power_save", O_RDWR);
204*d83cc019SAndroid Build Coastguard Worker if (fd < 0)
205*d83cc019SAndroid Build Coastguard Worker return 0;
206*d83cc019SAndroid Build Coastguard Worker
207*d83cc019SAndroid Build Coastguard Worker /* snd_hda_intel loaded but no path found is an error. */
208*d83cc019SAndroid Build Coastguard Worker if (!path) {
209*d83cc019SAndroid Build Coastguard Worker close(fd);
210*d83cc019SAndroid Build Coastguard Worker err = -ESRCH;
211*d83cc019SAndroid Build Coastguard Worker goto err;
212*d83cc019SAndroid Build Coastguard Worker }
213*d83cc019SAndroid Build Coastguard Worker
214*d83cc019SAndroid Build Coastguard Worker igt_assert(read(fd, __igt_pm_audio_runtime_power_save,
215*d83cc019SAndroid Build Coastguard Worker sizeof(__igt_pm_audio_runtime_power_save) - 1) > 0);
216*d83cc019SAndroid Build Coastguard Worker strchomp(__igt_pm_audio_runtime_power_save);
217*d83cc019SAndroid Build Coastguard Worker igt_install_exit_handler(__igt_pm_audio_runtime_exit_handler);
218*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(write(fd, "1\n", 2), 2);
219*d83cc019SAndroid Build Coastguard Worker close(fd);
220*d83cc019SAndroid Build Coastguard Worker
221*d83cc019SAndroid Build Coastguard Worker fd = open(path, O_RDWR);
222*d83cc019SAndroid Build Coastguard Worker if (fd < 0) {
223*d83cc019SAndroid Build Coastguard Worker err = -errno;
224*d83cc019SAndroid Build Coastguard Worker goto err;
225*d83cc019SAndroid Build Coastguard Worker }
226*d83cc019SAndroid Build Coastguard Worker
227*d83cc019SAndroid Build Coastguard Worker igt_assert(read(fd, __igt_pm_audio_runtime_control,
228*d83cc019SAndroid Build Coastguard Worker sizeof(__igt_pm_audio_runtime_control) - 1) > 0);
229*d83cc019SAndroid Build Coastguard Worker strchomp(__igt_pm_audio_runtime_control);
230*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(write(fd, "auto\n", 5), 5);
231*d83cc019SAndroid Build Coastguard Worker close(fd);
232*d83cc019SAndroid Build Coastguard Worker
233*d83cc019SAndroid Build Coastguard Worker __igt_pm_audio_runtime_control_path = path;
234*d83cc019SAndroid Build Coastguard Worker
235*d83cc019SAndroid Build Coastguard Worker igt_debug("Saved audio power management as '%s' and '%s'\n",
236*d83cc019SAndroid Build Coastguard Worker __igt_pm_audio_runtime_power_save,
237*d83cc019SAndroid Build Coastguard Worker __igt_pm_audio_runtime_control);
238*d83cc019SAndroid Build Coastguard Worker
239*d83cc019SAndroid Build Coastguard Worker /* Give some time for it to react. */
240*d83cc019SAndroid Build Coastguard Worker sleep(1);
241*d83cc019SAndroid Build Coastguard Worker return 0;
242*d83cc019SAndroid Build Coastguard Worker
243*d83cc019SAndroid Build Coastguard Worker err:
244*d83cc019SAndroid Build Coastguard Worker free(path);
245*d83cc019SAndroid Build Coastguard Worker return err;
246*d83cc019SAndroid Build Coastguard Worker }
247*d83cc019SAndroid Build Coastguard Worker
248*d83cc019SAndroid Build Coastguard Worker /**
249*d83cc019SAndroid Build Coastguard Worker * igt_pm_enable_audio_runtime_pm:
250*d83cc019SAndroid Build Coastguard Worker *
251*d83cc019SAndroid Build Coastguard Worker * We know that if we don't enable audio runtime PM, snd_hda_intel will never
252*d83cc019SAndroid Build Coastguard Worker * release its power well refcount, and we'll never reach the LPSP state.
253*d83cc019SAndroid Build Coastguard Worker * There's no guarantee that it will release the power well if we enable
254*d83cc019SAndroid Build Coastguard Worker * runtime PM, but at least we can try.
255*d83cc019SAndroid Build Coastguard Worker *
256*d83cc019SAndroid Build Coastguard Worker * We don't have any assertions on open since the user may not even have
257*d83cc019SAndroid Build Coastguard Worker * snd_hda_intel loaded, which is not a problem.
258*d83cc019SAndroid Build Coastguard Worker */
igt_pm_enable_audio_runtime_pm(void)259*d83cc019SAndroid Build Coastguard Worker void igt_pm_enable_audio_runtime_pm(void)
260*d83cc019SAndroid Build Coastguard Worker {
261*d83cc019SAndroid Build Coastguard Worker int err;
262*d83cc019SAndroid Build Coastguard Worker
263*d83cc019SAndroid Build Coastguard Worker /* Check if already enabled. */
264*d83cc019SAndroid Build Coastguard Worker if (__igt_pm_audio_runtime_power_save[0])
265*d83cc019SAndroid Build Coastguard Worker return;
266*d83cc019SAndroid Build Coastguard Worker
267*d83cc019SAndroid Build Coastguard Worker for (int count = 0; count < 110; count++) {
268*d83cc019SAndroid Build Coastguard Worker if (!__igt_pm_enable_audio_runtime_pm())
269*d83cc019SAndroid Build Coastguard Worker return;
270*d83cc019SAndroid Build Coastguard Worker
271*d83cc019SAndroid Build Coastguard Worker /* modprobe(sna-hda-intel) acts async so poll for sysfs */
272*d83cc019SAndroid Build Coastguard Worker if (count < 100)
273*d83cc019SAndroid Build Coastguard Worker usleep(10 * 1000); /* poll at 10ms for the first 1s */
274*d83cc019SAndroid Build Coastguard Worker else
275*d83cc019SAndroid Build Coastguard Worker sleep(1);
276*d83cc019SAndroid Build Coastguard Worker }
277*d83cc019SAndroid Build Coastguard Worker
278*d83cc019SAndroid Build Coastguard Worker err = __igt_pm_enable_audio_runtime_pm();
279*d83cc019SAndroid Build Coastguard Worker if (err)
280*d83cc019SAndroid Build Coastguard Worker igt_debug("Failed to enable audio runtime PM! (%d)\n", -err);
281*d83cc019SAndroid Build Coastguard Worker }
282*d83cc019SAndroid Build Coastguard Worker
283*d83cc019SAndroid Build Coastguard Worker /**
284*d83cc019SAndroid Build Coastguard Worker * igt_pm_enable_sata_link_power_management:
285*d83cc019SAndroid Build Coastguard Worker *
286*d83cc019SAndroid Build Coastguard Worker * Enable the min_power policy for SATA link power management.
287*d83cc019SAndroid Build Coastguard Worker * Without this we cannot reach deep runtime power states.
288*d83cc019SAndroid Build Coastguard Worker *
289*d83cc019SAndroid Build Coastguard Worker * We don't have any assertions on open since the system might not have
290*d83cc019SAndroid Build Coastguard Worker * a SATA host.
291*d83cc019SAndroid Build Coastguard Worker *
292*d83cc019SAndroid Build Coastguard Worker * Returns:
293*d83cc019SAndroid Build Coastguard Worker * An opaque pointer to the data needed to restore the default values
294*d83cc019SAndroid Build Coastguard Worker * after the test has terminated, or NULL if SATA link power management
295*d83cc019SAndroid Build Coastguard Worker * is not supported. This pointer should be freed when no longer used
296*d83cc019SAndroid Build Coastguard Worker * (typically after having called restore_sata_link_power_management()).
297*d83cc019SAndroid Build Coastguard Worker */
igt_pm_enable_sata_link_power_management(void)298*d83cc019SAndroid Build Coastguard Worker int8_t *igt_pm_enable_sata_link_power_management(void)
299*d83cc019SAndroid Build Coastguard Worker {
300*d83cc019SAndroid Build Coastguard Worker int fd, i;
301*d83cc019SAndroid Build Coastguard Worker ssize_t len;
302*d83cc019SAndroid Build Coastguard Worker char *buf;
303*d83cc019SAndroid Build Coastguard Worker char *file_name;
304*d83cc019SAndroid Build Coastguard Worker int8_t *link_pm_policies = NULL;
305*d83cc019SAndroid Build Coastguard Worker
306*d83cc019SAndroid Build Coastguard Worker file_name = malloc(PATH_MAX);
307*d83cc019SAndroid Build Coastguard Worker buf = malloc(MAX_POLICY_STRLEN + 1);
308*d83cc019SAndroid Build Coastguard Worker
309*d83cc019SAndroid Build Coastguard Worker for (i = 0; ; i++) {
310*d83cc019SAndroid Build Coastguard Worker int8_t policy;
311*d83cc019SAndroid Build Coastguard Worker
312*d83cc019SAndroid Build Coastguard Worker snprintf(file_name, PATH_MAX,
313*d83cc019SAndroid Build Coastguard Worker "/sys/class/scsi_host/host%d/link_power_management_policy",
314*d83cc019SAndroid Build Coastguard Worker i);
315*d83cc019SAndroid Build Coastguard Worker
316*d83cc019SAndroid Build Coastguard Worker fd = open(file_name, O_RDWR);
317*d83cc019SAndroid Build Coastguard Worker if (fd < 0)
318*d83cc019SAndroid Build Coastguard Worker break;
319*d83cc019SAndroid Build Coastguard Worker
320*d83cc019SAndroid Build Coastguard Worker len = read(fd, buf, MAX_POLICY_STRLEN);
321*d83cc019SAndroid Build Coastguard Worker buf[len] = '\0';
322*d83cc019SAndroid Build Coastguard Worker
323*d83cc019SAndroid Build Coastguard Worker if (!strncmp(MAX_PERFORMANCE_STR, buf,
324*d83cc019SAndroid Build Coastguard Worker strlen(MAX_PERFORMANCE_STR)))
325*d83cc019SAndroid Build Coastguard Worker policy = POLICY_MAX_PERFORMANCE;
326*d83cc019SAndroid Build Coastguard Worker else if (!strncmp(MEDIUM_POWER_STR, buf,
327*d83cc019SAndroid Build Coastguard Worker strlen(MEDIUM_POWER_STR)))
328*d83cc019SAndroid Build Coastguard Worker policy = POLICY_MEDIUM_POWER;
329*d83cc019SAndroid Build Coastguard Worker else if (!strncmp(MIN_POWER_STR, buf,
330*d83cc019SAndroid Build Coastguard Worker strlen(MIN_POWER_STR)))
331*d83cc019SAndroid Build Coastguard Worker policy = POLICY_MIN_POWER;
332*d83cc019SAndroid Build Coastguard Worker else
333*d83cc019SAndroid Build Coastguard Worker policy = POLICY_UNKNOWN;
334*d83cc019SAndroid Build Coastguard Worker
335*d83cc019SAndroid Build Coastguard Worker if (!(i % 256))
336*d83cc019SAndroid Build Coastguard Worker link_pm_policies = realloc(link_pm_policies,
337*d83cc019SAndroid Build Coastguard Worker (i / 256 + 1) * 256 + 1);
338*d83cc019SAndroid Build Coastguard Worker
339*d83cc019SAndroid Build Coastguard Worker link_pm_policies[i] = policy;
340*d83cc019SAndroid Build Coastguard Worker link_pm_policies[i + 1] = 0;
341*d83cc019SAndroid Build Coastguard Worker
342*d83cc019SAndroid Build Coastguard Worker /* If the policy is something we don't know about,
343*d83cc019SAndroid Build Coastguard Worker * don't touch it, since we might potentially break things.
344*d83cc019SAndroid Build Coastguard Worker * And we obviously don't need to touch anything if the
345*d83cc019SAndroid Build Coastguard Worker * setting is already correct...
346*d83cc019SAndroid Build Coastguard Worker */
347*d83cc019SAndroid Build Coastguard Worker if (policy != POLICY_UNKNOWN &&
348*d83cc019SAndroid Build Coastguard Worker policy != POLICY_MIN_POWER) {
349*d83cc019SAndroid Build Coastguard Worker lseek(fd, 0, SEEK_SET);
350*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(write(fd, MIN_POWER_STR,
351*d83cc019SAndroid Build Coastguard Worker strlen(MIN_POWER_STR)),
352*d83cc019SAndroid Build Coastguard Worker strlen(MIN_POWER_STR));
353*d83cc019SAndroid Build Coastguard Worker }
354*d83cc019SAndroid Build Coastguard Worker close(fd);
355*d83cc019SAndroid Build Coastguard Worker }
356*d83cc019SAndroid Build Coastguard Worker free(buf);
357*d83cc019SAndroid Build Coastguard Worker free(file_name);
358*d83cc019SAndroid Build Coastguard Worker
359*d83cc019SAndroid Build Coastguard Worker return link_pm_policies;
360*d83cc019SAndroid Build Coastguard Worker }
361*d83cc019SAndroid Build Coastguard Worker
362*d83cc019SAndroid Build Coastguard Worker /**
363*d83cc019SAndroid Build Coastguard Worker * igt_pm_restore_sata_link_power_management:
364*d83cc019SAndroid Build Coastguard Worker * @pm_data: An opaque pointer with saved link PM policies;
365*d83cc019SAndroid Build Coastguard Worker * If NULL is passed we force enable the "max_performance" policy.
366*d83cc019SAndroid Build Coastguard Worker *
367*d83cc019SAndroid Build Coastguard Worker * Restore the link power management policies to the values
368*d83cc019SAndroid Build Coastguard Worker * prior to enabling min_power.
369*d83cc019SAndroid Build Coastguard Worker *
370*d83cc019SAndroid Build Coastguard Worker * Caveat: If the system supports hotplugging and hotplugging takes
371*d83cc019SAndroid Build Coastguard Worker * place during our testing so that the hosts change numbers
372*d83cc019SAndroid Build Coastguard Worker * we might restore the settings to the wrong hosts.
373*d83cc019SAndroid Build Coastguard Worker */
igt_pm_restore_sata_link_power_management(int8_t * pm_data)374*d83cc019SAndroid Build Coastguard Worker void igt_pm_restore_sata_link_power_management(int8_t *pm_data)
375*d83cc019SAndroid Build Coastguard Worker
376*d83cc019SAndroid Build Coastguard Worker {
377*d83cc019SAndroid Build Coastguard Worker int fd, i;
378*d83cc019SAndroid Build Coastguard Worker char *file_name;
379*d83cc019SAndroid Build Coastguard Worker
380*d83cc019SAndroid Build Coastguard Worker /* Disk runtime PM policies. */
381*d83cc019SAndroid Build Coastguard Worker file_name = malloc(PATH_MAX);
382*d83cc019SAndroid Build Coastguard Worker for (i = 0; ; i++) {
383*d83cc019SAndroid Build Coastguard Worker int8_t policy;
384*d83cc019SAndroid Build Coastguard Worker
385*d83cc019SAndroid Build Coastguard Worker if (!pm_data)
386*d83cc019SAndroid Build Coastguard Worker policy = POLICY_MAX_PERFORMANCE;
387*d83cc019SAndroid Build Coastguard Worker else if (pm_data[i] == POLICY_UNKNOWN)
388*d83cc019SAndroid Build Coastguard Worker continue;
389*d83cc019SAndroid Build Coastguard Worker else
390*d83cc019SAndroid Build Coastguard Worker policy = pm_data[i];
391*d83cc019SAndroid Build Coastguard Worker
392*d83cc019SAndroid Build Coastguard Worker snprintf(file_name, PATH_MAX,
393*d83cc019SAndroid Build Coastguard Worker "/sys/class/scsi_host/host%d/link_power_management_policy",
394*d83cc019SAndroid Build Coastguard Worker i);
395*d83cc019SAndroid Build Coastguard Worker
396*d83cc019SAndroid Build Coastguard Worker fd = open(file_name, O_WRONLY);
397*d83cc019SAndroid Build Coastguard Worker if (fd < 0)
398*d83cc019SAndroid Build Coastguard Worker break;
399*d83cc019SAndroid Build Coastguard Worker
400*d83cc019SAndroid Build Coastguard Worker switch (policy) {
401*d83cc019SAndroid Build Coastguard Worker default:
402*d83cc019SAndroid Build Coastguard Worker case POLICY_MAX_PERFORMANCE:
403*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(write(fd, MAX_PERFORMANCE_STR,
404*d83cc019SAndroid Build Coastguard Worker strlen(MAX_PERFORMANCE_STR)),
405*d83cc019SAndroid Build Coastguard Worker strlen(MAX_PERFORMANCE_STR));
406*d83cc019SAndroid Build Coastguard Worker break;
407*d83cc019SAndroid Build Coastguard Worker
408*d83cc019SAndroid Build Coastguard Worker case POLICY_MEDIUM_POWER:
409*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(write(fd, MEDIUM_POWER_STR,
410*d83cc019SAndroid Build Coastguard Worker strlen(MEDIUM_POWER_STR)),
411*d83cc019SAndroid Build Coastguard Worker strlen(MEDIUM_POWER_STR));
412*d83cc019SAndroid Build Coastguard Worker break;
413*d83cc019SAndroid Build Coastguard Worker
414*d83cc019SAndroid Build Coastguard Worker case POLICY_MIN_POWER:
415*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(write(fd, MIN_POWER_STR,
416*d83cc019SAndroid Build Coastguard Worker strlen(MIN_POWER_STR)),
417*d83cc019SAndroid Build Coastguard Worker strlen(MIN_POWER_STR));
418*d83cc019SAndroid Build Coastguard Worker break;
419*d83cc019SAndroid Build Coastguard Worker }
420*d83cc019SAndroid Build Coastguard Worker
421*d83cc019SAndroid Build Coastguard Worker close(fd);
422*d83cc019SAndroid Build Coastguard Worker }
423*d83cc019SAndroid Build Coastguard Worker free(file_name);
424*d83cc019SAndroid Build Coastguard Worker }
425*d83cc019SAndroid Build Coastguard Worker #define POWER_DIR "/sys/devices/pci0000:00/0000:00:02.0/power"
426*d83cc019SAndroid Build Coastguard Worker /* We just leak this on exit ... */
427*d83cc019SAndroid Build Coastguard Worker int pm_status_fd = -1;
428*d83cc019SAndroid Build Coastguard Worker
429*d83cc019SAndroid Build Coastguard Worker static char __igt_pm_runtime_autosuspend[64];
430*d83cc019SAndroid Build Coastguard Worker static char __igt_pm_runtime_control[64];
431*d83cc019SAndroid Build Coastguard Worker
__igt_restore_runtime_pm(void)432*d83cc019SAndroid Build Coastguard Worker static int __igt_restore_runtime_pm(void)
433*d83cc019SAndroid Build Coastguard Worker {
434*d83cc019SAndroid Build Coastguard Worker int fd;
435*d83cc019SAndroid Build Coastguard Worker
436*d83cc019SAndroid Build Coastguard Worker if (pm_status_fd < 0)
437*d83cc019SAndroid Build Coastguard Worker return 0;
438*d83cc019SAndroid Build Coastguard Worker
439*d83cc019SAndroid Build Coastguard Worker fd = open(POWER_DIR "/autosuspend_delay_ms", O_WRONLY);
440*d83cc019SAndroid Build Coastguard Worker if (fd < 0)
441*d83cc019SAndroid Build Coastguard Worker return errno;
442*d83cc019SAndroid Build Coastguard Worker
443*d83cc019SAndroid Build Coastguard Worker if (write(fd, __igt_pm_runtime_autosuspend,
444*d83cc019SAndroid Build Coastguard Worker strlen(__igt_pm_runtime_autosuspend)) !=
445*d83cc019SAndroid Build Coastguard Worker strlen(__igt_pm_runtime_autosuspend)) {
446*d83cc019SAndroid Build Coastguard Worker close(fd);
447*d83cc019SAndroid Build Coastguard Worker return errno;
448*d83cc019SAndroid Build Coastguard Worker }
449*d83cc019SAndroid Build Coastguard Worker
450*d83cc019SAndroid Build Coastguard Worker close(fd);
451*d83cc019SAndroid Build Coastguard Worker
452*d83cc019SAndroid Build Coastguard Worker fd = open(POWER_DIR "/control", O_WRONLY);
453*d83cc019SAndroid Build Coastguard Worker if (fd < 0)
454*d83cc019SAndroid Build Coastguard Worker return errno;
455*d83cc019SAndroid Build Coastguard Worker
456*d83cc019SAndroid Build Coastguard Worker if (write(fd, __igt_pm_runtime_control,
457*d83cc019SAndroid Build Coastguard Worker strlen(__igt_pm_runtime_control)) !=
458*d83cc019SAndroid Build Coastguard Worker strlen(__igt_pm_runtime_control)) {
459*d83cc019SAndroid Build Coastguard Worker close(fd);
460*d83cc019SAndroid Build Coastguard Worker return errno;
461*d83cc019SAndroid Build Coastguard Worker }
462*d83cc019SAndroid Build Coastguard Worker
463*d83cc019SAndroid Build Coastguard Worker close(fd);
464*d83cc019SAndroid Build Coastguard Worker
465*d83cc019SAndroid Build Coastguard Worker close(pm_status_fd);
466*d83cc019SAndroid Build Coastguard Worker pm_status_fd = -1;
467*d83cc019SAndroid Build Coastguard Worker
468*d83cc019SAndroid Build Coastguard Worker return 0;
469*d83cc019SAndroid Build Coastguard Worker }
470*d83cc019SAndroid Build Coastguard Worker
471*d83cc019SAndroid Build Coastguard Worker /**
472*d83cc019SAndroid Build Coastguard Worker * igt_restore_runtime_pm:
473*d83cc019SAndroid Build Coastguard Worker *
474*d83cc019SAndroid Build Coastguard Worker * Restores the runtime PM configuration as it was before the call to
475*d83cc019SAndroid Build Coastguard Worker * igt_setup_runtime_pm.
476*d83cc019SAndroid Build Coastguard Worker */
igt_restore_runtime_pm(void)477*d83cc019SAndroid Build Coastguard Worker void igt_restore_runtime_pm(void)
478*d83cc019SAndroid Build Coastguard Worker {
479*d83cc019SAndroid Build Coastguard Worker int ret;
480*d83cc019SAndroid Build Coastguard Worker
481*d83cc019SAndroid Build Coastguard Worker if (pm_status_fd < 0)
482*d83cc019SAndroid Build Coastguard Worker return;
483*d83cc019SAndroid Build Coastguard Worker
484*d83cc019SAndroid Build Coastguard Worker igt_debug("Restoring runtime PM management to '%s' and '%s'\n",
485*d83cc019SAndroid Build Coastguard Worker __igt_pm_runtime_autosuspend,
486*d83cc019SAndroid Build Coastguard Worker __igt_pm_runtime_control);
487*d83cc019SAndroid Build Coastguard Worker
488*d83cc019SAndroid Build Coastguard Worker ret = __igt_restore_runtime_pm();
489*d83cc019SAndroid Build Coastguard Worker if (ret)
490*d83cc019SAndroid Build Coastguard Worker igt_warn("Failed to restore runtime PM! (errno=%d)\n", ret);
491*d83cc019SAndroid Build Coastguard Worker
492*d83cc019SAndroid Build Coastguard Worker igt_pm_audio_restore_runtime_pm();
493*d83cc019SAndroid Build Coastguard Worker }
494*d83cc019SAndroid Build Coastguard Worker
__igt_pm_runtime_exit_handler(int sig)495*d83cc019SAndroid Build Coastguard Worker static void __igt_pm_runtime_exit_handler(int sig)
496*d83cc019SAndroid Build Coastguard Worker {
497*d83cc019SAndroid Build Coastguard Worker __igt_restore_runtime_pm();
498*d83cc019SAndroid Build Coastguard Worker }
499*d83cc019SAndroid Build Coastguard Worker
500*d83cc019SAndroid Build Coastguard Worker /**
501*d83cc019SAndroid Build Coastguard Worker * igt_setup_runtime_pm:
502*d83cc019SAndroid Build Coastguard Worker *
503*d83cc019SAndroid Build Coastguard Worker * Sets up the runtime PM helper functions and enables runtime PM. To speed up
504*d83cc019SAndroid Build Coastguard Worker * tests the autosuspend delay is set to 0.
505*d83cc019SAndroid Build Coastguard Worker *
506*d83cc019SAndroid Build Coastguard Worker * Returns:
507*d83cc019SAndroid Build Coastguard Worker * True if runtime pm is available, false otherwise.
508*d83cc019SAndroid Build Coastguard Worker */
igt_setup_runtime_pm(void)509*d83cc019SAndroid Build Coastguard Worker bool igt_setup_runtime_pm(void)
510*d83cc019SAndroid Build Coastguard Worker {
511*d83cc019SAndroid Build Coastguard Worker int fd;
512*d83cc019SAndroid Build Coastguard Worker ssize_t size;
513*d83cc019SAndroid Build Coastguard Worker char buf[6];
514*d83cc019SAndroid Build Coastguard Worker
515*d83cc019SAndroid Build Coastguard Worker if (pm_status_fd >= 0)
516*d83cc019SAndroid Build Coastguard Worker return true;
517*d83cc019SAndroid Build Coastguard Worker
518*d83cc019SAndroid Build Coastguard Worker igt_pm_enable_audio_runtime_pm();
519*d83cc019SAndroid Build Coastguard Worker
520*d83cc019SAndroid Build Coastguard Worker /*
521*d83cc019SAndroid Build Coastguard Worker * Our implementation uses autosuspend. Try to set it to 0ms so the
522*d83cc019SAndroid Build Coastguard Worker * test suite goes faster and we have a higher probability of
523*d83cc019SAndroid Build Coastguard Worker * triggering race conditions.
524*d83cc019SAndroid Build Coastguard Worker */
525*d83cc019SAndroid Build Coastguard Worker fd = open(POWER_DIR "/autosuspend_delay_ms", O_RDWR);
526*d83cc019SAndroid Build Coastguard Worker if (fd < 0) {
527*d83cc019SAndroid Build Coastguard Worker igt_pm_audio_restore_runtime_pm();
528*d83cc019SAndroid Build Coastguard Worker return false;
529*d83cc019SAndroid Build Coastguard Worker }
530*d83cc019SAndroid Build Coastguard Worker
531*d83cc019SAndroid Build Coastguard Worker /*
532*d83cc019SAndroid Build Coastguard Worker * Save previous values to be able to install exit handler to restore
533*d83cc019SAndroid Build Coastguard Worker * them on test exit.
534*d83cc019SAndroid Build Coastguard Worker */
535*d83cc019SAndroid Build Coastguard Worker size = read(fd, __igt_pm_runtime_autosuspend,
536*d83cc019SAndroid Build Coastguard Worker sizeof(__igt_pm_runtime_autosuspend) - 1);
537*d83cc019SAndroid Build Coastguard Worker
538*d83cc019SAndroid Build Coastguard Worker /*
539*d83cc019SAndroid Build Coastguard Worker * If we fail to read from the file, it means this system doesn't
540*d83cc019SAndroid Build Coastguard Worker * support runtime PM.
541*d83cc019SAndroid Build Coastguard Worker */
542*d83cc019SAndroid Build Coastguard Worker if (size <= 0) {
543*d83cc019SAndroid Build Coastguard Worker close(fd);
544*d83cc019SAndroid Build Coastguard Worker igt_pm_audio_restore_runtime_pm();
545*d83cc019SAndroid Build Coastguard Worker return false;
546*d83cc019SAndroid Build Coastguard Worker }
547*d83cc019SAndroid Build Coastguard Worker
548*d83cc019SAndroid Build Coastguard Worker __igt_pm_runtime_autosuspend[size] = '\0';
549*d83cc019SAndroid Build Coastguard Worker
550*d83cc019SAndroid Build Coastguard Worker strchomp(__igt_pm_runtime_autosuspend);
551*d83cc019SAndroid Build Coastguard Worker igt_install_exit_handler(__igt_pm_runtime_exit_handler);
552*d83cc019SAndroid Build Coastguard Worker
553*d83cc019SAndroid Build Coastguard Worker size = write(fd, "0\n", 2);
554*d83cc019SAndroid Build Coastguard Worker
555*d83cc019SAndroid Build Coastguard Worker close(fd);
556*d83cc019SAndroid Build Coastguard Worker
557*d83cc019SAndroid Build Coastguard Worker if (size != 2)
558*d83cc019SAndroid Build Coastguard Worker return false;
559*d83cc019SAndroid Build Coastguard Worker
560*d83cc019SAndroid Build Coastguard Worker /* We know we support runtime PM, let's try to enable it now. */
561*d83cc019SAndroid Build Coastguard Worker fd = open(POWER_DIR "/control", O_RDWR);
562*d83cc019SAndroid Build Coastguard Worker igt_assert_f(fd >= 0, "Can't open " POWER_DIR "/control\n");
563*d83cc019SAndroid Build Coastguard Worker
564*d83cc019SAndroid Build Coastguard Worker igt_assert(read(fd, __igt_pm_runtime_control,
565*d83cc019SAndroid Build Coastguard Worker sizeof(__igt_pm_runtime_control) - 1) > 0);
566*d83cc019SAndroid Build Coastguard Worker strchomp(__igt_pm_runtime_control);
567*d83cc019SAndroid Build Coastguard Worker
568*d83cc019SAndroid Build Coastguard Worker igt_debug("Saved runtime power management as '%s' and '%s'\n",
569*d83cc019SAndroid Build Coastguard Worker __igt_pm_runtime_autosuspend, __igt_pm_runtime_control);
570*d83cc019SAndroid Build Coastguard Worker
571*d83cc019SAndroid Build Coastguard Worker size = write(fd, "auto\n", 5);
572*d83cc019SAndroid Build Coastguard Worker igt_assert(size == 5);
573*d83cc019SAndroid Build Coastguard Worker
574*d83cc019SAndroid Build Coastguard Worker lseek(fd, 0, SEEK_SET);
575*d83cc019SAndroid Build Coastguard Worker size = read(fd, buf, ARRAY_SIZE(buf));
576*d83cc019SAndroid Build Coastguard Worker igt_assert(size == 5);
577*d83cc019SAndroid Build Coastguard Worker igt_assert(strncmp(buf, "auto\n", 5) == 0);
578*d83cc019SAndroid Build Coastguard Worker
579*d83cc019SAndroid Build Coastguard Worker close(fd);
580*d83cc019SAndroid Build Coastguard Worker
581*d83cc019SAndroid Build Coastguard Worker pm_status_fd = open(POWER_DIR "/runtime_status", O_RDONLY);
582*d83cc019SAndroid Build Coastguard Worker igt_assert_f(pm_status_fd >= 0,
583*d83cc019SAndroid Build Coastguard Worker "Can't open " POWER_DIR "/runtime_status\n");
584*d83cc019SAndroid Build Coastguard Worker
585*d83cc019SAndroid Build Coastguard Worker return true;
586*d83cc019SAndroid Build Coastguard Worker }
587*d83cc019SAndroid Build Coastguard Worker
588*d83cc019SAndroid Build Coastguard Worker /**
589*d83cc019SAndroid Build Coastguard Worker * igt_get_runtime_pm_status:
590*d83cc019SAndroid Build Coastguard Worker *
591*d83cc019SAndroid Build Coastguard Worker * Returns: The current runtime PM status.
592*d83cc019SAndroid Build Coastguard Worker */
igt_get_runtime_pm_status(void)593*d83cc019SAndroid Build Coastguard Worker enum igt_runtime_pm_status igt_get_runtime_pm_status(void)
594*d83cc019SAndroid Build Coastguard Worker {
595*d83cc019SAndroid Build Coastguard Worker ssize_t n_read;
596*d83cc019SAndroid Build Coastguard Worker char buf[32];
597*d83cc019SAndroid Build Coastguard Worker
598*d83cc019SAndroid Build Coastguard Worker lseek(pm_status_fd, 0, SEEK_SET);
599*d83cc019SAndroid Build Coastguard Worker n_read = read(pm_status_fd, buf, ARRAY_SIZE(buf) - 1);
600*d83cc019SAndroid Build Coastguard Worker igt_assert(n_read >= 0);
601*d83cc019SAndroid Build Coastguard Worker buf[n_read] = '\0';
602*d83cc019SAndroid Build Coastguard Worker
603*d83cc019SAndroid Build Coastguard Worker if (strncmp(buf, "suspended\n", n_read) == 0)
604*d83cc019SAndroid Build Coastguard Worker return IGT_RUNTIME_PM_STATUS_SUSPENDED;
605*d83cc019SAndroid Build Coastguard Worker else if (strncmp(buf, "active\n", n_read) == 0)
606*d83cc019SAndroid Build Coastguard Worker return IGT_RUNTIME_PM_STATUS_ACTIVE;
607*d83cc019SAndroid Build Coastguard Worker else if (strncmp(buf, "suspending\n", n_read) == 0)
608*d83cc019SAndroid Build Coastguard Worker return IGT_RUNTIME_PM_STATUS_SUSPENDING;
609*d83cc019SAndroid Build Coastguard Worker else if (strncmp(buf, "resuming\n", n_read) == 0)
610*d83cc019SAndroid Build Coastguard Worker return IGT_RUNTIME_PM_STATUS_RESUMING;
611*d83cc019SAndroid Build Coastguard Worker
612*d83cc019SAndroid Build Coastguard Worker igt_assert_f(false, "Unknown status %s\n", buf);
613*d83cc019SAndroid Build Coastguard Worker return IGT_RUNTIME_PM_STATUS_UNKNOWN;
614*d83cc019SAndroid Build Coastguard Worker }
615*d83cc019SAndroid Build Coastguard Worker
616*d83cc019SAndroid Build Coastguard Worker /**
617*d83cc019SAndroid Build Coastguard Worker * igt_wait_for_pm_status:
618*d83cc019SAndroid Build Coastguard Worker * @status: desired runtime PM status
619*d83cc019SAndroid Build Coastguard Worker *
620*d83cc019SAndroid Build Coastguard Worker * Waits until for the driver to switch to into the desired runtime PM status,
621*d83cc019SAndroid Build Coastguard Worker * with a 10 second timeout.
622*d83cc019SAndroid Build Coastguard Worker *
623*d83cc019SAndroid Build Coastguard Worker * Returns:
624*d83cc019SAndroid Build Coastguard Worker * True if the desired runtime PM status was attained, false if the operation
625*d83cc019SAndroid Build Coastguard Worker * timed out.
626*d83cc019SAndroid Build Coastguard Worker */
igt_wait_for_pm_status(enum igt_runtime_pm_status status)627*d83cc019SAndroid Build Coastguard Worker bool igt_wait_for_pm_status(enum igt_runtime_pm_status status)
628*d83cc019SAndroid Build Coastguard Worker {
629*d83cc019SAndroid Build Coastguard Worker return igt_wait(igt_get_runtime_pm_status() == status, 10000, 100);
630*d83cc019SAndroid Build Coastguard Worker }
631