@@ -33,6 +33,7 @@
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <dirent.h>
#include "drmtest.h"
#include "igt_pm.h"
@@ -64,6 +65,7 @@ enum {
#define MAX_POLICY_STRLEN strlen(MAX_PERFORMANCE_STR)
static char __igt_pm_audio_runtime_power_save[64];
+static const char * __igt_pm_audio_runtime_control_path;
static char __igt_pm_audio_runtime_control[64];
static int __igt_pm_audio_restore_runtime_pm(void)
@@ -86,7 +88,7 @@ static int __igt_pm_audio_restore_runtime_pm(void)
close(fd);
- fd = open("/sys/bus/pci/devices/0000:00:03.0/power/control", O_WRONLY);
+ fd = open(__igt_pm_audio_runtime_control_path, O_WRONLY);
if (fd < 0)
return errno;
@@ -130,36 +132,77 @@ static void strchomp(char *str)
*/
void igt_pm_enable_audio_runtime_pm(void)
{
+ char *path = NULL;
+ struct dirent *de;
+ DIR *dir;
int fd;
/* Check if already enabled. */
if (__igt_pm_audio_runtime_power_save[0])
return;
- fd = open("/sys/module/snd_hda_intel/parameters/power_save", O_RDWR);
- if (fd >= 0) {
- igt_assert(read(fd, __igt_pm_audio_runtime_power_save,
- sizeof(__igt_pm_audio_runtime_power_save)) > 0);
- strchomp(__igt_pm_audio_runtime_power_save);
- igt_install_exit_handler(__igt_pm_audio_runtime_exit_handler);
- igt_assert_eq(write(fd, "1\n", 2), 2);
- close(fd);
- }
- fd = open("/sys/bus/pci/devices/0000:00:03.0/power/control", O_RDWR);
- if (fd >= 0) {
- igt_assert(read(fd, __igt_pm_audio_runtime_control,
- sizeof(__igt_pm_audio_runtime_control)) > 0);
- strchomp(__igt_pm_audio_runtime_control);
- igt_assert_eq(write(fd, "auto\n", 5), 5);
- close(fd);
+ dir = opendir("/sys/bus/pci/drivers/snd_hda_intel");
+ if (!dir)
+ return;
+
+ while ((de = readdir(dir))) {
+ const char *prefix = "/sys/bus/pci/devices/";
+ const char *suffix = "/power/control";
+ const char *match = "0000:00:";
+
+ if (strncmp(de->d_name, match, strlen(match)))
+ continue;
+
+ path = malloc(strlen(prefix) +
+ strlen(de->d_name) +
+ strlen(suffix) +
+ 1);
+ if (!path)
+ goto err;
+
+ strcpy(path, prefix);
+ strcat(path, de->d_name);
+ strcat(path, suffix);
+
+ igt_debug("Audio device PCI path is %s\n", path);
}
+ if (!path)
+ goto err;
+
+ fd = open("/sys/module/snd_hda_intel/parameters/power_save", O_RDWR);
+ if (fd < 0)
+ goto err;
+
+ igt_assert(read(fd, __igt_pm_audio_runtime_power_save,
+ sizeof(__igt_pm_audio_runtime_power_save)) > 0);
+ strchomp(__igt_pm_audio_runtime_power_save);
+ igt_install_exit_handler(__igt_pm_audio_runtime_exit_handler);
+ igt_assert_eq(write(fd, "1\n", 2), 2);
+ close(fd);
+
+ fd = open(path, O_RDWR);
+ if (fd < 0)
+ goto err;
+
+ igt_assert(read(fd, __igt_pm_audio_runtime_control,
+ sizeof(__igt_pm_audio_runtime_control)) > 0);
+ strchomp(__igt_pm_audio_runtime_control);
+ igt_assert_eq(write(fd, "auto\n", 5), 5);
+ close(fd);
+ __igt_pm_audio_runtime_control_path = path;
+
igt_debug("Saved audio power management as '%s' and '%s'\n",
__igt_pm_audio_runtime_power_save,
__igt_pm_audio_runtime_control);
/* Give some time for it to react. */
sleep(1);
+
+ return;
+
+err:
+ igt_warn("Failed to enable audio runtime PM! (%d)", errno);
}
/**