Re: [PATCH V5 Resend 1/2] i2c/adapter: Add bus recovery infrastructure

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

 



On 4 October 2012 13:30, Uwe Kleine-König
<u.kleine-koenig@xxxxxxxxxxxxxx> wrote:

Hi Uwe,

Please see if following fixup looks fine to you:


    fixup! i2c/adapter: Add bus recovery infrastructure
---
 drivers/i2c/i2c-core.c | 33 ++++++++++++++-------------------
 include/linux/i2c.h    | 22 ++++++++++++----------
 2 files changed, 26 insertions(+), 29 deletions(-)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index bdc249a..393d5f7 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -107,24 +107,14 @@ static int i2c_device_uevent(struct device *dev,
struct kobj_uevent_env *env)
 #endif /* CONFIG_HOTPLUG */

 /* i2c bus recovery routines */
-static inline void set_scl_value(struct i2c_adapter *adap, int val)
+static void set_scl_gpio_value(struct i2c_adapter *adap, int val)
 {
-       struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
-
-       if (bri->is_gpio_recovery)
-               gpio_set_value(bri->scl_gpio, val);
-       else
-               bri->set_scl(adap, val);
+       gpio_set_value(adap->bus_recovery_info->scl_gpio, val);
 }

-static inline int get_sda_value(struct i2c_adapter *adap)
+static int get_sda_gpio_value(struct i2c_adapter *adap)
 {
-       struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
-
-       if (bri->is_gpio_recovery)
-               return gpio_get_value(bri->sda_gpio);
-       else
-               return bri->get_sda(adap);
+       return gpio_get_value(adap->bus_recovery_info->sda_gpio);
 }

 static int i2c_get_gpios_for_recovery(struct i2c_adapter *adap)
@@ -152,8 +142,7 @@ static int i2c_get_gpios_for_recovery(struct
i2c_adapter *adap)
                        ret = bri->get_gpio(bri->sda_gpio);

                if (unlikely(ret ||
-                       gpio_request_one(bri->sda_gpio, bri->sda_gpio_flags,
-                               "i2c-sda"))) {
+                       gpio_request_one(bri->sda_gpio, GPIOF_IN, "i2c-sda"))) {
                        /* work without sda polling */
                        dev_warn(dev, "can't get sda: %d. Skip sda polling\n",
                                        bri->sda_gpio);
@@ -190,7 +179,7 @@ static int i2c_recover_bus(struct i2c_adapter *adap)
 {
        struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
        unsigned long delay = 1000000;
-       int i, ret, val = 1;
+       int i, ret, val = 0;

        if (bri->is_gpio_recovery) {
                ret = i2c_get_gpios_for_recovery(adap);
@@ -201,12 +190,12 @@ static int i2c_recover_bus(struct i2c_adapter *adap)
        delay = DIV_ROUND_UP(delay, bri->clock_rate_khz * 2);

        for (i = 0; i < bri->clock_cnt * 2; i++, val = !val) {
-               set_scl_value(adap, val);
+               bri->set_scl(adap, val);
                ndelay(delay);

                /* break if sda got high, check only when scl line is high */
                if (!bri->skip_sda_polling && val)
-                       if (unlikely(get_sda_value(adap)))
+                       if (unlikely(bri->get_sda(adap)))
                                break;
        }

@@ -1030,6 +1019,12 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
                        bri->recover_bus = i2c_recover_bus;

                         if (bri->is_gpio_recovery) {
+                               if (!bri->scl_gpio_flags)
+                                       bri->scl_gpio_flags = GPIOF_OPEN_DRAIN |
+                                               GPIOF_OUT_INIT_HIGH;
+
+                               bri->set_scl = set_scl_gpio_value;
+                               bri->get_sda = get_sda_gpio_value;
                                dev_info(&adap->dev,
                                        "registered for gpio bus recovery\n");
                        } else if (bri->set_scl) {
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index c43e5c4..dd470a1 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -382,10 +382,10 @@ struct i2c_algorithm {
  *     scl type recovery.
  * @clock_cnt: count of max clocks to be generated. Required for both gpio and
  *     scl type recovery.
- * @set_scl: controller specific scl configuration routine. Only required if
- *     is_gpio_recovery == false
- * @get_sda: controller specific sda read routine. Only required if
- *     is_gpio_recovery == false and skip_sda_polling == false.
+ * @set_scl: controller specific routine, if is_gpio_recovery == false.
+ *       set_scl_gpio_value otherwise
+ * @get_sda: controller specific routine, if is_gpio_recovery == false.
+ *       get_sda_gpio_value otherwise
  * @get_gpio: called before recover_bus() to get padmux configured
for scl line.
  *     as gpio. Only required if is_gpio_recovery == true. Return 0 on success.
  * @put_gpio: called after recover_bus() to get padmux configured for scl line
@@ -394,10 +394,9 @@ struct i2c_algorithm {
  *     true.
  * @sda_gpio: gpio number of the sda line. Only required if is_gpio_recovery ==
  *     true and skip_sda_polling == false.
- * @scl_gpio_flags: flag for gpio_request_one of scl_gpio. 0 implies
- *     GPIOF_OUT_INIT_LOW.
- * @sda_gpio_flags: flag for gpio_request_one of sda_gpio. 0 implies
- *     GPIOF_OUT_INIT_LOW.
+ * @scl_gpio_flags: flag for gpio_request_one of scl_gpio. If passed as 0,
+ *      (GPIOF_OPEN_DRAIN | GPIOF_OUT_INIT_HIGH) is used instead.
+ *      These is no need of sda_gpio_flags, as we always read it in input mode.
  */
 struct i2c_bus_recovery_info {
        int (*recover_bus)(struct i2c_adapter *);
@@ -406,7 +405,11 @@ struct i2c_bus_recovery_info {
        u32 clock_rate_khz;
        u8 clock_cnt;

-       /* scl/sda recovery */
+       /*
+        * Fn pointers for recovery, will point either to:
+        * - set_scl_gpio_value and get_sda_gpio_value for gpio recovery
+        * - Controller specific routines, otherwise
+        */
        void (*set_scl)(struct i2c_adapter *, int val);
        int (*get_sda)(struct i2c_adapter *);

@@ -416,7 +419,6 @@ struct i2c_bus_recovery_info {
        unsigned scl_gpio;
        unsigned sda_gpio;
        unsigned long scl_gpio_flags;
-       unsigned long sda_gpio_flags;
 };

 /*
--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux GPIO]     [Linux SPI]     [Linux Hardward Monitoring]     [LM Sensors]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux