* [PATCH v8 1/8] locking/mutex: introduce devm_mutex_init()
2024-04-11 16:10 [PATCH v8 0/8] devm_led_classdev_register() usage problem George Stark
@ 2024-04-11 16:10 ` George Stark
2024-04-11 16:10 ` [PATCH v8 2/8] leds: aw2013: use devm API to cleanup module's resources George Stark
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: George Stark @ 2024-04-11 16:10 UTC (permalink / raw)
To: andy.shevchenko, pavel, lee, vadimp, christophe.leroy, hdegoede,
mazziesaccount, peterz, mingo, will, longman, boqun.feng,
nikitos.tr, marek.behun, kabel
Cc: linux-leds, linux-kernel, kernel, George Stark
Using of devm API leads to a certain order of releasing resources.
So all dependent resources which are not devm-wrapped should be deleted
with respect to devm-release order. Mutex is one of such objects that
often is bound to other resources and has no own devm wrapping.
Since mutex_destroy() actually does nothing in non-debug builds
frequently calling mutex_destroy() is just ignored which is safe for now
but wrong formally and can lead to a problem if mutex_destroy() will be
extended so introduce devm_mutex_init().
Suggested-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: George Stark <gnstark@salutedevices.com>
Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Reviewed-by: Marek Behún <kabel@kernel.org>
Acked-by: Waiman Long <longman@redhat.com>
---
include/linux/mutex.h | 27 +++++++++++++++++++++++++++
kernel/locking/mutex-debug.c | 12 ++++++++++++
2 files changed, 39 insertions(+)
diff --git a/include/linux/mutex.h b/include/linux/mutex.h
index 7e208d46ba5b..66dfbbd66310 100644
--- a/include/linux/mutex.h
+++ b/include/linux/mutex.h
@@ -22,6 +22,8 @@
#include <linux/cleanup.h>
#include <linux/mutex_types.h>
+struct device;
+
#ifdef CONFIG_DEBUG_LOCK_ALLOC
# define __DEP_MAP_MUTEX_INITIALIZER(lockname) \
, .dep_map = { \
@@ -121,6 +123,31 @@ do { \
} while (0)
#endif /* CONFIG_PREEMPT_RT */
+#ifdef CONFIG_DEBUG_MUTEXES
+
+int __devm_mutex_init(struct device *dev, struct mutex *lock);
+
+#else
+
+static inline int __devm_mutex_init(struct device *dev, struct mutex *lock)
+{
+ /*
+ * When CONFIG_DEBUG_MUTEXES is off mutex_destroy() is just a nop so
+ * no really need to register it in the devm subsystem.
+ */
+ return 0;
+}
+
+#endif
+
+#define devm_mutex_init(dev, mutex) \
+({ \
+ typeof(mutex) mutex_ = (mutex); \
+ \
+ mutex_init(mutex_); \
+ __devm_mutex_init(dev, mutex_); \
+})
+
/*
* See kernel/locking/mutex.c for detailed documentation of these APIs.
* Also see Documentation/locking/mutex-design.rst.
diff --git a/kernel/locking/mutex-debug.c b/kernel/locking/mutex-debug.c
index bc8abb8549d2..6e6f6071cfa2 100644
--- a/kernel/locking/mutex-debug.c
+++ b/kernel/locking/mutex-debug.c
@@ -12,6 +12,7 @@
*/
#include <linux/mutex.h>
#include <linux/delay.h>
+#include <linux/device.h>
#include <linux/export.h>
#include <linux/poison.h>
#include <linux/sched.h>
@@ -89,6 +90,17 @@ void debug_mutex_init(struct mutex *lock, const char *name,
lock->magic = lock;
}
+static void devm_mutex_release(void *res)
+{
+ mutex_destroy(res);
+}
+
+int __devm_mutex_init(struct device *dev, struct mutex *lock)
+{
+ return devm_add_action_or_reset(dev, devm_mutex_release, lock);
+}
+EXPORT_SYMBOL_GPL(__devm_mutex_init);
+
/***
* mutex_destroy - mark a mutex unusable
* @lock: the mutex to be destroyed
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v8 2/8] leds: aw2013: use devm API to cleanup module's resources
2024-04-11 16:10 [PATCH v8 0/8] devm_led_classdev_register() usage problem George Stark
2024-04-11 16:10 ` [PATCH v8 1/8] locking/mutex: introduce devm_mutex_init() George Stark
@ 2024-04-11 16:10 ` George Stark
2024-04-11 16:10 ` [PATCH v8 3/8] leds: aw200xx: " George Stark
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: George Stark @ 2024-04-11 16:10 UTC (permalink / raw)
To: andy.shevchenko, pavel, lee, vadimp, christophe.leroy, hdegoede,
mazziesaccount, peterz, mingo, will, longman, boqun.feng,
nikitos.tr, marek.behun, kabel
Cc: linux-leds, linux-kernel, kernel, George Stark, Nikita Travkin
In this driver LEDs are registered using devm_led_classdev_register()
so they are automatically unregistered after module's remove() is done.
led_classdev_unregister() calls module's led_set_brightness() to turn off
the LEDs and that callback uses resources which were destroyed already
in module's remove() so use devm API instead of remove().
Signed-off-by: George Stark <gnstark@salutedevices.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Tested-by: Nikita Travkin <nikita@trvn.ru>
---
drivers/leds/leds-aw2013.c | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/drivers/leds/leds-aw2013.c b/drivers/leds/leds-aw2013.c
index 17235a5e576a..6475eadcb0df 100644
--- a/drivers/leds/leds-aw2013.c
+++ b/drivers/leds/leds-aw2013.c
@@ -320,6 +320,11 @@ static int aw2013_probe_dt(struct aw2013 *chip)
return 0;
}
+static void aw2013_chip_disable_action(void *data)
+{
+ aw2013_chip_disable(data);
+}
+
static const struct regmap_config aw2013_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
@@ -336,7 +341,10 @@ static int aw2013_probe(struct i2c_client *client)
if (!chip)
return -ENOMEM;
- mutex_init(&chip->mutex);
+ ret = devm_mutex_init(&client->dev, &chip->mutex);
+ if (ret)
+ return ret;
+
mutex_lock(&chip->mutex);
chip->client = client;
@@ -384,6 +392,10 @@ static int aw2013_probe(struct i2c_client *client)
goto error_reg;
}
+ ret = devm_add_action(&client->dev, aw2013_chip_disable_action, chip);
+ if (ret)
+ goto error_reg;
+
ret = aw2013_probe_dt(chip);
if (ret < 0)
goto error_reg;
@@ -406,19 +418,9 @@ static int aw2013_probe(struct i2c_client *client)
error:
mutex_unlock(&chip->mutex);
- mutex_destroy(&chip->mutex);
return ret;
}
-static void aw2013_remove(struct i2c_client *client)
-{
- struct aw2013 *chip = i2c_get_clientdata(client);
-
- aw2013_chip_disable(chip);
-
- mutex_destroy(&chip->mutex);
-}
-
static const struct of_device_id aw2013_match_table[] = {
{ .compatible = "awinic,aw2013", },
{ /* sentinel */ },
@@ -432,7 +434,6 @@ static struct i2c_driver aw2013_driver = {
.of_match_table = aw2013_match_table,
},
.probe = aw2013_probe,
- .remove = aw2013_remove,
};
module_i2c_driver(aw2013_driver);
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v8 3/8] leds: aw200xx: use devm API to cleanup module's resources
2024-04-11 16:10 [PATCH v8 0/8] devm_led_classdev_register() usage problem George Stark
2024-04-11 16:10 ` [PATCH v8 1/8] locking/mutex: introduce devm_mutex_init() George Stark
2024-04-11 16:10 ` [PATCH v8 2/8] leds: aw2013: use devm API to cleanup module's resources George Stark
@ 2024-04-11 16:10 ` George Stark
2024-04-11 16:10 ` [PATCH v8 4/8] leds: lp3952: " George Stark
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: George Stark @ 2024-04-11 16:10 UTC (permalink / raw)
To: andy.shevchenko, pavel, lee, vadimp, christophe.leroy, hdegoede,
mazziesaccount, peterz, mingo, will, longman, boqun.feng,
nikitos.tr, marek.behun, kabel
Cc: linux-leds, linux-kernel, kernel, George Stark
In this driver LEDs are registered using devm_led_classdev_register()
so they are automatically unregistered after module's remove() is done.
led_classdev_unregister() calls module's led_set_brightness() to turn off
the LEDs and that callback uses resources which were destroyed already
in module's remove() so use devm API instead of remove().
Signed-off-by: George Stark <gnstark@salutedevices.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
drivers/leds/leds-aw200xx.c | 32 +++++++++++++++++++++-----------
1 file changed, 21 insertions(+), 11 deletions(-)
diff --git a/drivers/leds/leds-aw200xx.c b/drivers/leds/leds-aw200xx.c
index f584a7f98fc5..5cba52d07b38 100644
--- a/drivers/leds/leds-aw200xx.c
+++ b/drivers/leds/leds-aw200xx.c
@@ -530,6 +530,16 @@ static const struct regmap_config aw200xx_regmap_config = {
.disable_locking = true,
};
+static void aw200xx_chip_reset_action(void *data)
+{
+ aw200xx_chip_reset(data);
+}
+
+static void aw200xx_disable_action(void *data)
+{
+ aw200xx_disable(data);
+}
+
static int aw200xx_probe(struct i2c_client *client)
{
const struct aw200xx_chipdef *cdef;
@@ -568,11 +578,17 @@ static int aw200xx_probe(struct i2c_client *client)
aw200xx_enable(chip);
+ ret = devm_add_action(&client->dev, aw200xx_disable_action, chip);
+ if (ret)
+ return ret;
+
ret = aw200xx_chip_check(chip);
if (ret)
return ret;
- mutex_init(&chip->mutex);
+ ret = devm_mutex_init(&client->dev, &chip->mutex);
+ if (ret)
+ return ret;
/* Need a lock now since after call aw200xx_probe_fw, sysfs nodes created */
mutex_lock(&chip->mutex);
@@ -581,6 +597,10 @@ static int aw200xx_probe(struct i2c_client *client)
if (ret)
goto out_unlock;
+ ret = devm_add_action(&client->dev, aw200xx_chip_reset_action, chip);
+ if (ret)
+ goto out_unlock;
+
ret = aw200xx_probe_fw(&client->dev, chip);
if (ret)
goto out_unlock;
@@ -595,15 +615,6 @@ static int aw200xx_probe(struct i2c_client *client)
return ret;
}
-static void aw200xx_remove(struct i2c_client *client)
-{
- struct aw200xx *chip = i2c_get_clientdata(client);
-
- aw200xx_chip_reset(chip);
- aw200xx_disable(chip);
- mutex_destroy(&chip->mutex);
-}
-
static const struct aw200xx_chipdef aw20036_cdef = {
.channels = 36,
.display_size_rows_max = 3,
@@ -652,7 +663,6 @@ static struct i2c_driver aw200xx_driver = {
.of_match_table = aw200xx_match_table,
},
.probe = aw200xx_probe,
- .remove = aw200xx_remove,
.id_table = aw200xx_id,
};
module_i2c_driver(aw200xx_driver);
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v8 4/8] leds: lp3952: use devm API to cleanup module's resources
2024-04-11 16:10 [PATCH v8 0/8] devm_led_classdev_register() usage problem George Stark
` (2 preceding siblings ...)
2024-04-11 16:10 ` [PATCH v8 3/8] leds: aw200xx: " George Stark
@ 2024-04-11 16:10 ` George Stark
2024-04-11 16:10 ` [PATCH v8 5/8] leds: lm3532: " George Stark
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: George Stark @ 2024-04-11 16:10 UTC (permalink / raw)
To: andy.shevchenko, pavel, lee, vadimp, christophe.leroy, hdegoede,
mazziesaccount, peterz, mingo, will, longman, boqun.feng,
nikitos.tr, marek.behun, kabel
Cc: linux-leds, linux-kernel, kernel, George Stark
In this driver LEDs are registered using devm_led_classdev_register()
so they are automatically unregistered after module's remove() is done.
led_classdev_unregister() calls module's led_set_brightness() to turn off
the LEDs and that callback uses resources which were destroyed already
in module's remove() so use devm API instead of remove().
Also drop explicit turning LEDs off from remove() due to they will be off
anyway by led_classdev_unregister().
Signed-off-by: George Stark <gnstark@salutedevices.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
drivers/leds/leds-lp3952.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/drivers/leds/leds-lp3952.c b/drivers/leds/leds-lp3952.c
index 5d18bbfd1f23..ff7bae2447dd 100644
--- a/drivers/leds/leds-lp3952.c
+++ b/drivers/leds/leds-lp3952.c
@@ -207,6 +207,13 @@ static const struct regmap_config lp3952_regmap = {
.cache_type = REGCACHE_MAPLE,
};
+static void gpio_set_low_action(void *data)
+{
+ struct lp3952_led_array *priv = data;
+
+ gpiod_set_value(priv->enable_gpio, 0);
+}
+
static int lp3952_probe(struct i2c_client *client)
{
int status;
@@ -226,6 +233,10 @@ static int lp3952_probe(struct i2c_client *client)
return status;
}
+ status = devm_add_action(&client->dev, gpio_set_low_action, priv);
+ if (status)
+ return status;
+
priv->regmap = devm_regmap_init_i2c(client, &lp3952_regmap);
if (IS_ERR(priv->regmap)) {
int err = PTR_ERR(priv->regmap);
@@ -254,15 +265,6 @@ static int lp3952_probe(struct i2c_client *client)
return 0;
}
-static void lp3952_remove(struct i2c_client *client)
-{
- struct lp3952_led_array *priv;
-
- priv = i2c_get_clientdata(client);
- lp3952_on_off(priv, LP3952_LED_ALL, false);
- gpiod_set_value(priv->enable_gpio, 0);
-}
-
static const struct i2c_device_id lp3952_id[] = {
{LP3952_NAME, 0},
{}
@@ -274,7 +276,6 @@ static struct i2c_driver lp3952_i2c_driver = {
.name = LP3952_NAME,
},
.probe = lp3952_probe,
- .remove = lp3952_remove,
.id_table = lp3952_id,
};
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v8 5/8] leds: lm3532: use devm API to cleanup module's resources
2024-04-11 16:10 [PATCH v8 0/8] devm_led_classdev_register() usage problem George Stark
` (3 preceding siblings ...)
2024-04-11 16:10 ` [PATCH v8 4/8] leds: lp3952: " George Stark
@ 2024-04-11 16:10 ` George Stark
2024-04-11 16:10 ` [PATCH v8 6/8] leds: nic78bx: " George Stark
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: George Stark @ 2024-04-11 16:10 UTC (permalink / raw)
To: andy.shevchenko, pavel, lee, vadimp, christophe.leroy, hdegoede,
mazziesaccount, peterz, mingo, will, longman, boqun.feng,
nikitos.tr, marek.behun, kabel
Cc: linux-leds, linux-kernel, kernel, George Stark
In this driver LEDs are registered using devm_led_classdev_register()
so they are automatically unregistered after module's remove() is done.
led_classdev_unregister() calls module's led_set_brightness() to turn off
the LEDs and that callback uses resources which were destroyed already
in module's remove() so use devm API instead of remove().
Signed-off-by: George Stark <gnstark@salutedevices.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
drivers/leds/leds-lm3532.c | 29 +++++++++++++++++------------
1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/drivers/leds/leds-lm3532.c b/drivers/leds/leds-lm3532.c
index 13662a4aa1f2..8c90701dc50d 100644
--- a/drivers/leds/leds-lm3532.c
+++ b/drivers/leds/leds-lm3532.c
@@ -542,6 +542,13 @@ static int lm3532_parse_als(struct lm3532_data *priv)
return ret;
}
+static void gpio_set_low_action(void *data)
+{
+ struct lm3532_data *priv = data;
+
+ gpiod_direction_output(priv->enable_gpio, 0);
+}
+
static int lm3532_parse_node(struct lm3532_data *priv)
{
struct fwnode_handle *child = NULL;
@@ -556,6 +563,12 @@ static int lm3532_parse_node(struct lm3532_data *priv)
if (IS_ERR(priv->enable_gpio))
priv->enable_gpio = NULL;
+ if (priv->enable_gpio) {
+ ret = devm_add_action(&priv->client->dev, gpio_set_low_action, priv);
+ if (ret)
+ return ret;
+ }
+
priv->regulator = devm_regulator_get(&priv->client->dev, "vin");
if (IS_ERR(priv->regulator))
priv->regulator = NULL;
@@ -691,7 +704,10 @@ static int lm3532_probe(struct i2c_client *client)
return ret;
}
- mutex_init(&drvdata->lock);
+ ret = devm_mutex_init(&client->dev, &drvdata->lock);
+ if (ret)
+ return ret;
+
i2c_set_clientdata(client, drvdata);
ret = lm3532_parse_node(drvdata);
@@ -703,16 +719,6 @@ static int lm3532_probe(struct i2c_client *client)
return ret;
}
-static void lm3532_remove(struct i2c_client *client)
-{
- struct lm3532_data *drvdata = i2c_get_clientdata(client);
-
- mutex_destroy(&drvdata->lock);
-
- if (drvdata->enable_gpio)
- gpiod_direction_output(drvdata->enable_gpio, 0);
-}
-
static const struct of_device_id of_lm3532_leds_match[] = {
{ .compatible = "ti,lm3532", },
{},
@@ -727,7 +733,6 @@ MODULE_DEVICE_TABLE(i2c, lm3532_id);
static struct i2c_driver lm3532_i2c_driver = {
.probe = lm3532_probe,
- .remove = lm3532_remove,
.id_table = lm3532_id,
.driver = {
.name = LM3532_NAME,
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v8 6/8] leds: nic78bx: use devm API to cleanup module's resources
2024-04-11 16:10 [PATCH v8 0/8] devm_led_classdev_register() usage problem George Stark
` (4 preceding siblings ...)
2024-04-11 16:10 ` [PATCH v8 5/8] leds: lm3532: " George Stark
@ 2024-04-11 16:10 ` George Stark
2024-04-11 16:10 ` [PATCH v8 7/8] leds: mlxreg: use devm_mutex_init() for mutex initialization George Stark
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: George Stark @ 2024-04-11 16:10 UTC (permalink / raw)
To: andy.shevchenko, pavel, lee, vadimp, christophe.leroy, hdegoede,
mazziesaccount, peterz, mingo, will, longman, boqun.feng,
nikitos.tr, marek.behun, kabel
Cc: linux-leds, linux-kernel, kernel, George Stark
In this driver LEDs are registered using devm_led_classdev_register()
so they are automatically unregistered after module's remove() is done.
led_classdev_unregister() calls module's led_set_brightness() to turn off
the LEDs and that callback uses resources which were destroyed already
in module's remove() so use devm API instead of remove().
Signed-off-by: George Stark <gnstark@salutedevices.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
drivers/leds/leds-nic78bx.c | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/drivers/leds/leds-nic78bx.c b/drivers/leds/leds-nic78bx.c
index a86b43dd995e..282d9e4cf116 100644
--- a/drivers/leds/leds-nic78bx.c
+++ b/drivers/leds/leds-nic78bx.c
@@ -118,6 +118,15 @@ static struct nic78bx_led nic78bx_leds[] = {
}
};
+static void lock_led_reg_action(void *data)
+{
+ struct nic78bx_led_data *led_data = data;
+
+ /* Lock LED register */
+ outb(NIC78BX_LOCK_VALUE,
+ led_data->io_base + NIC78BX_LOCK_REG_OFFSET);
+}
+
static int nic78bx_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -152,6 +161,10 @@ static int nic78bx_probe(struct platform_device *pdev)
led_data->io_base = io_rc->start;
spin_lock_init(&led_data->lock);
+ ret = devm_add_action(dev, lock_led_reg_action, led_data);
+ if (ret)
+ return ret;
+
for (i = 0; i < ARRAY_SIZE(nic78bx_leds); i++) {
nic78bx_leds[i].data = led_data;
@@ -167,15 +180,6 @@ static int nic78bx_probe(struct platform_device *pdev)
return ret;
}
-static void nic78bx_remove(struct platform_device *pdev)
-{
- struct nic78bx_led_data *led_data = platform_get_drvdata(pdev);
-
- /* Lock LED register */
- outb(NIC78BX_LOCK_VALUE,
- led_data->io_base + NIC78BX_LOCK_REG_OFFSET);
-}
-
static const struct acpi_device_id led_device_ids[] = {
{"NIC78B3", 0},
{"", 0},
@@ -184,7 +188,6 @@ MODULE_DEVICE_TABLE(acpi, led_device_ids);
static struct platform_driver led_driver = {
.probe = nic78bx_probe,
- .remove_new = nic78bx_remove,
.driver = {
.name = KBUILD_MODNAME,
.acpi_match_table = ACPI_PTR(led_device_ids),
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v8 7/8] leds: mlxreg: use devm_mutex_init() for mutex initialization
2024-04-11 16:10 [PATCH v8 0/8] devm_led_classdev_register() usage problem George Stark
` (5 preceding siblings ...)
2024-04-11 16:10 ` [PATCH v8 6/8] leds: nic78bx: " George Stark
@ 2024-04-11 16:10 ` George Stark
2024-04-11 16:10 ` [PATCH v8 8/8] leds: an30259a: " George Stark
2024-04-12 8:46 ` [GIT PULL] Immutable branch between LEDs and Locking due for the v6.10 merge window Lee Jones
8 siblings, 0 replies; 10+ messages in thread
From: George Stark @ 2024-04-11 16:10 UTC (permalink / raw)
To: andy.shevchenko, pavel, lee, vadimp, christophe.leroy, hdegoede,
mazziesaccount, peterz, mingo, will, longman, boqun.feng,
nikitos.tr, marek.behun, kabel
Cc: linux-leds, linux-kernel, kernel, George Stark
In this driver LEDs are registered using devm_led_classdev_register()
so they are automatically unregistered after module's remove() is done.
led_classdev_unregister() calls module's led_set_brightness() to turn off
the LEDs and that callback uses mutex which was destroyed already
in module's remove() so use devm API instead.
Signed-off-by: George Stark <gnstark@salutedevices.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
drivers/leds/leds-mlxreg.c | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/drivers/leds/leds-mlxreg.c b/drivers/leds/leds-mlxreg.c
index d8e3d5d8d2d0..b1510cd32e47 100644
--- a/drivers/leds/leds-mlxreg.c
+++ b/drivers/leds/leds-mlxreg.c
@@ -257,6 +257,7 @@ static int mlxreg_led_probe(struct platform_device *pdev)
{
struct mlxreg_core_platform_data *led_pdata;
struct mlxreg_led_priv_data *priv;
+ int err;
led_pdata = dev_get_platdata(&pdev->dev);
if (!led_pdata) {
@@ -268,26 +269,21 @@ static int mlxreg_led_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
- mutex_init(&priv->access_lock);
+ err = devm_mutex_init(&pdev->dev, &priv->access_lock);
+ if (err)
+ return err;
+
priv->pdev = pdev;
priv->pdata = led_pdata;
return mlxreg_led_config(priv);
}
-static void mlxreg_led_remove(struct platform_device *pdev)
-{
- struct mlxreg_led_priv_data *priv = dev_get_drvdata(&pdev->dev);
-
- mutex_destroy(&priv->access_lock);
-}
-
static struct platform_driver mlxreg_led_driver = {
.driver = {
.name = "leds-mlxreg",
},
.probe = mlxreg_led_probe,
- .remove_new = mlxreg_led_remove,
};
module_platform_driver(mlxreg_led_driver);
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v8 8/8] leds: an30259a: use devm_mutex_init() for mutex initialization
2024-04-11 16:10 [PATCH v8 0/8] devm_led_classdev_register() usage problem George Stark
` (6 preceding siblings ...)
2024-04-11 16:10 ` [PATCH v8 7/8] leds: mlxreg: use devm_mutex_init() for mutex initialization George Stark
@ 2024-04-11 16:10 ` George Stark
2024-04-12 8:46 ` [GIT PULL] Immutable branch between LEDs and Locking due for the v6.10 merge window Lee Jones
8 siblings, 0 replies; 10+ messages in thread
From: George Stark @ 2024-04-11 16:10 UTC (permalink / raw)
To: andy.shevchenko, pavel, lee, vadimp, christophe.leroy, hdegoede,
mazziesaccount, peterz, mingo, will, longman, boqun.feng,
nikitos.tr, marek.behun, kabel
Cc: linux-leds, linux-kernel, kernel, George Stark
In this driver LEDs are registered using devm_led_classdev_register()
so they are automatically unregistered after module's remove() is done.
led_classdev_unregister() calls module's led_set_brightness() to turn off
the LEDs and that callback uses mutex which was destroyed already
in module's remove() so use devm API instead.
Signed-off-by: George Stark <gnstark@salutedevices.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
drivers/leds/leds-an30259a.c | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/drivers/leds/leds-an30259a.c b/drivers/leds/leds-an30259a.c
index 0216afed3b6e..decfca447d8a 100644
--- a/drivers/leds/leds-an30259a.c
+++ b/drivers/leds/leds-an30259a.c
@@ -283,7 +283,10 @@ static int an30259a_probe(struct i2c_client *client)
if (err < 0)
return err;
- mutex_init(&chip->mutex);
+ err = devm_mutex_init(&client->dev, &chip->mutex);
+ if (err)
+ return err;
+
chip->client = client;
i2c_set_clientdata(client, chip);
@@ -317,17 +320,9 @@ static int an30259a_probe(struct i2c_client *client)
return 0;
exit:
- mutex_destroy(&chip->mutex);
return err;
}
-static void an30259a_remove(struct i2c_client *client)
-{
- struct an30259a *chip = i2c_get_clientdata(client);
-
- mutex_destroy(&chip->mutex);
-}
-
static const struct of_device_id an30259a_match_table[] = {
{ .compatible = "panasonic,an30259a", },
{ /* sentinel */ },
@@ -347,7 +342,6 @@ static struct i2c_driver an30259a_driver = {
.of_match_table = an30259a_match_table,
},
.probe = an30259a_probe,
- .remove = an30259a_remove,
.id_table = an30259a_id,
};
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [GIT PULL] Immutable branch between LEDs and Locking due for the v6.10 merge window
2024-04-11 16:10 [PATCH v8 0/8] devm_led_classdev_register() usage problem George Stark
` (7 preceding siblings ...)
2024-04-11 16:10 ` [PATCH v8 8/8] leds: an30259a: " George Stark
@ 2024-04-12 8:46 ` Lee Jones
8 siblings, 0 replies; 10+ messages in thread
From: Lee Jones @ 2024-04-12 8:46 UTC (permalink / raw)
To: George Stark
Cc: andy.shevchenko, pavel, vadimp, christophe.leroy, hdegoede,
mazziesaccount, peterz, mingo, will, longman, boqun.feng,
nikitos.tr, marek.behun, kabel, linux-leds, linux-kernel, kernel
Enjoy!
The following changes since commit 4cece764965020c22cff7665b18a012006359095:
Linux 6.9-rc1 (2024-03-24 14:10:05 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds.git ib-leds-locking-v6.10
for you to fetch changes up to c382e2e3eccb6b7ca8c7aff5092c1668428e7de6:
leds: an30259a: Use devm_mutex_init() for mutex initialization (2024-04-11 17:35:24 +0100)
----------------------------------------------------------------
Immutable branch between LEDs and Locking due for the v6.10 merge window
----------------------------------------------------------------
George Stark (8):
locking/mutex: Introduce devm_mutex_init()
leds: aw2013: Use devm API to cleanup module's resources
leds: aw200xx: Use devm API to cleanup module's resources
leds: lp3952: Use devm API to cleanup module's resources
leds: lm3532: Use devm API to cleanup module's resources
leds: nic78bx: Use devm API to cleanup module's resources
leds: mlxreg: Use devm_mutex_init() for mutex initialization
leds: an30259a: Use devm_mutex_init() for mutex initialization
drivers/leds/leds-an30259a.c | 14 ++++----------
drivers/leds/leds-aw200xx.c | 32 +++++++++++++++++++++-----------
drivers/leds/leds-aw2013.c | 25 +++++++++++++------------
drivers/leds/leds-lm3532.c | 29 +++++++++++++++++------------
drivers/leds/leds-lp3952.c | 21 +++++++++++----------
drivers/leds/leds-mlxreg.c | 14 +++++---------
drivers/leds/leds-nic78bx.c | 23 +++++++++++++----------
include/linux/mutex.h | 27 +++++++++++++++++++++++++++
kernel/locking/mutex-debug.c | 12 ++++++++++++
9 files changed, 123 insertions(+), 74 deletions(-)
--
Lee Jones [李琼斯]
^ permalink raw reply [flat|nested] 10+ messages in thread