Pull i3c updates from Boris Brezillon: "Core changes: - Export i3c_device_match_id() so driver can get per-device data - Add addr and lvr fields to i2c_dev_desc so we can attach I2C devices that are not described in the DT - Add a missing of_node_put() - Fix a memory leak - Use dev_to_i3cmaster() instead of open-coding it Driver changes: - Use for_each_set_bit() in the Cadence driver" * tag 'i3c/for-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux: i3c: master: Use dev_to_i3cmaster() i3c: master: fix a memory leak bug i3c: add addr and lvr to i2c_dev_desc structure i3c: master: cdns: Use for_each_set_bit() i3c: master: Add of_node_put() before return i3c: move i3c_device_match_id to device.c and export it
Unified · Split
| @@ -200,6 +200,59 @@ struct i3c_device *dev_to_i3cdev(struct device *dev) · 199 unmodified lines | ||
| 200 | 200 | } |
| 201 | 201 | EXPORT_SYMBOL_GPL(dev_to_i3cdev); |
| 202 | 202 | |
| 203 | +/** | |
| 204 | + * i3c_device_match_id() - Returns the i3c_device_id entry matching @i3cdev | |
| 205 | + * @i3cdev: I3C device | |
| 206 | + * @id_table: I3C device match table | |
| 207 | + * | |
| 208 | + * Return: a pointer to an i3c_device_id object or NULL if there's no match. | |
| 209 | + */ | |
| 210 | +const struct i3c_device_id * | |
| 211 | +i3c_device_match_id(struct i3c_device *i3cdev, | |
| 212 | + const struct i3c_device_id *id_table) | |
| 213 | +{ | |
| 214 | + struct i3c_device_info devinfo; | |
| 215 | + const struct i3c_device_id *id; | |
| 216 | + | |
| 217 | + i3c_device_get_info(i3cdev, &devinfo); | |
| 218 | + | |
| 219 | + /* | |
| 220 | + * The lower 32bits of the provisional ID is just filled with a random | |
| 221 | + * value, try to match using DCR info. | |
| 222 | + */ | |
| 223 | + if (!I3C_PID_RND_LOWER_32BITS(devinfo.pid)) { | |
| 224 | + u16 manuf = I3C_PID_MANUF_ID(devinfo.pid); | |
| 225 | + u16 part = I3C_PID_PART_ID(devinfo.pid); | |
| 226 | + u16 ext_info = I3C_PID_EXTRA_INFO(devinfo.pid); | |
| 227 | + | |
| 228 | + /* First try to match by manufacturer/part ID. */ | |
| 229 | + for (id = id_table; id->match_flags != 0; id++) { | |
| 230 | + if ((id->match_flags & I3C_MATCH_MANUF_AND_PART) != | |
| 231 | + I3C_MATCH_MANUF_AND_PART) | |
| 232 | + continue; | |
| 233 | + | |
| 234 | + if (manuf != id->manuf_id || part != id->part_id) | |
| 235 | + continue; | |
| 236 | + | |
| 237 | + if ((id->match_flags & I3C_MATCH_EXTRA_INFO) && | |
| 238 | + ext_info != id->extra_info) | |
| 239 | + continue; | |
| 240 | + | |
| 241 | + return id; | |
| 242 | + } | |
| 243 | + } | |
| 244 | + | |
| 245 | + /* Fallback to DCR match. */ | |
| 246 | + for (id = id_table; id->match_flags != 0; id++) { | |
| 247 | + if ((id->match_flags & I3C_MATCH_DCR) && | |
| 248 | + id->dcr == devinfo.dcr) | |
| 249 | + return id; | |
| 250 | + } | |
| 251 | + | |
| 252 | + return NULL; | |
| 253 | +} | |
| 254 | +EXPORT_SYMBOL_GPL(i3c_device_match_id); | |
| 255 | + | |
| 203 | 256 | /** |
| 204 | 257 | * i3c_driver_register_with_owner() - register an I3C device driver |
| 205 | 258 | * |
| @@ -123,7 +123,7 @@ static struct i3c_dev_desc *dev_to_i3cdesc(struct device *dev) · 122 unmodified lines | ||
| 123 | 123 | if (dev->type == &i3c_device_type) |
| 124 | 124 | return dev_to_i3cdev(dev)->desc; |
| 125 | 125 | |
| 126 | − master = container_of(dev, struct i3c_master_controller, dev); | |
| 126 | + master = dev_to_i3cmaster(dev); | |
| 127 | 127 | |
| 128 | 128 | return master->this; |
| 129 | 129 | } |
| @@ -276,51 +276,6 @@ static const struct device_type i3c_device_type = { · 146 unmodified lines | ||
| 276 | 276 | .uevent = i3c_device_uevent, |
| 277 | 277 | }; |
| 278 | 278 | |
| 279 | −static const struct i3c_device_id * | |
| 280 | −i3c_device_match_id(struct i3c_device *i3cdev, | |
| 281 | − const struct i3c_device_id *id_table) | |
| 282 | −{ | |
| 283 | − struct i3c_device_info devinfo; | |
| 284 | − const struct i3c_device_id *id; | |
| 285 | − | |
| 286 | − i3c_device_get_info(i3cdev, &devinfo); | |
| 287 | − | |
| 288 | − /* | |
| 289 | − * The lower 32bits of the provisional ID is just filled with a random | |
| 290 | − * value, try to match using DCR info. | |
| 291 | − */ | |
| 292 | − if (!I3C_PID_RND_LOWER_32BITS(devinfo.pid)) { | |
| 293 | − u16 manuf = I3C_PID_MANUF_ID(devinfo.pid); | |
| 294 | − u16 part = I3C_PID_PART_ID(devinfo.pid); | |
| 295 | − u16 ext_info = I3C_PID_EXTRA_INFO(devinfo.pid); | |
| 296 | − | |
| 297 | − /* First try to match by manufacturer/part ID. */ | |
| 298 | − for (id = id_table; id->match_flags != 0; id++) { | |
| 299 | − if ((id->match_flags & I3C_MATCH_MANUF_AND_PART) != | |
| 300 | − I3C_MATCH_MANUF_AND_PART) | |
| 301 | − continue; | |
| 302 | − | |
| 303 | − if (manuf != id->manuf_id || part != id->part_id) | |
| 304 | − continue; | |
| 305 | − | |
| 306 | − if ((id->match_flags & I3C_MATCH_EXTRA_INFO) && | |
| 307 | − ext_info != id->extra_info) | |
| 308 | − continue; | |
| 309 | − | |
| 310 | − return id; | |
| 311 | − } | |
| 312 | − } | |
| 313 | − | |
| 314 | − /* Fallback to DCR match. */ | |
| 315 | − for (id = id_table; id->match_flags != 0; id++) { | |
| 316 | − if ((id->match_flags & I3C_MATCH_DCR) && | |
| 317 | − id->dcr == devinfo.dcr) | |
| 318 | − return id; | |
| 319 | − } | |
| 320 | − | |
| 321 | − return NULL; | |
| 322 | −} | |
| 323 | − | |
| 324 | 279 | static int i3c_device_match(struct device *dev, struct device_driver *drv) |
| 325 | 280 | { |
| 326 | 281 | struct i3c_device *i3cdev; |
| @@ -645,6 +600,8 @@ i3c_master_alloc_i2c_dev(struct i3c_master_controller *master, · 318 unmodified lines | ||
| 645 | 600 | |
| 646 | 601 | dev->common.master = master; |
| 647 | 602 | dev->boardinfo = boardinfo; |
| 603 | + dev->addr = boardinfo->base.addr; | |
| 604 | + dev->lvr = boardinfo->lvr; | |
| 648 | 605 | |
| 649 | 606 | return dev; |
| 650 | 607 | } |
| @@ -963,8 +920,8 @@ int i3c_master_defslvs_locked(struct i3c_master_controller *master) · 312 unmodified lines | ||
| 963 | 920 | |
| 964 | 921 | desc = defslvs->slaves; |
| 965 | 922 | i3c_bus_for_each_i2cdev(bus, i2cdev) { |
| 966 | − desc->lvr = i2cdev->boardinfo->lvr; | |
| 967 | − desc->static_addr = i2cdev->boardinfo->base.addr << 1; | |
| 923 | + desc->lvr = i2cdev->lvr; | |
| 924 | + desc->static_addr = i2cdev->addr << 1; | |
| 968 | 925 | desc++; |
| 969 | 926 | } |
| 970 | 927 | |
| @@ -1084,8 +1041,10 @@ static int i3c_master_getmwl_locked(struct i3c_master_controller *master, · 113 unmodified lines | ||
| 1084 | 1041 | if (ret) |
| 1085 | 1042 | goto out; |
| 1086 | 1043 | |
| 1087 | − if (dest.payload.len != sizeof(*mwl)) | |
| 1088 | − return -EIO; | |
| 1044 | + if (dest.payload.len != sizeof(*mwl)) { | |
| 1045 | + ret = -EIO; | |
| 1046 | + goto out; | |
| 1047 | + } | |
| 1089 | 1048 | |
| 1090 | 1049 | info->max_write_len = be16_to_cpu(mwl->len); |
| 1091 | 1050 | |
| @@ -1631,8 +1590,8 @@ static void i3c_master_detach_free_devs(struct i3c_master_controller *master) · 539 unmodified lines | ||
| 1631 | 1590 | common.node) { |
| 1632 | 1591 | i3c_master_detach_i2c_dev(i2cdev); |
| 1633 | 1592 | i3c_bus_set_addr_slot_status(&master->bus, |
| 1634 | − i2cdev->boardinfo->base.addr, | |
| 1635 | − I3C_ADDR_SLOT_FREE); | |
| 1593 | + i2cdev->addr, | |
| 1594 | + I3C_ADDR_SLOT_FREE); | |
| 1636 | 1595 | i3c_master_free_i2c_dev(i2cdev); |
| 1637 | 1596 | } |
| 1638 | 1597 | } |
| @@ -2093,8 +2052,10 @@ static int of_populate_i3c_bus(struct i3c_master_controller *master) · 454 unmodified lines | ||
| 2093 | 2052 | |
| 2094 | 2053 | for_each_available_child_of_node(i3cbus_np, node) { |
| 2095 | 2054 | ret = of_i3c_master_add_dev(master, node); |
| 2096 | − if (ret) | |
| 2055 | + if (ret) { | |
| 2056 | + of_node_put(node); | |
| 2097 | 2057 | return ret; |
| 2058 | + } | |
| 2098 | 2059 | } |
| 2099 | 2060 | |
| 2100 | 2061 | /* |
| @@ -1033,12 +1033,12 @@ static int dw_i3c_master_attach_i2c_dev(struct i2c_dev_desc *dev) · 1032 unmodified lines | ||
| 1033 | 1033 | return -ENOMEM; |
| 1034 | 1034 | |
| 1035 | 1035 | data->index = pos; |
| 1036 | − master->addrs[pos] = dev->boardinfo->base.addr; | |
| 1036 | + master->addrs[pos] = dev->addr; | |
| 1037 | 1037 | master->free_pos &= ~BIT(pos); |
| 1038 | 1038 | i2c_dev_set_master_data(dev, data); |
| 1039 | 1039 | |
| 1040 | 1040 | writel(DEV_ADDR_TABLE_LEGACY_I2C_DEV | |
| 1041 | − DEV_ADDR_TABLE_STATIC_ADDR(dev->boardinfo->base.addr), | |
| 1041 | + DEV_ADDR_TABLE_STATIC_ADDR(dev->addr), | |
| 1042 | 1042 | master->regs + |
| 1043 | 1043 | DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); |
| 1044 | 1044 | |
| @@ -903,7 +903,8 @@ static void cdns_i3c_master_upd_i3c_addr(struct i3c_dev_desc *dev) · 902 unmodified lines | ||
| 903 | 903 | static int cdns_i3c_master_get_rr_slot(struct cdns_i3c_master *master, |
| 904 | 904 | u8 dyn_addr) |
| 905 | 905 | { |
| 906 | − u32 activedevs, rr; | |
| 906 | + unsigned long activedevs; | |
| 907 | + u32 rr; | |
| 907 | 908 | int i; |
| 908 | 909 | |
| 909 | 910 | if (!dyn_addr) { |
| @@ -913,13 +914,10 @@ static int cdns_i3c_master_get_rr_slot(struct cdns_i3c_master *master, · 3 unmodified lines | ||
| 913 | 914 | return ffs(master->free_rr_slots) - 1; |
| 914 | 915 | } |
| 915 | 916 | |
| 916 | − activedevs = readl(master->regs + DEVS_CTRL) & | |
| 917 | − DEVS_CTRL_DEVS_ACTIVE_MASK; | |
| 918 | − | |
| 919 | − for (i = 1; i <= master->maxdevs; i++) { | |
| 920 | − if (!(BIT(i) & activedevs)) | |
| 921 | − continue; | |
| 917 | + activedevs = readl(master->regs + DEVS_CTRL) & DEVS_CTRL_DEVS_ACTIVE_MASK; | |
| 918 | + activedevs &= ~BIT(0); | |
| 922 | 919 | |
| 920 | + for_each_set_bit(i, &activedevs, master->maxdevs + 1) { | |
| 923 | 921 | rr = readl(master->regs + DEV_ID_RR0(i)); |
| 924 | 922 | if (!(rr & DEV_ID_RR0_IS_I3C) || |
| 925 | 923 | DEV_ID_RR0_GET_DEV_ADDR(rr) != dyn_addr) |
| @@ -1005,9 +1003,9 @@ static int cdns_i3c_master_attach_i2c_dev(struct i2c_dev_desc *dev) · 79 unmodified lines | ||
| 1005 | 1003 | master->free_rr_slots &= ~BIT(slot); |
| 1006 | 1004 | i2c_dev_set_master_data(dev, data); |
| 1007 | 1005 | |
| 1008 | − writel(prepare_rr0_dev_address(dev->boardinfo->base.addr), | |
| 1006 | + writel(prepare_rr0_dev_address(dev->addr), | |
| 1009 | 1007 | master->regs + DEV_ID_RR0(data->id)); |
| 1010 | − writel(dev->boardinfo->lvr, master->regs + DEV_ID_RR2(data->id)); | |
| 1008 | + writel(dev->lvr, master->regs + DEV_ID_RR2(data->id)); | |
| 1011 | 1009 | writel(readl(master->regs + DEVS_CTRL) | |
| 1012 | 1010 | DEVS_CTRL_DEV_ACTIVE(data->id), |
| 1013 | 1011 | master->regs + DEVS_CTRL); |
| @@ -1126,18 +1124,16 @@ static void cdns_i3c_master_upd_i3c_scl_lim(struct cdns_i3c_master *master) · 112 unmodified lines | ||
| 1126 | 1124 | static int cdns_i3c_master_do_daa(struct i3c_master_controller *m) |
| 1127 | 1125 | { |
| 1128 | 1126 | struct cdns_i3c_master *master = to_cdns_i3c_master(m); |
| 1129 | − u32 olddevs, newdevs; | |
| 1127 | + unsigned long olddevs, newdevs; | |
| 1130 | 1128 | int ret, slot; |
| 1131 | 1129 | u8 addrs[MAX_DEVS] = { }; |
| 1132 | 1130 | u8 last_addr = 0; |
| 1133 | 1131 | |
| 1134 | 1132 | olddevs = readl(master->regs + DEVS_CTRL) & DEVS_CTRL_DEVS_ACTIVE_MASK; |
| 1133 | + olddevs |= BIT(0); | |
| 1135 | 1134 | |
| 1136 | 1135 | /* Prepare RR slots before launching DAA. */ |
| 1137 | − for (slot = 1; slot <= master->maxdevs; slot++) { | |
| 1138 | − if (olddevs & BIT(slot)) | |
| 1139 | − continue; | |
| 1140 | − | |
| 1136 | + for_each_clear_bit(slot, &olddevs, master->maxdevs + 1) { | |
| 1141 | 1137 | ret = i3c_master_get_free_addr(m, last_addr + 1); |
| 1142 | 1138 | if (ret < 0) |
| 1143 | 1139 | return -ENOSPC; |
| @@ -1161,10 +1157,8 @@ static int cdns_i3c_master_do_daa(struct i3c_master_controller *m) · 17 unmodified lines | ||
| 1161 | 1157 | * Clear all retaining registers filled during DAA. We already |
| 1162 | 1158 | * have the addressed assigned to them in the addrs array. |
| 1163 | 1159 | */ |
| 1164 | − for (slot = 1; slot <= master->maxdevs; slot++) { | |
| 1165 | − if (newdevs & BIT(slot)) | |
| 1166 | − i3c_master_add_i3c_dev_locked(m, addrs[slot]); | |
| 1167 | − } | |
| 1160 | + for_each_set_bit(slot, &newdevs, master->maxdevs + 1) | |
| 1161 | + i3c_master_add_i3c_dev_locked(m, addrs[slot]); | |
| 1168 | 1162 | |
| 1169 | 1163 | /* |
| 1170 | 1164 | * Clear slots that ended up not being used. Can be caused by I3C |
| @@ -188,6 +188,10 @@ static inline struct i3c_driver *drv_to_i3cdrv(struct device_driver *drv) · 187 unmodified lines | ||
| 188 | 188 | struct device *i3cdev_to_dev(struct i3c_device *i3cdev); |
| 189 | 189 | struct i3c_device *dev_to_i3cdev(struct device *dev); |
| 190 | 190 | |
| 191 | +const struct i3c_device_id * | |
| 192 | +i3c_device_match_id(struct i3c_device *i3cdev, | |
| 193 | + const struct i3c_device_id *id_table); | |
| 194 | + | |
| 191 | 195 | static inline void i3cdev_set_drvdata(struct i3c_device *i3cdev, |
| 192 | 196 | void *data) |
| 193 | 197 | { |
| @@ -71,6 +71,9 @@ struct i2c_dev_boardinfo { · 70 unmodified lines | ||
| 71 | 71 | * @common: common part of the I2C device descriptor |
| 72 | 72 | * @boardinfo: pointer to the boardinfo attached to this I2C device |
| 73 | 73 | * @dev: I2C device object registered to the I2C framework |
| 74 | + * @addr: I2C device address | |
| 75 | + * @lvr: LVR (Legacy Virtual Register) needed by the I3C core to know about | |
| 76 | + * the I2C device limitations | |
| 74 | 77 | * |
| 75 | 78 | * Each I2C device connected on the bus will have an i2c_dev_desc. |
| 76 | 79 | * This object is created by the core and later attached to the controller |
| @@ -84,6 +87,8 @@ struct i2c_dev_desc { · 7 unmodified lines | ||
| 84 | 87 | struct i3c_i2c_dev_desc common; |
| 85 | 88 | const struct i2c_dev_boardinfo *boardinfo; |
| 86 | 89 | struct i2c_client *dev; |
| 90 | + u16 addr; | |
| 91 | + u8 lvr; | |
| 87 | 92 | }; |
| 88 | 93 | |
| 89 | 94 | /** |