From patchwork Wed Sep 4 19:25:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 13791293 Received: from todd.t-8ch.de (todd.t-8ch.de [159.69.126.157]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4A5B81E6DC6; Wed, 4 Sep 2024 19:25:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=159.69.126.157 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725477955; cv=none; b=gzFxHHNywddLVGhJ8KkLs24nkvIFXlOCAst8oGTfM9n6xh3wSP+8+PRw0zadDoM8KYgXLqgZ8X0OGlDGHijppNIsJSNdxjz0Ygae7D2oeVcMUORI4NEZ1JQKgEIFaxi6DORihNlPD2Tb7r5e81sKo+/tWhoxcwoZqQNd49QFNsc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725477955; c=relaxed/simple; bh=hEkSIvpNPK0BIvtwX1OZ+TPL0VX03eyHv0tdX9hn8tM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MO0uaJDoeNd7/EWKzCaMllPahEYWG9M976tK3BY6L/6/76TePfvHvaUgFZ8iQx+WCzfgI33MtuoMpKuXK6e6VXEEcVlfUNgHCepOwURQ409mAzTwqRrrZqKkgtjNrYVdHIqMBkVpXjRllSN77G/jW91+ru8WQ7ri/MQzD8U1NcA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net; spf=pass smtp.mailfrom=weissschuh.net; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b=rWDxxD1c; arc=none smtp.client-ip=159.69.126.157 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b="rWDxxD1c" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1725477949; bh=hEkSIvpNPK0BIvtwX1OZ+TPL0VX03eyHv0tdX9hn8tM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=rWDxxD1cEqJOvQSH3Oi50pXPVQhGV1jsErhM3RJaTcyWyAosgb7NIjJ7azy8tTW/y ogslUeQV0VgZVIp4q4hXVRyLdYom3zPBMAuF0kdYiEnLdpp9j8pl0DipPqqS+I6hyi 8X7sxzwCbL1wG8zKsCVV0lFakuuTeQ0L+qVYFGZ8= From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= Date: Wed, 04 Sep 2024 21:25:34 +0200 Subject: [PATCH RFC v3 1/9] power: supply: core: rename psy_has_property() to psy_desc_has_property() Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240904-power-supply-extensions-v3-1-62efeb93f8ec@weissschuh.net> References: <20240904-power-supply-extensions-v3-0-62efeb93f8ec@weissschuh.net> In-Reply-To: <20240904-power-supply-extensions-v3-0-62efeb93f8ec@weissschuh.net> To: Sebastian Reichel , Armin Wolf , Hans de Goede Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?Thomas?= =?utf-8?q?_Wei=C3=9Fschuh?= X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1725477949; l=2126; i=linux@weissschuh.net; s=20221212; h=from:subject:message-id; bh=hEkSIvpNPK0BIvtwX1OZ+TPL0VX03eyHv0tdX9hn8tM=; b=8J3gHB8J8fm4jNAYK11JOvww0TkwXNmjViB3VSKQNL9BqdXa40DOmLE7A8PE92Pw8iiBIIn1o BXn6dPWCDc8DOKakNyXkC9hhvNYAMw8AYZPAneahEW8/c4enO1tLXsH X-Developer-Key: i=linux@weissschuh.net; a=ed25519; pk=KcycQgFPX2wGR5azS7RhpBqedglOZVgRPfdFSPB1LNw= The function only takes a desc as parameter, align the naming. Signed-off-by: Thomas Weißschuh Reviewed-by: Hans de Goede Reviewed-by: Sebastian Reichel --- drivers/power/supply/power_supply_core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c index 8f6025acd10a..cff68c4fd63c 100644 --- a/drivers/power/supply/power_supply_core.c +++ b/drivers/power/supply/power_supply_core.c @@ -1183,8 +1183,8 @@ bool power_supply_battery_bti_in_range(struct power_supply_battery_info *info, } EXPORT_SYMBOL_GPL(power_supply_battery_bti_in_range); -static bool psy_has_property(const struct power_supply_desc *psy_desc, - enum power_supply_property psp) +static bool psy_desc_has_property(const struct power_supply_desc *psy_desc, + enum power_supply_property psp) { bool found = false; int i; @@ -1209,7 +1209,7 @@ int power_supply_get_property(struct power_supply *psy, return -ENODEV; } - if (psy_has_property(psy->desc, psp)) + if (psy_desc_has_property(psy->desc, psp)) return psy->desc->get_property(psy, psp, val); else if (power_supply_battery_info_has_prop(psy->battery_info, psp)) return power_supply_battery_info_get_prop(psy->battery_info, psp, val); @@ -1308,7 +1308,7 @@ static int psy_register_thermal(struct power_supply *psy) return 0; /* Register battery zone device psy reports temperature */ - if (psy_has_property(psy->desc, POWER_SUPPLY_PROP_TEMP)) { + if (psy_desc_has_property(psy->desc, POWER_SUPPLY_PROP_TEMP)) { /* Prefer our hwmon device and avoid duplicates */ struct thermal_zone_params tzp = { .no_hwmon = IS_ENABLED(CONFIG_POWER_SUPPLY_HWMON) @@ -1361,7 +1361,7 @@ __power_supply_register(struct device *parent, pr_warn("%s: Expected proper parent device for '%s'\n", __func__, desc->name); - if (psy_has_property(desc, POWER_SUPPLY_PROP_USB_TYPE) && + if (psy_desc_has_property(desc, POWER_SUPPLY_PROP_USB_TYPE) && (!desc->usb_types || !desc->num_usb_types)) return ERR_PTR(-EINVAL); From patchwork Wed Sep 4 19:25:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 13791292 Received: from todd.t-8ch.de (todd.t-8ch.de [159.69.126.157]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DD4C21E6DC2; Wed, 4 Sep 2024 19:25:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=159.69.126.157 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725477954; cv=none; b=nI34yeuBHV7M1fXbAgv71tSPJMyR1bLEueSaHfGTwKFTEX1u97EZkwjfRkFrTADIdUFXagITQrD3nnth2blMxV7G34LcmloBIDeHENu/LiIFZTaIoaUGMosE6wv9OjphSRJgydoNxDf0gq/7Rlef1Ysl+J/QT/wmS/dObYuTOPk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725477954; c=relaxed/simple; bh=tSi4oRvOGQIXQ7gqeiL+uRkdyJkUIZbA/N22hcgrptg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=u7WbjSsbsPV8ASJK2Bfi/8NKeko1UTDFJ896aF/8yv/oEBMy1x43i8KRGYO/ScaO3N1Pk3NhKP5hHxuSEdMWA2slJz69XtC/EiUJuQyzGE0ZQpl5JxGZPeI16hoIAym/PxEiGsDr/mX63SJ65yMFOzZRn79MPQiVph6cPoVIA2U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net; spf=pass smtp.mailfrom=weissschuh.net; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b=VichUywS; arc=none smtp.client-ip=159.69.126.157 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b="VichUywS" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1725477949; bh=tSi4oRvOGQIXQ7gqeiL+uRkdyJkUIZbA/N22hcgrptg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=VichUywSGzWCRvZjoNtUbOcS7cG9+DpFa47j/NUuj0yq9fJxi2M8CrRuwo6p2+Eev uVeYLvufhXDJ0qT1oEsxYMV9GxZHwrFYHss/sMwHfhppvFo+/PIvk0m2KiD/h3luCv na1899RqEQGNmeRn300L8eC4XGXzgyIoUCzKP3mA= From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= Date: Wed, 04 Sep 2024 21:25:35 +0200 Subject: [PATCH RFC v3 2/9] power: supply: core: register thermal zone for battery Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240904-power-supply-extensions-v3-2-62efeb93f8ec@weissschuh.net> References: <20240904-power-supply-extensions-v3-0-62efeb93f8ec@weissschuh.net> In-Reply-To: <20240904-power-supply-extensions-v3-0-62efeb93f8ec@weissschuh.net> To: Sebastian Reichel , Armin Wolf , Hans de Goede Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?Thomas?= =?utf-8?q?_Wei=C3=9Fschuh?= X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1725477949; l=2347; i=linux@weissschuh.net; s=20221212; h=from:subject:message-id; bh=tSi4oRvOGQIXQ7gqeiL+uRkdyJkUIZbA/N22hcgrptg=; b=BU4CIHCEnBEnvYXSrcqUcr+HQ4oZhPLaoSakctQyipnUOX4vj8oEWk6mBPlRgaVZFOLnfspej TerdtMmZzs/B9HsYh55B2wzNiI0WQvkqTXJ5rPVTHKcE/zhvLdYdAhZ X-Developer-Key: i=linux@weissschuh.net; a=ed25519; pk=KcycQgFPX2wGR5azS7RhpBqedglOZVgRPfdFSPB1LNw= power_supply_read_team() can also read the temperature from the battery. But currently when registering the thermal zone, the battery is not checked for POWER_SUPPLY_PROP_TEMP. Introduce a helper which can check both the desc and the battery info for property existence and use that. Export the helper to the rest of the psy core because it will also be used by different subcomponents. Signed-off-by: Thomas Weißschuh Reviewed-by: Hans de Goede --- drivers/power/supply/power_supply.h | 3 +++ drivers/power/supply/power_supply_core.c | 14 +++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/power/supply/power_supply.h b/drivers/power/supply/power_supply.h index 3cbafc58bdad..b01faeaf7827 100644 --- a/drivers/power/supply/power_supply.h +++ b/drivers/power/supply/power_supply.h @@ -13,6 +13,9 @@ struct device; struct device_type; struct power_supply; +extern bool power_supply_has_property(struct power_supply *psy, + enum power_supply_property psp); + #ifdef CONFIG_SYSFS extern void power_supply_init_attrs(void); diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c index cff68c4fd63c..dcb7e4853030 100644 --- a/drivers/power/supply/power_supply_core.c +++ b/drivers/power/supply/power_supply_core.c @@ -1199,6 +1199,18 @@ static bool psy_desc_has_property(const struct power_supply_desc *psy_desc, return found; } +bool power_supply_has_property(struct power_supply *psy, + enum power_supply_property psp) +{ + if (psy_desc_has_property(psy->desc, psp)) + return true; + + if (power_supply_battery_info_has_prop(psy->battery_info, psp)) + return true; + + return false; +} + int power_supply_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) @@ -1308,7 +1320,7 @@ static int psy_register_thermal(struct power_supply *psy) return 0; /* Register battery zone device psy reports temperature */ - if (psy_desc_has_property(psy->desc, POWER_SUPPLY_PROP_TEMP)) { + if (power_supply_has_property(psy, POWER_SUPPLY_PROP_TEMP)) { /* Prefer our hwmon device and avoid duplicates */ struct thermal_zone_params tzp = { .no_hwmon = IS_ENABLED(CONFIG_POWER_SUPPLY_HWMON) From patchwork Wed Sep 4 19:25:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 13791289 Received: from todd.t-8ch.de (todd.t-8ch.de [159.69.126.157]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 32C631E6DC3; Wed, 4 Sep 2024 19:25:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=159.69.126.157 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725477954; cv=none; b=hanS83MnkO6NzJhnU5+6TwFWFBQ290uKHgVgr4MenYgYRc9UhP+tVIzm31jv1LzJYq9K8kfYvxdmzECfUwsroWHvcMmZAFTHmU6LT+/S/Jt/WpCN0MGCXCwCuUKbX9O52Wo5P3G+NS27jbT1k+fEuwZCkzNyAuxT+aCVGeckAC4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725477954; c=relaxed/simple; bh=EV6+zz4CmbgtMfZTkgUenuapQZpHRoJn6kiU2fst8eU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NOrM1S4kJP0m99Qk/G+4FCU3y81TyEpVotDJNmD6Vu3cyyBMdFHbzNPemQd7vf3B9mig2PmZ02cwr4qcj7ouJR/SZ1cCLUwBOC3FwhY2+HHmUBbPAy5apu28NZB8YicLXD7kqjr/0lwznp9JEqT+8I+idOVyAqQAML4SvekvWMk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net; spf=pass smtp.mailfrom=weissschuh.net; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b=NkqAtUkg; arc=none smtp.client-ip=159.69.126.157 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b="NkqAtUkg" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1725477949; bh=EV6+zz4CmbgtMfZTkgUenuapQZpHRoJn6kiU2fst8eU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=NkqAtUkgQ7X1tNJ/WN7qqdj4bs/ZmVGeEaF/0gNvuL/7pfcbpxsGJt/hVwgLkYAHX qb2uSXQNK2EKxl5GhUr6Dqi8XZwcOah0tQP1XkLWS/4f2T+/8r6Cr8GT5uI4gXnPia 9+LK0e/2qxH93u27HD2t1Tqu/lbMlM8c/ff2jVgQ= From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= Date: Wed, 04 Sep 2024 21:25:36 +0200 Subject: [PATCH RFC v3 3/9] power: supply: hwmon: register battery properties Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240904-power-supply-extensions-v3-3-62efeb93f8ec@weissschuh.net> References: <20240904-power-supply-extensions-v3-0-62efeb93f8ec@weissschuh.net> In-Reply-To: <20240904-power-supply-extensions-v3-0-62efeb93f8ec@weissschuh.net> To: Sebastian Reichel , Armin Wolf , Hans de Goede Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?Thomas?= =?utf-8?q?_Wei=C3=9Fschuh?= X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1725477949; l=3100; i=linux@weissschuh.net; s=20221212; h=from:subject:message-id; bh=EV6+zz4CmbgtMfZTkgUenuapQZpHRoJn6kiU2fst8eU=; b=97Z+BIzpLl/uyAcDMqYlGIi1i4RYmsJR3Y5+4OWUEJflVd8pdfW+cCM/lPoedVcBeohKw35mZ HlNgkaOj2dUBbHvfZAVfvtwSqbxOKFXVoJsDeQM4pZPCDE1dcNvT5z4 X-Developer-Key: i=linux@weissschuh.net; a=ed25519; pk=KcycQgFPX2wGR5azS7RhpBqedglOZVgRPfdFSPB1LNw= Instead of only registering properties from the psy_desc itself, also register the ones from the battery. Use power_supply_has_property() for this test which makes the logic also easier to read. Signed-off-by: Thomas Weißschuh Reviewed-by: Hans de Goede Reviewed-by: Sebastian Reichel --- drivers/power/supply/power_supply_hwmon.c | 52 +++++++++++++++---------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/power/supply/power_supply_hwmon.c b/drivers/power/supply/power_supply_hwmon.c index baacefbdf768..1c1ad3e1d81f 100644 --- a/drivers/power/supply/power_supply_hwmon.c +++ b/drivers/power/supply/power_supply_hwmon.c @@ -8,6 +8,8 @@ #include #include +#include "power_supply.h" + struct power_supply_hwmon { struct power_supply *psy; unsigned long *props; @@ -347,9 +349,28 @@ static const struct hwmon_chip_info power_supply_hwmon_chip_info = { .info = power_supply_hwmon_info, }; +static const enum power_supply_property power_supply_hwmon_props[] = { + POWER_SUPPLY_PROP_CURRENT_AVG, + POWER_SUPPLY_PROP_CURRENT_MAX, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_POWER_AVG, + POWER_SUPPLY_PROP_POWER_NOW, + POWER_SUPPLY_PROP_TEMP, + POWER_SUPPLY_PROP_TEMP_MAX, + POWER_SUPPLY_PROP_TEMP_MIN, + POWER_SUPPLY_PROP_TEMP_ALERT_MIN, + POWER_SUPPLY_PROP_TEMP_ALERT_MAX, + POWER_SUPPLY_PROP_TEMP_AMBIENT, + POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN, + POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX, + POWER_SUPPLY_PROP_VOLTAGE_AVG, + POWER_SUPPLY_PROP_VOLTAGE_MIN, + POWER_SUPPLY_PROP_VOLTAGE_MAX, + POWER_SUPPLY_PROP_VOLTAGE_NOW, +}; + int power_supply_add_hwmon_sysfs(struct power_supply *psy) { - const struct power_supply_desc *desc = psy->desc; struct power_supply_hwmon *psyhw; struct device *dev = &psy->dev; struct device *hwmon; @@ -375,32 +396,11 @@ int power_supply_add_hwmon_sysfs(struct power_supply *psy) goto error; } - for (i = 0; i < desc->num_properties; i++) { - const enum power_supply_property prop = desc->properties[i]; - - switch (prop) { - case POWER_SUPPLY_PROP_CURRENT_AVG: - case POWER_SUPPLY_PROP_CURRENT_MAX: - case POWER_SUPPLY_PROP_CURRENT_NOW: - case POWER_SUPPLY_PROP_POWER_AVG: - case POWER_SUPPLY_PROP_POWER_NOW: - case POWER_SUPPLY_PROP_TEMP: - case POWER_SUPPLY_PROP_TEMP_MAX: - case POWER_SUPPLY_PROP_TEMP_MIN: - case POWER_SUPPLY_PROP_TEMP_ALERT_MIN: - case POWER_SUPPLY_PROP_TEMP_ALERT_MAX: - case POWER_SUPPLY_PROP_TEMP_AMBIENT: - case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN: - case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX: - case POWER_SUPPLY_PROP_VOLTAGE_AVG: - case POWER_SUPPLY_PROP_VOLTAGE_MIN: - case POWER_SUPPLY_PROP_VOLTAGE_MAX: - case POWER_SUPPLY_PROP_VOLTAGE_NOW: + for (i = 0; i < ARRAY_SIZE(power_supply_hwmon_props); i++) { + const enum power_supply_property prop = power_supply_hwmon_props[i]; + + if (power_supply_has_property(psy, prop)) set_bit(prop, psyhw->props); - break; - default: - break; - } } name = psy->desc->name; From patchwork Wed Sep 4 19:25:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 13791291 Received: from todd.t-8ch.de (todd.t-8ch.de [159.69.126.157]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 48FE51E6DC5; Wed, 4 Sep 2024 19:25:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=159.69.126.157 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725477954; cv=none; b=VVv5/TO2J2hlsOT06UVwrlz8ITvG8VOO0o7UiKMUzSKKHxw2yHloB6HR5hNNMWCWRRJUjNdoL2HVw9Jey21G7Bqu+ApU1dN3VL5SmwkqIwOLDho6g2YvjTujP8aQLIfBikRUO0nq7dFPiz4xM5tiiaWlwJm7PGhLurDTQKSqiFo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725477954; c=relaxed/simple; bh=1qFuHiGvcngQBCI1NgBkTkcdy4K1lH92ip/hhc7BDJc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=VStfw6+Mr4ySfkn7rumvAy9q4gGffhcPmKorbd9HHawve3xr50u94IbWBIf8Hy3GHP+hrMAhPDejyxUzbQuhLQsj+7+AsoQz7Mgb0n4QC/3+9RBt2SzbejSuSSn7Qt5lQaBEh5YdgOuK2Vb5Z/2W1QHjb+ZL7jLGHbnPNuGMbSk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net; spf=pass smtp.mailfrom=weissschuh.net; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b=lhQH1abU; arc=none smtp.client-ip=159.69.126.157 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b="lhQH1abU" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1725477950; bh=1qFuHiGvcngQBCI1NgBkTkcdy4K1lH92ip/hhc7BDJc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=lhQH1abUdyfvDjezyT0yZh1wp3Qii3m7tOMm6L3LBG8bVOjQaE0V9hhKTY7Insmv/ UDgIKSPoQdfntekVHfuPoW532wBehdV3ixthYMfEtoRn+1kG3D/Ph6BMI8BGkluTgt K8EmH+ciytHA8W6pRDrarAfC3NyjrRVxZ5DzwwJA= From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= Date: Wed, 04 Sep 2024 21:25:37 +0200 Subject: [PATCH RFC v3 4/9] power: supply: sysfs: register battery properties Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240904-power-supply-extensions-v3-4-62efeb93f8ec@weissschuh.net> References: <20240904-power-supply-extensions-v3-0-62efeb93f8ec@weissschuh.net> In-Reply-To: <20240904-power-supply-extensions-v3-0-62efeb93f8ec@weissschuh.net> To: Sebastian Reichel , Armin Wolf , Hans de Goede Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?Thomas?= =?utf-8?q?_Wei=C3=9Fschuh?= X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1725477949; l=1586; i=linux@weissschuh.net; s=20221212; h=from:subject:message-id; bh=1qFuHiGvcngQBCI1NgBkTkcdy4K1lH92ip/hhc7BDJc=; b=wmtOZoyYq5meEWGN7VOBId6j+M3aTnjFqezy4K23vtTrY3rCZgyBeBgfRzYPknac7R9B6p+Jp HP7krbONEGKDtsbVnBRWObjPBK7Wa2yPS8wT2pWHIQ9ZEfyw2tc9vC6 X-Developer-Key: i=linux@weissschuh.net; a=ed25519; pk=KcycQgFPX2wGR5azS7RhpBqedglOZVgRPfdFSPB1LNw= Instead of only registering properties from the psy_desc itself, also register the ones from the battery. Use power_supply_has_property() for this test which makes the logic also easier to read. Signed-off-by: Thomas Weißschuh Reviewed-by: Hans de Goede --- drivers/power/supply/power_supply_sysfs.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c index 3e63d165b2f7..4ab08386bcb7 100644 --- a/drivers/power/supply/power_supply_sysfs.c +++ b/drivers/power/supply/power_supply_sysfs.c @@ -367,7 +367,6 @@ static umode_t power_supply_attr_is_visible(struct kobject *kobj, struct device *dev = kobj_to_dev(kobj); struct power_supply *psy = dev_get_drvdata(dev); umode_t mode = S_IRUSR | S_IRGRP | S_IROTH; - int i; if (!power_supply_attrs[attrno].prop_name) return 0; @@ -375,19 +374,11 @@ static umode_t power_supply_attr_is_visible(struct kobject *kobj, if (attrno == POWER_SUPPLY_PROP_TYPE) return mode; - for (i = 0; i < psy->desc->num_properties; i++) { - int property = psy->desc->properties[i]; - - if (property == attrno) { - if (power_supply_property_is_writeable(psy, property) > 0) - mode |= S_IWUSR; - - return mode; - } - } - - if (power_supply_battery_info_has_prop(psy->battery_info, attrno)) + if (power_supply_has_property(psy, attrno)) { + if (power_supply_property_is_writeable(psy, attrno) > 0) + mode |= S_IWUSR; return mode; + } return 0; } From patchwork Wed Sep 4 19:25:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 13791294 Received: from todd.t-8ch.de (todd.t-8ch.de [159.69.126.157]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A9AA21E7665; Wed, 4 Sep 2024 19:25:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=159.69.126.157 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725477957; cv=none; b=dPIwcCaN3e5hqLSoYBhxvWiDHS7PP06GyQ60eRsryWdwOw4sZ8hkHn6nKa6lUokuj6hvPB0OfOXI7dUo4ItJ5lX2crtXUfjJ4ReKGILBmxRH69ex6j2YX/+TWb7fuNVVO6sBUo/RsTPH5sHZ87TQT4c7ymOYsNTfu/oBCtZHeSQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725477957; c=relaxed/simple; bh=X7lrjE7x1vAygc53rzcx7av5ytjIigJ+NYfn3S4SJ4A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NvuewoTBHCbcym67NQVZp7H1LdMcM9GAczd7qXgpLVBUYt5AiKhfyF7vQr3FAYSis/gufm/TDglEaIdfvhffpgJPuapN3nYi8z02aRvkpS0mioZNHRNu/0TOJJLE+48rhBUBQJ4AdUvBDgl1UlkTQlNRtYyIX8h9lTAzDQm66W8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net; spf=pass smtp.mailfrom=weissschuh.net; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b=Jx/VexhN; arc=none smtp.client-ip=159.69.126.157 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b="Jx/VexhN" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1725477950; bh=X7lrjE7x1vAygc53rzcx7av5ytjIigJ+NYfn3S4SJ4A=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Jx/VexhNKkiGnsolG8rjeSiBr7Irw/YxP8gy/7S/pgwWwny5e2IJ296vj8A/rERoU zPWlMMUZJn5HvxpoxIyczJx46Mx+Fm/GdqKlxAeNbqfL8TFPNLNLOgyewFl2YtsDXy GJrapuGVkR8nsTzh4MQ1EUwAMzSf+w8BgafNVYXg= From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= Date: Wed, 04 Sep 2024 21:25:38 +0200 Subject: [PATCH RFC v3 5/9] power: supply: sysfs: rework uevent property loop Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240904-power-supply-extensions-v3-5-62efeb93f8ec@weissschuh.net> References: <20240904-power-supply-extensions-v3-0-62efeb93f8ec@weissschuh.net> In-Reply-To: <20240904-power-supply-extensions-v3-0-62efeb93f8ec@weissschuh.net> To: Sebastian Reichel , Armin Wolf , Hans de Goede Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?Thomas?= =?utf-8?q?_Wei=C3=9Fschuh?= X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1725477949; l=2599; i=linux@weissschuh.net; s=20221212; h=from:subject:message-id; bh=X7lrjE7x1vAygc53rzcx7av5ytjIigJ+NYfn3S4SJ4A=; b=1vjSgYQ94s1oECkeX/DTp6kXRi0vegsS8A+3bSox8QyG7q4IaF/lpF7hURPFC3nBLw0Ur+J7R zd4tZe3Y7+6BNHlv0Pp71iL610FFS1nFBH1ULfOTpYmNT6sdr6Q6ObY X-Developer-Key: i=linux@weissschuh.net; a=ed25519; pk=KcycQgFPX2wGR5azS7RhpBqedglOZVgRPfdFSPB1LNw= Instead of looping through all properties known to be supported by the psy, loop over all known properties and decide based on the return value of power_supply_get_property() whether the property existed. This makes the code shorter now and even more so when power supply extensions are added. It also simplifies the locking, as it can all happen inside power_supply_get_property(). Signed-off-by: Thomas Weißschuh Reviewed-by: Hans de Goede --- drivers/power/supply/power_supply_sysfs.c | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c index 4ab08386bcb7..915a4ba62258 100644 --- a/drivers/power/supply/power_supply_sysfs.c +++ b/drivers/power/supply/power_supply_sysfs.c @@ -290,6 +290,8 @@ static ssize_t power_supply_show_property(struct device *dev, dev_dbg_ratelimited(dev, "driver has no data for `%s' property\n", attr->attr.name); + else if (ret == -EINVAL) /* property is not supported */ + return -ENODATA; else if (ret != -ENODEV && ret != -EAGAIN) dev_err_ratelimited(dev, "driver failed to report `%s' property: %zd\n", @@ -451,11 +453,7 @@ static int add_prop_uevent(const struct device *dev, struct kobj_uevent_env *env int power_supply_uevent(const struct device *dev, struct kobj_uevent_env *env) { - const struct power_supply *psy = dev_get_drvdata(dev); - const enum power_supply_property *battery_props = - power_supply_battery_info_properties; - unsigned long psy_drv_properties[POWER_SUPPLY_ATTR_CNT / - sizeof(unsigned long) + 1] = {0}; + struct power_supply *psy = dev_get_drvdata(dev); int ret = 0, j; char *prop_buf; @@ -483,22 +481,8 @@ int power_supply_uevent(const struct device *dev, struct kobj_uevent_env *env) if (ret) goto out; - for (j = 0; j < psy->desc->num_properties; j++) { - set_bit(psy->desc->properties[j], psy_drv_properties); - ret = add_prop_uevent(dev, env, psy->desc->properties[j], - prop_buf); - if (ret) - goto out; - } - - for (j = 0; j < power_supply_battery_info_properties_size; j++) { - if (test_bit(battery_props[j], psy_drv_properties)) - continue; - if (!power_supply_battery_info_has_prop(psy->battery_info, - battery_props[j])) - continue; - ret = add_prop_uevent(dev, env, battery_props[j], - prop_buf); + for (j = 0; j < POWER_SUPPLY_ATTR_CNT; j++) { + ret = add_prop_uevent(dev, env, j, prop_buf); if (ret) goto out; } From patchwork Wed Sep 4 19:25:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 13791296 Received: from todd.t-8ch.de (todd.t-8ch.de [159.69.126.157]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D69131E7671; Wed, 4 Sep 2024 19:25:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=159.69.126.157 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725477957; cv=none; b=qfNNSn/ETA+GLWXal1ICA67kjWFXkFC0xryQFejkOgn133Il1z6kdCYubL2PkUOcsjo5oQ6oMv09cP+yGcTD05GnYv24Ino6cmSCsZIkTNOslkMUmEnIK1i5+Oi8nzcwjusZA/rqNyaa3cOSD2vh6ZPqlgxkxoQNuM1vjVqY4EM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725477957; c=relaxed/simple; bh=eMUeVr6CvVJ8cr1bCvgkx350hCvdH3yQPf0m+2CqLHA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=au4rxh3IpGxpdmWvu5uBB82RxFzDvdU9PD661/vY2V+0XBHWe4kJwsgWFNRZeQEiHbrbApYnJhgFsd2necwIVs6MVy4NKJ//GGN9LLLiWGwf+DOI8ZVovL97q89hSjPfPS/6qp9Kt6peWau7mqPBDXaGo69pvQWJwmB/wiebsVs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net; spf=pass smtp.mailfrom=weissschuh.net; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b=N+9+k8GY; arc=none smtp.client-ip=159.69.126.157 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b="N+9+k8GY" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1725477950; bh=eMUeVr6CvVJ8cr1bCvgkx350hCvdH3yQPf0m+2CqLHA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=N+9+k8GYmSNeqEvDMpLl/yTpau1e+PG/LfotsR4LTszfI7g8mpZUY5+V1c4qpaTLu csBDR28ReJz/bNAlfSg1KVHy6rMt4iu+cpkFmogfhDwP0fu7AUlFmTvi1Jt34Zc0Qh 7vK/vyL+raSeVFtNUjbG1/Pu9RbvXN0lQji0Jzp8= From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= Date: Wed, 04 Sep 2024 21:25:39 +0200 Subject: [PATCH RFC v3 6/9] power: supply: core: implement extension API Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240904-power-supply-extensions-v3-6-62efeb93f8ec@weissschuh.net> References: <20240904-power-supply-extensions-v3-0-62efeb93f8ec@weissschuh.net> In-Reply-To: <20240904-power-supply-extensions-v3-0-62efeb93f8ec@weissschuh.net> To: Sebastian Reichel , Armin Wolf , Hans de Goede Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?Thomas?= =?utf-8?q?_Wei=C3=9Fschuh?= X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1725477949; l=9950; i=linux@weissschuh.net; s=20221212; h=from:subject:message-id; bh=eMUeVr6CvVJ8cr1bCvgkx350hCvdH3yQPf0m+2CqLHA=; b=VmHC8xkSL0OqF2WzBDCzpSAcRUfXNZuWUz2So291TAyozjryq8RSMOxMweIsleqbqo3uKPUK4 YdMk4zKczb+AZGDvr6C31jOu0wi4PCbb+1L9x+gggxajsnk/sNmMFdD X-Developer-Key: i=linux@weissschuh.net; a=ed25519; pk=KcycQgFPX2wGR5azS7RhpBqedglOZVgRPfdFSPB1LNw= Signed-off-by: Thomas Weißschuh --- drivers/power/supply/power_supply.h | 12 ++++ drivers/power/supply/power_supply_core.c | 114 +++++++++++++++++++++++++++++- drivers/power/supply/power_supply_sysfs.c | 20 +++++- include/linux/power_supply.h | 30 ++++++++ 4 files changed, 171 insertions(+), 5 deletions(-) diff --git a/drivers/power/supply/power_supply.h b/drivers/power/supply/power_supply.h index b01faeaf7827..fb45f0717bd1 100644 --- a/drivers/power/supply/power_supply.h +++ b/drivers/power/supply/power_supply.h @@ -15,6 +15,18 @@ struct power_supply; extern bool power_supply_has_property(struct power_supply *psy, enum power_supply_property psp); +extern bool power_supply_ext_has_property(const struct power_supply_ext *ext, + enum power_supply_property psp); + +struct power_supply_ext_registration { + struct list_head list_head; + const struct power_supply_ext *ext; + void *data; +}; + +#define power_supply_for_each_extension(pos, psy) \ + list_for_each_entry(pos, &(psy)->extensions, list_head) + #ifdef CONFIG_SYSFS diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c index dcb7e4853030..db5e7af57e67 100644 --- a/drivers/power/supply/power_supply_core.c +++ b/drivers/power/supply/power_supply_core.c @@ -1199,15 +1199,40 @@ static bool psy_desc_has_property(const struct power_supply_desc *psy_desc, return found; } +bool power_supply_ext_has_property(const struct power_supply_ext *psy_ext, + enum power_supply_property psp) +{ + bool found = false; + int i; + + if (!psy_ext) + return false; + + for (i = 0; i < psy_ext->num_properties; i++) { + if (psy_ext->properties[i] == psp) { + found = true; + break; + } + } + + return found; +} + bool power_supply_has_property(struct power_supply *psy, enum power_supply_property psp) { + struct power_supply_ext_registration *reg; + if (psy_desc_has_property(psy->desc, psp)) return true; if (power_supply_battery_info_has_prop(psy->battery_info, psp)) return true; + power_supply_for_each_extension(reg, psy) + if (power_supply_ext_has_property(reg->ext, psp)) + return true; + return false; } @@ -1215,12 +1240,19 @@ int power_supply_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) { + struct power_supply_ext_registration *reg; + if (atomic_read(&psy->use_cnt) <= 0) { if (!psy->initialized) return -EAGAIN; return -ENODEV; } + power_supply_for_each_extension(reg, psy) { + if (power_supply_ext_has_property(reg->ext, psp)) + return reg->ext->get_property(psy, reg->ext, reg->data, psp, val); + } + if (psy_desc_has_property(psy->desc, psp)) return psy->desc->get_property(psy, psp, val); else if (power_supply_battery_info_has_prop(psy->battery_info, psp)) @@ -1234,7 +1266,21 @@ int power_supply_set_property(struct power_supply *psy, enum power_supply_property psp, const union power_supply_propval *val) { - if (atomic_read(&psy->use_cnt) <= 0 || !psy->desc->set_property) + struct power_supply_ext_registration *reg; + + if (atomic_read(&psy->use_cnt) <= 0) + return -ENODEV; + + power_supply_for_each_extension(reg, psy) { + if (power_supply_ext_has_property(reg->ext, psp)) { + if (reg->ext->set_property) + return reg->ext->set_property(psy, reg->ext, reg->data, psp, val); + else + return -ENODEV; + } + } + + if (!psy->desc->set_property) return -ENODEV; return psy->desc->set_property(psy, psp, val); @@ -1244,8 +1290,21 @@ EXPORT_SYMBOL_GPL(power_supply_set_property); int power_supply_property_is_writeable(struct power_supply *psy, enum power_supply_property psp) { - if (atomic_read(&psy->use_cnt) <= 0 || - !psy->desc->property_is_writeable) + struct power_supply_ext_registration *reg; + + if (atomic_read(&psy->use_cnt) <= 0) + return -ENODEV; + + power_supply_for_each_extension(reg, psy) { + if (power_supply_ext_has_property(reg->ext, psp)) { + if (reg->ext->property_is_writeable) + return reg->ext->property_is_writeable(psy, reg->ext, reg->data, psp); + else + return -ENODEV; + } + } + + if (!psy->desc->property_is_writeable) return -ENODEV; return psy->desc->property_is_writeable(psy, psp); @@ -1268,6 +1327,54 @@ int power_supply_powers(struct power_supply *psy, struct device *dev) } EXPORT_SYMBOL_GPL(power_supply_powers); +static int power_supply_update_groups(struct power_supply *psy) +{ + int ret; + + ret = sysfs_update_groups(&psy->dev.kobj, power_supply_dev_type.groups); + power_supply_changed(psy); + return ret; +} + +int power_supply_register_extension(struct power_supply *psy, const struct power_supply_ext *ext, + void *ext_data) +{ + struct power_supply_ext_registration *reg; + size_t i; + + for (i = 0; i < ext->num_properties; i++) { + if (power_supply_has_property(psy, ext->properties[i])) + return -EEXIST; + } + + reg = kmalloc(sizeof(*reg), GFP_KERNEL); + if (!reg) + return -ENOMEM; + + reg->ext = ext; + list_add(®->list_head, &psy->extensions); + + return power_supply_update_groups(psy); +} +EXPORT_SYMBOL_GPL(power_supply_register_extension); + +void power_supply_unregister_extension(struct power_supply *psy, const struct power_supply_ext *ext) +{ + struct power_supply_ext_registration *reg; + + power_supply_for_each_extension(reg, psy) { + if (reg->ext == ext) { + list_del(®->list_head); + kfree(reg); + power_supply_update_groups(psy); + return; + } + } + + dev_warn(&psy->dev, "Trying to unregister invalid extension"); +} +EXPORT_SYMBOL_GPL(power_supply_unregister_extension); + static void power_supply_dev_release(struct device *dev) { struct power_supply *psy = to_power_supply(dev); @@ -1427,6 +1534,7 @@ __power_supply_register(struct device *parent, } spin_lock_init(&psy->changed_lock); + INIT_LIST_HEAD(&psy->extensions); rc = device_add(dev); if (rc) goto device_add_failed; diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c index 915a4ba62258..e7c306afd846 100644 --- a/drivers/power/supply/power_supply_sysfs.c +++ b/drivers/power/supply/power_supply_sysfs.c @@ -271,6 +271,23 @@ static ssize_t power_supply_show_usb_type(struct device *dev, return count; } +static ssize_t power_supply_show_charge_behaviour(struct device *dev, + struct power_supply *psy, + union power_supply_propval *value, + char *buf) +{ + struct power_supply_ext_registration *reg; + + power_supply_for_each_extension(reg, psy) { + if (power_supply_ext_has_property(reg->ext, POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR)) + return power_supply_charge_behaviour_show(dev, reg->ext->charge_behaviours, + value->intval, buf); + } + + return power_supply_charge_behaviour_show(dev, psy->desc->charge_behaviours, + value->intval, buf); +} + static ssize_t power_supply_show_property(struct device *dev, struct device_attribute *attr, char *buf) { @@ -306,8 +323,7 @@ static ssize_t power_supply_show_property(struct device *dev, &value, buf); break; case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: - ret = power_supply_charge_behaviour_show(dev, psy->desc->charge_behaviours, - value.intval, buf); + ret = power_supply_show_charge_behaviour(dev, psy, &value, buf); break; case POWER_SUPPLY_PROP_MODEL_NAME ... POWER_SUPPLY_PROP_SERIAL_NUMBER: ret = sysfs_emit(buf, "%s\n", value.strval); diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index 72dc7e45c90c..51788faf1d66 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -280,6 +281,28 @@ struct power_supply_desc { int use_for_apm; }; +struct power_supply_ext { + u8 charge_behaviours; + const enum power_supply_property *properties; + size_t num_properties; + + int (*get_property)(struct power_supply *psy, + const struct power_supply_ext *ext, + void *ext_data, + enum power_supply_property psp, + union power_supply_propval *val); + int (*set_property)(struct power_supply *psy, + const struct power_supply_ext *ext, + void *ext_data, + enum power_supply_property psp, + const union power_supply_propval *val); + + int (*property_is_writeable)(struct power_supply *psy, + const struct power_supply_ext *ext, + void *ext_data, + enum power_supply_property psp); +}; + struct power_supply { const struct power_supply_desc *desc; @@ -303,6 +326,7 @@ struct power_supply { bool removing; atomic_t use_cnt; struct power_supply_battery_info *battery_info; + struct list_head extensions; #ifdef CONFIG_THERMAL struct thermal_zone_device *tzd; struct thermal_cooling_device *tcd; @@ -887,6 +911,12 @@ devm_power_supply_register_no_ws(struct device *parent, extern void power_supply_unregister(struct power_supply *psy); extern int power_supply_powers(struct power_supply *psy, struct device *dev); +extern int power_supply_register_extension(struct power_supply *psy, + const struct power_supply_ext *ext, + void *ext_data); +extern void power_supply_unregister_extension(struct power_supply *psy, + const struct power_supply_ext *ext); + #define to_power_supply(device) container_of(device, struct power_supply, dev) extern void *power_supply_get_drvdata(struct power_supply *psy); From patchwork Wed Sep 4 19:25:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 13791297 Received: from todd.t-8ch.de (todd.t-8ch.de [159.69.126.157]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D46AB1E7670; Wed, 4 Sep 2024 19:25:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=159.69.126.157 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725477957; cv=none; b=E1cnGIZJEtEPIqDZrqhw2cdmBOmwJXcrM63Y7asOkdV2J4BAxm0lupLIePvzDrgkLJDYW7GQuXIOEOLynnHKe2ARdY/SD/T/wNLdd+ccmTYI69pNMGcBmtOx/dQUvSW2z5Q8+u0NAobpRbNWISOqOGwn7C3WC1swcyE0BUuIvYs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725477957; c=relaxed/simple; bh=tHNlvPi7yYkH3oqJ16GU7YD6XTS+KrMh5eA+TUOzR88=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SD0kWXFF/p4Y3ELjtNSu3TXKcMOkdiM47yFifx97e9b4Mej0dL7csvbB12Er4PoyehbG0Ny6avOTw8O+cJ3/3utaextJWetDKp5RMi4kpHPw6XxP2RMrohOAEuR8arasoDhEwyVoyg8Yi7Ra74netpm5PRBXUa1TYYuU9nSJH/k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net; spf=pass smtp.mailfrom=weissschuh.net; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b=Pj3MBOzu; arc=none smtp.client-ip=159.69.126.157 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b="Pj3MBOzu" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1725477950; bh=tHNlvPi7yYkH3oqJ16GU7YD6XTS+KrMh5eA+TUOzR88=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Pj3MBOzuo2ikhtaUw4vyhPT+lkvtmaMpO0lB3wnTK8umsHiNPoVeFcj2WQd/wql6X anAylPIoWhst/TlKjhKb2ckVSMc8FDjsupRfeeVmBg5MaxqadkgtFdponPVUQ7QMVq +ZGzK0yHYv+H5lUisgSDsq2nFXgLzoNuGXikRyvQ= From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= Date: Wed, 04 Sep 2024 21:25:40 +0200 Subject: [PATCH RFC v3 7/9] power: supply: core: add locking around extension access Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240904-power-supply-extensions-v3-7-62efeb93f8ec@weissschuh.net> References: <20240904-power-supply-extensions-v3-0-62efeb93f8ec@weissschuh.net> In-Reply-To: <20240904-power-supply-extensions-v3-0-62efeb93f8ec@weissschuh.net> To: Sebastian Reichel , Armin Wolf , Hans de Goede Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?Thomas?= =?utf-8?q?_Wei=C3=9Fschuh?= X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1725477949; l=8384; i=linux@weissschuh.net; s=20221212; h=from:subject:message-id; bh=tHNlvPi7yYkH3oqJ16GU7YD6XTS+KrMh5eA+TUOzR88=; b=RME6lvjAeSoiHtkEuYGRp7ZyQerwE/vV7TLS0ZK8zb93CocCJfBZE4I2QiEbelK5AzREzIZs6 I0/FrTEuyEFDASazlCi+uKyBMxECqxZu8EW5CRRjamcOAdV1xnxr4m0 X-Developer-Key: i=linux@weissschuh.net; a=ed25519; pk=KcycQgFPX2wGR5azS7RhpBqedglOZVgRPfdFSPB1LNw= Signed-off-by: Thomas Weißschuh --- This is only separate for easier review during the RFC phase. It will be squashed into the actual power supply extension commit later. --- drivers/power/supply/power_supply.h | 3 ++ drivers/power/supply/power_supply_core.c | 49 ++++++++++++++++++++++++++----- drivers/power/supply/power_supply_leds.c | 2 ++ drivers/power/supply/power_supply_sysfs.c | 6 ++++ include/linux/power_supply.h | 3 ++ 5 files changed, 55 insertions(+), 8 deletions(-) diff --git a/drivers/power/supply/power_supply.h b/drivers/power/supply/power_supply.h index fb45f0717bd1..b8e14cc70fcf 100644 --- a/drivers/power/supply/power_supply.h +++ b/drivers/power/supply/power_supply.h @@ -9,6 +9,8 @@ * Modified: 2004, Oct Szabolcs Gyurko */ +#include + struct device; struct device_type; struct power_supply; @@ -25,6 +27,7 @@ struct power_supply_ext_registration { }; #define power_supply_for_each_extension(pos, psy) \ + lockdep_assert_held(&(psy)->extensions_sem); \ list_for_each_entry(pos, &(psy)->extensions, list_head) diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c index db5e7af57e67..4839be25e6be 100644 --- a/drivers/power/supply/power_supply_core.c +++ b/drivers/power/supply/power_supply_core.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -80,6 +81,7 @@ static int __power_supply_changed_work(struct device *dev, void *data) static void power_supply_changed_work(struct work_struct *work) { + int ret; unsigned long flags; struct power_supply *psy = container_of(work, struct power_supply, changed_work); @@ -87,6 +89,16 @@ static void power_supply_changed_work(struct work_struct *work) dev_dbg(&psy->dev, "%s\n", __func__); spin_lock_irqsave(&psy->changed_lock, flags); + + if (unlikely(psy->update_groups)) { + psy->update_groups = false; + spin_unlock_irqrestore(&psy->changed_lock, flags); + ret = sysfs_update_groups(&psy->dev.kobj, power_supply_dev_type.groups); + if (ret) + dev_warn(&psy->dev, "failed to update sysfs groups: %pe\n", ERR_PTR(ret)); + spin_lock_irqsave(&psy->changed_lock, flags); + } + /* * Check 'changed' here to avoid issues due to race between * power_supply_changed() and this routine. In worst case @@ -1218,17 +1230,26 @@ bool power_supply_ext_has_property(const struct power_supply_ext *psy_ext, return found; } -bool power_supply_has_property(struct power_supply *psy, - enum power_supply_property psp) +static bool psy_has_property_no_ext(struct power_supply *psy, + enum power_supply_property psp) { - struct power_supply_ext_registration *reg; - if (psy_desc_has_property(psy->desc, psp)) return true; if (power_supply_battery_info_has_prop(psy->battery_info, psp)) return true; + return false; +} + +bool power_supply_has_property(struct power_supply *psy, + enum power_supply_property psp) +{ + struct power_supply_ext_registration *reg; + + if (psy_has_property_no_ext(psy, psp)) + return true; + power_supply_for_each_extension(reg, psy) if (power_supply_ext_has_property(reg->ext, psp)) return true; @@ -1329,11 +1350,14 @@ EXPORT_SYMBOL_GPL(power_supply_powers); static int power_supply_update_groups(struct power_supply *psy) { - int ret; + unsigned long flags; + + spin_lock_irqsave(&psy->changed_lock, flags); + psy->update_groups = true; + spin_unlock_irqrestore(&psy->changed_lock, flags); - ret = sysfs_update_groups(&psy->dev.kobj, power_supply_dev_type.groups); power_supply_changed(psy); - return ret; + return 0; } int power_supply_register_extension(struct power_supply *psy, const struct power_supply_ext *ext, @@ -1342,6 +1366,8 @@ int power_supply_register_extension(struct power_supply *psy, const struct power struct power_supply_ext_registration *reg; size_t i; + guard(rwsem_write)(&psy->extensions_sem); + for (i = 0; i < ext->num_properties; i++) { if (power_supply_has_property(psy, ext->properties[i])) return -EEXIST; @@ -1362,6 +1388,8 @@ void power_supply_unregister_extension(struct power_supply *psy, const struct po { struct power_supply_ext_registration *reg; + guard(rwsem_write)(&psy->extensions_sem); + power_supply_for_each_extension(reg, psy) { if (reg->ext == ext) { list_del(®->list_head); @@ -1405,6 +1433,7 @@ static int power_supply_read_temp(struct thermal_zone_device *tzd, WARN_ON(tzd == NULL); psy = thermal_zone_device_priv(tzd); + guard(rwsem_read)(&psy->extensions_sem); ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_TEMP, &val); if (ret) return ret; @@ -1427,7 +1456,7 @@ static int psy_register_thermal(struct power_supply *psy) return 0; /* Register battery zone device psy reports temperature */ - if (power_supply_has_property(psy, POWER_SUPPLY_PROP_TEMP)) { + if (psy_has_property_no_ext(psy, POWER_SUPPLY_PROP_TEMP)) { /* Prefer our hwmon device and avoid duplicates */ struct thermal_zone_params tzp = { .no_hwmon = IS_ENABLED(CONFIG_POWER_SUPPLY_HWMON) @@ -1534,7 +1563,9 @@ __power_supply_register(struct device *parent, } spin_lock_init(&psy->changed_lock); + init_rwsem(&psy->extensions_sem); INIT_LIST_HEAD(&psy->extensions); + rc = device_add(dev); if (rc) goto device_add_failed; @@ -1547,6 +1578,8 @@ __power_supply_register(struct device *parent, if (rc) goto register_thermal_failed; + guard(rwsem_read)(&psy->extensions_sem); + rc = power_supply_create_triggers(psy); if (rc) goto create_triggers_failed; diff --git a/drivers/power/supply/power_supply_leds.c b/drivers/power/supply/power_supply_leds.c index f4a7e566bea1..09a6f3fe2f85 100644 --- a/drivers/power/supply/power_supply_leds.c +++ b/drivers/power/supply/power_supply_leds.c @@ -195,6 +195,8 @@ static void power_supply_remove_gen_triggers(struct power_supply *psy) void power_supply_update_leds(struct power_supply *psy) { + guard(rwsem_read)(&psy->extensions_sem); + if (psy->desc->type == POWER_SUPPLY_TYPE_BATTERY) power_supply_update_bat_leds(psy); else diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c index e7c306afd846..b56e0bd424f5 100644 --- a/drivers/power/supply/power_supply_sysfs.c +++ b/drivers/power/supply/power_supply_sysfs.c @@ -371,6 +371,8 @@ static ssize_t power_supply_store_property(struct device *dev, value.intval = ret; + guard(rwsem_read)(&psy->extensions_sem); + ret = power_supply_set_property(psy, psp, &value); if (ret < 0) return ret; @@ -392,6 +394,8 @@ static umode_t power_supply_attr_is_visible(struct kobject *kobj, if (attrno == POWER_SUPPLY_PROP_TYPE) return mode; + guard(rwsem_read)(&psy->extensions_sem); + if (power_supply_has_property(psy, attrno)) { if (power_supply_property_is_writeable(psy, attrno) > 0) mode |= S_IWUSR; @@ -497,6 +501,8 @@ int power_supply_uevent(const struct device *dev, struct kobj_uevent_env *env) if (ret) goto out; + guard(rwsem_read)(&psy->extensions_sem); + for (j = 0; j < POWER_SUPPLY_ATTR_CNT; j++) { ret = add_prop_uevent(dev, env, j, prop_buf); if (ret) diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index 51788faf1d66..87bc50698649 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -322,10 +323,12 @@ struct power_supply { struct delayed_work deferred_register_work; spinlock_t changed_lock; bool changed; + bool update_groups; bool initialized; bool removing; atomic_t use_cnt; struct power_supply_battery_info *battery_info; + struct rw_semaphore extensions_sem; /* protects "extensions" */ struct list_head extensions; #ifdef CONFIG_THERMAL struct thermal_zone_device *tzd; From patchwork Wed Sep 4 19:25:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 13791295 Received: from todd.t-8ch.de (todd.t-8ch.de [159.69.126.157]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B12201E7667; Wed, 4 Sep 2024 19:25:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=159.69.126.157 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725477957; cv=none; b=gIhi/u9QnyFnatrcgi6SvC/W9fiEtBRC3Cbmpg4tliTZcGVGuqckAJH1u0c6qFABnOXek/HHFp/SSpfAaOTahygmZLr3v0yqVCxieZ7sougpNGvC6pKsc9I0mc/fC+QpmB+Vd8PvsuSIS9ZB40XquuahCWt5xS/85Y6s2/gREIQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725477957; c=relaxed/simple; bh=5TiKBhsjhzC0/B94FnqYYVIpVnznuh8peUoRjUu3cuk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZiUyHpfiZcLAZh3I2r9LJsYzaOAsJ7TYyE4XlLWtSdyd3SCNIk+b/LQ4TLYdPYlgxNYdhXraNbLk6ecUr0aKyU/0BT9K46KEXE10MObPMu2io1H1AvLh+q+ETGh2ob4CjDOc1vH55BlwM3xH+znPZG4ZI3NmQVL64NS4vJASwXI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net; spf=pass smtp.mailfrom=weissschuh.net; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b=IdJjnJRE; arc=none smtp.client-ip=159.69.126.157 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b="IdJjnJRE" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1725477950; bh=5TiKBhsjhzC0/B94FnqYYVIpVnznuh8peUoRjUu3cuk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=IdJjnJREtLBNrKt6IMP+Z3UPZslWAr1423bZYMuL1iPaqv0H5kl0tssDtF7rgQaSd HDrqFm14vqhy2Q6c//rLmvAAsfWzAugz5nZ/mBjbmIF8JQUGcApK10jAQVS+EOBpud Uj25r5e+rRH/YPerI4ROPsQx0YtpPVPkLTRsVqU4= From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= Date: Wed, 04 Sep 2024 21:25:41 +0200 Subject: [PATCH RFC v3 8/9] power: supply: test-power: implement a power supply extension Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240904-power-supply-extensions-v3-8-62efeb93f8ec@weissschuh.net> References: <20240904-power-supply-extensions-v3-0-62efeb93f8ec@weissschuh.net> In-Reply-To: <20240904-power-supply-extensions-v3-0-62efeb93f8ec@weissschuh.net> To: Sebastian Reichel , Armin Wolf , Hans de Goede Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?Thomas?= =?utf-8?q?_Wei=C3=9Fschuh?= X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1725477949; l=5156; i=linux@weissschuh.net; s=20221212; h=from:subject:message-id; bh=5TiKBhsjhzC0/B94FnqYYVIpVnznuh8peUoRjUu3cuk=; b=+GXNrQ6DpEHK4GVGMCXqumorgIcBqxu9e6V6ElLwAMpz/FU3K3VT2ug8rqYUNyNJ6yaEW4T5V BdXLcZ61Rq9DSfYL9zAGjLD8bdZmQnvufdDjScJ8LYIE/sA6IiwTB81 X-Developer-Key: i=linux@weissschuh.net; a=ed25519; pk=KcycQgFPX2wGR5azS7RhpBqedglOZVgRPfdFSPB1LNw= Allow easy testing of the new power supply extension functionality. Signed-off-by: Thomas Weißschuh --- drivers/power/supply/test_power.c | 104 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/drivers/power/supply/test_power.c b/drivers/power/supply/test_power.c index 442ceb7795e1..da1877f31929 100644 --- a/drivers/power/supply/test_power.c +++ b/drivers/power/supply/test_power.c @@ -37,6 +37,7 @@ static int battery_charge_counter = -1000; static int battery_current = -1600; static enum power_supply_charge_behaviour battery_charge_behaviour = POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO; +static bool battery_hook; static bool module_initialized; @@ -238,6 +239,82 @@ static const struct power_supply_config test_power_configs[] = { }, }; +static int power_supply_ext_manufacture_year = 1234; +static const enum power_supply_property power_supply_ext_props[] = { + POWER_SUPPLY_PROP_MANUFACTURE_YEAR, +}; + +static int power_supply_ext_get_property(struct power_supply *psy, + const struct power_supply_ext *ext, + void *ext_data, + enum power_supply_property psp, + union power_supply_propval *val) +{ + switch (psp) { + case POWER_SUPPLY_PROP_MANUFACTURE_YEAR: + val->intval = power_supply_ext_manufacture_year; + break; + default: + pr_info("%s: some properties deliberately report errors.\n", + __func__); + return -EINVAL; + } + return 0; +} + +static int power_supply_ext_set_property(struct power_supply *psy, + const struct power_supply_ext *ext, + void *ext_data, + enum power_supply_property psp, + const union power_supply_propval *val) +{ + switch (psp) { + case POWER_SUPPLY_PROP_MANUFACTURE_YEAR: + power_supply_ext_manufacture_year = val->intval; + break; + default: + return -EINVAL; + } + return 0; +} + +static int power_supply_ext_property_is_writeable(struct power_supply *psy, + const struct power_supply_ext *ext, + void *ext_data, + enum power_supply_property psp) +{ + return true; +} + +static const struct power_supply_ext power_supply_ext = { + .properties = power_supply_ext_props, + .num_properties = ARRAY_SIZE(power_supply_ext_props), + .get_property = power_supply_ext_get_property, + .set_property = power_supply_ext_set_property, + .property_is_writeable = power_supply_ext_property_is_writeable, +}; + +static void test_battery_configure_battery_hook(bool enable) +{ + struct power_supply *psy; + + if (battery_hook == enable) + return; + + psy = test_power_supplies[TEST_BATTERY]; + + if (enable) { + if (power_supply_register_extension(psy, &power_supply_ext, NULL)) { + pr_err("registering battery extension failed\n"); + return; + } + } else { + power_supply_unregister_extension(psy, &power_supply_ext); + } + + battery_hook = enable; +} + static int __init test_power_init(void) { int i; @@ -258,6 +335,8 @@ static int __init test_power_init(void) } } + test_battery_configure_battery_hook(true); + module_initialized = true; return 0; failed: @@ -524,6 +603,22 @@ static int param_set_battery_current(const char *key, #define param_get_battery_current param_get_int +static int param_set_battery_hook(const char *key, + const struct kernel_param *kp) +{ + int tmp; + + if (1 != sscanf(key, "%d", &tmp)) + return -EINVAL; + if (tmp != 1 && tmp != 0) + return -EINVAL; + + test_battery_configure_battery_hook(tmp); + return 0; +} + +#define param_get_battery_hook param_get_int + static const struct kernel_param_ops param_ops_ac_online = { .set = param_set_ac_online, .get = param_get_ac_online, @@ -574,6 +669,11 @@ static const struct kernel_param_ops param_ops_battery_current = { .get = param_get_battery_current, }; +static const struct kernel_param_ops param_ops_battery_hook = { + .set = param_set_battery_hook, + .get = param_get_battery_hook, +}; + #define param_check_ac_online(name, p) __param_check(name, p, void); #define param_check_usb_online(name, p) __param_check(name, p, void); #define param_check_battery_status(name, p) __param_check(name, p, void); @@ -584,6 +684,7 @@ static const struct kernel_param_ops param_ops_battery_current = { #define param_check_battery_voltage(name, p) __param_check(name, p, void); #define param_check_battery_charge_counter(name, p) __param_check(name, p, void); #define param_check_battery_current(name, p) __param_check(name, p, void); +#define param_check_battery_hook(name, p) __param_check(name, p, void); module_param(ac_online, ac_online, 0644); @@ -621,6 +722,9 @@ MODULE_PARM_DESC(battery_charge_counter, module_param(battery_current, battery_current, 0644); MODULE_PARM_DESC(battery_current, "battery current (milliampere)"); +module_param(battery_hook, battery_hook, 0644); +MODULE_PARM_DESC(battery_hook, "battery hook"); + MODULE_DESCRIPTION("Power supply driver for testing"); MODULE_AUTHOR("Anton Vorontsov "); MODULE_LICENSE("GPL"); From patchwork Wed Sep 4 19:25:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 13791298 Received: from todd.t-8ch.de (todd.t-8ch.de [159.69.126.157]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D42301E766F; Wed, 4 Sep 2024 19:25:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=159.69.126.157 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725477958; cv=none; b=RIZfBWMEzW0mJAkCBl10Hh1sm5U0hj6k5pc+7L+ldbMhnHx+sTWvau1YqdzpauG6svF6RCqpNMyI42/zjJ5Hg7E3tIKSg6Y5knWnLCDw3Gt8063urjc9o/voQL7YkWi+bSPMyzfUihPPniWhMW9yVJIYC11uA7B61xaYypX0G34= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725477958; c=relaxed/simple; bh=I85wCUmCzAyQhRIqum8155x0h1PMiQC3CXIyjhbPiJ0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=paLTYwW6l0FA2lvgFxAkoMJQmb+XWHEV0Phdf6hODbFUJRQDJ0VSC8cLzmwXsFZ8SWbi4Tcj6RtnLrSeRzozeqOAy1iuFrzuHhwgdj9ztLfmYboK6UbRhd6AEXjb+ZltJfMwz7ha9ppeE27CZKj4EweoCDOUyZKOgFHyQlgIYD8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net; spf=pass smtp.mailfrom=weissschuh.net; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b=sz9VChhl; arc=none smtp.client-ip=159.69.126.157 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b="sz9VChhl" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1725477950; bh=I85wCUmCzAyQhRIqum8155x0h1PMiQC3CXIyjhbPiJ0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=sz9VChhlx6qVOF15zII4e53JOGDau/HSlbADRZS83apgOvxfdV5ap/x63S1/yUBFg l+XV6Ta8hiYlPNPs6qQYsdZNIvCyz6VMbAlKYOvWYPoE+Cd75iVN1huCL/tSn6gABQ SRKq3V5fV5SNJgjZeYEGbazj4ClqoE3c/KiE+lBg= From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= Date: Wed, 04 Sep 2024 21:25:42 +0200 Subject: [PATCH RFC v3 9/9] power: supply: cros_charge-control: use power_supply extensions Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240904-power-supply-extensions-v3-9-62efeb93f8ec@weissschuh.net> References: <20240904-power-supply-extensions-v3-0-62efeb93f8ec@weissschuh.net> In-Reply-To: <20240904-power-supply-extensions-v3-0-62efeb93f8ec@weissschuh.net> To: Sebastian Reichel , Armin Wolf , Hans de Goede Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?Thomas?= =?utf-8?q?_Wei=C3=9Fschuh?= X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1725477949; l=10831; i=linux@weissschuh.net; s=20221212; h=from:subject:message-id; bh=I85wCUmCzAyQhRIqum8155x0h1PMiQC3CXIyjhbPiJ0=; b=1JkghiKquNkJ5fqd5PBa1fM0w7b/XqGuuzQNcj7TdMkmJw5BRkFSITensasnFAAFLSQ80sC/x 5DKM7ASy8+hB8/BudeecqME+JkGGEQdh8Z/MoxlxdK14vmkiUIyQfuK X-Developer-Key: i=linux@weissschuh.net; a=ed25519; pk=KcycQgFPX2wGR5azS7RhpBqedglOZVgRPfdFSPB1LNw= Power supply extensions provide an easier mechanism to implement additional properties for existing power supplies. Use that instead of reimplementing the sysfs attributes manually. Signed-off-by: Thomas Weißschuh --- drivers/power/supply/cros_charge-control.c | 207 +++++++++++------------------ 1 file changed, 78 insertions(+), 129 deletions(-) diff --git a/drivers/power/supply/cros_charge-control.c b/drivers/power/supply/cros_charge-control.c index 17c53591ce19..dbfd87f8eb1d 100644 --- a/drivers/power/supply/cros_charge-control.c +++ b/drivers/power/supply/cros_charge-control.c @@ -18,13 +18,6 @@ BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE) | \ BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE)) -enum CROS_CHCTL_ATTR { - CROS_CHCTL_ATTR_START_THRESHOLD, - CROS_CHCTL_ATTR_END_THRESHOLD, - CROS_CHCTL_ATTR_CHARGE_BEHAVIOUR, - _CROS_CHCTL_ATTR_COUNT -}; - /* * Semantics of data *returned* from the EC API and Linux sysfs differ * slightly, also the v1 API can not return any data. @@ -41,13 +34,7 @@ struct cros_chctl_priv { struct power_supply *hooked_battery; u8 cmd_version; - /* The callbacks need to access this priv structure. - * As neither the struct device nor power_supply are under the drivers - * control, embed the attributes within priv to use with container_of(). - */ - struct device_attribute device_attrs[_CROS_CHCTL_ATTR_COUNT]; - struct attribute *attributes[_CROS_CHCTL_ATTR_COUNT]; - struct attribute_group group; + struct power_supply_ext psy_ext; enum power_supply_charge_behaviour current_behaviour; u8 current_start_threshold, current_end_threshold; @@ -114,123 +101,86 @@ static int cros_chctl_configure_ec(struct cros_chctl_priv *priv) return cros_chctl_send_charge_control_cmd(priv->cros_ec, priv->cmd_version, &req); } -static struct cros_chctl_priv *cros_chctl_attr_to_priv(struct attribute *attr, - enum CROS_CHCTL_ATTR idx) -{ - struct device_attribute *dev_attr = container_of(attr, struct device_attribute, attr); +static const enum power_supply_property cros_chctl_psy_ext_props[] = { + POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD, + POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD, + POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR, +}; - return container_of(dev_attr, struct cros_chctl_priv, device_attrs[idx]); -} +static const enum power_supply_property cros_chctl_psy_ext_props_v1[] = { + POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR, +}; -static ssize_t cros_chctl_store_threshold(struct device *dev, struct cros_chctl_priv *priv, - int is_end_threshold, const char *buf, size_t count) +static int cros_chctl_psy_ext_get_prop(struct power_supply *psy, + const struct power_supply_ext *ext, + void *data, + enum power_supply_property psp, + union power_supply_propval *val) { - int ret, val; + struct cros_chctl_priv *priv = data; - ret = kstrtoint(buf, 10, &val); - if (ret < 0) - return ret; - if (val < 0 || val > 100) + switch (psp) { + case POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD: + val->intval = priv->current_start_threshold; + return 0; + case POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD: + val->intval = priv->current_end_threshold; + return 0; + case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: + val->intval = priv->current_behaviour; + return 0; + default: return -EINVAL; - - if (is_end_threshold) { - if (val <= priv->current_start_threshold) - return -EINVAL; - priv->current_end_threshold = val; - } else { - if (val >= priv->current_end_threshold) - return -EINVAL; - priv->current_start_threshold = val; - } - - if (priv->current_behaviour == POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO) { - ret = cros_chctl_configure_ec(priv); - if (ret < 0) - return ret; } - - return count; -} - -static ssize_t charge_control_start_threshold_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct cros_chctl_priv *priv = cros_chctl_attr_to_priv(&attr->attr, - CROS_CHCTL_ATTR_START_THRESHOLD); - - return sysfs_emit(buf, "%u\n", (unsigned int)priv->current_start_threshold); -} - -static ssize_t charge_control_start_threshold_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct cros_chctl_priv *priv = cros_chctl_attr_to_priv(&attr->attr, - CROS_CHCTL_ATTR_START_THRESHOLD); - - return cros_chctl_store_threshold(dev, priv, 0, buf, count); -} - -static ssize_t charge_control_end_threshold_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct cros_chctl_priv *priv = cros_chctl_attr_to_priv(&attr->attr, - CROS_CHCTL_ATTR_END_THRESHOLD); - - return sysfs_emit(buf, "%u\n", (unsigned int)priv->current_end_threshold); -} - -static ssize_t charge_control_end_threshold_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct cros_chctl_priv *priv = cros_chctl_attr_to_priv(&attr->attr, - CROS_CHCTL_ATTR_END_THRESHOLD); - - return cros_chctl_store_threshold(dev, priv, 1, buf, count); } -static ssize_t charge_behaviour_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct cros_chctl_priv *priv = cros_chctl_attr_to_priv(&attr->attr, - CROS_CHCTL_ATTR_CHARGE_BEHAVIOUR); - - return power_supply_charge_behaviour_show(dev, EC_CHARGE_CONTROL_BEHAVIOURS, - priv->current_behaviour, buf); -} -static ssize_t charge_behaviour_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static int cros_chctl_psy_ext_set_prop(struct power_supply *psy, + const struct power_supply_ext *ext, + void *data, + enum power_supply_property psp, + const union power_supply_propval *val) { - struct cros_chctl_priv *priv = cros_chctl_attr_to_priv(&attr->attr, - CROS_CHCTL_ATTR_CHARGE_BEHAVIOUR); + struct cros_chctl_priv *priv = data; int ret; - ret = power_supply_charge_behaviour_parse(EC_CHARGE_CONTROL_BEHAVIOURS, buf); - if (ret < 0) - return ret; - - priv->current_behaviour = ret; + switch (psp) { + case POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD: + case POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD: + if (val->intval < 0 || val->intval > 100) + return -EINVAL; - ret = cros_chctl_configure_ec(priv); - if (ret < 0) - return ret; + if (psp == POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD) { + if (val->intval <= priv->current_start_threshold) + return -EINVAL; + priv->current_end_threshold = val->intval; + } else { + if (val->intval >= priv->current_end_threshold) + return -EINVAL; + priv->current_start_threshold = val->intval; + } + + if (priv->current_behaviour == POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO) { + ret = cros_chctl_configure_ec(priv); + if (ret < 0) + return ret; + } - return count; + return 0; + case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: + priv->current_behaviour = val->intval; + return cros_chctl_configure_ec(priv); /* FIXME > 0 */ + default: + return -EINVAL; + } } -static umode_t cros_chtl_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n) +static int cros_chctl_psy_prop_is_writeable(struct power_supply *psy, + const struct power_supply_ext *ext, + void *data, + enum power_supply_property psp) { - struct cros_chctl_priv *priv = cros_chctl_attr_to_priv(attr, n); - - if (priv->cmd_version < 2) { - if (n == CROS_CHCTL_ATTR_START_THRESHOLD) - return 0; - if (n == CROS_CHCTL_ATTR_END_THRESHOLD) - return 0; - } - - return attr->mode; + return true; } static int cros_chctl_add_battery(struct power_supply *battery, struct acpi_battery_hook *hook) @@ -241,7 +191,7 @@ static int cros_chctl_add_battery(struct power_supply *battery, struct acpi_batt return 0; priv->hooked_battery = battery; - return device_add_group(&battery->dev, &priv->group); + return power_supply_register_extension(battery, &priv->psy_ext, priv); } static int cros_chctl_remove_battery(struct power_supply *battery, struct acpi_battery_hook *hook) @@ -249,7 +199,7 @@ static int cros_chctl_remove_battery(struct power_supply *battery, struct acpi_b struct cros_chctl_priv *priv = container_of(hook, struct cros_chctl_priv, battery_hook); if (priv->hooked_battery == battery) { - device_remove_group(&battery->dev, &priv->group); + power_supply_unregister_extension(battery, &priv->psy_ext); priv->hooked_battery = NULL; } @@ -275,7 +225,6 @@ static int cros_chctl_probe(struct platform_device *pdev) struct cros_ec_dev *ec_dev = dev_get_drvdata(dev->parent); struct cros_ec_device *cros_ec = ec_dev->ec_dev; struct cros_chctl_priv *priv; - size_t i; int ret; ret = cros_chctl_fwk_charge_control_versions(cros_ec); @@ -305,23 +254,23 @@ static int cros_chctl_probe(struct platform_device *pdev) dev_dbg(dev, "Command version: %u\n", (unsigned int)priv->cmd_version); priv->cros_ec = cros_ec; - priv->device_attrs[CROS_CHCTL_ATTR_START_THRESHOLD] = - (struct device_attribute)__ATTR_RW(charge_control_start_threshold); - priv->device_attrs[CROS_CHCTL_ATTR_END_THRESHOLD] = - (struct device_attribute)__ATTR_RW(charge_control_end_threshold); - priv->device_attrs[CROS_CHCTL_ATTR_CHARGE_BEHAVIOUR] = - (struct device_attribute)__ATTR_RW(charge_behaviour); - for (i = 0; i < _CROS_CHCTL_ATTR_COUNT; i++) { - sysfs_attr_init(&priv->device_attrs[i].attr); - priv->attributes[i] = &priv->device_attrs[i].attr; - } - priv->group.is_visible = cros_chtl_attr_is_visible; - priv->group.attrs = priv->attributes; priv->battery_hook.name = dev_name(dev); priv->battery_hook.add_battery = cros_chctl_add_battery; priv->battery_hook.remove_battery = cros_chctl_remove_battery; + if (priv->cmd_version == 1) { + priv->psy_ext.properties = cros_chctl_psy_ext_props_v1; + priv->psy_ext.num_properties = ARRAY_SIZE(cros_chctl_psy_ext_props_v1); + } else { + priv->psy_ext.properties = cros_chctl_psy_ext_props; + priv->psy_ext.num_properties = ARRAY_SIZE(cros_chctl_psy_ext_props); + } + priv->psy_ext.charge_behaviours = EC_CHARGE_CONTROL_BEHAVIOURS; + priv->psy_ext.get_property = cros_chctl_psy_ext_get_prop; + priv->psy_ext.set_property = cros_chctl_psy_ext_set_prop; + priv->psy_ext.property_is_writeable = cros_chctl_psy_prop_is_writeable; + priv->current_behaviour = POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO; priv->current_start_threshold = 0; priv->current_end_threshold = 100;