* [PATCH 1/3] of: replace of_alias_get_highest_id() with of_alias_get_free_id()
@ 2025-12-17 14:51 Sascha Hauer
2025-12-17 14:51 ` [PATCH 2/3] i2c: implement i2c_unregister_device() Sascha Hauer
2025-12-17 14:51 ` [PATCH 3/3] eeprom: at24: unregister devices in error path Sascha Hauer
0 siblings, 2 replies; 3+ messages in thread
From: Sascha Hauer @ 2025-12-17 14:51 UTC (permalink / raw)
To: Barebox List
of_alias_get_highest_id() returns the highest alias id used for a stem.
This return value is not what the callers actually need. They need the
first free ID instead. Replace of_alias_get_highest_id() with
of_alias_get_free_id() which returns that value. This variant doesn't
need to handle the special case when no alias for a stem is found
in the device tree. In this case of_alias_get_highest_id() returned a
negative error code which must be handled. The new function is more
handy for the callers, it just returns 0 which can be used as a free
id.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/eeprom/at24.c | 2 +-
drivers/i2c/i2c.c | 16 +---------------
drivers/of/base.c | 10 +++++-----
include/of.h | 6 +++---
4 files changed, 10 insertions(+), 24 deletions(-)
diff --git a/drivers/eeprom/at24.c b/drivers/eeprom/at24.c
index 5dc1980097..508ddbc7b3 100644
--- a/drivers/eeprom/at24.c
+++ b/drivers/eeprom/at24.c
@@ -429,7 +429,7 @@ static int at24_probe(struct device *dev)
} else {
devname = "eeprom";
devid = get_free_deviceid_from(devname,
- of_alias_get_highest_id(devname) + 1);
+ of_alias_get_free_id(devname));
}
writable = !(chip.flags & AT24_FLAG_READONLY);
diff --git a/drivers/i2c/i2c.c b/drivers/i2c/i2c.c
index 7b11c35039..0f294a93bf 100644
--- a/drivers/i2c/i2c.c
+++ b/drivers/i2c/i2c.c
@@ -685,20 +685,6 @@ void i2c_parse_fw_timings(struct device *dev, struct i2c_timings *t,
}
EXPORT_SYMBOL_GPL(i2c_parse_fw_timings);
-/**
- * i2c_first_nonreserved_index() - get the first index that is not reserved
- */
-static int i2c_first_nonreserved_index(void)
-{
- int max;
-
- max = of_alias_get_highest_id("i2c");
- if (max < 0)
- return 0;
-
- return max + 1;
-}
-
/**
* i2c_add_numbered_adapter - declare i2c adapter, use static bus number
* @adapter: the adapter to register (with adap->nr initialized)
@@ -725,7 +711,7 @@ int i2c_add_numbered_adapter(struct i2c_adapter *adapter)
if (adapter->nr < 0) {
int nr;
- for (nr = i2c_first_nonreserved_index();
+ for (nr = of_alias_get_free_id("i2c");
i2c_get_adapter(nr); nr++)
;
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 0a7704ca10..ebedd7c56f 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -273,16 +273,16 @@ int of_alias_get_id(struct device_node *np, const char *stem)
EXPORT_SYMBOL_GPL(of_alias_get_id);
/**
- * of_alias_get_highest_id - Get highest alias id for the given stem
+ * of_alias_get_free_id - Get lowest free alias id for the given stem
* @stem: Alias stem to be examined
*
* The function travels the lookup table to get the highest alias id for the
- * given alias stem. It returns the alias id if found.
+ * given alias stem. It returns the lowest free alias id.
*/
-int of_alias_get_highest_id(const char *stem)
+int of_alias_get_free_id(const char *stem)
{
struct alias_prop *app;
- int id = -ENODEV;
+ int id = -1;
list_for_each_entry(app, &aliases_lookup, link) {
if (strcmp(app->stem, stem) != 0)
@@ -292,7 +292,7 @@ int of_alias_get_highest_id(const char *stem)
id = app->id;
}
- return id;
+ return id + 1;
}
EXPORT_SYMBOL_GPL(of_alias_get_highest_id);
diff --git a/include/of.h b/include/of.h
index d1efab13c7..a40f8bdd9d 100644
--- a/include/of.h
+++ b/include/of.h
@@ -410,7 +410,7 @@ extern void of_alias_scan(void);
extern int of_alias_get_id(struct device_node *np, const char *stem);
extern int of_alias_get_id_from(struct device_node *root, struct device_node *np,
const char *stem);
-extern int of_alias_get_highest_id(const char *stem);
+extern int of_alias_get_free_id(const char *stem);
extern const char *of_alias_get(struct device_node *np);
extern int of_modalias_node(struct device_node *node, char *modalias, int len);
@@ -1084,9 +1084,9 @@ static inline int of_alias_get_id_from(struct device_node *root, struct device_n
return -ENOSYS;
}
-static inline int of_alias_get_highest_id(const char *stem)
+static inline int of_alias_get_free_id(const char *stem)
{
- return -ENOSYS;
+ return 0;
}
static inline const char *of_alias_get(struct device_node *np)
--
2.47.3
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 2/3] i2c: implement i2c_unregister_device()
2025-12-17 14:51 [PATCH 1/3] of: replace of_alias_get_highest_id() with of_alias_get_free_id() Sascha Hauer
@ 2025-12-17 14:51 ` Sascha Hauer
2025-12-17 14:51 ` [PATCH 3/3] eeprom: at24: unregister devices in error path Sascha Hauer
1 sibling, 0 replies; 3+ messages in thread
From: Sascha Hauer @ 2025-12-17 14:51 UTC (permalink / raw)
To: Barebox List
We had no need so far, but we do in a followup patch.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/i2c/i2c.c | 6 ++++++
include/i2c/i2c.h | 2 ++
2 files changed, 8 insertions(+)
diff --git a/drivers/i2c/i2c.c b/drivers/i2c/i2c.c
index 0f294a93bf..407c4db8a7 100644
--- a/drivers/i2c/i2c.c
+++ b/drivers/i2c/i2c.c
@@ -421,6 +421,12 @@ static struct i2c_client *i2c_new_device(struct i2c_adapter *adapter,
return client;
}
+void i2c_unregister_device(struct i2c_client *client)
+{
+ unregister_device(&client->dev);
+ devinfo_del(&client->dev, i2c_info);
+}
+
static void of_i2c_register_devices(struct i2c_adapter *adap)
{
struct device_node *n;
diff --git a/include/i2c/i2c.h b/include/i2c/i2c.h
index 5c0174b0dd..fb3f43cabb 100644
--- a/include/i2c/i2c.h
+++ b/include/i2c/i2c.h
@@ -313,6 +313,8 @@ extern struct class i2c_adapter_class;
extern struct i2c_client *
i2c_new_dummy(struct i2c_adapter *adap, u16 address);
+void i2c_unregister_device(struct i2c_client *client);
+
/* Return the adapter number for a specific adapter */
static inline int i2c_adapter_id(struct i2c_adapter *adap)
{
--
2.47.3
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 3/3] eeprom: at24: unregister devices in error path
2025-12-17 14:51 [PATCH 1/3] of: replace of_alias_get_highest_id() with of_alias_get_free_id() Sascha Hauer
2025-12-17 14:51 ` [PATCH 2/3] i2c: implement i2c_unregister_device() Sascha Hauer
@ 2025-12-17 14:51 ` Sascha Hauer
1 sibling, 0 replies; 3+ messages in thread
From: Sascha Hauer @ 2025-12-17 14:51 UTC (permalink / raw)
To: Barebox List
The AT24 driver might register some i2c devices using i2c_new_dummy().
These are freed in the error path, but not unregistered which leads to
memory corruptions later.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/eeprom/at24.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/eeprom/at24.c b/drivers/eeprom/at24.c
index 508ddbc7b3..06a2a4b226 100644
--- a/drivers/eeprom/at24.c
+++ b/drivers/eeprom/at24.c
@@ -496,8 +496,11 @@ static int at24_probe(struct device *dev)
err_devfs_create:
err_clients:
- for (i = 1; i < num_addresses; i++)
+ for (i = 1; i < num_addresses; i++) {
+ if (at24->client[i])
+ i2c_unregister_device(at24->client[i]);
kfree(at24->client[i]);
+ }
if (gpio_is_valid(at24->wp_gpio))
gpio_free(at24->wp_gpio);
--
2.47.3
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-12-17 14:52 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-12-17 14:51 [PATCH 1/3] of: replace of_alias_get_highest_id() with of_alias_get_free_id() Sascha Hauer
2025-12-17 14:51 ` [PATCH 2/3] i2c: implement i2c_unregister_device() Sascha Hauer
2025-12-17 14:51 ` [PATCH 3/3] eeprom: at24: unregister devices in error path Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox