Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package power-profiles-daemon for 
openSUSE:Factory checked in at 2023-04-28 16:22:25
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/power-profiles-daemon (Old)
 and      /work/SRC/openSUSE:Factory/.power-profiles-daemon.new.1533 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "power-profiles-daemon"

Fri Apr 28 16:22:25 2023 rev:7 rq:1083162 version:0.13

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/power-profiles-daemon/power-profiles-daemon.changes  
    2022-07-08 14:01:32.530422942 +0200
+++ 
/work/SRC/openSUSE:Factory/.power-profiles-daemon.new.1533/power-profiles-daemon.changes
    2023-04-28 16:22:36.261742676 +0200
@@ -1,0 +2,9 @@
+Wed Apr 26 15:19:01 UTC 2023 - Enrico Belleri <ide...@protonmail.com>
+
+- Update to version 0.13:
+  * Add support for the AMD P-State driver included in Linux 6.3
+  * Fix mismatched profiles on some HP laptops and some
+    miscellaneous bug fixes.
+
+
+-------------------------------------------------------------------

Old:
----
  power-profiles-daemon-0.12.tar.bz2

New:
----
  power-profiles-daemon-0.13.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ power-profiles-daemon.spec ++++++
--- /var/tmp/diff_new_pack.wzVs3f/_old  2023-04-28 16:22:37.461749680 +0200
+++ /var/tmp/diff_new_pack.wzVs3f/_new  2023-04-28 16:22:37.465749704 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package power-profiles-daemon
 #
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           power-profiles-daemon
-Version:        0.12
+Version:        0.13
 Release:        0
 Summary:        Power profiles handling over D-Bus
 License:        GPL-3.0-or-later
@@ -28,16 +28,16 @@
 
 BuildRequires:  c_compiler
 BuildRequires:  gtk-doc
-BuildRequires:  meson
+BuildRequires:  meson >= 0.54.0
 BuildRequires:  pkgconfig
 BuildRequires:  python3-dbusmock
 BuildRequires:  pkgconfig(gio-2.0)
-BuildRequires:  pkgconfig(gudev-1.0)
+BuildRequires:  pkgconfig(gudev-1.0) >= 234
 BuildRequires:  pkgconfig(polkit-gobject-1) >= 0.114
 BuildRequires:  pkgconfig(systemd)
+BuildRequires:  pkgconfig(upower-glib)
 BuildRequires:  pkgconfig(udev)
 BuildRequires:  pkgconfig(umockdev-1.0)
-BuildRequires:  pkgconfig(upower-glib)
 Requires:       polkit
 
 %description
@@ -59,6 +59,7 @@
 %meson \
        -Dsystemdsystemunitdir=%{_unitdir} \
        -Dgtk_doc=true \
+       -Dtests=true \
        %{nil}
 %meson_build
 

++++++ power-profiles-daemon-0.12.tar.bz2 -> power-profiles-daemon-0.13.tar.bz2 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/power-profiles-daemon-0.12/.gitlab-ci.yml 
new/power-profiles-daemon-0.13/.gitlab-ci.yml
--- old/power-profiles-daemon-0.12/.gitlab-ci.yml       2022-06-28 
15:58:14.000000000 +0200
+++ new/power-profiles-daemon-0.13/.gitlab-ci.yml       2023-04-26 
14:53:07.000000000 +0200
@@ -18,6 +18,11 @@
                 umockdev
                 e2fsprogs
 
+workflow:
+  rules:
+    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
+    - if: $CI_PIPELINE_SOURCE == 'push'
+
 build_stable:
   before_script:
     - dnf upgrade -y --nogpgcheck fedora-release fedora-repos*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/power-profiles-daemon-0.12/NEWS 
new/power-profiles-daemon-0.13/NEWS
--- old/power-profiles-daemon-0.12/NEWS 2022-06-28 15:58:14.000000000 +0200
+++ new/power-profiles-daemon-0.13/NEWS 2023-04-26 14:53:07.000000000 +0200
@@ -1,3 +1,10 @@
+0.13
+----
+
+This release adds support for the AMD P-State driver that's been added to the
+6.3 Linux kernel. This release also fixes mismatched profiles on some HP
+laptops and some miscellaneous bug fixes.
+
 0.12
 ----
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/power-profiles-daemon-0.12/README.md 
new/power-profiles-daemon-0.13/README.md
--- old/power-profiles-daemon-0.12/README.md    2022-06-28 15:58:14.000000000 
+0200
+++ new/power-profiles-daemon-0.13/README.md    2023-04-26 14:53:07.000000000 
+0200
@@ -134,6 +134,35 @@
 For more information, please refer to the [Intel P-State scaling driver 
documentation](https://www.kernel.org/doc/html/v5.17/admin-guide/pm/intel_pstate.html)
 and the [Intel Performance and Energy Bias 
Hint](https://www.kernel.org/doc/html/v5.17/admin-guide/pm/intel_epb.html).
 
+Operations on AMD-based machines
+----------------------------------
+
+The "driver" for making the hardware act on the user-selected power profile on 
AMD CPU-based
+machines is based on the [AMD P-State scaling 
driver](https://www.kernel.org/doc/html/v6.3/admin-guide/pm/amd-pstate.html)
+if available.
+
+It is only used if a `platform_profile` driver isn't available for the system, 
the
+CPU supports Collaborative Processor Performance Control (CPPC), and the AMD 
P-State
+scaling driver is in `active` mode.
+
+Example of a system without `platform_profile` support but with `active` 
P-State
+operation mode:
+```
+$ cat /sys/firmware/acpi/platform_profile_choices
+cat: /sys/firmware/acpi/platform_profile_choices: No such file or directory
+$ cat /sys/devices/system/cpu/amd_pstate/status
+active
+```
+
+If the AMD P-State scaling driver is not loaded or is not in `active` mode, 
then
+the placeholder driver will be used, and there won't be a performance mode.
+
+Finally, if the AMD P-State scaling driver is used in `active` mode, the 
P-State
+scaling governor will be changed to `powersave` as it is the only P-State 
scaling
+governor that allows for the "Energy vs Performance Hints" to be taken into 
consideration.
+
+For more information, please refer to the [AMD P-State scaling driver 
documentation](https://www.kernel.org/doc/html/v6.3/admin-guide/pm/amd-pstate.html).
+
 Testing
 -------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/power-profiles-daemon-0.12/docs/meson.build 
new/power-profiles-daemon-0.13/docs/meson.build
--- old/power-profiles-daemon-0.12/docs/meson.build     2022-06-28 
15:58:14.000000000 +0200
+++ new/power-profiles-daemon-0.13/docs/meson.build     2023-04-26 
14:53:07.000000000 +0200
@@ -24,6 +24,7 @@
   'ppd-driver-balanced.h',
   'ppd-driver-fake.h',
   'ppd-driver-intel-pstate.h',
+  'ppd-driver-amd-pstate.h',
   'ppd-driver-placeholder.h',
   'ppd-driver-platform-profile.h',
   'ppd-driver-power-saver.h',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/power-profiles-daemon-0.12/meson.build 
new/power-profiles-daemon-0.13/meson.build
--- old/power-profiles-daemon-0.12/meson.build  2022-06-28 15:58:14.000000000 
+0200
+++ new/power-profiles-daemon-0.13/meson.build  2023-04-26 14:53:07.000000000 
+0200
@@ -1,5 +1,5 @@
 project('power-profiles-daemon', [ 'c' ],
-        version: '0.12',
+        version: '0.13',
         license: 'GPLv3+',
         default_options: [
           'buildtype=debugoptimized',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/power-profiles-daemon-0.12/src/meson.build 
new/power-profiles-daemon-0.13/src/meson.build
--- old/power-profiles-daemon-0.12/src/meson.build      2022-06-28 
15:58:14.000000000 +0200
+++ new/power-profiles-daemon-0.13/src/meson.build      2023-04-26 
14:53:07.000000000 +0200
@@ -46,6 +46,7 @@
   'power-profiles-daemon.c',
   'ppd-action-trickle-charge.c',
   'ppd-driver-intel-pstate.c',
+  'ppd-driver-amd-pstate.c',
   'ppd-driver-platform-profile.c',
   'ppd-driver-placeholder.c',
   'ppd-driver-fake.c',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/power-profiles-daemon-0.12/src/power-profiles-daemon.c 
new/power-profiles-daemon-0.13/src/power-profiles-daemon.c
--- old/power-profiles-daemon-0.12/src/power-profiles-daemon.c  2022-06-28 
15:58:14.000000000 +0200
+++ new/power-profiles-daemon-0.13/src/power-profiles-daemon.c  2023-04-26 
14:53:07.000000000 +0200
@@ -75,6 +75,7 @@
 #include "ppd-driver-placeholder.h"
 #include "ppd-driver-platform-profile.h"
 #include "ppd-driver-intel-pstate.h"
+#include "ppd-driver-amd-pstate.h"
 #include "ppd-driver-fake.h"
 
 typedef GType (*GTypeGetFunc) (void);
@@ -84,6 +85,7 @@
   ppd_driver_fake_get_type,
   ppd_driver_platform_profile_get_type,
   ppd_driver_intel_pstate_get_type,
+  ppd_driver_amd_pstate_get_type,
 
   /* Generic profile driver */
   ppd_driver_placeholder_get_type,
@@ -103,6 +105,16 @@
 
 #define PROP_ALL (PROP_ACTIVE_PROFILE | PROP_INHIBITED | PROP_PROFILES | 
PROP_ACTIONS | PROP_DEGRADED | PROP_ACTIVE_PROFILE_HOLDS)
 
+static gboolean
+get_profile_available (PpdApp     *data,
+                       PpdProfile  profile)
+{
+    PpdDriver *driver;
+
+    driver = GET_DRIVER(profile);
+    return driver != NULL;
+}
+
 static const char *
 get_active_profile (PpdApp *data)
 {
@@ -386,6 +398,11 @@
                  "Invalid profile name '%s'", profile);
     return FALSE;
   }
+  if (!get_profile_available (data, target_profile)) {
+    g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
+                 "Cannot switch to unavailable profile '%s'", profile);
+    return FALSE;
+  }
 
   if (target_profile == data->active_profile)
     return TRUE;
@@ -554,8 +571,14 @@
   profile = ppd_profile_from_str (profile_name);
   if (profile != PPD_PROFILE_PERFORMANCE &&
       profile != PPD_PROFILE_POWER_SAVER) {
+    g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, 
G_DBUS_ERROR_INVALID_ARGS,
+                                                   "Only profiles 
'performance' and 'power-saver' can be a hold profile");
+    return;
+  }
+  if (!get_profile_available (data, profile)) {
     g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, 
G_DBUS_ERROR_INVALID_ARGS,
-                                           "Only profiles 'performance' and 
'power-saver' can be a hold profile");
+                                           "Cannot hold profile '%s' as it is 
not available",
+                                           profile_name);
     return;
   }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/power-profiles-daemon-0.12/src/powerprofilesctl.in 
new/power-profiles-daemon-0.13/src/powerprofilesctl.in
--- old/power-profiles-daemon-0.12/src/powerprofilesctl.in      2022-06-28 
15:58:14.000000000 +0200
+++ new/power-profiles-daemon-0.13/src/powerprofilesctl.in      2023-04-26 
14:53:07.000000000 +0200
@@ -127,44 +127,43 @@
         profiles = proxy.Get('(ss)', 'net.hadess.PowerProfiles', prop)
     except:
         raise
-    else:
-        return profiles
+    return profiles
 
 def _list():
     try:
         profiles = get_profiles_property('Profiles')
         reason = get_proxy().Get('(ss)', 'net.hadess.PowerProfiles', 
'PerformanceDegraded')
-        degraded = (reason != '')
+        degraded = reason != ''
         active = get_proxy().Get('(ss)', 'net.hadess.PowerProfiles', 
'ActiveProfile')
     except:
         raise
-    else:
-        index = 0
-        for profile in reversed(profiles):
-            if index > 0:
-                print('')
-            marker = '*' if profile['Profile'] == active else ' '
-            print(f'{marker} {profile["Profile"]}:')
-            print('    Driver:    ', profile['Driver'])
-            if profile['Profile'] == 'performance':
-                print('    Degraded:  ', f'yes ({reason})' if degraded else 
'no')
-            index += 1
+
+    index = 0
+    for profile in reversed(profiles):
+        if index > 0:
+            print('')
+        marker = '*' if profile['Profile'] == active else ' '
+        print(f'{marker} {profile["Profile"]}:')
+        print('    Driver:    ', profile['Driver'])
+        if profile['Profile'] == 'performance':
+            print('    Degraded:  ', f'yes ({reason})' if degraded else 'no')
+        index += 1
 
 def _list_holds():
     try:
         holds = get_profiles_property('ActiveProfileHolds')
     except:
         raise
-    else:
-        index = 0
-        for hold in holds:
-            if index > 0:
-                print('')
-            print('Hold:')
-            print('  Profile:        ', hold['Profile'])
-            print('  Application ID: ', hold['ApplicationId'])
-            print('  Reason:         ', hold['Reason'])
-            index += 1
+
+    index = 0
+    for hold in holds:
+        if index > 0:
+            print('')
+        print('Hold:')
+        print('  Profile:        ', hold['Profile'])
+        print('  Application ID: ', hold['ApplicationId'])
+        print('  Reason:         ', hold['Reason'])
+        index += 1
 
 def _launch(args, profile, appid, reason):
     try:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/power-profiles-daemon-0.12/src/ppd-driver-amd-pstate.c 
new/power-profiles-daemon-0.13/src/ppd-driver-amd-pstate.c
--- old/power-profiles-daemon-0.12/src/ppd-driver-amd-pstate.c  1970-01-01 
01:00:00.000000000 +0100
+++ new/power-profiles-daemon-0.13/src/ppd-driver-amd-pstate.c  2023-04-26 
14:53:07.000000000 +0200
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2020 Bastien Nocera <had...@hadess.net>
+ * Copyright (c) 2022 Prajna Sariputra <putr...@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published by
+ * the Free Software Foundation.
+ *
+ */
+
+#include <upower.h>
+
+#include "ppd-utils.h"
+#include "ppd-driver-amd-pstate.h"
+
+#define CPUFREQ_POLICY_DIR "/sys/devices/system/cpu/cpufreq/"
+#define DEFAULT_CPU_FREQ_SCALING_GOV "powersave"
+#define PSTATE_STATUS_PATH "/sys/devices/system/cpu/amd_pstate/status"
+
+struct _PpdDriverAmdPstate
+{
+  PpdDriver  parent_instance;
+
+  PpdProfile activated_profile;
+  GList *epp_devices; /* GList of paths */
+};
+
+G_DEFINE_TYPE (PpdDriverAmdPstate, ppd_driver_amd_pstate, PPD_TYPE_DRIVER)
+
+static gboolean ppd_driver_amd_pstate_activate_profile (PpdDriver              
     *driver,
+                                                        PpdProfile             
      profile,
+                                                        
PpdProfileActivationReason   reason,
+                                                        GError                 
    **error);
+
+static GObject*
+ppd_driver_amd_pstate_constructor (GType                  type,
+                                   guint                  n_construct_params,
+                                   GObjectConstructParam *construct_params)
+{
+  GObject *object;
+
+  object = G_OBJECT_CLASS (ppd_driver_amd_pstate_parent_class)->constructor 
(type,
+                                                                             
n_construct_params,
+                                                                             
construct_params);
+  g_object_set (object,
+                "driver-name", "amd_pstate",
+                "profiles", PPD_PROFILE_PERFORMANCE | PPD_PROFILE_BALANCED | 
PPD_PROFILE_POWER_SAVER,
+                NULL);
+
+  return object;
+}
+
+static PpdProbeResult
+probe_epp (PpdDriverAmdPstate *pstate)
+{
+  g_autoptr(GDir) dir = NULL;
+  g_autofree char *policy_dir = NULL;
+  g_autofree char *pstate_status_path = NULL;
+  g_autofree char *status = NULL;
+  const char *dirname;
+  PpdProbeResult ret = PPD_PROBE_RESULT_FAIL;
+
+  /* Verify that AMD P-State is running in active mode */
+  pstate_status_path = ppd_utils_get_sysfs_path (PSTATE_STATUS_PATH);
+  if (!g_file_get_contents (pstate_status_path, &status, NULL, NULL))
+    return ret;
+  status = g_strchomp (status);
+  if (g_strcmp0 (status, "active") != 0) {
+    g_debug ("AMD P-State is not running in active mode");
+    return ret;
+  }
+
+  policy_dir = ppd_utils_get_sysfs_path (CPUFREQ_POLICY_DIR);
+  dir = g_dir_open (policy_dir, 0, NULL);
+  if (!dir) {
+    g_debug ("Could not open %s", policy_dir);
+    return ret;
+  }
+
+  while ((dirname = g_dir_read_name (dir)) != NULL) {
+    g_autofree char *path = NULL;
+    g_autofree char *gov_path = NULL;
+    g_autoptr(GError) error = NULL;
+
+    path = g_build_filename (policy_dir,
+                             dirname,
+                             "energy_performance_preference",
+                             NULL);
+    if (!g_file_test (path, G_FILE_TEST_EXISTS))
+      continue;
+
+    /* Force a scaling_governor where the preference can be written */
+    gov_path = g_build_filename (policy_dir,
+                                 dirname,
+                                 "scaling_governor",
+                                 NULL);
+    if (!ppd_utils_write (gov_path, DEFAULT_CPU_FREQ_SCALING_GOV, &error)) {
+      g_warning ("Could not change scaling governor %s to '%s'", dirname, 
DEFAULT_CPU_FREQ_SCALING_GOV);
+      continue;
+    }
+
+    pstate->epp_devices = g_list_prepend (pstate->epp_devices, g_steal_pointer 
(&path));
+    ret = PPD_PROBE_RESULT_SUCCESS;
+  }
+
+  return ret;
+}
+
+static PpdProbeResult
+ppd_driver_amd_pstate_probe (PpdDriver  *driver)
+{
+  PpdDriverAmdPstate *pstate = PPD_DRIVER_AMD_PSTATE (driver);
+  PpdProbeResult ret = PPD_PROBE_RESULT_FAIL;
+
+  ret = probe_epp (pstate);
+
+  if (ret != PPD_PROBE_RESULT_SUCCESS)
+    goto out;
+
+out:
+  g_debug ("%s p-state settings",
+           ret == PPD_PROBE_RESULT_SUCCESS ? "Found" : "Didn't find");
+  return ret;
+}
+
+static const char *
+profile_to_epp_pref (PpdProfile profile)
+{
+  /* Note that we don't check "energy_performance_available_preferences"
+   * as all the values are always available */
+  switch (profile) {
+  case PPD_PROFILE_POWER_SAVER:
+    return "power";
+  case PPD_PROFILE_BALANCED:
+    return "balance_performance";
+  case PPD_PROFILE_PERFORMANCE:
+    return "performance";
+  }
+
+  g_assert_not_reached ();
+}
+
+static gboolean
+apply_pref_to_devices (GList       *devices,
+                       const char  *pref,
+                       GError     **error)
+{
+  gboolean ret = TRUE;
+  GList *l;
+
+  for (l = devices; l != NULL; l = l->next) {
+    const char *path = l->data;
+
+    ret = ppd_utils_write (path, pref, error);
+    if (!ret)
+      break;
+  }
+
+  return ret;
+}
+
+static gboolean
+ppd_driver_amd_pstate_activate_profile (PpdDriver                    *driver,
+                                          PpdProfile                   profile,
+                                          PpdProfileActivationReason   reason,
+                                          GError                     **error)
+{
+  PpdDriverAmdPstate *pstate = PPD_DRIVER_AMD_PSTATE (driver);
+  gboolean ret = FALSE;
+  const char *pref;
+
+  g_return_val_if_fail (pstate->epp_devices != NULL, FALSE);
+
+  if (pstate->epp_devices) {
+    pref = profile_to_epp_pref (profile);
+    ret = apply_pref_to_devices (pstate->epp_devices, pref, error);
+    if (!ret)
+      return ret;
+  }
+
+  if (ret)
+    pstate->activated_profile = profile;
+
+  return ret;
+}
+
+static void
+ppd_driver_amd_pstate_finalize (GObject *object)
+{
+  PpdDriverAmdPstate *driver;
+
+  driver = PPD_DRIVER_AMD_PSTATE (object);
+  g_clear_list (&driver->epp_devices, g_free);
+  G_OBJECT_CLASS (ppd_driver_amd_pstate_parent_class)->finalize (object);
+}
+
+static void
+ppd_driver_amd_pstate_class_init (PpdDriverAmdPstateClass *klass)
+{
+  GObjectClass *object_class;
+  PpdDriverClass *driver_class;
+
+  object_class = G_OBJECT_CLASS(klass);
+  object_class->constructor = ppd_driver_amd_pstate_constructor;
+  object_class->finalize = ppd_driver_amd_pstate_finalize;
+
+  driver_class = PPD_DRIVER_CLASS(klass);
+  driver_class->probe = ppd_driver_amd_pstate_probe;
+  driver_class->activate_profile = ppd_driver_amd_pstate_activate_profile;
+}
+
+static void
+ppd_driver_amd_pstate_init (PpdDriverAmdPstate *self)
+{
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/power-profiles-daemon-0.12/src/ppd-driver-amd-pstate.h 
new/power-profiles-daemon-0.13/src/ppd-driver-amd-pstate.h
--- old/power-profiles-daemon-0.12/src/ppd-driver-amd-pstate.h  1970-01-01 
01:00:00.000000000 +0100
+++ new/power-profiles-daemon-0.13/src/ppd-driver-amd-pstate.h  2023-04-26 
14:53:07.000000000 +0200
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2020 Bastien Nocera <had...@hadess.net>
+ * Copyright (c) 2022 Prajna Sariputra <putr...@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published by
+ * the Free Software Foundation.
+ *
+ */
+
+#pragma once
+
+#include "ppd-driver.h"
+
+#define PPD_TYPE_DRIVER_AMD_PSTATE (ppd_driver_amd_pstate_get_type())
+G_DECLARE_FINAL_TYPE(PpdDriverAmdPstate, ppd_driver_amd_pstate, PPD, 
DRIVER_AMD_PSTATE, PpdDriver)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/power-profiles-daemon-0.12/src/ppd-driver-intel-pstate.c 
new/power-profiles-daemon-0.13/src/ppd-driver-intel-pstate.c
--- old/power-profiles-daemon-0.12/src/ppd-driver-intel-pstate.c        
2022-06-28 15:58:14.000000000 +0200
+++ new/power-profiles-daemon-0.13/src/ppd-driver-intel-pstate.c        
2023-04-26 14:53:07.000000000 +0200
@@ -171,7 +171,6 @@
 
   while ((dirname = g_dir_read_name (dir)) != NULL) {
     g_autofree char *path = NULL;
-    g_autofree char *gov_path = NULL;
 
     path = g_build_filename (policy_dir,
                              dirname,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/power-profiles-daemon-0.12/src/ppd-driver-platform-profile.c 
new/power-profiles-daemon-0.13/src/ppd-driver-platform-profile.c
--- old/power-profiles-daemon-0.12/src/ppd-driver-platform-profile.c    
2022-06-28 15:58:14.000000000 +0200
+++ new/power-profiles-daemon-0.13/src/ppd-driver-platform-profile.c    
2023-04-26 14:53:07.000000000 +0200
@@ -26,6 +26,7 @@
   int lapmode;
   PpdProfile acpi_platform_profile;
   char **profile_choices;
+  gboolean has_low_power;
   GFileMonitor *lapmode_mon;
   GFileMonitor *acpi_platform_profile_mon;
   guint acpi_platform_profile_changed_id;
@@ -57,10 +58,10 @@
 {
   switch (profile) {
   case PPD_PROFILE_POWER_SAVER:
+    if (!self->has_low_power)
+      return "balanced";
     if (g_strv_contains ((const char * const*) self->profile_choices, 
"low-power"))
       return "low-power";
-    if (g_strv_contains ((const char * const*) self->profile_choices, "cool"))
-      return "cool";
     return "quiet";
   case PPD_PROFILE_BALANCED:
     return "balanced";
@@ -79,9 +80,9 @@
 
   switch (str[0]) {
   case 'l': /* low-power */
-  case 'c': /* cool */
   case 'q': /* quiet */
     return PPD_PROFILE_POWER_SAVER;
+  case 'c': /* cool */
   case 'b':
     return PPD_PROFILE_BALANCED;
   case 'p':
@@ -142,12 +143,15 @@
 {
   const char * const *choices = (const char * const*) self->profile_choices;
 
-  if ((g_strv_contains (choices, "low-power") ||
-       g_strv_contains (choices, "cool") ||
-       g_strv_contains (choices, "quiet")) &&
-      g_strv_contains (choices, "balanced") &&
-      g_strv_contains (choices, "performance"))
+  if (g_strv_contains (choices, "balanced") &&
+      g_strv_contains (choices, "performance")) {
+    if (g_strv_contains (choices, "low-power") ||
+        g_strv_contains (choices, "quiet"))
+      self->has_low_power = TRUE;
+    else
+      g_debug ("No \"low-power\" profile for device, will be emulated");
     return PPD_PROBE_RESULT_SUCCESS;
+  }
   return PPD_PROBE_RESULT_DEFER;
 }
 
@@ -203,7 +207,7 @@
                                gpointer           user_data)
 {
   PpdDriverPlatformProfile *self = user_data;
-  g_debug (ACPI_PLATFORM_PROFILE_PATH " changed");
+  g_debug (ACPI_PLATFORM_PROFILE_PATH " changed (%d)", event_type);
   if (self->probe_result == PPD_PROBE_RESULT_DEFER) {
     g_signal_emit_by_name (G_OBJECT (self), "probe-request", 0);
     return;
@@ -219,6 +223,7 @@
 {
   PpdDriverPlatformProfile *self = PPD_DRIVER_PLATFORM_PROFILE (driver);
   g_autofree char *platform_profile_path = NULL;
+  const char *platform_profile_value;
 
   g_return_val_if_fail (self->acpi_platform_profile_mon, FALSE);
 
@@ -227,6 +232,14 @@
              ppd_profile_to_str (profile));
     return TRUE;
   }
+
+  platform_profile_value = profile_to_acpi_platform_profile_value (self, 
profile);
+  if (self->acpi_platform_profile == acpi_platform_profile_value_to_profile 
(platform_profile_value)) {
+    g_debug ("Not switching to platform_profile %s, emulating for %s, already 
there",
+             platform_profile_value,
+             ppd_profile_to_str (profile));
+    return TRUE;
+  }
 
   g_signal_handler_block (G_OBJECT (self->acpi_platform_profile_mon), 
self->acpi_platform_profile_changed_id);
   platform_profile_path = ppd_utils_get_sysfs_path 
(ACPI_PLATFORM_PROFILE_PATH);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/power-profiles-daemon-0.12/src/ppd-utils.c 
new/power-profiles-daemon-0.13/src/ppd-utils.c
--- old/power-profiles-daemon-0.12/src/ppd-utils.c      2022-06-28 
15:58:14.000000000 +0200
+++ new/power-profiles-daemon-0.13/src/ppd-utils.c      2023-04-26 
14:53:07.000000000 +0200
@@ -85,6 +85,7 @@
 
   path = g_build_filename (g_udev_device_get_sysfs_path (device), attribute, 
NULL);
   file = g_file_new_for_path (path);
+  g_debug ("Monitoring file %s for changes", path);
   return g_file_monitor_file (file,
                               G_FILE_MONITOR_NONE,
                               NULL,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/power-profiles-daemon-0.12/tests/integration-test.py 
new/power-profiles-daemon-0.13/tests/integration-test.py
--- old/power-profiles-daemon-0.12/tests/integration-test.py    2022-06-28 
15:58:14.000000000 +0200
+++ new/power-profiles-daemon-0.13/tests/integration-test.py    2023-04-26 
14:53:07.000000000 +0200
@@ -320,6 +320,13 @@
       self.set_dbus_property('ActiveProfile', 
GLib.Variant.new_string('power-saver'))
       self.assertEqual(self.get_dbus_property('ActiveProfile'), 'power-saver')
 
+      with self.assertRaises(gi.repository.GLib.GError):
+        self.set_dbus_property('ActiveProfile', 
GLib.Variant.new_string('performance'))
+      self.assertEqual(self.get_dbus_property('ActiveProfile'), 'power-saver')
+
+      with self.assertRaises(gi.repository.GLib.GError):
+        cookie = self.call_dbus_method('HoldProfile', GLib.Variant("(sss)", 
('performance', 'testReason', 'testApplication')))
+
       # process = subprocess.Popen(['gdbus', 'introspect', '--system', 
'--dest', 'net.hadess.PowerProfiles', '--object-path', 
'/net/hadess/PowerProfiles'])
       # print (self.get_dbus_property('GPUs'))
 
@@ -598,6 +605,183 @@
 
       self.stop_daemon()
 
+    def test_amd_pstate(self):
+      '''AMD P-State driver (no UPower)'''
+
+      # Create 2 CPUs with preferences
+      dir1 = os.path.join(self.testbed.get_root_dir(), 
"sys/devices/system/cpu/cpufreq/policy0/")
+      os.makedirs(dir1)
+      with open(os.path.join(dir1, 'scaling_governor'), 'w') as gov:
+        gov.write('powersave\n')
+      with open(os.path.join(dir1, "energy_performance_preference"),'w') as 
prefs:
+        prefs.write("performance\n")
+      dir2 = os.path.join(self.testbed.get_root_dir(), 
"sys/devices/system/cpu/cpufreq/policy1/")
+      os.makedirs(dir2)
+      with open(os.path.join(dir2, 'scaling_governor'), 'w') as gov:
+        gov.write('powersave\n')
+      with open(os.path.join(dir2, "energy_performance_preference"),'w') as 
prefs:
+        prefs.write("performance\n")
+
+      # Create AMD P-State configuration
+      pstate_dir = os.path.join(self.testbed.get_root_dir(), 
"sys/devices/system/cpu/amd_pstate")
+      os.makedirs(pstate_dir)
+      with open(os.path.join(pstate_dir, "status"),'w') as status:
+        status.write("active\n")
+
+      self.start_daemon()
+
+      profiles = self.get_dbus_property('Profiles')
+      self.assertEqual(len(profiles), 3)
+      self.assertEqual(profiles[0]['Driver'], 'amd_pstate')
+      self.assertEqual(profiles[0]['Profile'], 'power-saver')
+
+      contents = None
+      with open(os.path.join(dir2, "energy_performance_preference"), 'rb') as 
f:
+        contents = f.read()
+      self.assertEqual(contents, b'balance_performance')
+
+      # Set performance mode
+      self.set_dbus_property('ActiveProfile', 
GLib.Variant.new_string('performance'))
+      self.assertEqual(self.get_dbus_property('ActiveProfile'), 'performance')
+
+      contents = None
+      with open(os.path.join(dir2, "energy_performance_preference"), 'rb') as 
f:
+        contents = f.read()
+      self.assertEqual(contents, b'performance')
+
+      self.stop_daemon()
+
+      # Verify that the Lenovo DYTC driver still gets preferred
+      self.create_platform_profile()
+      self.start_daemon()
+
+      profiles = self.get_dbus_property('Profiles')
+      self.assertEqual(len(profiles), 3)
+      self.assertEqual(profiles[0]['Driver'], 'platform_profile')
+
+    def test_amd_pstate_balance(self):
+      '''AMD P-State driver (balance)'''
+
+      # Create CPU with preference
+      dir1 = os.path.join(self.testbed.get_root_dir(), 
"sys/devices/system/cpu/cpufreq/policy0/")
+      os.makedirs(dir1)
+      gov_path = os.path.join(dir1, 'scaling_governor')
+      with open(gov_path, 'w') as gov:
+        gov.write('performance\n')
+      with open(os.path.join(dir1, "energy_performance_preference"),'w') as 
prefs:
+        prefs.write("performance\n")
+      pstate_dir = os.path.join(self.testbed.get_root_dir(), 
"sys/devices/system/cpu/amd_pstate")
+      os.makedirs(pstate_dir)
+      with open(os.path.join(pstate_dir, "status"),'w') as status:
+        status.write("active\n")
+
+      upowerd, obj_upower = self.spawn_server_template(
+            'upower', {'DaemonVersion': '0.99', 'OnBattery': False}, 
stdout=subprocess.PIPE)
+
+      self.start_daemon()
+
+      with open(gov_path, 'rb') as f:
+        contents = f.read()
+        self.assertEqual(contents, b'powersave')
+
+      profiles = self.get_dbus_property('Profiles')
+      self.assertEqual(len(profiles), 3)
+      self.assertEqual(profiles[0]['Driver'], 'amd_pstate')
+      self.assertEqual(profiles[0]['Profile'], 'power-saver')
+
+      contents = None
+      with open(os.path.join(dir1, "energy_performance_preference"), 'rb') as 
f:
+        contents = f.read()
+      # This matches what's written by ppd-driver-amd-pstate.c
+      self.assertEqual(contents, b'balance_performance')
+
+      self.stop_daemon()
+
+      upowerd.terminate()
+      upowerd.wait()
+      upowerd.stdout.close()
+
+    def test_amd_pstate_error(self):
+      '''AMD P-State driver in error state'''
+
+      pstate_dir = os.path.join(self.testbed.get_root_dir(), 
"sys/devices/system/cpu/amd_pstate")
+      os.makedirs(pstate_dir)
+      with open(os.path.join(pstate_dir, "status"),'w') as status:
+        status.write("active\n")
+
+      dir1 = os.path.join(self.testbed.get_root_dir(), 
"sys/devices/system/cpu/cpufreq/policy0/")
+      os.makedirs(dir1)
+      with open(os.path.join(dir1, 'scaling_governor'), 'w') as gov:
+        gov.write('powersave\n')
+      pref_path = os.path.join(dir1, "energy_performance_preference")
+      old_umask = os.umask(0o333)
+      with open(pref_path,'w') as prefs:
+        prefs.write("balance_performance\n")
+      os.umask(old_umask)
+      # Make file non-writable to root
+      if os.geteuid() == 0:
+        if not GLib.find_program_in_path('chattr'):
+          os._exit(77)
+        subprocess.check_output(['chattr', '+i', pref_path])
+
+      self.start_daemon()
+
+      self.assertEqual(self.get_dbus_property('ActiveProfile'), 'balanced')
+
+      # Error when setting performance mode
+      with self.assertRaises(gi.repository.GLib.GError):
+        self.set_dbus_property('ActiveProfile', 
GLib.Variant.new_string('performance'))
+      self.assertEqual(self.get_dbus_property('ActiveProfile'), 'balanced')
+
+      contents = None
+      with open(os.path.join(dir1, "energy_performance_preference"), 'rb') as 
f:
+        contents = f.read()
+      self.assertEqual(contents, b'balance_performance\n')
+
+      self.stop_daemon()
+
+      if os.geteuid() == 0:
+        subprocess.check_output(['chattr', '-i', pref_path])
+
+    def test_amd_pstate_passive(self):
+      '''AMD P-State in passive mode -> placeholder'''
+
+      dir1 = os.path.join(self.testbed.get_root_dir(), 
"sys/devices/system/cpu/cpufreq/policy0/")
+      os.makedirs(dir1)
+      with open(os.path.join(dir1, 'scaling_governor'), 'w') as gov:
+        gov.write('powersave\n')
+      with open(os.path.join(dir1, "energy_performance_preference"),'w') as 
prefs:
+        prefs.write("performance\n")
+
+      # Create AMD P-State configuration
+      pstate_dir = os.path.join(self.testbed.get_root_dir(), 
"sys/devices/system/cpu/amd_pstate")
+      os.makedirs(pstate_dir)
+      with open(os.path.join(pstate_dir, "status"),'w') as status:
+        status.write("passive\n")
+
+      self.start_daemon()
+
+      profiles = self.get_dbus_property('Profiles')
+      self.assertEqual(len(profiles), 2)
+      self.assertEqual(profiles[0]['Driver'], 'placeholder')
+      self.assertEqual(self.get_dbus_property('ActiveProfile'), 'balanced')
+
+      contents = None
+      with open(os.path.join(dir1, "energy_performance_preference"), 'rb') as 
f:
+        contents = f.read()
+      self.assertEqual(contents, b'performance\n')
+
+      # Set performance mode
+      self.set_dbus_property('ActiveProfile', 
GLib.Variant.new_string('power-saver'))
+      self.assertEqual(self.get_dbus_property('ActiveProfile'), 'power-saver')
+
+      contents = None
+      with open(os.path.join(dir1, "energy_performance_preference"), 'rb') as 
f:
+        contents = f.read()
+      self.assertEqual(contents, b'performance\n')
+
+      self.stop_daemon()
+
     def test_dytc_performance_driver(self):
       '''Lenovo DYTC performance driver'''
 
@@ -753,19 +937,23 @@
       self.assertEqual(profiles[0]['Driver'], 'platform_profile')
       self.assertEqual(profiles[0]['Profile'], 'power-saver')
       self.assertEqual(self.get_dbus_property('ActiveProfile'), 'balanced')
-      
self.assertEqual(self.read_sysfs_file("sys/firmware/acpi/platform_profile"), 
b'balanced')
+      
self.assertEqual(self.read_sysfs_file("sys/firmware/acpi/platform_profile"), 
b'cool')
       self.set_dbus_property('ActiveProfile', 
GLib.Variant.new_string('power-saver'))
       self.assertEqual(self.get_dbus_property('ActiveProfile'), 'power-saver')
       
self.assertEqual(self.read_sysfs_file("sys/firmware/acpi/platform_profile"), 
b'cool')
 
+      self.set_dbus_property('ActiveProfile', 
GLib.Variant.new_string('performance'))
+      self.set_dbus_property('ActiveProfile', 
GLib.Variant.new_string('balanced'))
+      
self.assertEqual(self.read_sysfs_file("sys/firmware/acpi/platform_profile"), 
b'balanced')
+
       self.stop_daemon()
 
     def test_quiet(self):
-      # Uses cool instead of low-power
+      # Uses quiet instead of low-power
       acpi_dir = os.path.join(self.testbed.get_root_dir(), 
"sys/firmware/acpi/")
       os.makedirs(acpi_dir)
       with open(os.path.join(acpi_dir, "platform_profile"),'w') as profile:
-        profile.write("cool\n")
+        profile.write("quiet\n")
       with open(os.path.join(acpi_dir, "platform_profile_choices"),'w') as 
choices:
         choices.write("quiet balanced balanced-performance performance\n")
 

Reply via email to