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 'mhi-for-v6.20' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/mani/mhi into char-misc-next

Manivannan writes:

MHI Host
--------

- Add support for loading dual ELF image format firmware to Qcom Trust
Management Engine Lit (TME-L) supported devices like QCC2072, which require
separate ELF header for SBL and WLAN firmware segments in a single firmware.

- Remove the MHI auto_queue feature support. This feature was added to offload
the queuing of buffers from the client drivers to the MHI stack, but it caused
a lot of race over the time. So remove this feature from the QRTR client
driver and also from the MHI stack/controller drivers.

- Move the .probe() and .remove() callbacks from driver level to bus level.

MHI Endpoint
------------

- Move the .probe() and .remove() callbacks from driver level to bus level.

* tag 'mhi-for-v6.20' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/mani/mhi:
bus: mhi: ep: Use bus callbacks for .probe() and .remove()
bus: mhi: host: Use bus callbacks for .probe() and .remove()
bus: mhi: host: Drop the auto_queue support
net: qrtr: Drop the MHI auto_queue feature for IPCR DL channels
mhi: host: Add support for loading dual ELF image format

+82 -201
-44
drivers/accel/qaic/mhi_controller.c
··· 39 39 .lpm_notify = false, 40 40 .offload_channel = false, 41 41 .doorbell_mode_switch = false, 42 - .auto_queue = false, 43 42 .wake_capable = false, 44 43 }, 45 44 { ··· 54 55 .lpm_notify = false, 55 56 .offload_channel = false, 56 57 .doorbell_mode_switch = false, 57 - .auto_queue = false, 58 58 .wake_capable = false, 59 59 }, 60 60 { ··· 69 71 .lpm_notify = false, 70 72 .offload_channel = false, 71 73 .doorbell_mode_switch = false, 72 - .auto_queue = false, 73 74 .wake_capable = false, 74 75 }, 75 76 { ··· 84 87 .lpm_notify = false, 85 88 .offload_channel = false, 86 89 .doorbell_mode_switch = false, 87 - .auto_queue = false, 88 90 .wake_capable = false, 89 91 }, 90 92 { ··· 99 103 .lpm_notify = false, 100 104 .offload_channel = false, 101 105 .doorbell_mode_switch = false, 102 - .auto_queue = false, 103 106 .wake_capable = false, 104 107 }, 105 108 { ··· 114 119 .lpm_notify = false, 115 120 .offload_channel = false, 116 121 .doorbell_mode_switch = false, 117 - .auto_queue = false, 118 122 .wake_capable = false, 119 123 }, 120 124 { ··· 129 135 .lpm_notify = false, 130 136 .offload_channel = false, 131 137 .doorbell_mode_switch = false, 132 - .auto_queue = false, 133 138 .wake_capable = false, 134 139 }, 135 140 { ··· 144 151 .lpm_notify = false, 145 152 .offload_channel = false, 146 153 .doorbell_mode_switch = false, 147 - .auto_queue = false, 148 154 .wake_capable = false, 149 155 }, 150 156 { ··· 159 167 .lpm_notify = false, 160 168 .offload_channel = false, 161 169 .doorbell_mode_switch = false, 162 - .auto_queue = false, 163 170 .wake_capable = false, 164 171 }, 165 172 { ··· 174 183 .lpm_notify = false, 175 184 .offload_channel = false, 176 185 .doorbell_mode_switch = false, 177 - .auto_queue = false, 178 186 .wake_capable = false, 179 187 }, 180 188 { ··· 189 199 .lpm_notify = false, 190 200 .offload_channel = false, 191 201 .doorbell_mode_switch = false, 192 - .auto_queue = false, 193 202 .wake_capable = false, 194 203 }, 195 204 { ··· 204 215 .lpm_notify = false, 205 216 .offload_channel = false, 206 217 .doorbell_mode_switch = false, 207 - .auto_queue = false, 208 218 .wake_capable = false, 209 219 }, 210 220 { ··· 219 231 .lpm_notify = false, 220 232 .offload_channel = false, 221 233 .doorbell_mode_switch = false, 222 - .auto_queue = false, 223 234 .wake_capable = false, 224 235 }, 225 236 { ··· 234 247 .lpm_notify = false, 235 248 .offload_channel = false, 236 249 .doorbell_mode_switch = false, 237 - .auto_queue = false, 238 250 .wake_capable = false, 239 251 }, 240 252 { ··· 249 263 .lpm_notify = false, 250 264 .offload_channel = false, 251 265 .doorbell_mode_switch = false, 252 - .auto_queue = false, 253 266 .wake_capable = false, 254 267 }, 255 268 { ··· 264 279 .lpm_notify = false, 265 280 .offload_channel = false, 266 281 .doorbell_mode_switch = false, 267 - .auto_queue = false, 268 282 .wake_capable = false, 269 283 }, 270 284 { ··· 279 295 .lpm_notify = false, 280 296 .offload_channel = false, 281 297 .doorbell_mode_switch = false, 282 - .auto_queue = false, 283 298 .wake_capable = false, 284 299 }, 285 300 { ··· 294 311 .lpm_notify = false, 295 312 .offload_channel = false, 296 313 .doorbell_mode_switch = false, 297 - .auto_queue = false, 298 314 .wake_capable = false, 299 315 }, 300 316 { ··· 309 327 .lpm_notify = false, 310 328 .offload_channel = false, 311 329 .doorbell_mode_switch = false, 312 - .auto_queue = false, 313 330 .wake_capable = false, 314 331 }, 315 332 { ··· 324 343 .lpm_notify = false, 325 344 .offload_channel = false, 326 345 .doorbell_mode_switch = false, 327 - .auto_queue = false, 328 346 .wake_capable = false, 329 347 }, 330 348 { ··· 339 359 .lpm_notify = false, 340 360 .offload_channel = false, 341 361 .doorbell_mode_switch = false, 342 - .auto_queue = false, 343 362 .wake_capable = false, 344 363 }, 345 364 { ··· 354 375 .lpm_notify = false, 355 376 .offload_channel = false, 356 377 .doorbell_mode_switch = false, 357 - .auto_queue = false, 358 378 .wake_capable = false, 359 379 }, 360 380 { ··· 369 391 .lpm_notify = false, 370 392 .offload_channel = false, 371 393 .doorbell_mode_switch = false, 372 - .auto_queue = false, 373 394 .wake_capable = false, 374 395 }, 375 396 { ··· 384 407 .lpm_notify = false, 385 408 .offload_channel = false, 386 409 .doorbell_mode_switch = false, 387 - .auto_queue = false, 388 410 .wake_capable = false, 389 411 }, 390 412 { ··· 399 423 .lpm_notify = false, 400 424 .offload_channel = false, 401 425 .doorbell_mode_switch = false, 402 - .auto_queue = false, 403 426 .wake_capable = false, 404 427 }, 405 428 { ··· 414 439 .lpm_notify = false, 415 440 .offload_channel = false, 416 441 .doorbell_mode_switch = false, 417 - .auto_queue = true, 418 442 .wake_capable = false, 419 443 }, 420 444 }; ··· 432 458 .lpm_notify = false, 433 459 .offload_channel = false, 434 460 .doorbell_mode_switch = false, 435 - .auto_queue = false, 436 461 .wake_capable = false, 437 462 }, 438 463 { ··· 447 474 .lpm_notify = false, 448 475 .offload_channel = false, 449 476 .doorbell_mode_switch = false, 450 - .auto_queue = false, 451 477 .wake_capable = false, 452 478 }, 453 479 { ··· 462 490 .lpm_notify = false, 463 491 .offload_channel = false, 464 492 .doorbell_mode_switch = false, 465 - .auto_queue = false, 466 493 .wake_capable = false, 467 494 }, 468 495 { ··· 477 506 .lpm_notify = false, 478 507 .offload_channel = false, 479 508 .doorbell_mode_switch = false, 480 - .auto_queue = false, 481 509 .wake_capable = false, 482 510 }, 483 511 { ··· 492 522 .lpm_notify = false, 493 523 .offload_channel = false, 494 524 .doorbell_mode_switch = false, 495 - .auto_queue = false, 496 525 .wake_capable = false, 497 526 }, 498 527 { ··· 507 538 .lpm_notify = false, 508 539 .offload_channel = false, 509 540 .doorbell_mode_switch = false, 510 - .auto_queue = false, 511 541 .wake_capable = false, 512 542 }, 513 543 { ··· 522 554 .lpm_notify = false, 523 555 .offload_channel = false, 524 556 .doorbell_mode_switch = false, 525 - .auto_queue = false, 526 557 .wake_capable = false, 527 558 }, 528 559 { ··· 537 570 .lpm_notify = false, 538 571 .offload_channel = false, 539 572 .doorbell_mode_switch = false, 540 - .auto_queue = false, 541 573 .wake_capable = false, 542 574 }, 543 575 { ··· 552 586 .lpm_notify = false, 553 587 .offload_channel = false, 554 588 .doorbell_mode_switch = false, 555 - .auto_queue = false, 556 589 .wake_capable = false, 557 590 }, 558 591 { ··· 567 602 .lpm_notify = false, 568 603 .offload_channel = false, 569 604 .doorbell_mode_switch = false, 570 - .auto_queue = false, 571 605 .wake_capable = false, 572 606 }, 573 607 { ··· 582 618 .lpm_notify = false, 583 619 .offload_channel = false, 584 620 .doorbell_mode_switch = false, 585 - .auto_queue = false, 586 621 .wake_capable = false, 587 622 }, 588 623 { ··· 597 634 .lpm_notify = false, 598 635 .offload_channel = false, 599 636 .doorbell_mode_switch = false, 600 - .auto_queue = false, 601 637 .wake_capable = false, 602 638 }, 603 639 { ··· 612 650 .lpm_notify = false, 613 651 .offload_channel = false, 614 652 .doorbell_mode_switch = false, 615 - .auto_queue = false, 616 653 .wake_capable = false, 617 654 }, 618 655 { ··· 627 666 .lpm_notify = false, 628 667 .offload_channel = false, 629 668 .doorbell_mode_switch = false, 630 - .auto_queue = false, 631 669 .wake_capable = false, 632 670 }, 633 671 { ··· 642 682 .lpm_notify = false, 643 683 .offload_channel = false, 644 684 .doorbell_mode_switch = false, 645 - .auto_queue = false, 646 685 .wake_capable = false, 647 686 }, 648 687 { ··· 657 698 .lpm_notify = false, 658 699 .offload_channel = false, 659 700 .doorbell_mode_switch = false, 660 - .auto_queue = false, 661 701 .wake_capable = false, 662 702 }, 663 703 { ··· 672 714 .lpm_notify = false, 673 715 .offload_channel = false, 674 716 .doorbell_mode_switch = false, 675 - .auto_queue = false, 676 717 .wake_capable = false, 677 718 }, 678 719 { ··· 687 730 .lpm_notify = false, 688 731 .offload_channel = false, 689 732 .doorbell_mode_switch = false, 690 - .auto_queue = true, 691 733 .wake_capable = false, 692 734 }, 693 735 };
+5 -7
drivers/bus/mhi/ep/main.c
··· 1596 1596 } 1597 1597 EXPORT_SYMBOL_GPL(mhi_ep_unregister_controller); 1598 1598 1599 - static int mhi_ep_driver_probe(struct device *dev) 1599 + static int mhi_ep_probe(struct device *dev) 1600 1600 { 1601 1601 struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); 1602 1602 struct mhi_ep_driver *mhi_drv = to_mhi_ep_driver(dev->driver); ··· 1609 1609 return mhi_drv->probe(mhi_dev, mhi_dev->id); 1610 1610 } 1611 1611 1612 - static int mhi_ep_driver_remove(struct device *dev) 1612 + static void mhi_ep_remove(struct device *dev) 1613 1613 { 1614 1614 struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); 1615 1615 struct mhi_ep_driver *mhi_drv = to_mhi_ep_driver(dev->driver); ··· 1619 1619 1620 1620 /* Skip if it is a controller device */ 1621 1621 if (mhi_dev->dev_type == MHI_DEVICE_CONTROLLER) 1622 - return 0; 1622 + return; 1623 1623 1624 1624 /* Disconnect the channels associated with the driver */ 1625 1625 for (dir = 0; dir < 2; dir++) { ··· 1643 1643 1644 1644 /* Remove the client driver now */ 1645 1645 mhi_drv->remove(mhi_dev); 1646 - 1647 - return 0; 1648 1646 } 1649 1647 1650 1648 int __mhi_ep_driver_register(struct mhi_ep_driver *mhi_drv, struct module *owner) ··· 1658 1660 1659 1661 driver->bus = &mhi_ep_bus_type; 1660 1662 driver->owner = owner; 1661 - driver->probe = mhi_ep_driver_probe; 1662 - driver->remove = mhi_ep_driver_remove; 1663 1663 1664 1664 return driver_register(driver); 1665 1665 } ··· 1704 1708 .dev_name = "mhi_ep", 1705 1709 .match = mhi_ep_match, 1706 1710 .uevent = mhi_ep_uevent, 1711 + .probe = mhi_ep_probe, 1712 + .remove = mhi_ep_remove, 1707 1713 }; 1708 1714 1709 1715 static int __init mhi_ep_init(void)
+10
drivers/bus/mhi/host/boot.c
··· 584 584 * device transitioning into MHI READY state 585 585 */ 586 586 if (fw_load_type == MHI_FW_LOAD_FBC) { 587 + /* 588 + * Some FW combine two separate ELF images (SBL + WLAN FW) in a single 589 + * file. Hence, check for the existence of the second ELF header after 590 + * SBL. If present, load the second image separately. 591 + */ 592 + if (!memcmp(fw_data + mhi_cntrl->sbl_size, ELFMAG, SELFMAG)) { 593 + fw_data += mhi_cntrl->sbl_size; 594 + fw_sz -= mhi_cntrl->sbl_size; 595 + } 596 + 587 597 ret = mhi_alloc_bhie_table(mhi_cntrl, &mhi_cntrl->fbc_image, fw_sz); 588 598 if (ret) { 589 599 release_firmware(firmware);
+5 -17
drivers/bus/mhi/host/init.c
··· 841 841 mhi_chan->lpm_notify = ch_cfg->lpm_notify; 842 842 mhi_chan->offload_ch = ch_cfg->offload_channel; 843 843 mhi_chan->db_cfg.reset_req = ch_cfg->doorbell_mode_switch; 844 - mhi_chan->pre_alloc = ch_cfg->auto_queue; 845 844 mhi_chan->wake_capable = ch_cfg->wake_capable; 846 - 847 - /* 848 - * If MHI host allocates buffers, then the channel direction 849 - * should be DMA_FROM_DEVICE 850 - */ 851 - if (mhi_chan->pre_alloc && mhi_chan->dir != DMA_FROM_DEVICE) { 852 - dev_err(dev, "Invalid channel configuration\n"); 853 - goto error_chan_cfg; 854 - } 855 845 856 846 /* 857 847 * Bi-directional and direction less channel must be an ··· 1255 1265 return mhi_dev; 1256 1266 } 1257 1267 1258 - static int mhi_driver_probe(struct device *dev) 1268 + static int mhi_probe(struct device *dev) 1259 1269 { 1260 1270 struct mhi_device *mhi_dev = to_mhi_device(dev); 1261 1271 struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; ··· 1331 1341 return ret; 1332 1342 } 1333 1343 1334 - static int mhi_driver_remove(struct device *dev) 1344 + static void mhi_remove(struct device *dev) 1335 1345 { 1336 1346 struct mhi_device *mhi_dev = to_mhi_device(dev); 1337 1347 struct mhi_driver *mhi_drv = to_mhi_driver(dev->driver); ··· 1345 1355 1346 1356 /* Skip if it is a controller device */ 1347 1357 if (mhi_dev->dev_type == MHI_DEVICE_CONTROLLER) 1348 - return 0; 1358 + return; 1349 1359 1350 1360 /* Reset both channels */ 1351 1361 for (dir = 0; dir < 2; dir++) { ··· 1397 1407 1398 1408 while (mhi_dev->dev_wake) 1399 1409 mhi_device_put(mhi_dev); 1400 - 1401 - return 0; 1402 1410 } 1403 1411 1404 1412 int __mhi_driver_register(struct mhi_driver *mhi_drv, struct module *owner) ··· 1408 1420 1409 1421 driver->bus = &mhi_bus_type; 1410 1422 driver->owner = owner; 1411 - driver->probe = mhi_driver_probe; 1412 - driver->remove = mhi_driver_remove; 1413 1423 1414 1424 return driver_register(driver); 1415 1425 } ··· 1454 1468 .dev_name = "mhi", 1455 1469 .match = mhi_match, 1456 1470 .uevent = mhi_uevent, 1471 + .probe = mhi_probe, 1472 + .remove = mhi_remove, 1457 1473 .dev_groups = mhi_dev_groups, 1458 1474 }; 1459 1475
-3
drivers/bus/mhi/host/internal.h
··· 286 286 bool lpm_notify; 287 287 bool configured; 288 288 bool offload_ch; 289 - bool pre_alloc; 290 289 bool wake_capable; 291 290 }; 292 291 ··· 388 389 struct image_info *img_info); 389 390 void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl); 390 391 391 - /* Automatically allocate and queue inbound buffers */ 392 - #define MHI_CH_INBOUND_ALLOC_BUFS BIT(0) 393 392 int mhi_init_chan_ctxt(struct mhi_controller *mhi_cntrl, 394 393 struct mhi_chan *mhi_chan); 395 394 void mhi_deinit_chan_ctxt(struct mhi_controller *mhi_cntrl,
+2 -79
drivers/bus/mhi/host/main.c
··· 664 664 mhi_cntrl->runtime_put(mhi_cntrl); 665 665 } 666 666 667 - /* 668 - * Recycle the buffer if buffer is pre-allocated, 669 - * if there is an error, not much we can do apart 670 - * from dropping the packet 671 - */ 672 - if (mhi_chan->pre_alloc) { 673 - if (mhi_queue_buf(mhi_chan->mhi_dev, 674 - mhi_chan->dir, 675 - buf_info->cb_buf, 676 - buf_info->len, MHI_EOT)) { 677 - dev_err(dev, 678 - "Error recycling buffer for chan:%d\n", 679 - mhi_chan->chan); 680 - kfree(buf_info->cb_buf); 681 - } 682 - } 683 - 684 667 read_lock_bh(&mhi_chan->lock); 685 668 } 686 669 break; ··· 1160 1177 int mhi_queue_skb(struct mhi_device *mhi_dev, enum dma_data_direction dir, 1161 1178 struct sk_buff *skb, size_t len, enum mhi_flags mflags) 1162 1179 { 1163 - struct mhi_chan *mhi_chan = (dir == DMA_TO_DEVICE) ? mhi_dev->ul_chan : 1164 - mhi_dev->dl_chan; 1165 1180 struct mhi_buf_info buf_info = { }; 1166 1181 1167 1182 buf_info.v_addr = skb->data; 1168 1183 buf_info.cb_buf = skb; 1169 1184 buf_info.len = len; 1170 - 1171 - if (unlikely(mhi_chan->pre_alloc)) 1172 - return -EINVAL; 1173 1185 1174 1186 return mhi_queue(mhi_dev, &buf_info, dir, mflags); 1175 1187 } ··· 1450 1472 if (ret) 1451 1473 goto error_pm_state; 1452 1474 1453 - if (mhi_chan->dir == DMA_FROM_DEVICE) 1454 - mhi_chan->pre_alloc = !!(flags & MHI_CH_INBOUND_ALLOC_BUFS); 1455 - 1456 - /* Pre-allocate buffer for xfer ring */ 1457 - if (mhi_chan->pre_alloc) { 1458 - int nr_el = get_nr_avail_ring_elements(mhi_cntrl, 1459 - &mhi_chan->tre_ring); 1460 - size_t len = mhi_cntrl->buffer_len; 1461 - 1462 - while (nr_el--) { 1463 - void *buf; 1464 - struct mhi_buf_info info = { }; 1465 - 1466 - buf = kmalloc(len, GFP_KERNEL); 1467 - if (!buf) { 1468 - ret = -ENOMEM; 1469 - goto error_pre_alloc; 1470 - } 1471 - 1472 - /* Prepare transfer descriptors */ 1473 - info.v_addr = buf; 1474 - info.cb_buf = buf; 1475 - info.len = len; 1476 - ret = mhi_gen_tre(mhi_cntrl, mhi_chan, &info, MHI_EOT); 1477 - if (ret) { 1478 - kfree(buf); 1479 - goto error_pre_alloc; 1480 - } 1481 - } 1482 - 1483 - read_lock_bh(&mhi_cntrl->pm_lock); 1484 - if (MHI_DB_ACCESS_VALID(mhi_cntrl)) { 1485 - read_lock_irq(&mhi_chan->lock); 1486 - mhi_ring_chan_db(mhi_cntrl, mhi_chan); 1487 - read_unlock_irq(&mhi_chan->lock); 1488 - } 1489 - read_unlock_bh(&mhi_cntrl->pm_lock); 1490 - } 1491 - 1492 1475 mutex_unlock(&mhi_chan->mutex); 1493 1476 1494 1477 return 0; ··· 1460 1521 1461 1522 error_init_chan: 1462 1523 mutex_unlock(&mhi_chan->mutex); 1463 - 1464 - return ret; 1465 - 1466 - error_pre_alloc: 1467 - mutex_unlock(&mhi_chan->mutex); 1468 - mhi_unprepare_channel(mhi_cntrl, mhi_chan); 1469 1524 1470 1525 return ret; 1471 1526 } ··· 1533 1600 mhi_del_ring_element(mhi_cntrl, buf_ring); 1534 1601 mhi_del_ring_element(mhi_cntrl, tre_ring); 1535 1602 1536 - if (mhi_chan->pre_alloc) { 1537 - kfree(buf_info->cb_buf); 1538 - } else { 1539 - result.buf_addr = buf_info->cb_buf; 1540 - mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); 1541 - } 1603 + result.buf_addr = buf_info->cb_buf; 1604 + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); 1542 1605 } 1543 1606 } 1544 1607 ··· 1594 1665 return __mhi_prepare_for_transfer(mhi_dev, 0); 1595 1666 } 1596 1667 EXPORT_SYMBOL_GPL(mhi_prepare_for_transfer); 1597 - 1598 - int mhi_prepare_for_transfer_autoqueue(struct mhi_device *mhi_dev) 1599 - { 1600 - return __mhi_prepare_for_transfer(mhi_dev, MHI_CH_INBOUND_ALLOC_BUFS); 1601 - } 1602 - EXPORT_SYMBOL_GPL(mhi_prepare_for_transfer_autoqueue); 1603 1668 1604 1669 void mhi_unprepare_from_transfer(struct mhi_device *mhi_dev) 1605 1670 {
+2 -18
drivers/bus/mhi/host/pci_generic.c
··· 94 94 .doorbell_mode_switch = false, \ 95 95 } 96 96 97 - #define MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(ch_num, ch_name, el_count, ev_ring) \ 98 - { \ 99 - .num = ch_num, \ 100 - .name = ch_name, \ 101 - .num_elements = el_count, \ 102 - .event_ring = ev_ring, \ 103 - .dir = DMA_FROM_DEVICE, \ 104 - .ee_mask = BIT(MHI_EE_AMSS), \ 105 - .pollcfg = 0, \ 106 - .doorbell = MHI_DB_BRST_DISABLE, \ 107 - .lpm_notify = false, \ 108 - .offload_channel = false, \ 109 - .doorbell_mode_switch = false, \ 110 - .auto_queue = true, \ 111 - } 112 - 113 97 #define MHI_EVENT_CONFIG_CTRL(ev_ring, el_count) \ 114 98 { \ 115 99 .num_elements = el_count, \ ··· 313 329 MHI_CHANNEL_CONFIG_UL(14, "QMI", 4, 0), 314 330 MHI_CHANNEL_CONFIG_DL(15, "QMI", 4, 0), 315 331 MHI_CHANNEL_CONFIG_UL(20, "IPCR", 8, 0), 316 - MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(21, "IPCR", 8, 0), 332 + MHI_CHANNEL_CONFIG_DL(21, "IPCR", 8, 0), 317 333 MHI_CHANNEL_CONFIG_UL_FP(34, "FIREHOSE", 32, 0), 318 334 MHI_CHANNEL_CONFIG_DL_FP(35, "FIREHOSE", 32, 0), 319 335 MHI_CHANNEL_CONFIG_UL(46, "IP_SW0", 64, 2), ··· 746 762 MHI_CHANNEL_CONFIG_UL(14, "QMI", 32, 0), 747 763 MHI_CHANNEL_CONFIG_DL(15, "QMI", 32, 0), 748 764 MHI_CHANNEL_CONFIG_UL(20, "IPCR", 16, 0), 749 - MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(21, "IPCR", 16, 0), 765 + MHI_CHANNEL_CONFIG_DL(21, "IPCR", 16, 0), 750 766 MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 128, 1), 751 767 MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0", 128, 2), 752 768 };
-4
drivers/net/wireless/ath/ath11k/mhi.c
··· 34 34 .lpm_notify = false, 35 35 .offload_channel = false, 36 36 .doorbell_mode_switch = false, 37 - .auto_queue = false, 38 37 }, 39 38 { 40 39 .num = 21, ··· 47 48 .lpm_notify = false, 48 49 .offload_channel = false, 49 50 .doorbell_mode_switch = false, 50 - .auto_queue = true, 51 51 }, 52 52 }; 53 53 ··· 97 99 .lpm_notify = false, 98 100 .offload_channel = false, 99 101 .doorbell_mode_switch = false, 100 - .auto_queue = false, 101 102 }, 102 103 { 103 104 .num = 21, ··· 110 113 .lpm_notify = false, 111 114 .offload_channel = false, 112 115 .doorbell_mode_switch = false, 113 - .auto_queue = true, 114 116 }, 115 117 }; 116 118
-4
drivers/net/wireless/ath/ath12k/mhi.c
··· 31 31 .lpm_notify = false, 32 32 .offload_channel = false, 33 33 .doorbell_mode_switch = false, 34 - .auto_queue = false, 35 34 }, 36 35 { 37 36 .num = 21, ··· 44 45 .lpm_notify = false, 45 46 .offload_channel = false, 46 47 .doorbell_mode_switch = false, 47 - .auto_queue = true, 48 48 }, 49 49 }; 50 50 ··· 94 96 .lpm_notify = false, 95 97 .offload_channel = false, 96 98 .doorbell_mode_switch = false, 97 - .auto_queue = false, 98 99 }, 99 100 { 100 101 .num = 21, ··· 107 110 .lpm_notify = false, 108 111 .offload_channel = false, 109 112 .doorbell_mode_switch = false, 110 - .auto_queue = true, 111 113 }, 112 114 }; 113 115
-14
include/linux/mhi.h
··· 215 215 * @lpm_notify: The channel master requires low power mode notifications 216 216 * @offload_channel: The client manages the channel completely 217 217 * @doorbell_mode_switch: Channel switches to doorbell mode on M0 transition 218 - * @auto_queue: Framework will automatically queue buffers for DL traffic 219 218 * @wake-capable: Channel capable of waking up the system 220 219 */ 221 220 struct mhi_channel_config { ··· 231 232 bool lpm_notify; 232 233 bool offload_channel; 233 234 bool doorbell_mode_switch; 234 - bool auto_queue; 235 235 bool wake_capable; 236 236 }; 237 237 ··· 740 742 * device execution environments match and channels are in a DISABLED state. 741 743 */ 742 744 int mhi_prepare_for_transfer(struct mhi_device *mhi_dev); 743 - 744 - /** 745 - * mhi_prepare_for_transfer_autoqueue - Setup UL and DL channels with auto queue 746 - * buffers for DL traffic 747 - * @mhi_dev: Device associated with the channels 748 - * 749 - * Allocate and initialize the channel context and also issue the START channel 750 - * command to both channels. Channels can be started only if both host and 751 - * device execution environments match and channels are in a DISABLED state. 752 - * The MHI core will automatically allocate and queue buffers for the DL traffic. 753 - */ 754 - int mhi_prepare_for_transfer_autoqueue(struct mhi_device *mhi_dev); 755 745 756 746 /** 757 747 * mhi_unprepare_from_transfer - Reset UL and DL channels for data transfer.
+58 -11
net/qrtr/mhi.c
··· 24 24 struct qrtr_mhi_dev *qdev = dev_get_drvdata(&mhi_dev->dev); 25 25 int rc; 26 26 27 - if (!qdev || mhi_res->transaction_status) 27 + if (!qdev || (mhi_res->transaction_status && mhi_res->transaction_status != -ENOTCONN)) 28 28 return; 29 + 30 + /* Channel got reset. So just free the buffer */ 31 + if (mhi_res->transaction_status == -ENOTCONN) { 32 + devm_kfree(&mhi_dev->dev, mhi_res->buf_addr); 33 + return; 34 + } 29 35 30 36 rc = qrtr_endpoint_post(&qdev->ep, mhi_res->buf_addr, 31 37 mhi_res->bytes_xferd); 32 38 if (rc == -EINVAL) 33 39 dev_err(qdev->dev, "invalid ipcrouter packet\n"); 40 + 41 + /* Done with the buffer, now recycle it for future use */ 42 + rc = mhi_queue_buf(mhi_dev, DMA_FROM_DEVICE, mhi_res->buf_addr, 43 + mhi_dev->mhi_cntrl->buffer_len, MHI_EOT); 44 + if (rc) 45 + dev_err(&mhi_dev->dev, "Failed to recycle the buffer: %d\n", rc); 34 46 } 35 47 36 48 /* From QRTR to MHI */ ··· 84 72 return rc; 85 73 } 86 74 75 + static int qcom_mhi_qrtr_queue_dl_buffers(struct mhi_device *mhi_dev) 76 + { 77 + u32 free_desc; 78 + void *buf; 79 + int ret; 80 + 81 + free_desc = mhi_get_free_desc_count(mhi_dev, DMA_FROM_DEVICE); 82 + while (free_desc--) { 83 + buf = devm_kmalloc(&mhi_dev->dev, mhi_dev->mhi_cntrl->buffer_len, GFP_KERNEL); 84 + if (!buf) 85 + return -ENOMEM; 86 + 87 + ret = mhi_queue_buf(mhi_dev, DMA_FROM_DEVICE, buf, mhi_dev->mhi_cntrl->buffer_len, 88 + MHI_EOT); 89 + if (ret) { 90 + dev_err(&mhi_dev->dev, "Failed to queue buffer: %d\n", ret); 91 + return ret; 92 + } 93 + } 94 + 95 + return 0; 96 + } 97 + 87 98 static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev, 88 99 const struct mhi_device_id *id) 89 100 { ··· 122 87 qdev->ep.xmit = qcom_mhi_qrtr_send; 123 88 124 89 dev_set_drvdata(&mhi_dev->dev, qdev); 125 - rc = qrtr_endpoint_register(&qdev->ep, QRTR_EP_NID_AUTO); 90 + 91 + /* start channels */ 92 + rc = mhi_prepare_for_transfer(mhi_dev); 126 93 if (rc) 127 94 return rc; 128 95 129 - /* start channels */ 130 - rc = mhi_prepare_for_transfer_autoqueue(mhi_dev); 131 - if (rc) { 132 - qrtr_endpoint_unregister(&qdev->ep); 133 - return rc; 134 - } 96 + rc = qrtr_endpoint_register(&qdev->ep, QRTR_EP_NID_AUTO); 97 + if (rc) 98 + goto err_unprepare; 99 + 100 + rc = qcom_mhi_qrtr_queue_dl_buffers(mhi_dev); 101 + if (rc) 102 + goto err_unregister; 135 103 136 104 dev_dbg(qdev->dev, "Qualcomm MHI QRTR driver probed\n"); 137 105 138 106 return 0; 107 + 108 + err_unregister: 109 + qrtr_endpoint_unregister(&qdev->ep); 110 + err_unprepare: 111 + mhi_unprepare_from_transfer(mhi_dev); 112 + 113 + return rc; 139 114 } 140 115 141 116 static void qcom_mhi_qrtr_remove(struct mhi_device *mhi_dev) ··· 196 151 if (state == MHI_STATE_M3) 197 152 return 0; 198 153 199 - rc = mhi_prepare_for_transfer_autoqueue(mhi_dev); 200 - if (rc) 154 + rc = mhi_prepare_for_transfer(mhi_dev); 155 + if (rc) { 201 156 dev_err(dev, "failed to prepare for autoqueue transfer %d\n", rc); 157 + return rc; 158 + } 202 159 203 - return rc; 160 + return qcom_mhi_qrtr_queue_dl_buffers(mhi_dev); 204 161 } 205 162 206 163 static const struct dev_pm_ops qcom_mhi_qrtr_pm_ops = {