Merge tag 'i3c/for-5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 9 Jul 2019 16:04:31 +0000 (09:04 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 9 Jul 2019 16:04:31 +0000 (09:04 -0700)
Pull ic3 updates from Boris Brezillon:

 - Drop support for 10-bit I2C addresses

 - Add support for limited bus mode

 - Fix the Cadence DT binding doc

 - Use struct_size() to allocate a DEFSLVS packet

* tag 'i3c/for-5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux:
  i3c: master: Use struct_size() helper
  dt-bindings: i3c: cdns: Use correct cells for I2C device
  i3c: dw: add limited bus mode support
  i3c: add mixed limited bus mode
  i3c: fix i2c and i3c scl rate by bus mode
  dt-bindings: i3c: Document dropped support for I2C 10 bit devices
  i3c: Drop support for I2C 10 bit addresing

Documentation/devicetree/bindings/i3c/cdns,i3c-master.txt
Documentation/devicetree/bindings/i3c/i3c.txt
drivers/i3c/master.c
drivers/i3c/master/dw-i3c-master.c
drivers/i3c/master/i3c-master-cdns.c
include/linux/i3c/master.h

index 69da2115abdc0b51d057ff771d138f415c4d41fc..1cf6182f888c86713e27833c14ad13dcee337230 100644 (file)
@@ -38,6 +38,6 @@ Example:
 
                nunchuk: nunchuk@52 {
                        compatible = "nintendo,nunchuk";
-                       reg = <0x52 0x80000010 0>;
+                       reg = <0x52 0x0 0x10>;
                };
        };
index ab729a0a86ae7f5aee85cc8034ad882da4727469..4ffe059f0feca1a6bc1d26489cf51a619ee7e265 100644 (file)
@@ -39,7 +39,9 @@ valid here, but several new properties have been added.
 New constraint on existing properties:
 --------------------------------------
 - reg: contains 3 cells
-  + first cell : still encoding the I2C address
+  + first cell : still encoding the I2C address. 10 bit addressing is not
+    supported. Devices with 10 bit address can't be properly passed through
+    DEFSLVS command.
 
   + second cell: shall be 0
 
index 5f4bd52121fe93c5843767ce4614a97965cddd2d..d6f8b038a89678fcd40bce106e020c902aa4cbd3 100644 (file)
@@ -91,6 +91,12 @@ void i3c_bus_normaluse_unlock(struct i3c_bus *bus)
        up_read(&bus->lock);
 }
 
+static struct i3c_master_controller *
+i3c_bus_to_i3c_master(struct i3c_bus *i3cbus)
+{
+       return container_of(i3cbus, struct i3c_master_controller, bus);
+}
+
 static struct i3c_master_controller *dev_to_i3cmaster(struct device *dev)
 {
        return container_of(dev, struct i3c_master_controller, dev);
@@ -464,6 +470,7 @@ static int i3c_bus_init(struct i3c_bus *i3cbus)
 static const char * const i3c_bus_mode_strings[] = {
        [I3C_BUS_MODE_PURE] = "pure",
        [I3C_BUS_MODE_MIXED_FAST] = "mixed-fast",
+       [I3C_BUS_MODE_MIXED_LIMITED] = "mixed-limited",
        [I3C_BUS_MODE_MIXED_SLOW] = "mixed-slow",
 };
 
@@ -565,20 +572,39 @@ static const struct device_type i3c_masterdev_type = {
        .groups = i3c_masterdev_groups,
 };
 
-int i3c_bus_set_mode(struct i3c_bus *i3cbus, enum i3c_bus_mode mode)
+int i3c_bus_set_mode(struct i3c_bus *i3cbus, enum i3c_bus_mode mode,
+                    unsigned long max_i2c_scl_rate)
 {
-       i3cbus->mode = mode;
+       struct i3c_master_controller *master = i3c_bus_to_i3c_master(i3cbus);
 
-       if (!i3cbus->scl_rate.i3c)
-               i3cbus->scl_rate.i3c = I3C_BUS_TYP_I3C_SCL_RATE;
+       i3cbus->mode = mode;
 
-       if (!i3cbus->scl_rate.i2c) {
-               if (i3cbus->mode == I3C_BUS_MODE_MIXED_SLOW)
-                       i3cbus->scl_rate.i2c = I3C_BUS_I2C_FM_SCL_RATE;
-               else
-                       i3cbus->scl_rate.i2c = I3C_BUS_I2C_FM_PLUS_SCL_RATE;
+       switch (i3cbus->mode) {
+       case I3C_BUS_MODE_PURE:
+               if (!i3cbus->scl_rate.i3c)
+                       i3cbus->scl_rate.i3c = I3C_BUS_TYP_I3C_SCL_RATE;
+               break;
+       case I3C_BUS_MODE_MIXED_FAST:
+       case I3C_BUS_MODE_MIXED_LIMITED:
+               if (!i3cbus->scl_rate.i3c)
+                       i3cbus->scl_rate.i3c = I3C_BUS_TYP_I3C_SCL_RATE;
+               if (!i3cbus->scl_rate.i2c)
+                       i3cbus->scl_rate.i2c = max_i2c_scl_rate;
+               break;
+       case I3C_BUS_MODE_MIXED_SLOW:
+               if (!i3cbus->scl_rate.i2c)
+                       i3cbus->scl_rate.i2c = max_i2c_scl_rate;
+               if (!i3cbus->scl_rate.i3c ||
+                   i3cbus->scl_rate.i3c > i3cbus->scl_rate.i2c)
+                       i3cbus->scl_rate.i3c = i3cbus->scl_rate.i2c;
+               break;
+       default:
+               return -EINVAL;
        }
 
+       dev_dbg(&master->dev, "i2c-scl = %ld Hz i3c-scl = %ld Hz\n",
+               i3cbus->scl_rate.i2c, i3cbus->scl_rate.i3c);
+
        /*
         * I3C/I2C frequency may have been overridden, check that user-provided
         * values are not exceeding max possible frequency.
@@ -924,9 +950,8 @@ int i3c_master_defslvs_locked(struct i3c_master_controller *master)
                ndevs++;
 
        defslvs = i3c_ccc_cmd_dest_init(&dest, I3C_BROADCAST_ADDR,
-                                       sizeof(*defslvs) +
-                                       ((ndevs - 1) *
-                                        sizeof(struct i3c_ccc_dev_desc)));
+                                       struct_size(defslvs, slaves,
+                                                   ndevs - 1));
        if (!defslvs)
                return -ENOMEM;
 
@@ -1963,12 +1988,19 @@ of_i3c_master_add_i2c_boardinfo(struct i3c_master_controller *master,
        if (ret)
                return ret;
 
+       /*
+        * The I3C Specification does not clearly say I2C devices with 10-bit
+        * address are supported. These devices can't be passed properly through
+        * DEFSLVS command.
+        */
+       if (boardinfo->base.flags & I2C_CLIENT_TEN) {
+               dev_err(&master->dev, "I2C device with 10 bit address not supported.");
+               return -ENOTSUPP;
+       }
+
        /* LVR is encoded in reg[2]. */
        boardinfo->lvr = reg[2];
 
-       if (boardinfo->lvr & I3C_LVR_I2C_FM_MODE)
-               master->bus.scl_rate.i2c = I3C_BUS_I2C_FM_SCL_RATE;
-
        list_add_tail(&boardinfo->node, &master->boardinfo.i2c);
        of_node_get(node);
 
@@ -2111,16 +2143,14 @@ static int i3c_master_i2c_adapter_xfer(struct i2c_adapter *adap,
        return ret ? ret : nxfers;
 }
 
-static u32 i3c_master_i2c_functionalities(struct i2c_adapter *adap)
+static u32 i3c_master_i2c_funcs(struct i2c_adapter *adapter)
 {
-       struct i3c_master_controller *master = i2c_adapter_to_i3c_master(adap);
-
-       return master->ops->i2c_funcs(master);
+       return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
 }
 
 static const struct i2c_algorithm i3c_master_i2c_algo = {
        .master_xfer = i3c_master_i2c_adapter_xfer,
-       .functionality = i3c_master_i2c_functionalities,
+       .functionality = i3c_master_i2c_funcs,
 };
 
 static int i3c_master_i2c_adapter_init(struct i3c_master_controller *master)
@@ -2379,8 +2409,7 @@ EXPORT_SYMBOL_GPL(i3c_generic_ibi_recycle_slot);
 static int i3c_master_check_ops(const struct i3c_master_controller_ops *ops)
 {
        if (!ops || !ops->bus_init || !ops->priv_xfers ||
-           !ops->send_ccc_cmd || !ops->do_daa || !ops->i2c_xfers ||
-           !ops->i2c_funcs)
+           !ops->send_ccc_cmd || !ops->do_daa || !ops->i2c_xfers)
                return -EINVAL;
 
        if (ops->request_ibi &&
@@ -2417,6 +2446,7 @@ int i3c_master_register(struct i3c_master_controller *master,
                        const struct i3c_master_controller_ops *ops,
                        bool secondary)
 {
+       unsigned long i2c_scl_rate = I3C_BUS_I2C_FM_PLUS_SCL_RATE;
        struct i3c_bus *i3cbus = i3c_master_get_bus(master);
        enum i3c_bus_mode mode = I3C_BUS_MODE_PURE;
        struct i2c_dev_boardinfo *i2cbi;
@@ -2458,6 +2488,9 @@ int i3c_master_register(struct i3c_master_controller *master,
                                mode = I3C_BUS_MODE_MIXED_FAST;
                        break;
                case I3C_LVR_I2C_INDEX(1):
+                       if (mode < I3C_BUS_MODE_MIXED_LIMITED)
+                               mode = I3C_BUS_MODE_MIXED_LIMITED;
+                       break;
                case I3C_LVR_I2C_INDEX(2):
                        if (mode < I3C_BUS_MODE_MIXED_SLOW)
                                mode = I3C_BUS_MODE_MIXED_SLOW;
@@ -2466,9 +2499,12 @@ int i3c_master_register(struct i3c_master_controller *master,
                        ret = -EINVAL;
                        goto err_put_dev;
                }
+
+               if (i2cbi->lvr & I3C_LVR_I2C_FM_MODE)
+                       i2c_scl_rate = I3C_BUS_I2C_FM_SCL_RATE;
        }
 
-       ret = i3c_bus_set_mode(i3cbus, mode);
+       ret = i3c_bus_set_mode(i3cbus, mode, i2c_scl_rate);
        if (ret)
                goto err_put_dev;
 
index 1d83c97431c72a9d12f9ab662d317e0ad0e1ab6e..09912d75c6d5398e63ebd5148a6cc5441721d595 100644 (file)
@@ -599,6 +599,7 @@ static int dw_i3c_master_bus_init(struct i3c_master_controller *m)
 
        switch (bus->mode) {
        case I3C_BUS_MODE_MIXED_FAST:
+       case I3C_BUS_MODE_MIXED_LIMITED:
                ret = dw_i2c_clk_cfg(master);
                if (ret)
                        return ret;
@@ -1060,11 +1061,6 @@ static void dw_i3c_master_detach_i2c_dev(struct i2c_dev_desc *dev)
        kfree(data);
 }
 
-static u32 dw_i3c_master_i2c_funcs(struct i3c_master_controller *m)
-{
-       return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
 static irqreturn_t dw_i3c_master_irq_handler(int irq, void *dev_id)
 {
        struct dw_i3c_master *master = dev_id;
@@ -1099,7 +1095,6 @@ static const struct i3c_master_controller_ops dw_mipi_i3c_ops = {
        .attach_i2c_dev = dw_i3c_master_attach_i2c_dev,
        .detach_i2c_dev = dw_i3c_master_detach_i2c_dev,
        .i2c_xfers = dw_i3c_master_i2c_xfers,
-       .i2c_funcs = dw_i3c_master_i2c_funcs,
 };
 
 static int dw_i3c_probe(struct platform_device *pdev)
index 8889a4fdb4541a06a94dfc0d0b858adf661f37e9..237f24adddc632bc3470df59572cb6a68a9198f9 100644 (file)
@@ -864,11 +864,6 @@ static int cdns_i3c_master_i2c_xfers(struct i2c_dev_desc *dev,
        return ret;
 }
 
-static u32 cdns_i3c_master_i2c_funcs(struct i3c_master_controller *m)
-{
-       return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR;
-}
-
 struct cdns_i3c_i2c_dev_data {
        u16 id;
        s16 ibi;
@@ -1010,9 +1005,7 @@ static int cdns_i3c_master_attach_i2c_dev(struct i2c_dev_desc *dev)
        master->free_rr_slots &= ~BIT(slot);
        i2c_dev_set_master_data(dev, data);
 
-       writel(prepare_rr0_dev_address(dev->boardinfo->base.addr) |
-              (dev->boardinfo->base.flags & I2C_CLIENT_TEN ?
-               DEV_ID_RR0_LVR_EXT_ADDR : 0),
+       writel(prepare_rr0_dev_address(dev->boardinfo->base.addr),
               master->regs + DEV_ID_RR0(data->id));
        writel(dev->boardinfo->lvr, master->regs + DEV_ID_RR2(data->id));
        writel(readl(master->regs + DEVS_CTRL) |
@@ -1518,7 +1511,6 @@ static const struct i3c_master_controller_ops cdns_i3c_master_ops = {
        .send_ccc_cmd = cdns_i3c_master_send_ccc_cmd,
        .priv_xfers = cdns_i3c_master_priv_xfers,
        .i2c_xfers = cdns_i3c_master_i2c_xfers,
-       .i2c_funcs = cdns_i3c_master_i2c_funcs,
        .enable_ibi = cdns_i3c_master_enable_ibi,
        .disable_ibi = cdns_i3c_master_disable_ibi,
        .request_ibi = cdns_i3c_master_request_ibi,
index f13fd8b1dd79bfb8abbd4e3918aff141eb15dccf..1f08fa8d69d2725e204f761260692b610b89b31e 100644 (file)
@@ -48,7 +48,7 @@ struct i3c_i2c_dev_desc {
 #define I3C_LVR_I2C_INDEX(x)           ((x) << 5)
 #define I3C_LVR_I2C_FM_MODE            BIT(4)
 
-#define I2C_MAX_ADDR                   GENMASK(9, 0)
+#define I2C_MAX_ADDR                   GENMASK(6, 0)
 
 /**
  * struct i2c_dev_boardinfo - I2C device board information
@@ -250,12 +250,17 @@ struct i3c_device {
  *                          the bus. The only impact in this mode is that the
  *                          high SCL pulse has to stay below 50ns to trick I2C
  *                          devices when transmitting I3C frames
+ * @I3C_BUS_MODE_MIXED_LIMITED: I2C devices without 50ns spike filter are
+ *                             present on the bus. However they allow
+ *                             compliance up to the maximum SDR SCL clock
+ *                             frequency.
  * @I3C_BUS_MODE_MIXED_SLOW: I2C devices without 50ns spike filter are present
  *                          on the bus
  */
 enum i3c_bus_mode {
        I3C_BUS_MODE_PURE,
        I3C_BUS_MODE_MIXED_FAST,
+       I3C_BUS_MODE_MIXED_LIMITED,
        I3C_BUS_MODE_MIXED_SLOW,
 };
 
@@ -390,8 +395,6 @@ struct i3c_bus {
  *            and i2c_put_dma_safe_msg_buf() helpers provided by the I2C
  *            framework.
  *            This method is mandatory.
- * @i2c_funcs: expose the supported I2C functionalities.
- *            This method is mandatory.
  * @request_ibi: attach an IBI handler to an I3C device. This implies defining
  *              an IBI handler and the constraints of the IBI (maximum payload
  *              length and number of pre-allocated slots).
@@ -437,7 +440,6 @@ struct i3c_master_controller_ops {
        void (*detach_i2c_dev)(struct i2c_dev_desc *dev);
        int (*i2c_xfers)(struct i2c_dev_desc *dev,
                         const struct i2c_msg *xfers, int nxfers);
-       u32 (*i2c_funcs)(struct i3c_master_controller *master);
        int (*request_ibi)(struct i3c_dev_desc *dev,
                           const struct i3c_ibi_setup *req);
        void (*free_ibi)(struct i3c_dev_desc *dev);