Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 11 Jan 2020 23:40:43 +0000 (15:40 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 11 Jan 2020 23:40:43 +0000 (15:40 -0800)
Pull i2c fixes from Wolfram Sang:
 "Two driver bugfixes, a documentation fix, and a removal of a spec
  violation for the bus recovery algorithm in the core"

* 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: fix bus recovery stop mode timing
  i2c: bcm2835: Store pointer to bus clock
  dt-bindings: i2c: at91: fix i2c-sda-hold-time-ns documentation for sam9x60
  i2c: at91: fix clk_offset for sam9x60

Documentation/devicetree/bindings/i2c/i2c-at91.txt
drivers/i2c/busses/i2c-at91-core.c
drivers/i2c/busses/i2c-bcm2835.c
drivers/i2c/i2c-core-base.c

index 2210f43..8347b1e 100644 (file)
@@ -18,8 +18,10 @@ Optional properties:
 - dma-names: should contain "tx" and "rx".
 - atmel,fifo-size: maximum number of data the RX and TX FIFOs can store for FIFO
   capable I2C controllers.
-- i2c-sda-hold-time-ns: TWD hold time, only available for "atmel,sama5d4-i2c"
-  and "atmel,sama5d2-i2c".
+- i2c-sda-hold-time-ns: TWD hold time, only available for:
+       "atmel,sama5d4-i2c",
+       "atmel,sama5d2-i2c",
+       "microchip,sam9x60-i2c".
 - Child nodes conforming to i2c bus binding
 
 Examples :
index e13af48..5137e62 100644 (file)
@@ -174,7 +174,7 @@ static struct at91_twi_pdata sama5d2_config = {
 
 static struct at91_twi_pdata sam9x60_config = {
        .clk_max_div = 7,
-       .clk_offset = 4,
+       .clk_offset = 3,
        .has_unre_flag = true,
        .has_alt_cmd = true,
        .has_hold_field = true,
index e01b2b5..5ab901a 100644 (file)
@@ -58,6 +58,7 @@ struct bcm2835_i2c_dev {
        struct i2c_adapter adapter;
        struct completion completion;
        struct i2c_msg *curr_msg;
+       struct clk *bus_clk;
        int num_msgs;
        u32 msg_err;
        u8 *msg_buf;
@@ -404,7 +405,6 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
        struct resource *mem, *irq;
        int ret;
        struct i2c_adapter *adap;
-       struct clk *bus_clk;
        struct clk *mclk;
        u32 bus_clk_rate;
 
@@ -427,11 +427,11 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
                return PTR_ERR(mclk);
        }
 
-       bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk, i2c_dev);
+       i2c_dev->bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk, i2c_dev);
 
-       if (IS_ERR(bus_clk)) {
+       if (IS_ERR(i2c_dev->bus_clk)) {
                dev_err(&pdev->dev, "Could not register clock\n");
-               return PTR_ERR(bus_clk);
+               return PTR_ERR(i2c_dev->bus_clk);
        }
 
        ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency",
@@ -442,13 +442,13 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
                bus_clk_rate = 100000;
        }
 
-       ret = clk_set_rate_exclusive(bus_clk, bus_clk_rate);
+       ret = clk_set_rate_exclusive(i2c_dev->bus_clk, bus_clk_rate);
        if (ret < 0) {
                dev_err(&pdev->dev, "Could not set clock frequency\n");
                return ret;
        }
 
-       ret = clk_prepare_enable(bus_clk);
+       ret = clk_prepare_enable(i2c_dev->bus_clk);
        if (ret) {
                dev_err(&pdev->dev, "Couldn't prepare clock");
                return ret;
@@ -491,10 +491,9 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
 static int bcm2835_i2c_remove(struct platform_device *pdev)
 {
        struct bcm2835_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
-       struct clk *bus_clk = devm_clk_get(i2c_dev->dev, "div");
 
-       clk_rate_exclusive_put(bus_clk);
-       clk_disable_unprepare(bus_clk);
+       clk_rate_exclusive_put(i2c_dev->bus_clk);
+       clk_disable_unprepare(i2c_dev->bus_clk);
 
        free_irq(i2c_dev->irq, i2c_dev);
        i2c_del_adapter(&i2c_dev->adapter);
index 9f8dcd3..35b2097 100644 (file)
@@ -186,10 +186,11 @@ int i2c_generic_scl_recovery(struct i2c_adapter *adap)
         * If we can set SDA, we will always create a STOP to ensure additional
         * pulses will do no harm. This is achieved by letting SDA follow SCL
         * half a cycle later. Check the 'incomplete_write_byte' fault injector
-        * for details.
+        * for details. Note that we must honour tsu:sto, 4us, but lets use 5us
+        * here for simplicity.
         */
        bri->set_scl(adap, scl);
-       ndelay(RECOVERY_NDELAY / 2);
+       ndelay(RECOVERY_NDELAY);
        if (bri->set_sda)
                bri->set_sda(adap, scl);
        ndelay(RECOVERY_NDELAY / 2);
@@ -211,7 +212,13 @@ int i2c_generic_scl_recovery(struct i2c_adapter *adap)
                scl = !scl;
                bri->set_scl(adap, scl);
                /* Creating STOP again, see above */
-               ndelay(RECOVERY_NDELAY / 2);
+               if (scl)  {
+                       /* Honour minimum tsu:sto */
+                       ndelay(RECOVERY_NDELAY);
+               } else {
+                       /* Honour minimum tf and thd:dat */
+                       ndelay(RECOVERY_NDELAY / 2);
+               }
                if (bri->set_sda)
                        bri->set_sda(adap, scl);
                ndelay(RECOVERY_NDELAY / 2);