[PATCH master 3/3] i2c: order dynamically numbered adapter after highest alias id

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Instead of assuming there is at most 32 aliased adapters, let's
determine at runtime how many aliases we have and assign unaliased
adapters IDs directly following the highest aliased id.

This has the added benefit that we may avoid moving around adapter
numbers for many boards.

Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx>
---
 drivers/i2c/i2c.c | 21 ++++++++++++++++++---
 drivers/of/base.c | 24 ++++++++++++++++++++++++
 include/of.h      |  6 ++++++
 3 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/i2c.c b/drivers/i2c/i2c.c
index 017842f026dd..0d11a61593d8 100644
--- a/drivers/i2c/i2c.c
+++ b/drivers/i2c/i2c.c
@@ -685,6 +685,20 @@ 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)
@@ -711,9 +725,10 @@ int i2c_add_numbered_adapter(struct i2c_adapter *adapter)
 	if (adapter->nr < 0) {
 		int nr;
 
-		for (nr = 32;; nr++)
-			if (!i2c_get_adapter(nr))
-				break;
+		for (nr = i2c_first_nonreserved_index();
+		     i2c_get_adapter(nr); nr++)
+			;
+
 		adapter->nr = nr;
 	} else {
 		if (i2c_get_adapter(adapter->nr))
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 97b2306a75b1..125f24056eec 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -270,6 +270,30 @@ 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
+ * @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.
+ */
+int of_alias_get_highest_id(const char *stem)
+{
+	struct alias_prop *app;
+	int id = -ENODEV;
+
+	list_for_each_entry(app, &aliases_lookup, link) {
+		if (strcmp(app->stem, stem) != 0)
+			continue;
+
+		if (app->id > id)
+			id = app->id;
+	}
+
+	return id;
+}
+EXPORT_SYMBOL_GPL(of_alias_get_highest_id);
+
 int of_alias_get_id_from(struct device_node *root, struct device_node *np,
 			 const char *stem)
 {
diff --git a/include/of.h b/include/of.h
index c0577404c320..bc8afd9cf540 100644
--- a/include/of.h
+++ b/include/of.h
@@ -311,6 +311,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 const char *of_alias_get(struct device_node *np);
 extern int of_modalias_node(struct device_node *node, char *modalias, int len);
 
@@ -941,6 +942,11 @@ 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)
+{
+	return -ENOSYS;
+}
+
 static inline const char *of_alias_get(struct device_node *np)
 {
 	return NULL;
-- 
2.39.5





[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux