amdgpu: Handle disconnected panels correctly

Some systems have multiple GPUs with an eDP output but the panel
isn't connected to all of them (or it's controlled by a mux).

Handle this case by ensuring that the panel is connected when
before writing an attribute.
This commit is contained in:
Mario Limonciello 2024-02-12 11:24:52 -06:00 committed by Marco Trevisan
parent 07a77652b1
commit 70849a6686
2 changed files with 37 additions and 2 deletions

View file

@ -20,6 +20,7 @@
#define PROC_CPUINFO_PATH "/proc/cpuinfo"
#define PANEL_POWER_SYSFS_NAME "amdgpu/panel_power_savings"
#define PANEL_STATUS_SYSFS_NAME "status"
#define UPOWER_DBUS_NAME "org.freedesktop.UPower"
#define UPOWER_DBUS_PATH "/org/freedesktop/UPower"
@ -68,6 +69,20 @@ ppd_action_amdgpu_panel_power_constructor (GType type,
return object;
}
static gboolean
panel_connected (GUdevDevice *device)
{
const char *value;
g_autofree gchar *stripped = NULL;
value = g_udev_device_get_sysfs_attr_uncached (device, PANEL_STATUS_SYSFS_NAME);
if (!value)
return FALSE;
stripped = g_strchomp (g_strdup (value));
return g_strcmp0 (stripped, "connected") == 0;
}
static gboolean
set_panel_power (PpdActionAmdgpuPanelPower *self, gint power, GError **error)
{
@ -91,6 +106,9 @@ set_panel_power (PpdActionAmdgpuPanelPower *self, gint power, GError **error)
if (g_strcmp0 (value, "drm_connector") != 0)
continue;
if (!panel_connected (dev))
continue;
value = g_udev_device_get_sysfs_attr_uncached (dev, PANEL_POWER_SYSFS_NAME);
if (!value)
continue;
@ -203,6 +221,9 @@ udev_uevent_cb (GUdevClient *client,
if (!g_udev_device_has_sysfs_attr (device, PANEL_POWER_SYSFS_NAME))
return;
if (!panel_connected (device))
return;
g_debug ("Updating panel power saving for '%s' to '%d'",
g_udev_device_get_sysfs_path (device),
self->panel_power_saving);

View file

@ -1393,7 +1393,7 @@ class Tests(dbusmock.DBusTestCase):
"drm",
"card1-eDP",
None,
["amdgpu/panel_power_savings", "0"],
["status", "connected\n", "amdgpu/panel_power_savings", "0"],
["DEVTYPE", "drm_connector"],
)
@ -1428,7 +1428,7 @@ class Tests(dbusmock.DBusTestCase):
"drm",
"card2-eDP",
None,
["amdgpu/panel_power_savings", "0"],
["status", "connected\n", "amdgpu/panel_power_savings", "0"],
["DEVTYPE", "drm_connector"],
)
@ -1437,6 +1437,20 @@ class Tests(dbusmock.DBusTestCase):
lambda: self.read_sysfs_attr(edp2, "amdgpu/panel_power_savings") == b"4"
)
# add another device that supports the feature, but panel is disconnected
edp3 = self.testbed.add_device(
"drm",
"card3-eDP",
None,
["status", "disconnected\n", "amdgpu/panel_power_savings", "0"],
["DEVTYPE", "drm_connector"],
)
# verify power saver didn't get updated for it
self.assert_eventually(
lambda: self.read_sysfs_attr(edp3, "amdgpu/panel_power_savings") == b"0"
)
def test_trickle_charge_system(self):
"""Trickle power_supply charge type"""