mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [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