* [PATCH/RFC 1/1] recover from davinci i2c time out conditions
@ 2009-07-15 7:34 Philby John
[not found] ` <1247643267.5981.82.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
0 siblings, 1 reply; 15+ messages in thread
From: Philby John @ 2009-07-15 7:34 UTC (permalink / raw)
To: linux-i2c-u79uwXL29TY76Z2rM5mHXA
Cc: davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/,
khali-PUYAD+kWke1g9hUCZPvPmw, Karicheri, Muralidharan,
Kevin Hilman
>From dbe7e824d576636bb15b82a20fd2557fddc9a8f7 Mon Sep 17 00:00:00 2001
From: Philby John <pjohn-k0rHJ+Hhz/SB+jHODAdFcQ@public.gmane.org>
Date: Tue, 14 Jul 2009 21:46:47 +0530
Subject: [PATCH] Reset i2c bus to come out of time out conditions
Get out of i2c time out condition by resetting
the i2c bus. The kernel must be robust enough to
gracefully recover from i2c bus failure without having
to reset the machine. This is done by first NACKing the slave
and then resetting the i2c bus after a certain timeout.
Signed-off-by: Philby John <pjohn-k0rHJ+Hhz/SB+jHODAdFcQ@public.gmane.org>
---
drivers/i2c/busses/i2c-davinci.c | 98 +++++++++++++++++++++++++++++++++++--
1 files changed, 92 insertions(+), 6 deletions(-)
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 17f2ee7..4ed1a4c 100755
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -35,14 +35,18 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/gpio.h>
#include <mach/hardware.h>
#include <mach/i2c.h>
+#include <mach/mux.h>
+#include <mach/cputype.h>
/* ----- global defines ----------------------------------------------- */
#define DAVINCI_I2C_TIMEOUT (1*HZ)
+#define DAVINCI_I2C_MAX_TRIES 2
#define I2C_DAVINCI_INTR_ALL (DAVINCI_I2C_IMR_AAS | \
DAVINCI_I2C_IMR_SCD | \
DAVINCI_I2C_IMR_ARDY | \
@@ -135,6 +139,50 @@ static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg)
}
/*
+ * Configure the i2c data pin as a GPIO input and the i2c clock pin as a
+ * high GPIO output.
+ */
+static void disable_i2c_pins(void)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (cpu_is_davinci_dm355()) {
+ gpio_direction_input(15);
+ gpio_direction_output(14, 0);
+ gpio_set_value(14, 1);
+ davinci_cfg_reg(DM355_I2C_SDA);
+ davinci_cfg_reg(DM355_I2C_SCL);
+ }
+ local_irq_restore(flags);
+}
+
+/* Connect the i2c pins to the i2c controller. */
+static void enable_i2c_pins(void)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (cpu_is_davinci_dm355()) {
+ davinci_cfg_reg(DM355_I2C_SDA);
+ davinci_cfg_reg(DM355_I2C_SCL);
+ }
+ local_irq_restore(flags);
+}
+
+
+/* Generate a pulse on the i2c clock pin. */
+static void pulse_i2c_clock(void)
+{
+ if (cpu_is_davinci_dm355()) {
+ gpio_set_value(14, 0);
+ udelay(20);
+ gpio_set_value(14, 1);
+ udelay(20);
+ }
+}
+
+/*
* This functions configures I2C and brings I2C out of reset.
* This function is called during I2C init function. This function
* also gets called if I2C encounters any errors.
@@ -221,14 +269,36 @@ static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev,
char allow_sleep)
{
unsigned long timeout;
+ u16 i;
+ static u16 to_cnt = 0;
+ u32 flag = 0;
timeout = jiffies + dev->adapter.timeout;
while (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG)
- & DAVINCI_I2C_STR_BB) {
- if (time_after(jiffies, timeout)) {
- dev_warn(dev->dev,
- "timeout waiting for bus ready\n");
- return -ETIMEDOUT;
+ & DAVINCI_I2C_STR_BB) {
+
+ if (to_cnt <= DAVINCI_I2C_MAX_TRIES) {
+ if (time_after(jiffies, timeout)) {
+ dev_warn(dev->dev,
+ "timeout waiting for bus ready\n");
+ to_cnt++;
+ return -ETIMEDOUT;
+ }
+ } else if (cpu_is_davinci_dm644x() || cpu_is_davinci_dm355()) {
+ to_cnt = 0;
+ dev_err(dev->dev, "initiating i2c bus recovery\n");
+ /* Send the NACK to the slave */
+ flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG);
+ flag |= DAVINCI_I2C_MDR_NACK;
+ /* write the data into mode register */
+ davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
+ /* Disable i2c */
+ disable_i2c_pins();
+ for (i = 0; i < 10; i++)
+ pulse_i2c_clock();
+ /* Re-enable i2c */
+ enable_i2c_pins();
+ i2c_davinci_init(dev);
}
if (allow_sleep)
schedule_timeout(1);
@@ -309,7 +379,23 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
r = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
dev->adapter.timeout);
if (r == 0) {
- dev_err(dev->dev, "controller timed out\n");
+ u16 i;
+ u32 flag = 0;
+ if (cpu_is_davinci_dm644x() || cpu_is_davinci_dm355()) {
+ dev_err(dev->dev, "initiating i2c bus recovery\n");
+ /* Send the NACK to the slave */
+ flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG);
+ flag |= DAVINCI_I2C_MDR_NACK;
+ /* write the data into mode register */
+ davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
+ /* Disable i2c */
+ disable_i2c_pins();
+ /* Send high and low on the SCL line */
+ for (i = 0; i < 10; i++)
+ pulse_i2c_clock();
+ /* Re-enable i2c */
+ enable_i2c_pins();
+ }
i2c_davinci_init(dev);
dev->buf_len = 0;
return -ETIMEDOUT;
--
1.6.3.3.MVISTA
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH/RFC 1/1] recover from davinci i2c time out conditions
[not found] ` <1247643267.5981.82.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
@ 2009-07-15 12:34 ` Sergei Shtylyov
[not found] ` <4A5DCCBD.909-hkdhdckH98+B+jHODAdFcQ@public.gmane.org>
2009-07-15 17:10 ` David Brownell
` (2 subsequent siblings)
3 siblings, 1 reply; 15+ messages in thread
From: Sergei Shtylyov @ 2009-07-15 12:34 UTC (permalink / raw)
To: Philby John
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA, khali-PUYAD+kWke1g9hUCZPvPmw,
davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/
Hello.
Philby John wrote:
>>From dbe7e824d576636bb15b82a20fd2557fddc9a8f7 Mon Sep 17 00:00:00 2001
> From: Philby John <pjohn-k0rHJ+Hhz/SB+jHODAdFcQ@public.gmane.org>
> Date: Tue, 14 Jul 2009 21:46:47 +0530
> Subject: [PATCH] Reset i2c bus to come out of time out conditions
> Get out of i2c time out condition by resetting
> the i2c bus. The kernel must be robust enough to
> gracefully recover from i2c bus failure without having
> to reset the machine. This is done by first NACKing the slave
> and then resetting the i2c bus after a certain timeout.
> Signed-off-by: Philby John <pjohn-k0rHJ+Hhz/SB+jHODAdFcQ@public.gmane.org>
> diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
> index 17f2ee7..4ed1a4c 100755
> --- a/drivers/i2c/busses/i2c-davinci.c
> +++ b/drivers/i2c/busses/i2c-davinci.c
> @@ -35,14 +35,18 @@
> #include <linux/interrupt.h>
> #include <linux/platform_device.h>
> #include <linux/io.h>
> +#include <linux/gpio.h>
>
> #include <mach/hardware.h>
>
> #include <mach/i2c.h>
> +#include <mach/mux.h>
> +#include <mach/cputype.h>
>
> /* ----- global defines ----------------------------------------------- */
>
> #define DAVINCI_I2C_TIMEOUT (1*HZ)
> +#define DAVINCI_I2C_MAX_TRIES 2
> #define I2C_DAVINCI_INTR_ALL (DAVINCI_I2C_IMR_AAS | \
> DAVINCI_I2C_IMR_SCD | \
> DAVINCI_I2C_IMR_ARDY | \
> @@ -135,6 +139,50 @@ static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg)
> }
>
> /*
> + * Configure the i2c data pin as a GPIO input and the i2c clock pin as a
> + * high GPIO output.
> + */
> +static void disable_i2c_pins(void)
> +{
> + unsigned long flags;
> +
> + local_irq_save(flags);
> + if (cpu_is_davinci_dm355()) {
> + gpio_direction_input(15);
> + gpio_direction_output(14, 0);
> + gpio_set_value(14, 1);
Why not just:
gpio_direction_output(14, 1);
> + davinci_cfg_reg(DM355_I2C_SDA);
> + davinci_cfg_reg(DM355_I2C_SCL);
Why enable the pins here?
> + }
> + local_irq_restore(flags);
> +}
> +
> +/* Connect the i2c pins to the i2c controller. */
> +static void enable_i2c_pins(void)
> +{
> + unsigned long flags;
> +
> + local_irq_save(flags);
> + if (cpu_is_davinci_dm355()) {
> + davinci_cfg_reg(DM355_I2C_SDA);
> + davinci_cfg_reg(DM355_I2C_SCL);
> + }
> + local_irq_restore(flags);
> +}
> +
> +
> +/* Generate a pulse on the i2c clock pin. */
> +static void pulse_i2c_clock(void)
> +{
> + if (cpu_is_davinci_dm355()) {
> + gpio_set_value(14, 0);
> + udelay(20);
> + gpio_set_value(14, 1);
> + udelay(20);
> + }
> +}
> +
> +/*
> * This functions configures I2C and brings I2C out of reset.
> * This function is called during I2C init function. This function
> * also gets called if I2C encounters any errors.
> @@ -221,14 +269,36 @@ static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev,
> char allow_sleep)
> {
> unsigned long timeout;
> + u16 i;
> + static u16 to_cnt = 0;
> + u32 flag = 0;
>
> timeout = jiffies + dev->adapter.timeout;
> while (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG)
> - & DAVINCI_I2C_STR_BB) {
> - if (time_after(jiffies, timeout)) {
> - dev_warn(dev->dev,
> - "timeout waiting for bus ready\n");
> - return -ETIMEDOUT;
> + & DAVINCI_I2C_STR_BB) {
> +
> + if (to_cnt <= DAVINCI_I2C_MAX_TRIES) {
> + if (time_after(jiffies, timeout)) {
> + dev_warn(dev->dev,
> + "timeout waiting for bus ready\n");
> + to_cnt++;
> + return -ETIMEDOUT;
> + }
> + } else if (cpu_is_davinci_dm644x() || cpu_is_davinci_dm355()) {
> + to_cnt = 0;
> + dev_err(dev->dev, "initiating i2c bus recovery\n");
> + /* Send the NACK to the slave */
> + flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG);
> + flag |= DAVINCI_I2C_MDR_NACK;
Superflous space here...
> + /* write the data into mode register */
> + davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
How come you're reading from the interrupt mask register but writing
into the mode register which has different layout? :-O
> + /* Disable i2c */
> + disable_i2c_pins();
> + for (i = 0; i < 10; i++)
> + pulse_i2c_clock();
> + /* Re-enable i2c */
> + enable_i2c_pins();
> + i2c_davinci_init(dev);
> }
> if (allow_sleep)
> schedule_timeout(1);
> @@ -309,7 +379,23 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
> r = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
> dev->adapter.timeout);
> if (r == 0) {
> - dev_err(dev->dev, "controller timed out\n");
> + u16 i;
> + u32 flag = 0;
> + if (cpu_is_davinci_dm644x() || cpu_is_davinci_dm355()) {
> + dev_err(dev->dev, "initiating i2c bus recovery\n");
> + /* Send the NACK to the slave */
> + flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG);
> + flag |= DAVINCI_I2C_MDR_NACK;
... and here.
> + /* write the data into mode register */
> + davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
> + /* Disable i2c */
> + disable_i2c_pins();
> + /* Send high and low on the SCL line */
> + for (i = 0; i < 10; i++)
> + pulse_i2c_clock();
> + /* Re-enable i2c */
> + enable_i2c_pins();
Please factor out the completely identical recovery procedures into the
> + }
> i2c_davinci_init(dev);
> dev->buf_len = 0;
> return -ETIMEDOUT;
WBR, Sergei
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH/RFC 1/1] recover from davinci i2c time out conditions
[not found] ` <1247643267.5981.82.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2009-07-15 12:34 ` Sergei Shtylyov
@ 2009-07-15 17:10 ` David Brownell
[not found] ` <200907151010.18709.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2009-07-15 17:15 ` Troy Kisky
2009-07-22 11:03 ` Nitin Mahajan
3 siblings, 1 reply; 15+ messages in thread
From: David Brownell @ 2009-07-15 17:10 UTC (permalink / raw)
To: davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/
Cc: khali-PUYAD+kWke1g9hUCZPvPmw, linux-i2c-u79uwXL29TY76Z2rM5mHXA
On Wednesday 15 July 2009, Philby John wrote:
> /*
> + * Configure the i2c data pin as a GPIO input and the i2c clock pin as a
> + * high GPIO output.
> + */
> +static void disable_i2c_pins(void)
> +{
> + unsigned long flags;
> +
> + local_irq_save(flags);
> + if (cpu_is_davinci_dm355()) {
> + gpio_direction_input(15);
> + gpio_direction_output(14, 0);
> + gpio_set_value(14, 1);
As noted: gpio_direction_output(14, 1) is better.
> + davinci_cfg_reg(DM355_I2C_SDA);
> + davinci_cfg_reg(DM355_I2C_SCL);
> + }
> + local_irq_restore(flags);
> +}
> +
> +/* Connect the i2c pins to the i2c controller. */
> +static void enable_i2c_pins(void)
> +{
> + unsigned long flags;
> +
> + local_irq_save(flags);
> + if (cpu_is_davinci_dm355()) {
> + davinci_cfg_reg(DM355_I2C_SDA);
> + davinci_cfg_reg(DM355_I2C_SCL);
> + }
> + local_irq_restore(flags);
> +}
> +
> +
> +/* Generate a pulse on the i2c clock pin. */
> +static void pulse_i2c_clock(void)
> +{
> + if (cpu_is_davinci_dm355()) {
> + gpio_set_value(14, 0);
> + udelay(20);
> + gpio_set_value(14, 1);
> + udelay(20);
> + }
> +}
> +
The general problem with how that's done is that the SoC-specific
bits should not be in this file. The mach-davinc/dm355.c file
should hold that configuration; likewise for other SoCs.
> + /* Disable i2c */
> + disable_i2c_pins();
> + for (i = 0; i < 10; i++)
> + pulse_i2c_clock();
> + /* Re-enable i2c */
> + enable_i2c_pins();
A better description of this is that you're trying to follow
the I2Cv3 instructions about how to *reset* the bus, yes?
> + i2c_davinci_init(dev);
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH/RFC 1/1] recover from davinci i2c time out conditions
[not found] ` <1247643267.5981.82.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2009-07-15 12:34 ` Sergei Shtylyov
2009-07-15 17:10 ` David Brownell
@ 2009-07-15 17:15 ` Troy Kisky
[not found] ` <4A5E0E98.2030108-Q5RJGjKts06CY9SHAMCTRUEOCMrvLtNR@public.gmane.org>
2009-07-22 11:03 ` Nitin Mahajan
3 siblings, 1 reply; 15+ messages in thread
From: Troy Kisky @ 2009-07-15 17:15 UTC (permalink / raw)
To: Philby John
Cc: khali-PUYAD+kWke1g9hUCZPvPmw,
davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/,
linux-i2c-u79uwXL29TY76Z2rM5mHXA
Philby John wrote:
>>From dbe7e824d576636bb15b82a20fd2557fddc9a8f7 Mon Sep 17 00:00:00 2001
> From: Philby John <pjohn-k0rHJ+Hhz/SB+jHODAdFcQ@public.gmane.org>
> Date: Tue, 14 Jul 2009 21:46:47 +0530
> Subject: [PATCH] Reset i2c bus to come out of time out conditions
>
> Get out of i2c time out condition by resetting
> the i2c bus. The kernel must be robust enough to
> gracefully recover from i2c bus failure without having
> to reset the machine. This is done by first NACKing the slave
> and then resetting the i2c bus after a certain timeout.
>
> Signed-off-by: Philby John <pjohn-k0rHJ+Hhz/SB+jHODAdFcQ@public.gmane.org>
> ---
I personally like the idea behind this patch. But I have
heard others argue against it. But it is not related to the
^C issue others have mentioned. That should not happen in
the GIT kernel.
> drivers/i2c/busses/i2c-davinci.c | 98 +++++++++++++++++++++++++++++++++++--
> 1 files changed, 92 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
> index 17f2ee7..4ed1a4c 100755
> --- a/drivers/i2c/busses/i2c-davinci.c
> +++ b/drivers/i2c/busses/i2c-davinci.c
> @@ -35,14 +35,18 @@
> #include <linux/interrupt.h>
> #include <linux/platform_device.h>
> #include <linux/io.h>
> +#include <linux/gpio.h>
>
> #include <mach/hardware.h>
>
> #include <mach/i2c.h>
> +#include <mach/mux.h>
> +#include <mach/cputype.h>
>
> /* ----- global defines ----------------------------------------------- */
>
> #define DAVINCI_I2C_TIMEOUT (1*HZ)
> +#define DAVINCI_I2C_MAX_TRIES 2
> #define I2C_DAVINCI_INTR_ALL (DAVINCI_I2C_IMR_AAS | \
> DAVINCI_I2C_IMR_SCD | \
> DAVINCI_I2C_IMR_ARDY | \
> @@ -135,6 +139,50 @@ static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg)
> }
>
> /*
> + * Configure the i2c data pin as a GPIO input and the i2c clock pin as a
> + * high GPIO output.
> + */
> +static void disable_i2c_pins(void)
> +{
> + unsigned long flags;
> +
> + local_irq_save(flags);
> + if (cpu_is_davinci_dm355()) {
> + gpio_direction_input(15);
> + gpio_direction_output(14, 0);
> + gpio_set_value(14, 1);
> + davinci_cfg_reg(DM355_I2C_SDA);
> + davinci_cfg_reg(DM355_I2C_SCL);
> + }
> + local_irq_restore(flags);
> +}
> +
> +/* Connect the i2c pins to the i2c controller. */
> +static void enable_i2c_pins(void)
> +{
> + unsigned long flags;
> +
> + local_irq_save(flags);
> + if (cpu_is_davinci_dm355()) {
> + davinci_cfg_reg(DM355_I2C_SDA);
> + davinci_cfg_reg(DM355_I2C_SCL);
> + }
> + local_irq_restore(flags);
> +}
> +
> +
> +/* Generate a pulse on the i2c clock pin. */
> +static void pulse_i2c_clock(void)
> +{
> + if (cpu_is_davinci_dm355()) {
> + gpio_set_value(14, 0);
> + udelay(20);
> + gpio_set_value(14, 1);
> + udelay(20);
> + }
> +}
> +
> +/*
> * This functions configures I2C and brings I2C out of reset.
> * This function is called during I2C init function. This function
> * also gets called if I2C encounters any errors.
> @@ -221,14 +269,36 @@ static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev,
> char allow_sleep)
> {
> unsigned long timeout;
> + u16 i;
> + static u16 to_cnt = 0;
> + u32 flag = 0;
>
> timeout = jiffies + dev->adapter.timeout;
> while (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG)
> - & DAVINCI_I2C_STR_BB) {
> - if (time_after(jiffies, timeout)) {
> - dev_warn(dev->dev,
> - "timeout waiting for bus ready\n");
> - return -ETIMEDOUT;
> + & DAVINCI_I2C_STR_BB) {
> +
> + if (to_cnt <= DAVINCI_I2C_MAX_TRIES) {
> + if (time_after(jiffies, timeout)) {
> + dev_warn(dev->dev,
> + "timeout waiting for bus ready\n");
> + to_cnt++;
> + return -ETIMEDOUT;
> + }
> + } else if (cpu_is_davinci_dm644x() || cpu_is_davinci_dm355()) {
I would not initiate recovery until a timeout occurs.
This can be a multi master bus, so a busy condition
may be valid. Then, after multiple timeouts and recovery attempts,
return -ETIMEDOUT
> + to_cnt = 0;
> + dev_err(dev->dev, "initiating i2c bus recovery\n");
> + /* Send the NACK to the slave */
> + flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG);
> + flag |= DAVINCI_I2C_MDR_NACK;
> + /* write the data into mode register */
> + davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
> + /* Disable i2c */
> + disable_i2c_pins();
> + for (i = 0; i < 10; i++)
> + pulse_i2c_clock();
> + /* Re-enable i2c */
> + enable_i2c_pins();
> + i2c_davinci_init(dev);
> }
> if (allow_sleep)
> schedule_timeout(1);
> @@ -309,7 +379,23 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
> r = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
> dev->adapter.timeout);
> if (r == 0) {
> - dev_err(dev->dev, "controller timed out\n");
> + u16 i;
> + u32 flag = 0;
> + if (cpu_is_davinci_dm644x() || cpu_is_davinci_dm355()) {
> + dev_err(dev->dev, "initiating i2c bus recovery\n");
> + /* Send the NACK to the slave */
> + flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG);
> + flag |= DAVINCI_I2C_MDR_NACK;
> + /* write the data into mode register */
> + davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
> + /* Disable i2c */
> + disable_i2c_pins();
> + /* Send high and low on the SCL line */
> + for (i = 0; i < 10; i++)
> + pulse_i2c_clock();
> + /* Re-enable i2c */
> + enable_i2c_pins();
> + }
> i2c_davinci_init(dev);
> dev->buf_len = 0;
> return -ETIMEDOUT;
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH/RFC 1/1] recover from davinci i2c time out conditions
[not found] ` <1247643267.5981.82.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
` (2 preceding siblings ...)
2009-07-15 17:15 ` Troy Kisky
@ 2009-07-22 11:03 ` Nitin Mahajan
[not found] ` <218571.29671.qm-LK+a5U5w+t2B9c0Qi4KiSl5cfvJIxWXgQQ4Iyu8u01E@public.gmane.org>
3 siblings, 1 reply; 15+ messages in thread
From: Nitin Mahajan @ 2009-07-22 11:03 UTC (permalink / raw)
To: Philby John, linux-i2c-u79uwXL29TY76Z2rM5mHXA
Cc: khali-PUYAD+kWke1g9hUCZPvPmw,
davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/
Hello,
----- Original Message ----
> From: Philby John <pjohn@in.mvista.com>
> To: linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Cc: khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org; davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org
> Sent: Wednesday, July 15, 2009 13:04:27
> Subject: [PATCH/RFC 1/1] recover from davinci i2c time out conditions
>
> >From dbe7e824d576636bb15b82a20fd2557fddc9a8f7 Mon Sep 17 00:00:00 2001
> From: Philby John
> Date: Tue, 14 Jul 2009 21:46:47 +0530
> Subject: [PATCH] Reset i2c bus to come out of time out conditions
>
> Get out of i2c time out condition by resetting
> the i2c bus. The kernel must be robust enough to
> gracefully recover from i2c bus failure without having
> to reset the machine. This is done by first NACKing the slave
> and then resetting the i2c bus after a certain timeout.
>
> Signed-off-by: Philby John
I tried this on DM6443 based board with 2.6.18 kernel. The result I am posting below. It gives controller time out again and again.
dhcppc9 login: i2c_davinci i2c_davinci.1: controller timed out
i2c_davinci i2c_davinci.1: initiating i2c bus recovery
i2c_davinci i2c_davinci.1: controller timed out
i2c_davinci i2c_davinci.1: initiating i2c bus recovery
i2c_davinci i2c_davinci.1: controller timed out
i2c_davinci i2c_davinci.1: initiating i2c bus recovery
i2c_davinci i2c_davinci.1: controller timed out
i2c_davinci i2c_davinci.1: initiating i2c bus recovery
i2c_davinci i2c_davinci.1: controller timed out
i2c_davinci i2c_davinci.1: initiating i2c bus recovery
i2c_davinci i2c_davinci.1: controller timed out
i2c_davinci i2c_davinci.1: initiating i2c bus recovery
i2c_davinci i2c_davinci.1: controller timed out
i2c_davinci i2c_davinci.1: initiating i2c bus recovery
i2c_davinci i2c_davinci.1: controller timed out
i2c_davinci i2c_davinci.1: initiating i2c bus recovery
i2c_davinci i2c_davinci.1: controller timed out
i2c_davinci i2c_davinci.1: initiating i2c bus recovery
i2c_davinci i2c_davinci.1: controller timed out
i2c_davinci i2c_davinci.1: initiating i2c bus recovery
i2c_davinci i2c_davinci.1: controller timed out
i2c_davinci i2c_davinci.1: initiating i2c bus recovery
regards
-Nitin
> ---
> drivers/i2c/busses/i2c-davinci.c | 98 +++++++++++++++++++++++++++++++++++--
> 1 files changed, 92 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
> index 17f2ee7..4ed1a4c 100755
> --- a/drivers/i2c/busses/i2c-davinci.c
> +++ b/drivers/i2c/busses/i2c-davinci.c
> @@ -35,14 +35,18 @@
> #include
> #include
> #include
> +#include
>
> #include
>
> #include
> +#include
> +#include
>
> /* ----- global defines ----------------------------------------------- */
>
> #define DAVINCI_I2C_TIMEOUT (1*HZ)
> +#define DAVINCI_I2C_MAX_TRIES 2
> #define I2C_DAVINCI_INTR_ALL (DAVINCI_I2C_IMR_AAS | \
> DAVINCI_I2C_IMR_SCD | \
> DAVINCI_I2C_IMR_ARDY | \
> @@ -135,6 +139,50 @@ static inline u16 davinci_i2c_read_reg(struct
> davinci_i2c_dev *i2c_dev, int reg)
> }
>
> /*
> + * Configure the i2c data pin as a GPIO input and the i2c clock pin as a
> + * high GPIO output.
> + */
> +static void disable_i2c_pins(void)
> +{
> + unsigned long flags;
> +
> + local_irq_save(flags);
> + if (cpu_is_davinci_dm355()) {
> + gpio_direction_input(15);
> + gpio_direction_output(14, 0);
> + gpio_set_value(14, 1);
> + davinci_cfg_reg(DM355_I2C_SDA);
> + davinci_cfg_reg(DM355_I2C_SCL);
> + }
> + local_irq_restore(flags);
> +}
> +
> +/* Connect the i2c pins to the i2c controller. */
> +static void enable_i2c_pins(void)
> +{
> + unsigned long flags;
> +
> + local_irq_save(flags);
> + if (cpu_is_davinci_dm355()) {
> + davinci_cfg_reg(DM355_I2C_SDA);
> + davinci_cfg_reg(DM355_I2C_SCL);
> + }
> + local_irq_restore(flags);
> +}
> +
> +
> +/* Generate a pulse on the i2c clock pin. */
> +static void pulse_i2c_clock(void)
> +{
> + if (cpu_is_davinci_dm355()) {
> + gpio_set_value(14, 0);
> + udelay(20);
> + gpio_set_value(14, 1);
> + udelay(20);
> + }
> +}
> +
> +/*
> * This functions configures I2C and brings I2C out of reset.
> * This function is called during I2C init function. This function
> * also gets called if I2C encounters any errors.
> @@ -221,14 +269,36 @@ static int i2c_davinci_wait_bus_not_busy(struct
> davinci_i2c_dev *dev,
> char allow_sleep)
> {
> unsigned long timeout;
> + u16 i;
> + static u16 to_cnt = 0;
> + u32 flag = 0;
>
> timeout = jiffies + dev->adapter.timeout;
> while (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG)
> - & DAVINCI_I2C_STR_BB) {
> - if (time_after(jiffies, timeout)) {
> - dev_warn(dev->dev,
> - "timeout waiting for bus ready\n");
> - return -ETIMEDOUT;
> + & DAVINCI_I2C_STR_BB) {
> +
> + if (to_cnt <= DAVINCI_I2C_MAX_TRIES) {
> + if (time_after(jiffies, timeout)) {
> + dev_warn(dev->dev,
> + "timeout waiting for bus ready\n");
> + to_cnt++;
> + return -ETIMEDOUT;
> + }
> + } else if (cpu_is_davinci_dm644x() || cpu_is_davinci_dm355()) {
> + to_cnt = 0;
> + dev_err(dev->dev, "initiating i2c bus recovery\n");
> + /* Send the NACK to the slave */
> + flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG);
> + flag |= DAVINCI_I2C_MDR_NACK;
> + /* write the data into mode register */
> + davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
> + /* Disable i2c */
> + disable_i2c_pins();
> + for (i = 0; i < 10; i++)
> + pulse_i2c_clock();
> + /* Re-enable i2c */
> + enable_i2c_pins();
> + i2c_davinci_init(dev);
> }
> if (allow_sleep)
> schedule_timeout(1);
> @@ -309,7 +379,23 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct
> i2c_msg *msg, int stop)
> r = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
> dev->adapter.timeout);
> if (r == 0) {
> - dev_err(dev->dev, "controller timed out\n");
> + u16 i;
> + u32 flag = 0;
> + if (cpu_is_davinci_dm644x() || cpu_is_davinci_dm355()) {
> + dev_err(dev->dev, "initiating i2c bus recovery\n");
> + /* Send the NACK to the slave */
> + flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG);
> + flag |= DAVINCI_I2C_MDR_NACK;
> + /* write the data into mode register */
> + davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
> + /* Disable i2c */
> + disable_i2c_pins();
> + /* Send high and low on the SCL line */
> + for (i = 0; i < 10; i++)
> + pulse_i2c_clock();
> + /* Re-enable i2c */
> + enable_i2c_pins();
> + }
> i2c_davinci_init(dev);
> dev->buf_len = 0;
> return -ETIMEDOUT;
> --
> 1.6.3.3.MVISTA
>
>
> _______________________________________________
> Davinci-linux-open-source mailing list
> Davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi+G/Ez6ZCGd0@public.gmane.orgcom
> http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
New Email addresses available on Yahoo!
Get the Email name you've always wanted on the new @ymail and @rocketmail.
Hurry before someone else does!
http://mail.promotions.yahoo.com/newdomains/aa/
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH/RFC 1/1] recover from davinci i2c time out conditions
[not found] ` <218571.29671.qm-LK+a5U5w+t2B9c0Qi4KiSl5cfvJIxWXgQQ4Iyu8u01E@public.gmane.org>
@ 2009-07-22 11:14 ` Philby John
[not found] ` <1248261275.4077.4.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
0 siblings, 1 reply; 15+ messages in thread
From: Philby John @ 2009-07-22 11:14 UTC (permalink / raw)
To: Nitin Mahajan
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA, khali-PUYAD+kWke1g9hUCZPvPmw,
davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/
On Wed, 2009-07-22 at 04:03 -0700, Nitin Mahajan wrote:
> Hello,
>
> ----- Original Message ----
> > From: Philby John <pjohn-k0rHJ+Hhz/SB+jHODAdFcQ@public.gmane.org>
> > To: linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > Cc: khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org; davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org
> > Sent: Wednesday, July 15, 2009 13:04:27
> > Subject: [PATCH/RFC 1/1] recover from davinci i2c time out conditions
> >
> > >From dbe7e824d576636bb15b82a20fd2557fddc9a8f7 Mon Sep 17 00:00:00 2001
> > From: Philby John
> > Date: Tue, 14 Jul 2009 21:46:47 +0530
> > Subject: [PATCH] Reset i2c bus to come out of time out conditions
> >
> > Get out of i2c time out condition by resetting
> > the i2c bus. The kernel must be robust enough to
> > gracefully recover from i2c bus failure without having
> > to reset the machine. This is done by first NACKing the slave
> > and then resetting the i2c bus after a certain timeout.
> >
> > Signed-off-by: Philby John
>
> I tried this on DM6443 based board with 2.6.18 kernel. The result I am posting below. It gives controller time out again and again.
>
> dhcppc9 login: i2c_davinci i2c_davinci.1: controller timed out
> i2c_davinci i2c_davinci.1: initiating i2c bus recovery
> i2c_davinci i2c_davinci.1: controller timed out
> i2c_davinci i2c_davinci.1: initiating i2c bus recovery
There is something gravely wrong about this patch and I would submit a
fix shortly incorporating the review comments. But please be aware that
I do not guarantee a definitive time line for a fix cause I have much at
hand at the moment.
Regards,
Philby
^ permalink raw reply [flat|nested] 15+ messages in thread
* RE: [PATCH/RFC 1/1] recover from davinci i2c time out conditions
[not found] ` <4A5E0E98.2030108-Q5RJGjKts06CY9SHAMCTRUEOCMrvLtNR@public.gmane.org>
@ 2009-07-24 14:34 ` Karicheri, Muralidharan
[not found] ` <A69FA2915331DC488A831521EAE36FE40144FDB54B-UmuGNrFEPrGIQmiDNMet8wC/G2K4zDHf@public.gmane.org>
2009-11-23 15:24 ` Philby John
1 sibling, 1 reply; 15+ messages in thread
From: Karicheri, Muralidharan @ 2009-07-24 14:34 UTC (permalink / raw)
To: Troy Kisky, Philby John
Cc: khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org,
davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org,
linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Troy,
>
<Snip>
>I personally like the idea behind this patch. But I have
>heard others argue against it. But it is not related to the
>^C issue others have mentioned.That should not happen in
>the GIT kernel.
>
I do get this ^c timeout issue in DM6446 and DM355. I have the video loopback application running that uses tvp5146 to capture from a video source. When I kill the application it starts giving the error while
the tvp5146 driver tries to send i2c commands to stop capture at tvp5146.
But in this case, it works again when the application is run again. But when I have mt9t031 connected and I do the same thing, it also fails with timeout when application is killed. But it never recovers and I have to reboot the board to recover from the error. So what you mean by "That should not happen in the GIT kernel" ?
Could you explain please?
Murali
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH/RFC 1/1] recover from davinci i2c time out conditions
[not found] ` <A69FA2915331DC488A831521EAE36FE40144FDB54B-UmuGNrFEPrGIQmiDNMet8wC/G2K4zDHf@public.gmane.org>
@ 2009-07-24 18:14 ` Troy Kisky
0 siblings, 0 replies; 15+ messages in thread
From: Troy Kisky @ 2009-07-24 18:14 UTC (permalink / raw)
To: Karicheri, Muralidharan
Cc: Philby John, khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org,
davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org,
linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Karicheri, Muralidharan wrote:
> Troy,
> <Snip>
>
>> I personally like the idea behind this patch. But I have
>> heard others argue against it. But it is not related to the
>> ^C issue others have mentioned.That should not happen in
>> the GIT kernel.
>>
> I do get this ^c timeout issue in DM6446 and DM355. I have the video loopback application running that uses tvp5146 to capture from a video source. When I kill the application it starts giving the error while
> the tvp5146 driver tries to send i2c commands to stop capture at tvp5146.
> But in this case, it works again when the application is run again. But when I have mt9t031 connected and I do the same thing, it also fails with timeout when application is killed. But it never recovers and I have to reboot the board to recover from the error. So what you mean by "That should not happen in the GIT kernel" ?
>
> Could you explain please?
>
> Murali
>
please see commit 5a0d5f5ffa5d294d895ef54fc220c6182db63998
I don't know if your issue has the same root cause.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH/RFC 1/1] recover from davinci i2c time out conditions
[not found] ` <1248261275.4077.4.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
@ 2009-09-19 5:12 ` Craig Matsuura
[not found] ` <200909182312.58018.cmatsuura-/SMLdF/PHsZWk0Htik3J/w@public.gmane.org>
0 siblings, 1 reply; 15+ messages in thread
From: Craig Matsuura @ 2009-09-19 5:12 UTC (permalink / raw)
To: davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/
Cc: khali-PUYAD+kWke1g9hUCZPvPmw, linux-i2c-u79uwXL29TY76Z2rM5mHXA
[-- Attachment #1.1: Type: text/plain, Size: 2562 bytes --]
The patch submitted appears specific to the dm355. The changes are very
similar to the 2.6.10 kernel from mv. If the correct gpio's and pinmux are
disabled/enabled it should work for the dm644x.
I took the patch from Philby and tried it on our dm6443 platform (on a 2.6.28
kernel) and it appears to work for the problem we have when the i2c appears to
lock up.
Craig
On Wednesday 22 July 2009 5:14:35 am Philby John wrote:
> On Wed, 2009-07-22 at 04:03 -0700, Nitin Mahajan wrote:
> > Hello,
> >
> > ----- Original Message ----
> >
> > > From: Philby John <pjohn-k0rHJ+Hhz/SB+jHODAdFcQ@public.gmane.org>
> > > To: linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > > Cc: khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org; davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org
> > > Sent: Wednesday, July 15, 2009 13:04:27
> > > Subject: [PATCH/RFC 1/1] recover from davinci i2c time out conditions
> > >
> > > >From dbe7e824d576636bb15b82a20fd2557fddc9a8f7 Mon Sep 17 00:00:00 2001
> > >
> > > From: Philby John
> > > Date: Tue, 14 Jul 2009 21:46:47 +0530
> > > Subject: [PATCH] Reset i2c bus to come out of time out conditions
> > >
> > > Get out of i2c time out condition by resetting
> > > the i2c bus. The kernel must be robust enough to
> > > gracefully recover from i2c bus failure without having
> > > to reset the machine. This is done by first NACKing the slave
> > > and then resetting the i2c bus after a certain timeout.
> > >
> > > Signed-off-by: Philby John
> >
> > I tried this on DM6443 based board with 2.6.18 kernel. The result I am
> > posting below. It gives controller time out again and again.
> >
> > dhcppc9 login: i2c_davinci i2c_davinci.1: controller timed out
> > i2c_davinci i2c_davinci.1: initiating i2c bus recovery
> > i2c_davinci i2c_davinci.1: controller timed out
> > i2c_davinci i2c_davinci.1: initiating i2c bus recovery
>
> There is something gravely wrong about this patch and I would submit a
> fix shortly incorporating the review comments. But please be aware that
> I do not guarantee a definitive time line for a fix cause I have much at
> hand at the moment.
>
>
> Regards,
> Philby
>
>
> _______________________________________________
> Davinci-linux-open-source mailing list
> Davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org
> http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
--
Craig Matsuura - Principal Engineer
Control4
11734 South Election Road - Suite 200
Salt Lake City, UT 84020-6432
PH: 801-523-3161
FX: 801-523-3199
[-- Attachment #1.2: Type: text/html, Size: 4477 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH/RFC 1/1] recover from davinci i2c time out conditions
[not found] ` <200909182312.58018.cmatsuura-/SMLdF/PHsZWk0Htik3J/w@public.gmane.org>
@ 2009-09-21 6:31 ` Philby John
[not found] ` <1253514660.4507.2.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
0 siblings, 1 reply; 15+ messages in thread
From: Philby John @ 2009-09-21 6:31 UTC (permalink / raw)
To: Craig Matsuura
Cc: davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/,
Nitin Mahajan, khali-PUYAD+kWke1g9hUCZPvPmw,
linux-i2c-u79uwXL29TY76Z2rM5mHXA
Hello Craig,
Good to know. With out any modifications on a DM6443?
Regards,
Philby
On Fri, 2009-09-18 at 23:12 -0600, Craig Matsuura wrote:
> The patch submitted appears specific to the dm355. The changes are
> very similar to the 2.6.10 kernel from mv. If the correct gpio's and
> pinmux are disabled/enabled it should work for the dm644x.
>
>
>
> I took the patch from Philby and tried it on our dm6443 platform (on a
> 2.6.28 kernel) and it appears to work for the problem we have when the
> i2c appears to lock up.
>
>
>
> Craig
>
>
>
>
> On Wednesday 22 July 2009 5:14:35 am Philby John wrote:
> > On Wed, 2009-07-22 at 04:03 -0700, Nitin Mahajan wrote:
> > > Hello,
> > >
> > > ----- Original Message ----
> > >
> > > > From: Philby John <pjohn-k0rHJ+Hhz/SB+jHODAdFcQ@public.gmane.org>
> > > > To: linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > > > Cc: khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org;
> davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org
> > > > Sent: Wednesday, July 15, 2009 13:04:27
> > > > Subject: [PATCH/RFC 1/1] recover from davinci i2c time out
> conditions
> > > >
> > > > >From dbe7e824d576636bb15b82a20fd2557fddc9a8f7 Mon Sep 17
> 00:00:00 2001
> > > >
> > > > From: Philby John
> > > > Date: Tue, 14 Jul 2009 21:46:47 +0530
> > > > Subject: [PATCH] Reset i2c bus to come out of time out
> conditions
> > > >
> > > > Get out of i2c time out condition by resetting
> > > > the i2c bus. The kernel must be robust enough to
> > > > gracefully recover from i2c bus failure without having
> > > > to reset the machine. This is done by first NACKing the slave
> > > > and then resetting the i2c bus after a certain timeout.
> > > >
> > > > Signed-off-by: Philby John
> > >
> > > I tried this on DM6443 based board with 2.6.18 kernel. The result
> I am
> > > posting below. It gives controller time out again and again.
> > >
> > > dhcppc9 login: i2c_davinci i2c_davinci.1: controller timed out
> > > i2c_davinci i2c_davinci.1: initiating i2c bus recovery
> > > i2c_davinci i2c_davinci.1: controller timed out
> > > i2c_davinci i2c_davinci.1: initiating i2c bus recovery
> >
> > There is something gravely wrong about this patch and I would submit
> a
> > fix shortly incorporating the review comments. But please be aware
> that
> > I do not guarantee a definitive time line for a fix cause I have
> much at
> > hand at the moment.
> >
> >
> > Regards,
> > Philby
> >
> >
> > _______________________________________________
> > Davinci-linux-open-source mailing list
> > Davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org
> >
> http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
>
> --
>
>
>
>
>
> ______________________________________________________________________
>
>
> Craig Matsuura - Principal Engineer
> Control4
> 11734 South Election Road - Suite 200
> Salt Lake City, UT 84020-6432
> PH: 801-523-3161
> FX: 801-523-3199
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH/RFC 1/1] recover from davinci i2c time out conditions
[not found] ` <1253514660.4507.2.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
@ 2009-09-21 13:34 ` Craig Matsuura
2009-09-21 13:41 ` Craig Matsuura
1 sibling, 0 replies; 15+ messages in thread
From: Craig Matsuura @ 2009-09-21 13:34 UTC (permalink / raw)
To: Philby John
Cc: khali-PUYAD+kWke1g9hUCZPvPmw,
davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/,
linux-i2c-u79uwXL29TY76Z2rM5mHXA
[-- Attachment #1.1: Type: text/plain, Size: 3623 bytes --]
i did modify the patch to work for the dm644x. I believe it is correct, I
looked at the 2.6.10 kernel and made the changes to your the i2c-davinci.c
after patching it with your patch.
It did nothing without the changes from the 2.6.10 kernel.
Craig
On Monday 21 September 2009 12:31:00 am Philby John wrote:
> Hello Craig,
>
> Good to know. With out any modifications on a DM6443?
>
> Regards,
> Philby
>
> On Fri, 2009-09-18 at 23:12 -0600, Craig Matsuura wrote:
> > The patch submitted appears specific to the dm355. The changes are
> > very similar to the 2.6.10 kernel from mv. If the correct gpio's and
> > pinmux are disabled/enabled it should work for the dm644x.
> >
> >
> >
> > I took the patch from Philby and tried it on our dm6443 platform (on a
> > 2.6.28 kernel) and it appears to work for the problem we have when the
> > i2c appears to lock up.
> >
> >
> >
> > Craig
> >
> > On Wednesday 22 July 2009 5:14:35 am Philby John wrote:
> > > On Wed, 2009-07-22 at 04:03 -0700, Nitin Mahajan wrote:
> > > > Hello,
> > > >
> > > > ----- Original Message ----
> > > >
> > > > > From: Philby John <pjohn-k0rHJ+Hhz/SB+jHODAdFcQ@public.gmane.org>
> > > > > To: linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > > > > Cc: khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org;
> >
> > davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org
> >
> > > > > Sent: Wednesday, July 15, 2009 13:04:27
> > > > > Subject: [PATCH/RFC 1/1] recover from davinci i2c time out
> >
> > conditions
> >
> > > > > >From dbe7e824d576636bb15b82a20fd2557fddc9a8f7 Mon Sep 17
> >
> > 00:00:00 2001
> >
> > > > > From: Philby John
> > > > > Date: Tue, 14 Jul 2009 21:46:47 +0530
> > > > > Subject: [PATCH] Reset i2c bus to come out of time out
> >
> > conditions
> >
> > > > > Get out of i2c time out condition by resetting
> > > > > the i2c bus. The kernel must be robust enough to
> > > > > gracefully recover from i2c bus failure without having
> > > > > to reset the machine. This is done by first NACKing the slave
> > > > > and then resetting the i2c bus after a certain timeout.
> > > > >
> > > > > Signed-off-by: Philby John
> > > >
> > > > I tried this on DM6443 based board with 2.6.18 kernel. The result
> >
> > I am
> >
> > > > posting below. It gives controller time out again and again.
> > > >
> > > > dhcppc9 login: i2c_davinci i2c_davinci.1: controller timed out
> > > > i2c_davinci i2c_davinci.1: initiating i2c bus recovery
> > > > i2c_davinci i2c_davinci.1: controller timed out
> > > > i2c_davinci i2c_davinci.1: initiating i2c bus recovery
> > >
> > > There is something gravely wrong about this patch and I would submit
> >
> > a
> >
> > > fix shortly incorporating the review comments. But please be aware
> >
> > that
> >
> > > I do not guarantee a definitive time line for a fix cause I have
> >
> > much at
> >
> > > hand at the moment.
> > >
> > >
> > > Regards,
> > > Philby
> > >
> > >
> > > _______________________________________________
> > > Davinci-linux-open-source mailing list
> > > Davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org
> >
> > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
> >
> > --
> >
> >
> >
> >
> >
> > ______________________________________________________________________
> >
> >
> > Craig Matsuura - Principal Engineer
> > Control4
> > 11734 South Election Road - Suite 200
> > Salt Lake City, UT 84020-6432
> > PH: 801-523-3161
> > FX: 801-523-3199
--
Craig Matsuura - Principal Engineer
Control4
11734 South Election Road - Suite 200
Salt Lake City, UT 84020-6432
PH: 801-523-3161
FX: 801-523-3199
[-- Attachment #1.2: Type: text/html, Size: 6378 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH/RFC 1/1] recover from davinci i2c time out conditions
[not found] ` <1253514660.4507.2.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2009-09-21 13:34 ` Craig Matsuura
@ 2009-09-21 13:41 ` Craig Matsuura
1 sibling, 0 replies; 15+ messages in thread
From: Craig Matsuura @ 2009-09-21 13:41 UTC (permalink / raw)
To: Philby John
Cc: khali-PUYAD+kWke1g9hUCZPvPmw,
davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/,
linux-i2c-u79uwXL29TY76Z2rM5mHXA
[-- Attachment #1.1: Type: text/plain, Size: 3800 bytes --]
Philby,
Sorry, I forgot to mention, I did correct a problem with accessing a regs, it
is where yo usend a NACK. I changed the read from DAVINCI_I2C_IMR_REG to
DAVINCI_I2C_MDR_REG.
+ flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG);
+ flag |= DAVINCI_I2C_MDR_NACK;
+ /* write the data into mode register */
+ davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
Craig
On Monday 21 September 2009 12:31:00 am Philby John wrote:
> Hello Craig,
>
> Good to know. With out any modifications on a DM6443?
>
> Regards,
> Philby
>
> On Fri, 2009-09-18 at 23:12 -0600, Craig Matsuura wrote:
> > The patch submitted appears specific to the dm355. The changes are
> > very similar to the 2.6.10 kernel from mv. If the correct gpio's and
> > pinmux are disabled/enabled it should work for the dm644x.
> >
> >
> >
> > I took the patch from Philby and tried it on our dm6443 platform (on a
> > 2.6.28 kernel) and it appears to work for the problem we have when the
> > i2c appears to lock up.
> >
> >
> >
> > Craig
> >
> > On Wednesday 22 July 2009 5:14:35 am Philby John wrote:
> > > On Wed, 2009-07-22 at 04:03 -0700, Nitin Mahajan wrote:
> > > > Hello,
> > > >
> > > > ----- Original Message ----
> > > >
> > > > > From: Philby John <pjohn-k0rHJ+Hhz/SB+jHODAdFcQ@public.gmane.org>
> > > > > To: linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > > > > Cc: khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org;
> >
> > davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org
> >
> > > > > Sent: Wednesday, July 15, 2009 13:04:27
> > > > > Subject: [PATCH/RFC 1/1] recover from davinci i2c time out
> >
> > conditions
> >
> > > > > >From dbe7e824d576636bb15b82a20fd2557fddc9a8f7 Mon Sep 17
> >
> > 00:00:00 2001
> >
> > > > > From: Philby John
> > > > > Date: Tue, 14 Jul 2009 21:46:47 +0530
> > > > > Subject: [PATCH] Reset i2c bus to come out of time out
> >
> > conditions
> >
> > > > > Get out of i2c time out condition by resetting
> > > > > the i2c bus. The kernel must be robust enough to
> > > > > gracefully recover from i2c bus failure without having
> > > > > to reset the machine. This is done by first NACKing the slave
> > > > > and then resetting the i2c bus after a certain timeout.
> > > > >
> > > > > Signed-off-by: Philby John
> > > >
> > > > I tried this on DM6443 based board with 2.6.18 kernel. The result
> >
> > I am
> >
> > > > posting below. It gives controller time out again and again.
> > > >
> > > > dhcppc9 login: i2c_davinci i2c_davinci.1: controller timed out
> > > > i2c_davinci i2c_davinci.1: initiating i2c bus recovery
> > > > i2c_davinci i2c_davinci.1: controller timed out
> > > > i2c_davinci i2c_davinci.1: initiating i2c bus recovery
> > >
> > > There is something gravely wrong about this patch and I would submit
> >
> > a
> >
> > > fix shortly incorporating the review comments. But please be aware
> >
> > that
> >
> > > I do not guarantee a definitive time line for a fix cause I have
> >
> > much at
> >
> > > hand at the moment.
> > >
> > >
> > > Regards,
> > > Philby
> > >
> > >
> > > _______________________________________________
> > > Davinci-linux-open-source mailing list
> > > Davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org
> >
> > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
> >
> > --
> >
> >
> >
> >
> >
> > ______________________________________________________________________
> >
> >
> > Craig Matsuura - Principal Engineer
> > Control4
> > 11734 South Election Road - Suite 200
> > Salt Lake City, UT 84020-6432
> > PH: 801-523-3161
> > FX: 801-523-3199
--
Craig Matsuura - Principal Engineer
Control4
11734 South Election Road - Suite 200
Salt Lake City, UT 84020-6432
PH: 801-523-3161
FX: 801-523-3199
[-- Attachment #1.2: Type: text/html, Size: 6740 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH/RFC 1/1] recover from davinci i2c time out conditions
[not found] ` <4A5DCCBD.909-hkdhdckH98+B+jHODAdFcQ@public.gmane.org>
@ 2009-11-23 15:23 ` Philby John
0 siblings, 0 replies; 15+ messages in thread
From: Philby John @ 2009-11-23 15:23 UTC (permalink / raw)
To: Sergei Shtylyov
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA, khali-PUYAD+kWke1g9hUCZPvPmw,
davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/
Hello Sergei,
On Wed, 2009-07-15 at 16:34 +0400, Sergei Shtylyov wrote:
> Hello.
>
> Philby John wrote:
>
> >>From dbe7e824d576636bb15b82a20fd2557fddc9a8f7 Mon Sep 17 00:00:00 2001
> > From: Philby John <pjohn-k0rHJ+Hhz/SB+jHODAdFcQ@public.gmane.org>
> > Date: Tue, 14 Jul 2009 21:46:47 +0530
> > Subject: [PATCH] Reset i2c bus to come out of time out conditions
>
> > Get out of i2c time out condition by resetting
> > the i2c bus. The kernel must be robust enough to
> > gracefully recover from i2c bus failure without having
> > to reset the machine. This is done by first NACKing the slave
> > and then resetting the i2c bus after a certain timeout.
>
> > Signed-off-by: Philby John <pjohn-k0rHJ+Hhz/SB+jHODAdFcQ@public.gmane.org>
>
> > diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
> > index 17f2ee7..4ed1a4c 100755
> > --- a/drivers/i2c/busses/i2c-davinci.c
> > +++ b/drivers/i2c/busses/i2c-davinci.c
> > @@ -35,14 +35,18 @@
> > #include <linux/interrupt.h>
> > #include <linux/platform_device.h>
> > #include <linux/io.h>
> > +#include <linux/gpio.h>
> >
> > #include <mach/hardware.h>
> >
> > #include <mach/i2c.h>
> > +#include <mach/mux.h>
> > +#include <mach/cputype.h>
> >
> > /* ----- global defines ----------------------------------------------- */
> >
> > #define DAVINCI_I2C_TIMEOUT (1*HZ)
> > +#define DAVINCI_I2C_MAX_TRIES 2
> > #define I2C_DAVINCI_INTR_ALL (DAVINCI_I2C_IMR_AAS | \
> > DAVINCI_I2C_IMR_SCD | \
> > DAVINCI_I2C_IMR_ARDY | \
> > @@ -135,6 +139,50 @@ static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg)
> > }
> >
> > /*
> > + * Configure the i2c data pin as a GPIO input and the i2c clock pin as a
> > + * high GPIO output.
> > + */
> > +static void disable_i2c_pins(void)
> > +{
> > + unsigned long flags;
> > +
> > + local_irq_save(flags);
> > + if (cpu_is_davinci_dm355()) {
> > + gpio_direction_input(15);
> > + gpio_direction_output(14, 0);
> > + gpio_set_value(14, 1);
>
> Why not just:
>
> gpio_direction_output(14, 1);
>
> > + davinci_cfg_reg(DM355_I2C_SDA);
> > + davinci_cfg_reg(DM355_I2C_SCL);
>
> Why enable the pins here?
Corrected.
>
> > + }
> > + local_irq_restore(flags);
> > +}
> > +
> > +/* Connect the i2c pins to the i2c controller. */
> > +static void enable_i2c_pins(void)
> > +{
> > + unsigned long flags;
> > +
> > + local_irq_save(flags);
> > + if (cpu_is_davinci_dm355()) {
> > + davinci_cfg_reg(DM355_I2C_SDA);
> > + davinci_cfg_reg(DM355_I2C_SCL);
> > + }
> > + local_irq_restore(flags);
> > +}
> > +
> > +
> > +/* Generate a pulse on the i2c clock pin. */
> > +static void pulse_i2c_clock(void)
> > +{
> > + if (cpu_is_davinci_dm355()) {
> > + gpio_set_value(14, 0);
> > + udelay(20);
> > + gpio_set_value(14, 1);
> > + udelay(20);
> > + }
> > +}
> > +
> > +/*
> > * This functions configures I2C and brings I2C out of reset.
> > * This function is called during I2C init function. This function
> > * also gets called if I2C encounters any errors.
> > @@ -221,14 +269,36 @@ static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev,
> > char allow_sleep)
> > {
> > unsigned long timeout;
> > + u16 i;
> > + static u16 to_cnt = 0;
> > + u32 flag = 0;
> >
> > timeout = jiffies + dev->adapter.timeout;
> > while (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG)
> > - & DAVINCI_I2C_STR_BB) {
> > - if (time_after(jiffies, timeout)) {
> > - dev_warn(dev->dev,
> > - "timeout waiting for bus ready\n");
> > - return -ETIMEDOUT;
> > + & DAVINCI_I2C_STR_BB) {
> > +
> > + if (to_cnt <= DAVINCI_I2C_MAX_TRIES) {
> > + if (time_after(jiffies, timeout)) {
> > + dev_warn(dev->dev,
> > + "timeout waiting for bus ready\n");
> > + to_cnt++;
> > + return -ETIMEDOUT;
> > + }
> > + } else if (cpu_is_davinci_dm644x() || cpu_is_davinci_dm355()) {
> > + to_cnt = 0;
> > + dev_err(dev->dev, "initiating i2c bus recovery\n");
> > + /* Send the NACK to the slave */
> > + flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG);
> > + flag |= DAVINCI_I2C_MDR_NACK;
>
> Superflous space here...
Corrected!!
>
> > + /* write the data into mode register */
> > + davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
>
> How come you're reading from the interrupt mask register but writing
> into the mode register which has different layout? :-O
>
> > + /* Disable i2c */
> > + disable_i2c_pins();
> > + for (i = 0; i < 10; i++)
> > + pulse_i2c_clock();
> > + /* Re-enable i2c */
> > + enable_i2c_pins();
> > + i2c_davinci_init(dev);
> > }
> > if (allow_sleep)
> > schedule_timeout(1);
> > @@ -309,7 +379,23 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
> > r = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
> > dev->adapter.timeout);
> > if (r == 0) {
> > - dev_err(dev->dev, "controller timed out\n");
> > + u16 i;
> > + u32 flag = 0;
> > + if (cpu_is_davinci_dm644x() || cpu_is_davinci_dm355()) {
> > + dev_err(dev->dev, "initiating i2c bus recovery\n");
> > + /* Send the NACK to the slave */
> > + flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG);
> > + flag |= DAVINCI_I2C_MDR_NACK;
>
> ... and here.
Corrected!
>
> > + /* write the data into mode register */
> > + davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
> > + /* Disable i2c */
> > + disable_i2c_pins();
> > + /* Send high and low on the SCL line */
> > + for (i = 0; i < 10; i++)
> > + pulse_i2c_clock();
> > + /* Re-enable i2c */
> > + enable_i2c_pins();
>
> Please factor out the completely identical recovery procedures into the
Understood what you meant to say, now corrected.
Thank you for your valuable comments.
Regards,
Philby
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH/RFC 1/1] recover from davinci i2c time out conditions
[not found] ` <200907151010.18709.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
@ 2009-11-23 15:23 ` Philby John
0 siblings, 0 replies; 15+ messages in thread
From: Philby John @ 2009-11-23 15:23 UTC (permalink / raw)
To: David Brownell
Cc: davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/,
linux-i2c-u79uwXL29TY76Z2rM5mHXA, khali-PUYAD+kWke1g9hUCZPvPmw
Hello David,
On Wed, 2009-07-15 at 10:10 -0700, David Brownell wrote:
> On Wednesday 15 July 2009, Philby John wrote:
> > /*
> > + * Configure the i2c data pin as a GPIO input and the i2c clock pin as a
> > + * high GPIO output.
> > + */
> > +static void disable_i2c_pins(void)
> > +{
> > + unsigned long flags;
> > +
> > + local_irq_save(flags);
> > + if (cpu_is_davinci_dm355()) {
> > + gpio_direction_input(15);
> > + gpio_direction_output(14, 0);
> > + gpio_set_value(14, 1);
>
> As noted: gpio_direction_output(14, 1) is better.
Now Corrected!
>
> > + davinci_cfg_reg(DM355_I2C_SDA);
> > + davinci_cfg_reg(DM355_I2C_SCL);
> > + }
> > + local_irq_restore(flags);
> > +}
> > +
> > +/* Connect the i2c pins to the i2c controller. */
> > +static void enable_i2c_pins(void)
> > +{
> > + unsigned long flags;
> > +
> > + local_irq_save(flags);
> > + if (cpu_is_davinci_dm355()) {
> > + davinci_cfg_reg(DM355_I2C_SDA);
> > + davinci_cfg_reg(DM355_I2C_SCL);
> > + }
> > + local_irq_restore(flags);
> > +}
> > +
> > +
> > +/* Generate a pulse on the i2c clock pin. */
> > +static void pulse_i2c_clock(void)
> > +{
> > + if (cpu_is_davinci_dm355()) {
> > + gpio_set_value(14, 0);
> > + udelay(20);
> > + gpio_set_value(14, 1);
> > + udelay(20);
> > + }
> > +}
> > +
>
> The general problem with how that's done is that the SoC-specific
> bits should not be in this file. The mach-davinc/dm355.c file
> should hold that configuration; likewise for other SoCs.
Not quite sure what you were expecting here. What I could do is to set
sda_pin and scl_pin in struct davinci_i2c_platform_data, for all davinci
platforms there is, rather than make davinci specific changes to
i2c-gpio.c I would also prefer not to make changes to
board-dm646x-evm.c/board-dm365-evm.c/board-dm355-evm.c etc...
Please let me know what you think.
>
> > + /* Disable i2c */
> > + disable_i2c_pins();
> > + for (i = 0; i < 10; i++)
> > + pulse_i2c_clock();
> > + /* Re-enable i2c */
> > + enable_i2c_pins();
>
> A better description of this is that you're trying to follow
> the I2Cv3 instructions about how to *reset* the bus, yes?
This is correct. To be precise, I am following the bus recovery
procedure as outlined in AN10216-01 I2C Manual. Reproducing here as
general information.
•SDA line is then non usable anymore because of the
“Slave-Transmitter”mode.
•Methods to recover the SDA line are:
–Reset the slave device (assuming the device has a Reset pin)
–Use a bus recovery sequence to leave the “Slave-Transmitter” mode
•Bus recovery sequence is done as following:
1-Send 9 clock pulses on SCL line
2-Ask the master to keep SDA High until the “Slave-Transmitter” releases
the SDA line to perform the ACK operation
3-Keeping SDA High during the ACK means that the “Master-Receiver”does
not acknowledge the previous byte receive
4-The “Slave-Transmitter” then goes in an idle state
5-The master then sends a STOP command initializing completely the bus
Thank you for your comments.
Regards,
Philby
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH/RFC 1/1] recover from davinci i2c time out conditions
[not found] ` <4A5E0E98.2030108-Q5RJGjKts06CY9SHAMCTRUEOCMrvLtNR@public.gmane.org>
2009-07-24 14:34 ` Karicheri, Muralidharan
@ 2009-11-23 15:24 ` Philby John
1 sibling, 0 replies; 15+ messages in thread
From: Philby John @ 2009-11-23 15:24 UTC (permalink / raw)
To: Troy Kisky
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA, khali-PUYAD+kWke1g9hUCZPvPmw,
davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/
Hello Troy,
On Wed, 2009-07-15 at 10:15 -0700, Troy Kisky wrote:
> Philby John wrote:
> >>From dbe7e824d576636bb15b82a20fd2557fddc9a8f7 Mon Sep 17 00:00:00 2001
> > From: Philby John <pjohn-k0rHJ+Hhz/SB+jHODAdFcQ@public.gmane.org>
> > Date: Tue, 14 Jul 2009 21:46:47 +0530
> > Subject: [PATCH] Reset i2c bus to come out of time out conditions
> >
> > Get out of i2c time out condition by resetting
> > the i2c bus. The kernel must be robust enough to
> > gracefully recover from i2c bus failure without having
> > to reset the machine. This is done by first NACKing the slave
> > and then resetting the i2c bus after a certain timeout.
> >
> > Signed-off-by: Philby John <pjohn-k0rHJ+Hhz/SB+jHODAdFcQ@public.gmane.org>
> > ---
>
> I personally like the idea behind this patch. But I have
> heard others argue against it. But it is not related to the
> ^C issue others have mentioned. That should not happen in
> the GIT kernel.
>
> > drivers/i2c/busses/i2c-davinci.c | 98 +++++++++++++++++++++++++++++++++++--
> > 1 files changed, 92 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
> > index 17f2ee7..4ed1a4c 100755
> > --- a/drivers/i2c/busses/i2c-davinci.c
> > +++ b/drivers/i2c/busses/i2c-davinci.c
> > @@ -35,14 +35,18 @@
> > #include <linux/interrupt.h>
> > #include <linux/platform_device.h>
> > #include <linux/io.h>
> > +#include <linux/gpio.h>
> >
> > #include <mach/hardware.h>
> >
> > #include <mach/i2c.h>
> > +#include <mach/mux.h>
> > +#include <mach/cputype.h>
> >
> > /* ----- global defines ----------------------------------------------- */
> >
> > #define DAVINCI_I2C_TIMEOUT (1*HZ)
> > +#define DAVINCI_I2C_MAX_TRIES 2
> > #define I2C_DAVINCI_INTR_ALL (DAVINCI_I2C_IMR_AAS | \
> > DAVINCI_I2C_IMR_SCD | \
> > DAVINCI_I2C_IMR_ARDY | \
> > @@ -135,6 +139,50 @@ static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg)
> > }
> >
> > /*
> > + * Configure the i2c data pin as a GPIO input and the i2c clock pin as a
> > + * high GPIO output.
> > + */
> > +static void disable_i2c_pins(void)
> > +{
> > + unsigned long flags;
> > +
> > + local_irq_save(flags);
> > + if (cpu_is_davinci_dm355()) {
> > + gpio_direction_input(15);
> > + gpio_direction_output(14, 0);
> > + gpio_set_value(14, 1);
> > + davinci_cfg_reg(DM355_I2C_SDA);
> > + davinci_cfg_reg(DM355_I2C_SCL);
> > + }
> > + local_irq_restore(flags);
> > +}
> > +
> > +/* Connect the i2c pins to the i2c controller. */
> > +static void enable_i2c_pins(void)
> > +{
> > + unsigned long flags;
> > +
> > + local_irq_save(flags);
> > + if (cpu_is_davinci_dm355()) {
> > + davinci_cfg_reg(DM355_I2C_SDA);
> > + davinci_cfg_reg(DM355_I2C_SCL);
> > + }
> > + local_irq_restore(flags);
> > +}
> > +
> > +
> > +/* Generate a pulse on the i2c clock pin. */
> > +static void pulse_i2c_clock(void)
> > +{
> > + if (cpu_is_davinci_dm355()) {
> > + gpio_set_value(14, 0);
> > + udelay(20);
> > + gpio_set_value(14, 1);
> > + udelay(20);
> > + }
> > +}
> > +
> > +/*
> > * This functions configures I2C and brings I2C out of reset.
> > * This function is called during I2C init function. This function
> > * also gets called if I2C encounters any errors.
> > @@ -221,14 +269,36 @@ static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev,
> > char allow_sleep)
> > {
> > unsigned long timeout;
> > + u16 i;
> > + static u16 to_cnt = 0;
> > + u32 flag = 0;
> >
> > timeout = jiffies + dev->adapter.timeout;
> > while (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG)
> > - & DAVINCI_I2C_STR_BB) {
> > - if (time_after(jiffies, timeout)) {
> > - dev_warn(dev->dev,
> > - "timeout waiting for bus ready\n");
> > - return -ETIMEDOUT;
> > + & DAVINCI_I2C_STR_BB) {
> > +
> > + if (to_cnt <= DAVINCI_I2C_MAX_TRIES) {
> > + if (time_after(jiffies, timeout)) {
> > + dev_warn(dev->dev,
> > + "timeout waiting for bus ready\n");
> > + to_cnt++;
> > + return -ETIMEDOUT;
> > + }
> > + } else if (cpu_is_davinci_dm644x() || cpu_is_davinci_dm355()) {
>
> I would not initiate recovery until a timeout occurs.
> This can be a multi master bus, so a busy condition
> may be valid. Then, after multiple timeouts and recovery attempts,
> return -ETIMEDOUT
Yes, I agree. I wait for a maximum of 2 tries when a timeout occurs
before initiating bus recovery.
Regards,
Philby
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2009-11-23 15:24 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-15 7:34 [PATCH/RFC 1/1] recover from davinci i2c time out conditions Philby John
[not found] ` <1247643267.5981.82.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2009-07-15 12:34 ` Sergei Shtylyov
[not found] ` <4A5DCCBD.909-hkdhdckH98+B+jHODAdFcQ@public.gmane.org>
2009-11-23 15:23 ` Philby John
2009-07-15 17:10 ` David Brownell
[not found] ` <200907151010.18709.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2009-11-23 15:23 ` Philby John
2009-07-15 17:15 ` Troy Kisky
[not found] ` <4A5E0E98.2030108-Q5RJGjKts06CY9SHAMCTRUEOCMrvLtNR@public.gmane.org>
2009-07-24 14:34 ` Karicheri, Muralidharan
[not found] ` <A69FA2915331DC488A831521EAE36FE40144FDB54B-UmuGNrFEPrGIQmiDNMet8wC/G2K4zDHf@public.gmane.org>
2009-07-24 18:14 ` Troy Kisky
2009-11-23 15:24 ` Philby John
2009-07-22 11:03 ` Nitin Mahajan
[not found] ` <218571.29671.qm-LK+a5U5w+t2B9c0Qi4KiSl5cfvJIxWXgQQ4Iyu8u01E@public.gmane.org>
2009-07-22 11:14 ` Philby John
[not found] ` <1248261275.4077.4.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2009-09-19 5:12 ` Craig Matsuura
[not found] ` <200909182312.58018.cmatsuura-/SMLdF/PHsZWk0Htik3J/w@public.gmane.org>
2009-09-21 6:31 ` Philby John
[not found] ` <1253514660.4507.2.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2009-09-21 13:34 ` Craig Matsuura
2009-09-21 13:41 ` Craig Matsuura
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).