platform-driver-x86.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Armin Wolf <W_Armin@gmx.de>
To: hdegoede@redhat.com, markgross@kernel.org
Cc: rafael@kernel.org, lenb@kernel.org, hmh@hmh.eng.br,
	matan@svgalib.org, corentin.chary@gmail.com, jeremy@system76.com,
	productdev@system76.com, platform-driver-x86@vger.kernel.org,
	linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 3/5] ACPI: battery: Allow battery hooks to be registered multiple times.
Date: Mon, 12 Sep 2022 14:53:40 +0200	[thread overview]
Message-ID: <20220912125342.7395-4-W_Armin@gmx.de> (raw)
In-Reply-To: <20220912125342.7395-1-W_Armin@gmx.de>

Registering multiple instances of a battery hook is beneficial
for drivers which can be instantiated multiple times. Until now,
this would mean that such a driver would have to implement some
logic to manage battery hooks.

Extend the battery hook handling instead.

Signed-off-by: Armin Wolf <W_Armin@gmx.de>
---
 drivers/acpi/battery.c               | 21 ++++++++++++++++-----
 drivers/platform/x86/asus-wmi.c      | 15 ++++++---------
 drivers/platform/x86/huawei-wmi.c    | 11 +++++++----
 drivers/platform/x86/lg-laptop.c     | 10 ++++++----
 drivers/platform/x86/system76_acpi.c | 18 ++++++++++--------
 drivers/platform/x86/thinkpad_acpi.c | 11 +++++++----
 include/acpi/battery.h               | 11 ++++++++---
 7 files changed, 60 insertions(+), 37 deletions(-)

diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 4aea65f3d8c3..15bb5d868a56 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -696,19 +696,28 @@ void battery_hook_unregister(struct acpi_battery_hook *hook)
 	mutex_lock(&hook_mutex);

 	list_for_each_entry(battery, &acpi_battery_list, list) {
-		hook->remove_battery(battery->bat);
+		hook->ops->remove_battery(battery->bat);
 	}
 	list_del(&hook->list);

 	mutex_unlock(&hook_mutex);
 	pr_info("extension unregistered: %s\n", hook->name);
+	kfree(hook);
 }
 EXPORT_SYMBOL_GPL(battery_hook_unregister);

-void battery_hook_register(struct acpi_battery_hook *hook)
+struct acpi_battery_hook *battery_hook_register(const char *name,
+						const struct acpi_battery_hook_ops *ops)
 {
+	struct acpi_battery_hook *hook = kzalloc(sizeof(*hook), GFP_KERNEL);
 	struct acpi_battery *battery;

+	if (!hook)
+		return ERR_PTR(-ENOMEM);
+
+	hook->name = name;
+	hook->ops = ops;
+
 	mutex_lock(&hook_mutex);
 	INIT_LIST_HEAD(&hook->list);
 	list_add(&hook->list, &battery_hook_list);
@@ -719,11 +728,13 @@ void battery_hook_register(struct acpi_battery_hook *hook)
 	 * its attributes.
 	 */
 	list_for_each_entry(battery, &acpi_battery_list, list) {
-		hook->add_battery(battery->bat);
+		hook->ops->add_battery(battery->bat);
 	}
 	pr_info("new extension: %s\n", hook->name);

 	mutex_unlock(&hook_mutex);
+
+	return hook;
 }
 EXPORT_SYMBOL_GPL(battery_hook_register);

@@ -747,7 +758,7 @@ static void battery_hook_add_battery(struct acpi_battery *battery)
 	 * during the battery module initialization.
 	 */
 	list_for_each_entry_safe(hook_node, tmp, &battery_hook_list, list) {
-		hook_node->add_battery(battery->bat);
+		hook_node->ops->add_battery(battery->bat);
 	}
 	mutex_unlock(&hook_mutex);
 }
@@ -762,7 +773,7 @@ static void battery_hook_remove_battery(struct acpi_battery *battery)
 	 * custom attributes from the battery.
 	 */
 	list_for_each_entry(hook, &battery_hook_list, list) {
-		hook->remove_battery(battery->bat);
+		hook->ops->remove_battery(battery->bat);
 	}
 	/* Then, just remove the battery from the list */
 	list_del(&battery->list);
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index d95170b7dba0..37d8649418f4 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -252,8 +252,8 @@ struct asus_wmi {
 	struct platform_profile_handler platform_profile_handler;
 	bool platform_profile_support;

-	// The RSOC controls the maximum charging percentage.
-	bool battery_rsoc_available;
+	// The RSOC battery hook controls the maximum charging percentage.
+	struct acpi_battery_hook *hook;

 	bool panel_overdrive_available;

@@ -916,25 +916,22 @@ static int asus_wmi_battery_remove(struct power_supply *battery)
 	return 0;
 }

-static struct acpi_battery_hook battery_hook = {
+static const struct acpi_battery_hook_ops battery_hook_ops = {
 	.add_battery = asus_wmi_battery_add,
 	.remove_battery = asus_wmi_battery_remove,
-	.name = "ASUS Battery Extension",
 };

 static void asus_wmi_battery_init(struct asus_wmi *asus)
 {
-	asus->battery_rsoc_available = false;
 	if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_RSOC)) {
-		asus->battery_rsoc_available = true;
-		battery_hook_register(&battery_hook);
+		asus->hook = battery_hook_register("ASUS Battery Extension", &battery_hook_ops);
 	}
 }

 static void asus_wmi_battery_exit(struct asus_wmi *asus)
 {
-	if (asus->battery_rsoc_available)
-		battery_hook_unregister(&battery_hook);
+	if (!IS_ERR_OR_NULL(asus->hook))
+		battery_hook_unregister(asus->hook);
 }

 /* LEDs ***********************************************************************/
diff --git a/drivers/platform/x86/huawei-wmi.c b/drivers/platform/x86/huawei-wmi.c
index eac3e6b4ea11..6fd02b25a97b 100644
--- a/drivers/platform/x86/huawei-wmi.c
+++ b/drivers/platform/x86/huawei-wmi.c
@@ -62,6 +62,7 @@ struct huawei_wmi {
 	bool battery_available;
 	bool fn_lock_available;

+	struct acpi_battery_hook *hook;
 	struct huawei_wmi_debug debug;
 	struct input_dev *idev[2];
 	struct led_classdev cdev;
@@ -491,10 +492,9 @@ static int huawei_wmi_battery_remove(struct power_supply *battery)
 	return 0;
 }

-static struct acpi_battery_hook huawei_wmi_battery_hook = {
+static const struct acpi_battery_hook_ops huawei_wmi_battery_hook_ops = {
 	.add_battery = huawei_wmi_battery_add,
 	.remove_battery = huawei_wmi_battery_remove,
-	.name = "Huawei Battery Extension"
 };

 static void huawei_wmi_battery_setup(struct device *dev)
@@ -507,7 +507,8 @@ static void huawei_wmi_battery_setup(struct device *dev)
 		return;
 	}

-	battery_hook_register(&huawei_wmi_battery_hook);
+	huawei->hook = battery_hook_register("Huawei Battery Extension",
+					     &huawei_wmi_battery_hook_ops);
 	device_create_file(dev, &dev_attr_charge_control_thresholds);
 }

@@ -516,7 +517,9 @@ static void huawei_wmi_battery_exit(struct device *dev)
 	struct huawei_wmi *huawei = dev_get_drvdata(dev);

 	if (huawei->battery_available) {
-		battery_hook_unregister(&huawei_wmi_battery_hook);
+		if (!IS_ERR(huawei->hook))
+			battery_hook_unregister(huawei->hook);
+
 		device_remove_file(dev, &dev_attr_charge_control_thresholds);
 	}
 }
diff --git a/drivers/platform/x86/lg-laptop.c b/drivers/platform/x86/lg-laptop.c
index 332868b140ed..d8a61a07313e 100644
--- a/drivers/platform/x86/lg-laptop.c
+++ b/drivers/platform/x86/lg-laptop.c
@@ -73,6 +73,7 @@ static u32 inited;
 #define INIT_SPARSE_KEYMAP      0x80

 static int battery_limit_use_wmbb;
+static struct acpi_battery_hook *hook;
 static struct led_classdev kbd_backlight;
 static enum led_brightness get_kbd_backlight_level(void);

@@ -562,10 +563,9 @@ static int lg_battery_remove(struct power_supply *battery)
 	return 0;
 }

-static struct acpi_battery_hook battery_hook = {
+static const struct acpi_battery_hook_ops battery_hook_ops = {
 	.add_battery = lg_battery_add,
 	.remove_battery = lg_battery_remove,
-	.name = "LG Battery Extension",
 };

 static struct attribute *dev_attributes[] = {
@@ -750,7 +750,7 @@ static int acpi_add(struct acpi_device *device)
 	led_classdev_register(&pf_device->dev, &tpad_led);

 	wmi_input_setup();
-	battery_hook_register(&battery_hook);
+	hook = battery_hook_register("LG Battery Extension", &battery_hook_ops);

 	return 0;

@@ -768,7 +768,9 @@ static int acpi_remove(struct acpi_device *device)
 	led_classdev_unregister(&tpad_led);
 	led_classdev_unregister(&kbd_backlight);

-	battery_hook_unregister(&battery_hook);
+	if (!IS_ERR(hook))
+		battery_hook_unregister(hook);
+
 	wmi_input_destroy();
 	platform_device_unregister(pf_device);
 	pf_device = NULL;
diff --git a/drivers/platform/x86/system76_acpi.c b/drivers/platform/x86/system76_acpi.c
index 958df41ad509..1ec22db32bd0 100644
--- a/drivers/platform/x86/system76_acpi.c
+++ b/drivers/platform/x86/system76_acpi.c
@@ -26,6 +26,7 @@

 struct system76_data {
 	struct acpi_device *acpi_dev;
+	struct acpi_battery_hook *hook;
 	struct led_classdev ap_led;
 	struct led_classdev kb_led;
 	enum led_brightness kb_brightness;
@@ -272,20 +273,21 @@ static int system76_battery_remove(struct power_supply *battery)
 	return 0;
 }

-static struct acpi_battery_hook system76_battery_hook = {
+static const struct acpi_battery_hook_ops system76_battery_hook_ops = {
 	.add_battery = system76_battery_add,
 	.remove_battery = system76_battery_remove,
-	.name = "System76 Battery Extension",
 };

-static void system76_battery_init(void)
+static void system76_battery_init(struct system76_data *data)
 {
-	battery_hook_register(&system76_battery_hook);
+	data->hook = battery_hook_register("System76 Battery Extension",
+					   &system76_battery_hook_ops);
 }

-static void system76_battery_exit(void)
+static void system76_battery_exit(struct system76_data *data)
 {
-	battery_hook_unregister(&system76_battery_hook);
+	if (!IS_ERR(data->hook))
+		battery_hook_unregister(data->hook);
 }

 // Get the airplane mode LED brightness
@@ -730,7 +732,7 @@ static int system76_add(struct acpi_device *acpi_dev)
 		if (err)
 			goto error;

-		system76_battery_init();
+		system76_battery_init(data);
 	}

 	return 0;
@@ -751,7 +753,7 @@ static int system76_remove(struct acpi_device *acpi_dev)
 	data = acpi_driver_data(acpi_dev);

 	if (data->has_open_ec) {
-		system76_battery_exit();
+		system76_battery_exit(data);
 		kfree(data->nfan);
 		kfree(data->ntmp);
 	}
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 8fbe21ebcc52..8adafc3c31fa 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -9407,6 +9407,7 @@ struct tpacpi_battery_data {

 struct tpacpi_battery_driver_data {
 	struct tpacpi_battery_data batteries[3];
+	struct acpi_battery_hook *hook;
 	int individual_addressing;
 };

@@ -9914,10 +9915,9 @@ static int tpacpi_battery_remove(struct power_supply *battery)
 	return 0;
 }

-static struct acpi_battery_hook battery_hook = {
+static const struct acpi_battery_hook_ops battery_hook_ops = {
 	.add_battery = tpacpi_battery_add,
 	.remove_battery = tpacpi_battery_remove,
-	.name = "ThinkPad Battery Extension",
 };

 /* Subdriver init/exit */
@@ -9943,13 +9943,16 @@ static int __init tpacpi_battery_init(struct ibm_init_struct *ibm)
 					battery_quirk_table,
 					ARRAY_SIZE(battery_quirk_table));

-	battery_hook_register(&battery_hook);
+	battery_info.hook = battery_hook_register("ThinkPad Battery Extension",
+						  &battery_hook_ops);
+
 	return 0;
 }

 static void tpacpi_battery_exit(void)
 {
-	battery_hook_unregister(&battery_hook);
+	if (!IS_ERR(battery_info.hook))
+		battery_hook_unregister(battery_info.hook);
 }

 static struct ibm_struct battery_driver_data = {
diff --git a/include/acpi/battery.h b/include/acpi/battery.h
index b8d56b702c7a..b3c81abada1e 100644
--- a/include/acpi/battery.h
+++ b/include/acpi/battery.h
@@ -10,14 +10,19 @@
 #define ACPI_BATTERY_NOTIFY_INFO	0x81
 #define ACPI_BATTERY_NOTIFY_THRESHOLD   0x82

-struct acpi_battery_hook {
-	const char *name;
+struct acpi_battery_hook_ops {
 	int (*add_battery)(struct power_supply *battery);
 	int (*remove_battery)(struct power_supply *battery);
+};
+
+struct acpi_battery_hook {
+	const char *name;
+	const struct acpi_battery_hook_ops *ops;
 	struct list_head list;
 };

-void battery_hook_register(struct acpi_battery_hook *hook);
+struct acpi_battery_hook *battery_hook_register(const char *name,
+						const struct acpi_battery_hook_ops *hook);
 void battery_hook_unregister(struct acpi_battery_hook *hook);

 #endif
--
2.30.2


  parent reply	other threads:[~2022-09-12 12:54 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-12 12:53 [PATCH 0/5] platform/x86: dell: Add new dell-wmi-ddv driver Armin Wolf
2022-09-12 12:53 ` [PATCH 1/5] ACPI: battery: Do not unload battery hooks on single error Armin Wolf
2022-09-19 10:42   ` Hans de Goede
2022-09-19 16:27     ` Rafael J. Wysocki
2022-09-19 19:12       ` Armin Wolf
2022-09-19 20:35         ` Armin Wolf
2022-09-27 14:29           ` Hans de Goede
2022-09-27 15:44             ` Armin Wolf
2022-09-12 12:53 ` [PATCH 2/5] ACPI: battery: Simplify battery_hook_unregister() Armin Wolf
2022-09-19 10:42   ` Hans de Goede
2022-09-12 12:53 ` Armin Wolf [this message]
2022-09-12 16:42   ` [PATCH 3/5] ACPI: battery: Allow battery hooks to be registered multiple times Barnabás Pőcze
2022-09-12 17:29     ` Armin Wolf
2022-09-19 11:18       ` Hans de Goede
2022-09-19 17:42       ` Barnabás Pőcze
2022-09-12 12:53 ` [PATCH 4/5] ACPI: battery: Allow for passing data to battery hooks Armin Wolf
2022-09-19 11:08   ` Hans de Goede
2022-09-12 12:53 ` [PATCH 5/5] platform/x86: dell: Add new dell-wmi-ddv driver Armin Wolf
2022-09-12 21:56   ` Randy Dunlap
2022-09-13 14:40     ` Armin Wolf
2022-09-13 16:08       ` Limonciello, Mario
2022-09-13 16:45         ` Armin Wolf
2022-09-13 18:27         ` Randy Dunlap
2022-09-13 18:30           ` Limonciello, Mario
2022-09-13 18:37             ` Randy Dunlap
2022-09-19 11:33   ` Hans de Goede

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220912125342.7395-4-W_Armin@gmx.de \
    --to=w_armin@gmx.de \
    --cc=corentin.chary@gmail.com \
    --cc=hdegoede@redhat.com \
    --cc=hmh@hmh.eng.br \
    --cc=jeremy@system76.com \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=markgross@kernel.org \
    --cc=matan@svgalib.org \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=productdev@system76.com \
    --cc=rafael@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).