Patchwork [U-Boot,2/3,v4] exynos: i2c: Change FDT bus setup code to enumerate ports correctly

login
register
mail settings
Submitter Naveen Krishna Ch
Date Oct. 15, 2013, 10:32 a.m.
Message ID <1381833130-26275-1-git-send-email-ch.naveen@samsung.com>
Download mbox | patch
Permalink /patch/283568/
State Accepted
Delegated to: Heiko Schocher
Headers show

Comments

Naveen Krishna Ch - Oct. 15, 2013, 10:32 a.m.
From: Simon Glass <sjg@chromium.org>

At present the i2c ports are enumerated in a strange way - the
fdtdec_find_aliases_for_id() function is used, but then the ID returned
is ignored and the ports are renumbered. The effect is the same provided
that the device tree has the ports in the same order, or uses aliases,
and has no gaps, but it is not correct.

Adjust the code to use the function as intended. This will allows device
tree aliases to change the device order if required.

As a result, the i2c_busses variable is dropped. We can't be sure that
there are no 'holes' in the list of buses, so must check the whole
array.

Note: it seems that non-FDT operation is now broken in this drive and
will need to be reinstated for upstream.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/59369
Signed-off-by: Naveen Krishna Chatradhi <ch.naveen@samsung.com>
---
Changes since v1:
Nonei

Changes since v2:
None
 
Changes since v3:
None; ran # ./MAKEALL -v samsung
 
 drivers/i2c/s3c24x0_i2c.c |   25 ++++++++++++++++++-------
 drivers/i2c/s3c24x0_i2c.h |    1 +
 2 files changed, 19 insertions(+), 7 deletions(-)
Heiko Schocher - Oct. 17, 2013, 6:31 a.m.
Hello Naveen,

Am 15.10.2013 12:32, schrieb Naveen Krishna Ch:
> From: Simon Glass<sjg@chromium.org>
>
> At present the i2c ports are enumerated in a strange way - the
> fdtdec_find_aliases_for_id() function is used, but then the ID returned
> is ignored and the ports are renumbered. The effect is the same provided
> that the device tree has the ports in the same order, or uses aliases,
> and has no gaps, but it is not correct.
>
> Adjust the code to use the function as intended. This will allows device
> tree aliases to change the device order if required.
>
> As a result, the i2c_busses variable is dropped. We can't be sure that
> there are no 'holes' in the list of buses, so must check the whole
> array.
>
> Note: it seems that non-FDT operation is now broken in this drive and
> will need to be reinstated for upstream.
>
> Signed-off-by: Simon Glass<sjg@chromium.org>
> Reviewed-on: https://gerrit.chromium.org/gerrit/59369
> Signed-off-by: Naveen Krishna Chatradhi<ch.naveen@samsung.com>
>
> ---
> Changes since v1:
> Nonei
>
> Changes since v2:
> None
>
> Changes since v3:
> None; ran # ./MAKEALL -v samsung
>
>   drivers/i2c/s3c24x0_i2c.c |   25 ++++++++++++++++++-------
>   drivers/i2c/s3c24x0_i2c.h |    1 +
>   2 files changed, 19 insertions(+), 7 deletions(-)

Thanks!

Applied to u-boot-i2c.git

bye,
Heiko

Patch

diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c
index c65360d..0e6f241 100644
--- a/drivers/i2c/s3c24x0_i2c.c
+++ b/drivers/i2c/s3c24x0_i2c.c
@@ -52,7 +52,6 @@ 
  */
 static unsigned int g_current_bus __attribute__((section(".data")));
 #ifdef CONFIG_OF_CONTROL
-static int i2c_busses __attribute__((section(".data")));
 static struct s3c24x0_i2c_bus i2c_bus[CONFIG_MAX_I2C_NUM]
 			__attribute__((section(".data")));
 #endif
@@ -164,8 +163,8 @@  int i2c_set_bus_num(unsigned int bus)
 {
 	struct s3c24x0_i2c *i2c;
 
-	if ((bus < 0) || (bus >= CONFIG_MAX_I2C_NUM)) {
-		debug("Bad bus: %d\n", bus);
+	i2c_bus = get_bus(bus);
+	if (!i2c_bus)
 		return -1;
 	}
 
@@ -483,19 +482,31 @@  void board_i2c_init(const void *blob)
 		if (node <= 0)
 			continue;
 		bus = &i2c_bus[i];
+		bus->active = true;
 		bus->regs = (struct s3c24x0_i2c *)
 			fdtdec_get_addr(blob, node, "reg");
 		bus->id = pinmux_decode_periph_id(blob, node);
 		bus->node = node;
-		bus->bus_num = i2c_busses++;
+		bus->bus_num = i;
 		exynos_pinmux_config(bus->id, 0);
 	}
 }
 
+/**
+ * Get a pointer to the given bus index
+ *
+ * @bus_idx: Bus index to look up
+ * @return pointer to bus, or NULL if invalid or not available
+ */
 static struct s3c24x0_i2c_bus *get_bus(unsigned int bus_idx)
 {
-	if (bus_idx < i2c_busses)
-		return &i2c_bus[bus_idx];
+	if (bus_idx < ARRAY_SIZE(i2c_bus)) {
+		struct s3c24x0_i2c_bus *bus;
+
+		bus = &i2c_bus[bus_idx];
+		if (bus->active)
+			return bus;
+	}
 
 	debug("Undefined bus: %d\n", bus_idx);
 	return NULL;
@@ -505,7 +516,7 @@  int i2c_get_bus_num_fdt(int node)
 {
 	int i;
 
-	for (i = 0; i < i2c_busses; i++) {
+	for (i = 0; i < ARRAY_SIZE(i2c_bus); i++) {
 		if (node == i2c_bus[i].node)
 			return i;
 	}
diff --git a/drivers/i2c/s3c24x0_i2c.h b/drivers/i2c/s3c24x0_i2c.h
index b4a337a..882af62 100644
--- a/drivers/i2c/s3c24x0_i2c.h
+++ b/drivers/i2c/s3c24x0_i2c.h
@@ -16,6 +16,7 @@  struct s3c24x0_i2c {
 };
 
 struct s3c24x0_i2c_bus {
+	bool active;	/* port is active and available */
 	int node;	/* device tree node */
 	int bus_num;	/* i2c bus number */
 	struct s3c24x0_i2c *regs;