Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'i3c/for-6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux

Pull i3c updates from Alexandre Belloni:
"We are continuing to see more fixes as hardware is available and code
is actually getting tested.

Core:
- Add a sysfs control for hotjoin
- Add fallback method for GETMXDS CCC

Drivers:
- cdns: fix prescale for i2c clock
- mipi-i3c-hci: more fixes now that the driver is used
- svc: hotjoin enabling/disabling support"

* tag 'i3c/for-6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux:
i3c: document hotjoin sysfs entry
i3c: master: fix kernel-doc check warning
i3c: master: cdns: Update maximum prescaler value for i2c clock
i3c: master: fix Excess kernel-doc description warning
i3c: master: svc: return actual transfer data len
i3c: master: svc: rename read_len as actual_len
i3c: add actual_len in i3c_priv_xfer
i3c: master: svc: add hot join support
i3c: master: add enable(disable) hot join in sys entry
i3c: master: Fix build error
i3c: Add fallback method for GETMXDS CCC
i3c: mipi-i3c-hci: Add DMA bounce buffer for private transfers
i3c: mipi-i3c-hci: Handle I3C address header error in hci_cmd_v1_daa()
i3c: mipi-i3c-hci: Do not overallocate transfers in hci_cmd_v1_daa()
i3c: mipi-i3c-hci: Report NACK response from CCC command to core

+256 -28
+15
Documentation/ABI/testing/sysfs-bus-i3c
··· 88 88 This entry describes the HDRCAP of the master controller 89 89 driving the bus. 90 90 91 + What: /sys/bus/i3c/devices/i3c-<bus-id>/hotjoin 92 + KernelVersion: 6.8 93 + Contact: linux-i3c@vger.kernel.org 94 + Description: 95 + I3C’s Hot-Join mechanism allows an I3C Device to inform the 96 + Active Controller that a newly-joined Target is present on the 97 + I3C Bus and is ready to receive a Dynamic Address, in order to 98 + become fully functional on the Bus. Hot-Join is used when the 99 + Target is mounted on the same I3C bus and remains depowered 100 + until needed or until the Target is physically inserted into the 101 + I3C bus 102 + 103 + This entry allows to enable or disable Hot-join of the Current 104 + Controller driving the bus. 105 + 91 106 What: /sys/bus/i3c/devices/i3c-<bus-id>/<bus-id>-<device-pid> 92 107 KernelVersion: 5.0 93 108 Contact: linux-i3c@vger.kernel.org
+93 -2
drivers/i3c/master.c
··· 557 557 } 558 558 static DEVICE_ATTR_RO(i2c_scl_frequency); 559 559 560 + static int i3c_set_hotjoin(struct i3c_master_controller *master, bool enable) 561 + { 562 + int ret; 563 + 564 + if (!master || !master->ops) 565 + return -EINVAL; 566 + 567 + if (!master->ops->enable_hotjoin || !master->ops->disable_hotjoin) 568 + return -EINVAL; 569 + 570 + i3c_bus_normaluse_lock(&master->bus); 571 + 572 + if (enable) 573 + ret = master->ops->enable_hotjoin(master); 574 + else 575 + ret = master->ops->disable_hotjoin(master); 576 + 577 + master->hotjoin = enable; 578 + 579 + i3c_bus_normaluse_unlock(&master->bus); 580 + 581 + return ret; 582 + } 583 + 584 + static ssize_t hotjoin_store(struct device *dev, struct device_attribute *attr, 585 + const char *buf, size_t count) 586 + { 587 + struct i3c_bus *i3cbus = dev_to_i3cbus(dev); 588 + int ret; 589 + bool res; 590 + 591 + if (!i3cbus->cur_master) 592 + return -EINVAL; 593 + 594 + if (kstrtobool(buf, &res)) 595 + return -EINVAL; 596 + 597 + ret = i3c_set_hotjoin(i3cbus->cur_master->common.master, res); 598 + if (ret) 599 + return ret; 600 + 601 + return count; 602 + } 603 + 604 + /* 605 + * i3c_master_enable_hotjoin - Enable hotjoin 606 + * @master: I3C master object 607 + * 608 + * Return: a 0 in case of success, an negative error code otherwise. 609 + */ 610 + int i3c_master_enable_hotjoin(struct i3c_master_controller *master) 611 + { 612 + return i3c_set_hotjoin(master, true); 613 + } 614 + EXPORT_SYMBOL_GPL(i3c_master_enable_hotjoin); 615 + 616 + /* 617 + * i3c_master_disable_hotjoin - Disable hotjoin 618 + * @master: I3C master object 619 + * 620 + * Return: a 0 in case of success, an negative error code otherwise. 621 + */ 622 + int i3c_master_disable_hotjoin(struct i3c_master_controller *master) 623 + { 624 + return i3c_set_hotjoin(master, false); 625 + } 626 + EXPORT_SYMBOL_GPL(i3c_master_disable_hotjoin); 627 + 628 + static ssize_t hotjoin_show(struct device *dev, struct device_attribute *da, char *buf) 629 + { 630 + struct i3c_bus *i3cbus = dev_to_i3cbus(dev); 631 + ssize_t ret; 632 + 633 + i3c_bus_normaluse_lock(i3cbus); 634 + ret = sysfs_emit(buf, "%d\n", i3cbus->cur_master->common.master->hotjoin); 635 + i3c_bus_normaluse_unlock(i3cbus); 636 + 637 + return ret; 638 + } 639 + 640 + static DEVICE_ATTR_RW(hotjoin); 641 + 560 642 static struct attribute *i3c_masterdev_attrs[] = { 561 643 &dev_attr_mode.attr, 562 644 &dev_attr_current_master.attr, ··· 649 567 &dev_attr_pid.attr, 650 568 &dev_attr_dynamic_address.attr, 651 569 &dev_attr_hdrcap.attr, 570 + &dev_attr_hotjoin.attr, 652 571 NULL, 653 572 }; 654 573 ATTRIBUTE_GROUPS(i3c_masterdev); ··· 1213 1130 1214 1131 i3c_ccc_cmd_init(&cmd, true, I3C_CCC_GETMXDS, &dest, 1); 1215 1132 ret = i3c_master_send_ccc_cmd_locked(master, &cmd); 1216 - if (ret) 1217 - goto out; 1133 + if (ret) { 1134 + /* 1135 + * Retry when the device does not support max read turnaround 1136 + * while expecting shorter length from this CCC command. 1137 + */ 1138 + dest.payload.len -= 3; 1139 + ret = i3c_master_send_ccc_cmd_locked(master, &cmd); 1140 + if (ret) 1141 + goto out; 1142 + } 1218 1143 1219 1144 if (dest.payload.len != 2 && dest.payload.len != 5) { 1220 1145 ret = -EIO;
+4 -3
drivers/i3c/master/i3c-master-cdns.c
··· 76 76 #define PRESCL_CTRL0 0x14 77 77 #define PRESCL_CTRL0_I2C(x) ((x) << 16) 78 78 #define PRESCL_CTRL0_I3C(x) (x) 79 - #define PRESCL_CTRL0_MAX GENMASK(9, 0) 79 + #define PRESCL_CTRL0_I3C_MAX GENMASK(9, 0) 80 + #define PRESCL_CTRL0_I2C_MAX GENMASK(15, 0) 80 81 81 82 #define PRESCL_CTRL1 0x18 82 83 #define PRESCL_CTRL1_PP_LOW_MASK GENMASK(15, 8) ··· 1234 1233 return -EINVAL; 1235 1234 1236 1235 pres = DIV_ROUND_UP(sysclk_rate, (bus->scl_rate.i3c * 4)) - 1; 1237 - if (pres > PRESCL_CTRL0_MAX) 1236 + if (pres > PRESCL_CTRL0_I3C_MAX) 1238 1237 return -ERANGE; 1239 1238 1240 1239 bus->scl_rate.i3c = sysclk_rate / ((pres + 1) * 4); ··· 1247 1246 max_i2cfreq = bus->scl_rate.i2c; 1248 1247 1249 1248 pres = (sysclk_rate / (max_i2cfreq * 5)) - 1; 1250 - if (pres > PRESCL_CTRL0_MAX) 1249 + if (pres > PRESCL_CTRL0_I2C_MAX) 1251 1250 return -ERANGE; 1252 1251 1253 1252 bus->scl_rate.i2c = sysclk_rate / ((pres + 1) * 5);
+4 -3
drivers/i3c/master/mipi-i3c-hci/cmd_v1.c
··· 298 298 unsigned int dcr, bcr; 299 299 DECLARE_COMPLETION_ONSTACK(done); 300 300 301 - xfer = hci_alloc_xfer(2); 301 + xfer = hci_alloc_xfer(1); 302 302 if (!xfer) 303 303 return -ENOMEM; 304 304 ··· 339 339 ret = -ETIME; 340 340 break; 341 341 } 342 - if (RESP_STATUS(xfer[0].response) == RESP_ERR_NACK && 342 + if ((RESP_STATUS(xfer->response) == RESP_ERR_ADDR_HEADER || 343 + RESP_STATUS(xfer->response) == RESP_ERR_NACK) && 343 344 RESP_DATA_LENGTH(xfer->response) == 1) { 344 345 ret = 0; /* no more devices to be assigned */ 345 346 break; 346 347 } 347 - if (RESP_STATUS(xfer[0].response) != RESP_SUCCESS) { 348 + if (RESP_STATUS(xfer->response) != RESP_SUCCESS) { 348 349 ret = -EIO; 349 350 break; 350 351 }
+48 -1
drivers/i3c/master/mipi-i3c-hci/core.c
··· 245 245 if (ccc->rnw) 246 246 ccc->dests[i - prefixed].payload.len = 247 247 RESP_DATA_LENGTH(xfer[i].response); 248 - if (RESP_STATUS(xfer[i].response) != RESP_SUCCESS) { 248 + switch (RESP_STATUS(xfer[i].response)) { 249 + case RESP_SUCCESS: 250 + continue; 251 + case RESP_ERR_ADDR_HEADER: 252 + case RESP_ERR_NACK: 253 + ccc->err = I3C_ERROR_M2; 254 + fallthrough; 255 + default: 249 256 ret = -EIO; 250 257 goto out; 251 258 } ··· 274 267 DBG(""); 275 268 276 269 return hci->cmd->perform_daa(hci); 270 + } 271 + 272 + static int i3c_hci_alloc_safe_xfer_buf(struct i3c_hci *hci, 273 + struct hci_xfer *xfer) 274 + { 275 + if (hci->io != &mipi_i3c_hci_dma || 276 + xfer->data == NULL || !is_vmalloc_addr(xfer->data)) 277 + return 0; 278 + 279 + if (xfer->rnw) 280 + xfer->bounce_buf = kzalloc(xfer->data_len, GFP_KERNEL); 281 + else 282 + xfer->bounce_buf = kmemdup(xfer->data, 283 + xfer->data_len, GFP_KERNEL); 284 + 285 + return xfer->bounce_buf == NULL ? -ENOMEM : 0; 286 + } 287 + 288 + static void i3c_hci_free_safe_xfer_buf(struct i3c_hci *hci, 289 + struct hci_xfer *xfer) 290 + { 291 + if (hci->io != &mipi_i3c_hci_dma || xfer->bounce_buf == NULL) 292 + return; 293 + 294 + if (xfer->rnw) 295 + memcpy(xfer->data, xfer->bounce_buf, xfer->data_len); 296 + 297 + kfree(xfer->bounce_buf); 277 298 } 278 299 279 300 static int i3c_hci_priv_xfers(struct i3c_dev_desc *dev, ··· 337 302 } 338 303 hci->cmd->prep_i3c_xfer(hci, dev, &xfer[i]); 339 304 xfer[i].cmd_desc[0] |= CMD_0_ROC; 305 + ret = i3c_hci_alloc_safe_xfer_buf(hci, &xfer[i]); 306 + if (ret) 307 + goto out; 340 308 } 341 309 last = i - 1; 342 310 xfer[last].cmd_desc[0] |= CMD_0_TOC; ··· 363 325 } 364 326 365 327 out: 328 + for (i = 0; i < nxfers; i++) 329 + i3c_hci_free_safe_xfer_buf(hci, &xfer[i]); 330 + 366 331 hci_free_xfer(xfer, nxfers); 367 332 return ret; 368 333 } ··· 391 350 xfer[i].rnw = i2c_xfers[i].flags & I2C_M_RD; 392 351 hci->cmd->prep_i2c_xfer(hci, dev, &xfer[i]); 393 352 xfer[i].cmd_desc[0] |= CMD_0_ROC; 353 + ret = i3c_hci_alloc_safe_xfer_buf(hci, &xfer[i]); 354 + if (ret) 355 + goto out; 394 356 } 395 357 last = i - 1; 396 358 xfer[last].cmd_desc[0] |= CMD_0_TOC; ··· 415 371 } 416 372 417 373 out: 374 + for (i = 0; i < nxfers; i++) 375 + i3c_hci_free_safe_xfer_buf(hci, &xfer[i]); 376 + 418 377 hci_free_xfer(xfer, nxfers); 419 378 return ret; 420 379 }
+3 -1
drivers/i3c/master/mipi-i3c-hci/dma.c
··· 362 362 struct hci_rh_data *rh; 363 363 unsigned int i, ring, enqueue_ptr; 364 364 u32 op1_val, op2_val; 365 + void *buf; 365 366 366 367 /* For now we only use ring 0 */ 367 368 ring = 0; ··· 391 390 392 391 /* 2nd and 3rd words of Data Buffer Descriptor Structure */ 393 392 if (xfer->data) { 393 + buf = xfer->bounce_buf ? xfer->bounce_buf : xfer->data; 394 394 xfer->data_dma = 395 395 dma_map_single(&hci->master.dev, 396 - xfer->data, 396 + buf, 397 397 xfer->data_len, 398 398 xfer->rnw ? 399 399 DMA_FROM_DEVICE :
+1
drivers/i3c/master/mipi-i3c-hci/hci.h
··· 90 90 struct { 91 91 /* DMA specific */ 92 92 dma_addr_t data_dma; 93 + void *bounce_buf; 93 94 int ring_number; 94 95 int ring_entry; 95 96 };
+78 -17
drivers/i3c/master/svc-i3c-master.c
··· 128 128 /* This parameter depends on the implementation and may be tuned */ 129 129 #define SVC_I3C_FIFO_SIZE 16 130 130 131 + #define SVC_I3C_EVENT_IBI BIT(0) 132 + #define SVC_I3C_EVENT_HOTJOIN BIT(1) 133 + 131 134 struct svc_i3c_cmd { 132 135 u8 addr; 133 136 bool rnw; 134 137 u8 *in; 135 138 const void *out; 136 139 unsigned int len; 137 - unsigned int read_len; 140 + unsigned int actual_len; 141 + struct i3c_priv_xfer *xfer; 138 142 bool continued; 139 143 }; 140 144 ··· 181 177 * @ibi.tbq_slot: To be queued IBI slot 182 178 * @ibi.lock: IBI lock 183 179 * @lock: Transfer lock, protect between IBI work thread and callbacks from master 180 + * @enabled_events: Bit masks for enable events (IBI, HotJoin). 184 181 */ 185 182 struct svc_i3c_master { 186 183 struct i3c_master_controller base; ··· 211 206 spinlock_t lock; 212 207 } ibi; 213 208 struct mutex lock; 209 + int enabled_events; 214 210 }; 215 211 216 212 /** ··· 225 219 int ibi; 226 220 struct i3c_generic_ibi_pool *ibi_pool; 227 221 }; 222 + 223 + static inline bool is_events_enabled(struct svc_i3c_master *master, u32 mask) 224 + { 225 + return !!(master->enabled_events & mask); 226 + } 228 227 229 228 static bool svc_i3c_master_error(struct svc_i3c_master *master) 230 229 { ··· 440 429 switch (ibitype) { 441 430 case SVC_I3C_MSTATUS_IBITYPE_IBI: 442 431 dev = svc_i3c_master_dev_from_addr(master, ibiaddr); 443 - if (!dev) 432 + if (!dev || !is_events_enabled(master, SVC_I3C_EVENT_IBI)) 444 433 svc_i3c_master_nack_ibi(master); 445 434 else 446 435 svc_i3c_master_handle_ibi(master, dev); 447 436 break; 448 437 case SVC_I3C_MSTATUS_IBITYPE_HOT_JOIN: 449 - svc_i3c_master_ack_ibi(master, false); 438 + if (is_events_enabled(master, SVC_I3C_EVENT_HOTJOIN)) 439 + svc_i3c_master_ack_ibi(master, false); 440 + else 441 + svc_i3c_master_nack_ibi(master); 450 442 break; 451 443 case SVC_I3C_MSTATUS_IBITYPE_MASTER_REQUEST: 452 444 svc_i3c_master_nack_ibi(master); ··· 486 472 svc_i3c_master_emit_stop(master); 487 473 break; 488 474 case SVC_I3C_MSTATUS_IBITYPE_HOT_JOIN: 489 - queue_work(master->base.wq, &master->hj_work); 475 + svc_i3c_master_emit_stop(master); 476 + if (is_events_enabled(master, SVC_I3C_EVENT_HOTJOIN)) 477 + queue_work(master->base.wq, &master->hj_work); 490 478 break; 491 479 case SVC_I3C_MSTATUS_IBITYPE_MASTER_REQUEST: 492 480 default: ··· 1040 1024 static int svc_i3c_master_xfer(struct svc_i3c_master *master, 1041 1025 bool rnw, unsigned int xfer_type, u8 addr, 1042 1026 u8 *in, const u8 *out, unsigned int xfer_len, 1043 - unsigned int *read_len, bool continued) 1027 + unsigned int *actual_len, bool continued) 1044 1028 { 1045 1029 u32 reg; 1046 1030 int ret; ··· 1053 1037 SVC_I3C_MCTRL_IBIRESP_NACK | 1054 1038 SVC_I3C_MCTRL_DIR(rnw) | 1055 1039 SVC_I3C_MCTRL_ADDR(addr) | 1056 - SVC_I3C_MCTRL_RDTERM(*read_len), 1040 + SVC_I3C_MCTRL_RDTERM(*actual_len), 1057 1041 master->regs + SVC_I3C_MCTRL); 1058 1042 1059 1043 ret = readl_poll_timeout(master->regs + SVC_I3C_MSTATUS, reg, ··· 1063 1047 1064 1048 if (readl(master->regs + SVC_I3C_MERRWARN) & SVC_I3C_MERRWARN_NACK) { 1065 1049 ret = -ENXIO; 1050 + *actual_len = 0; 1066 1051 goto emit_stop; 1067 1052 } 1068 1053 ··· 1081 1064 */ 1082 1065 if (SVC_I3C_MSTATUS_IBIWON(reg)) { 1083 1066 ret = -ENXIO; 1067 + *actual_len = 0; 1084 1068 goto emit_stop; 1085 1069 } 1086 1070 ··· 1093 1075 goto emit_stop; 1094 1076 1095 1077 if (rnw) 1096 - *read_len = ret; 1078 + *actual_len = ret; 1097 1079 1098 1080 ret = readl_poll_timeout(master->regs + SVC_I3C_MSTATUS, reg, 1099 1081 SVC_I3C_MSTATUS_COMPLETE(reg), 0, 1000); ··· 1175 1157 1176 1158 ret = svc_i3c_master_xfer(master, cmd->rnw, xfer->type, 1177 1159 cmd->addr, cmd->in, cmd->out, 1178 - cmd->len, &cmd->read_len, 1160 + cmd->len, &cmd->actual_len, 1179 1161 cmd->continued); 1162 + /* cmd->xfer is NULL if I2C or CCC transfer */ 1163 + if (cmd->xfer) 1164 + cmd->xfer->actual_len = cmd->actual_len; 1165 + 1180 1166 if (ret) 1181 1167 break; 1182 1168 } ··· 1265 1243 cmd->in = NULL; 1266 1244 cmd->out = buf; 1267 1245 cmd->len = xfer_len; 1268 - cmd->read_len = 0; 1246 + cmd->actual_len = 0; 1269 1247 cmd->continued = false; 1270 1248 1271 1249 mutex_lock(&master->lock); ··· 1285 1263 struct i3c_ccc_cmd *ccc) 1286 1264 { 1287 1265 unsigned int xfer_len = ccc->dests[0].payload.len; 1288 - unsigned int read_len = ccc->rnw ? xfer_len : 0; 1266 + unsigned int actual_len = ccc->rnw ? xfer_len : 0; 1289 1267 struct svc_i3c_xfer *xfer; 1290 1268 struct svc_i3c_cmd *cmd; 1291 1269 int ret; ··· 1303 1281 cmd->in = NULL; 1304 1282 cmd->out = &ccc->id; 1305 1283 cmd->len = 1; 1306 - cmd->read_len = 0; 1284 + cmd->actual_len = 0; 1307 1285 cmd->continued = true; 1308 1286 1309 1287 /* Directed message */ ··· 1313 1291 cmd->in = ccc->rnw ? ccc->dests[0].payload.data : NULL; 1314 1292 cmd->out = ccc->rnw ? NULL : ccc->dests[0].payload.data, 1315 1293 cmd->len = xfer_len; 1316 - cmd->read_len = read_len; 1294 + cmd->actual_len = actual_len; 1317 1295 cmd->continued = false; 1318 1296 1319 1297 mutex_lock(&master->lock); ··· 1322 1300 svc_i3c_master_dequeue_xfer(master, xfer); 1323 1301 mutex_unlock(&master->lock); 1324 1302 1325 - if (cmd->read_len != xfer_len) 1326 - ccc->dests[0].payload.len = cmd->read_len; 1303 + if (cmd->actual_len != xfer_len) 1304 + ccc->dests[0].payload.len = cmd->actual_len; 1327 1305 1328 1306 ret = xfer->ret; 1329 1307 svc_i3c_master_free_xfer(xfer); ··· 1368 1346 for (i = 0; i < nxfers; i++) { 1369 1347 struct svc_i3c_cmd *cmd = &xfer->cmds[i]; 1370 1348 1349 + cmd->xfer = &xfers[i]; 1371 1350 cmd->addr = master->addrs[data->index]; 1372 1351 cmd->rnw = xfers[i].rnw; 1373 1352 cmd->in = xfers[i].rnw ? xfers[i].data.in : NULL; 1374 1353 cmd->out = xfers[i].rnw ? NULL : xfers[i].data.out; 1375 1354 cmd->len = xfers[i].len; 1376 - cmd->read_len = xfers[i].rnw ? xfers[i].len : 0; 1355 + cmd->actual_len = xfers[i].rnw ? xfers[i].len : 0; 1377 1356 cmd->continued = (i + 1) < nxfers; 1378 1357 } 1379 1358 ··· 1414 1391 cmd->in = cmd->rnw ? xfers[i].buf : NULL; 1415 1392 cmd->out = cmd->rnw ? NULL : xfers[i].buf; 1416 1393 cmd->len = xfers[i].len; 1417 - cmd->read_len = cmd->rnw ? xfers[i].len : 0; 1394 + cmd->actual_len = cmd->rnw ? xfers[i].len : 0; 1418 1395 cmd->continued = (i + 1 < nxfers); 1419 1396 } 1420 1397 ··· 1495 1472 return ret; 1496 1473 } 1497 1474 1475 + master->enabled_events |= SVC_I3C_EVENT_IBI; 1498 1476 svc_i3c_master_enable_interrupts(master, SVC_I3C_MINT_SLVSTART); 1499 1477 1500 1478 return i3c_master_enec_locked(m, dev->info.dyn_addr, I3C_CCC_EVENT_SIR); ··· 1507 1483 struct svc_i3c_master *master = to_svc_i3c_master(m); 1508 1484 int ret; 1509 1485 1510 - svc_i3c_master_disable_interrupts(master); 1486 + master->enabled_events &= ~SVC_I3C_EVENT_IBI; 1487 + if (!master->enabled_events) 1488 + svc_i3c_master_disable_interrupts(master); 1511 1489 1512 1490 ret = i3c_master_disec_locked(m, dev->info.dyn_addr, I3C_CCC_EVENT_SIR); 1513 1491 ··· 1517 1491 pm_runtime_put_autosuspend(master->dev); 1518 1492 1519 1493 return ret; 1494 + } 1495 + 1496 + static int svc_i3c_master_enable_hotjoin(struct i3c_master_controller *m) 1497 + { 1498 + struct svc_i3c_master *master = to_svc_i3c_master(m); 1499 + int ret; 1500 + 1501 + ret = pm_runtime_resume_and_get(master->dev); 1502 + if (ret < 0) { 1503 + dev_err(master->dev, "<%s> Cannot get runtime PM.\n", __func__); 1504 + return ret; 1505 + } 1506 + 1507 + master->enabled_events |= SVC_I3C_EVENT_HOTJOIN; 1508 + 1509 + svc_i3c_master_enable_interrupts(master, SVC_I3C_MINT_SLVSTART); 1510 + 1511 + return 0; 1512 + } 1513 + 1514 + static int svc_i3c_master_disable_hotjoin(struct i3c_master_controller *m) 1515 + { 1516 + struct svc_i3c_master *master = to_svc_i3c_master(m); 1517 + 1518 + master->enabled_events &= ~SVC_I3C_EVENT_HOTJOIN; 1519 + 1520 + if (!master->enabled_events) 1521 + svc_i3c_master_disable_interrupts(master); 1522 + 1523 + pm_runtime_mark_last_busy(master->dev); 1524 + pm_runtime_put_autosuspend(master->dev); 1525 + 1526 + return 0; 1520 1527 } 1521 1528 1522 1529 static void svc_i3c_master_recycle_ibi_slot(struct i3c_dev_desc *dev, ··· 1578 1519 .recycle_ibi_slot = svc_i3c_master_recycle_ibi_slot, 1579 1520 .enable_ibi = svc_i3c_master_enable_ibi, 1580 1521 .disable_ibi = svc_i3c_master_disable_ibi, 1522 + .enable_hotjoin = svc_i3c_master_enable_hotjoin, 1523 + .disable_hotjoin = svc_i3c_master_disable_hotjoin, 1581 1524 }; 1582 1525 1583 1526 static int svc_i3c_master_prepare_clks(struct svc_i3c_master *master)
+2
include/linux/i3c/device.h
··· 54 54 * struct i3c_priv_xfer - I3C SDR private transfer 55 55 * @rnw: encodes the transfer direction. true for a read, false for a write 56 56 * @len: transfer length in bytes of the transfer 57 + * @actual_len: actual length in bytes are transferred by the controller 57 58 * @data: input/output buffer 58 59 * @data.in: input buffer. Must point to a DMA-able buffer 59 60 * @data.out: output buffer. Must point to a DMA-able buffer ··· 63 62 struct i3c_priv_xfer { 64 63 u8 rnw; 65 64 u16 len; 65 + u16 actual_len; 66 66 union { 67 67 void *in; 68 68 const void *out;
+8 -1
include/linux/i3c/master.h
··· 76 76 /** 77 77 * struct i2c_dev_desc - I2C device descriptor 78 78 * @common: common part of the I2C device descriptor 79 - * @boardinfo: pointer to the boardinfo attached to this I2C device 80 79 * @dev: I2C device object registered to the I2C framework 81 80 * @addr: I2C device address 82 81 * @lvr: LVR (Legacy Virtual Register) needed by the I3C core to know about ··· 433 434 * for a future IBI 434 435 * This method is mandatory only if ->request_ibi is not 435 436 * NULL. 437 + * @enable_hotjoin: enable hot join event detect. 438 + * @disable_hotjoin: disable hot join event detect. 436 439 */ 437 440 struct i3c_master_controller_ops { 438 441 int (*bus_init)(struct i3c_master_controller *master); ··· 461 460 int (*disable_ibi)(struct i3c_dev_desc *dev); 462 461 void (*recycle_ibi_slot)(struct i3c_dev_desc *dev, 463 462 struct i3c_ibi_slot *slot); 463 + int (*enable_hotjoin)(struct i3c_master_controller *master); 464 + int (*disable_hotjoin)(struct i3c_master_controller *master); 464 465 }; 465 466 466 467 /** ··· 476 473 * @ops: master operations. See &struct i3c_master_controller_ops 477 474 * @secondary: true if the master is a secondary master 478 475 * @init_done: true when the bus initialization is done 476 + * @hotjoin: true if the master support hotjoin 479 477 * @boardinfo.i3c: list of I3C boardinfo objects 480 478 * @boardinfo.i2c: list of I2C boardinfo objects 481 479 * @boardinfo: board-level information attached to devices connected on the bus ··· 499 495 const struct i3c_master_controller_ops *ops; 500 496 unsigned int secondary : 1; 501 497 unsigned int init_done : 1; 498 + unsigned int hotjoin: 1; 502 499 struct { 503 500 struct list_head i3c; 504 501 struct list_head i2c; ··· 556 551 const struct i3c_master_controller_ops *ops, 557 552 bool secondary); 558 553 void i3c_master_unregister(struct i3c_master_controller *master); 554 + int i3c_master_enable_hotjoin(struct i3c_master_controller *master); 555 + int i3c_master_disable_hotjoin(struct i3c_master_controller *master); 559 556 560 557 /** 561 558 * i3c_dev_get_master_data() - get master private data attached to an I3C