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

Manivannan writes:

MHI Host
========

- Make local functions static (as they should be).

- Fix the modem name for Foxconn T99W640 modem.

- Disable runtime PM for Qcom QDU100 modem as it doesn't support M3 state.

- Fix endianness of BHI vector table to allow MHI to work correctly on big
endian platforms like PowerPC.

- Add modem support for Semtech EM929x, Foxconn T99W696 and Telit FN990B40
modems.

- Fix the OOB access to Transfer Ring Element (TRE) by hardening the checks in
parse_xfer_event().

* tag 'mhi-for-v6.17' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/mani/mhi:
bus: mhi: host: pci_generic: Add Telit FN990B40 modem support
bus: mhi: host: Detect events pointing to unexpected TREs
bus: mhi: host: pci_generic: Add Foxconn T99W696 modem
bus: mhi: host: Use str_true_false() helper
bus: mhi: host: pci_generic: Add support for EM929x and set MRU to 32768 for better performance.
bus: mhi: host: Fix endianness of BHI vector table
bus: mhi: host: pci_generic: Disable runtime PM for QDU100
bus: mhi: host: pci_generic: Fix the modem name of Foxconn T99W640
bus: mhi: host: Make local functions static

+102 -26
+4 -4
drivers/bus/mhi/host/boot.c
··· 31 31 int ret; 32 32 33 33 for (i = 0; i < img_info->entries - 1; i++, mhi_buf++, bhi_vec++) { 34 - bhi_vec->dma_addr = mhi_buf->dma_addr; 35 - bhi_vec->size = mhi_buf->len; 34 + bhi_vec->dma_addr = cpu_to_le64(mhi_buf->dma_addr); 35 + bhi_vec->size = cpu_to_le64(mhi_buf->len); 36 36 } 37 37 38 38 dev_dbg(dev, "BHIe programming for RDDM\n"); ··· 431 431 while (remainder) { 432 432 to_cpy = min(remainder, mhi_buf->len); 433 433 memcpy(mhi_buf->buf, buf, to_cpy); 434 - bhi_vec->dma_addr = mhi_buf->dma_addr; 435 - bhi_vec->size = to_cpy; 434 + bhi_vec->dma_addr = cpu_to_le64(mhi_buf->dma_addr); 435 + bhi_vec->size = cpu_to_le64(to_cpy); 436 436 437 437 buf += to_cpy; 438 438 remainder -= to_cpy;
+2 -1
drivers/bus/mhi/host/debugfs.c
··· 10 10 #include <linux/list.h> 11 11 #include <linux/mhi.h> 12 12 #include <linux/module.h> 13 + #include <linux/string_choices.h> 13 14 #include "internal.h" 14 15 15 16 static int mhi_debugfs_states_show(struct seq_file *m, void *d) ··· 23 22 mhi_is_active(mhi_cntrl) ? "Active" : "Inactive", 24 23 mhi_state_str(mhi_cntrl->dev_state), 25 24 TO_MHI_EXEC_STR(mhi_cntrl->ee), 26 - mhi_cntrl->wake_set ? "true" : "false"); 25 + str_true_false(mhi_cntrl->wake_set)); 27 26 28 27 /* counters */ 29 28 seq_printf(m, "M0: %u M2: %u M3: %u", mhi_cntrl->M0, mhi_cntrl->M2,
+4 -4
drivers/bus/mhi/host/init.c
··· 176 176 return 0; 177 177 } 178 178 179 - void mhi_deinit_free_irq(struct mhi_controller *mhi_cntrl) 179 + static void mhi_deinit_free_irq(struct mhi_controller *mhi_cntrl) 180 180 { 181 181 int i; 182 182 struct mhi_event *mhi_event = mhi_cntrl->mhi_event; ··· 191 191 free_irq(mhi_cntrl->irq[0], mhi_cntrl); 192 192 } 193 193 194 - int mhi_init_irq_setup(struct mhi_controller *mhi_cntrl) 194 + static int mhi_init_irq_setup(struct mhi_controller *mhi_cntrl) 195 195 { 196 196 struct mhi_event *mhi_event = mhi_cntrl->mhi_event; 197 197 struct device *dev = &mhi_cntrl->mhi_dev->dev; ··· 254 254 return ret; 255 255 } 256 256 257 - void mhi_deinit_dev_ctxt(struct mhi_controller *mhi_cntrl) 257 + static void mhi_deinit_dev_ctxt(struct mhi_controller *mhi_cntrl) 258 258 { 259 259 int i; 260 260 struct mhi_ctxt *mhi_ctxt = mhi_cntrl->mhi_ctxt; ··· 299 299 mhi_cntrl->mhi_ctxt = NULL; 300 300 } 301 301 302 - int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl) 302 + static int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl) 303 303 { 304 304 struct mhi_ctxt *mhi_ctxt; 305 305 struct mhi_chan_ctxt *chan_ctxt;
+2 -9
drivers/bus/mhi/host/internal.h
··· 25 25 }; 26 26 27 27 struct bhi_vec_entry { 28 - u64 dma_addr; 29 - u64 size; 28 + __le64 dma_addr; 29 + __le64 size; 30 30 }; 31 31 32 32 enum mhi_fw_load_type { ··· 383 383 384 384 /* Initialization methods */ 385 385 int mhi_init_mmio(struct mhi_controller *mhi_cntrl); 386 - int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl); 387 - void mhi_deinit_dev_ctxt(struct mhi_controller *mhi_cntrl); 388 - int mhi_init_irq_setup(struct mhi_controller *mhi_cntrl); 389 - void mhi_deinit_free_irq(struct mhi_controller *mhi_cntrl); 390 386 int mhi_rddm_prepare(struct mhi_controller *mhi_cntrl, 391 387 struct image_info *img_info); 392 388 void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl); 393 389 394 390 /* Automatically allocate and queue inbound buffers */ 395 391 #define MHI_CH_INBOUND_ALLOC_BUFS BIT(0) 396 - int mhi_prepare_channel(struct mhi_controller *mhi_cntrl, 397 - struct mhi_chan *mhi_chan, unsigned int flags); 398 - 399 392 int mhi_init_chan_ctxt(struct mhi_controller *mhi_cntrl, 400 393 struct mhi_chan *mhi_chan); 401 394 void mhi_deinit_chan_ctxt(struct mhi_controller *mhi_cntrl,
+12 -2
drivers/bus/mhi/host/main.c
··· 602 602 { 603 603 dma_addr_t ptr = MHI_TRE_GET_EV_PTR(event); 604 604 struct mhi_ring_element *local_rp, *ev_tre; 605 - void *dev_rp; 605 + void *dev_rp, *next_rp; 606 606 struct mhi_buf_info *buf_info; 607 607 u16 xfer_len; 608 608 ··· 621 621 result.dir = mhi_chan->dir; 622 622 623 623 local_rp = tre_ring->rp; 624 + 625 + next_rp = local_rp + 1; 626 + if (next_rp >= tre_ring->base + tre_ring->len) 627 + next_rp = tre_ring->base; 628 + if (dev_rp != next_rp && !MHI_TRE_DATA_GET_CHAIN(local_rp)) { 629 + dev_err(&mhi_cntrl->mhi_dev->dev, 630 + "Event element points to an unexpected TRE\n"); 631 + break; 632 + } 633 + 624 634 while (local_rp != dev_rp) { 625 635 buf_info = buf_ring->rp; 626 636 /* If it's the last TRE, get length from the event */ ··· 1445 1435 mutex_unlock(&mhi_chan->mutex); 1446 1436 } 1447 1437 1448 - int mhi_prepare_channel(struct mhi_controller *mhi_cntrl, 1438 + static int mhi_prepare_channel(struct mhi_controller *mhi_cntrl, 1449 1439 struct mhi_chan *mhi_chan, unsigned int flags) 1450 1440 { 1451 1441 int ret = 0;
+78 -6
drivers/bus/mhi/host/pci_generic.c
··· 43 43 * @mru_default: default MRU size for MBIM network packets 44 44 * @sideband_wake: Devices using dedicated sideband GPIO for wakeup instead 45 45 * of inband wake support (such as sdx24) 46 + * @no_m3: M3 not supported 46 47 */ 47 48 struct mhi_pci_dev_info { 48 49 const struct mhi_controller_config *config; ··· 55 54 unsigned int dma_data_width; 56 55 unsigned int mru_default; 57 56 bool sideband_wake; 57 + bool no_m3; 58 58 }; 59 59 60 60 #define MHI_CHANNEL_CONFIG_UL(ch_num, ch_name, el_count, ev_ring) \ ··· 297 295 .bar_num = MHI_PCI_DEFAULT_BAR_NUM, 298 296 .dma_data_width = 32, 299 297 .sideband_wake = false, 298 + .no_m3 = true, 300 299 }; 301 300 302 301 static const struct mhi_channel_config mhi_qcom_sa8775p_channels[] = { ··· 493 490 MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0_MBIM", 128, 3), 494 491 }; 495 492 493 + static const struct mhi_channel_config mhi_foxconn_sdx61_channels[] = { 494 + MHI_CHANNEL_CONFIG_UL(0, "LOOPBACK", 32, 0), 495 + MHI_CHANNEL_CONFIG_DL(1, "LOOPBACK", 32, 0), 496 + MHI_CHANNEL_CONFIG_UL(4, "DIAG", 32, 1), 497 + MHI_CHANNEL_CONFIG_DL(5, "DIAG", 32, 1), 498 + MHI_CHANNEL_CONFIG_UL(12, "MBIM", 32, 0), 499 + MHI_CHANNEL_CONFIG_DL(13, "MBIM", 32, 0), 500 + MHI_CHANNEL_CONFIG_UL(32, "DUN", 32, 0), 501 + MHI_CHANNEL_CONFIG_DL(33, "DUN", 32, 0), 502 + MHI_CHANNEL_CONFIG_UL_FP(34, "FIREHOSE", 32, 0), 503 + MHI_CHANNEL_CONFIG_DL_FP(35, "FIREHOSE", 32, 0), 504 + MHI_CHANNEL_CONFIG_UL(50, "NMEA", 32, 0), 505 + MHI_CHANNEL_CONFIG_DL(51, "NMEA", 32, 0), 506 + MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0_MBIM", 128, 2), 507 + MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0_MBIM", 128, 3), 508 + }; 509 + 496 510 static struct mhi_event_config mhi_foxconn_sdx55_events[] = { 497 511 MHI_EVENT_CONFIG_CTRL(0, 128), 498 512 MHI_EVENT_CONFIG_DATA(1, 128), ··· 522 502 .timeout_ms = 20000, 523 503 .num_channels = ARRAY_SIZE(mhi_foxconn_sdx55_channels), 524 504 .ch_cfg = mhi_foxconn_sdx55_channels, 505 + .num_events = ARRAY_SIZE(mhi_foxconn_sdx55_events), 506 + .event_cfg = mhi_foxconn_sdx55_events, 507 + }; 508 + 509 + static const struct mhi_controller_config modem_foxconn_sdx61_config = { 510 + .max_channels = 128, 511 + .timeout_ms = 20000, 512 + .num_channels = ARRAY_SIZE(mhi_foxconn_sdx61_channels), 513 + .ch_cfg = mhi_foxconn_sdx61_channels, 525 514 .num_events = ARRAY_SIZE(mhi_foxconn_sdx55_events), 526 515 .event_cfg = mhi_foxconn_sdx55_events, 527 516 }; ··· 622 593 .sideband_wake = false, 623 594 }; 624 595 625 - static const struct mhi_pci_dev_info mhi_foxconn_t99w515_info = { 626 - .name = "foxconn-t99w515", 596 + static const struct mhi_pci_dev_info mhi_foxconn_t99w640_info = { 597 + .name = "foxconn-t99w640", 627 598 .edl = "qcom/sdx72m/foxconn/edl.mbn", 628 599 .edl_trigger = true, 629 600 .config = &modem_foxconn_sdx72_config, ··· 638 609 .edl = "qcom/sdx72m/foxconn/edl.mbn", 639 610 .edl_trigger = true, 640 611 .config = &modem_foxconn_sdx72_config, 612 + .bar_num = MHI_PCI_DEFAULT_BAR_NUM, 613 + .dma_data_width = 32, 614 + .mru_default = 32768, 615 + .sideband_wake = false, 616 + }; 617 + 618 + static const struct mhi_pci_dev_info mhi_foxconn_t99w696_info = { 619 + .name = "foxconn-t99w696", 620 + .edl = "qcom/sdx61/foxconn/prog_firehose_lite.elf", 621 + .edl_trigger = true, 622 + .config = &modem_foxconn_sdx61_config, 641 623 .bar_num = MHI_PCI_DEFAULT_BAR_NUM, 642 624 .dma_data_width = 32, 643 625 .mru_default = 32768, ··· 735 695 .config = &modem_sierra_em919x_config, 736 696 .bar_num = MHI_PCI_DEFAULT_BAR_NUM, 737 697 .dma_data_width = 32, 698 + .mru_default = 32768, 738 699 .sideband_wake = false, 739 700 }; 740 701 ··· 859 818 .edl_trigger = true, 860 819 }; 861 820 821 + static const struct mhi_pci_dev_info mhi_telit_fn990b40_info = { 822 + .name = "telit-fn990b40", 823 + .config = &modem_telit_fn920c04_config, 824 + .bar_num = MHI_PCI_DEFAULT_BAR_NUM, 825 + .dma_data_width = 32, 826 + .sideband_wake = false, 827 + .mru_default = 32768, 828 + .edl_trigger = true, 829 + }; 830 + 862 831 static const struct mhi_pci_dev_info mhi_netprisma_lcur57_info = { 863 832 .name = "netprisma-lcur57", 864 833 .edl = "qcom/prog_firehose_sdx24.mbn", ··· 903 852 /* EM919x (sdx55), use the same vid:pid as qcom-sdx55m */ 904 853 { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, 0x18d7, 0x0200), 905 854 .driver_data = (kernel_ulong_t) &mhi_sierra_em919x_info }, 855 + /* EM929x (sdx65), use the same configuration as EM919x */ 856 + { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, 0x18d7, 0x0301), 857 + .driver_data = (kernel_ulong_t) &mhi_sierra_em919x_info }, 906 858 /* Telit FN980 hardware revision v1 */ 907 859 { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, 0x1C5D, 0x2000), 908 860 .driver_data = (kernel_ulong_t) &mhi_telit_fn980_hw_v1_info }, ··· 917 863 /* Telit FE990A */ 918 864 { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, 0x1c5d, 0x2015), 919 865 .driver_data = (kernel_ulong_t) &mhi_telit_fe990a_info }, 866 + /* Foxconn T99W696.01, Lenovo Generic SKU */ 867 + { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, PCI_VENDOR_ID_FOXCONN, 0xe142), 868 + .driver_data = (kernel_ulong_t) &mhi_foxconn_t99w696_info }, 869 + /* Foxconn T99W696.02, Lenovo X1 Carbon SKU */ 870 + { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, PCI_VENDOR_ID_FOXCONN, 0xe143), 871 + .driver_data = (kernel_ulong_t) &mhi_foxconn_t99w696_info }, 872 + /* Foxconn T99W696.03, Lenovo X1 2in1 SKU */ 873 + { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, PCI_VENDOR_ID_FOXCONN, 0xe144), 874 + .driver_data = (kernel_ulong_t) &mhi_foxconn_t99w696_info }, 875 + /* Foxconn T99W696.04, Lenovo PRC SKU */ 876 + { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, PCI_VENDOR_ID_FOXCONN, 0xe145), 877 + .driver_data = (kernel_ulong_t) &mhi_foxconn_t99w696_info }, 878 + /* Foxconn T99W696.00, Foxconn SKU */ 879 + { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, PCI_VENDOR_ID_FOXCONN, 0xe146), 880 + .driver_data = (kernel_ulong_t) &mhi_foxconn_t99w696_info }, 920 881 { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0308), 921 882 .driver_data = (kernel_ulong_t) &mhi_qcom_sdx65_info }, 883 + /* Telit FN990B40 (sdx72) */ 884 + { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0309, 0x1c5d, 0x201a), 885 + .driver_data = (kernel_ulong_t) &mhi_telit_fn990b40_info }, 922 886 { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0309), 923 887 .driver_data = (kernel_ulong_t) &mhi_qcom_sdx75_info }, 924 888 /* QDU100, x100-DU */ ··· 992 920 /* DW5932e (sdx62), Non-eSIM */ 993 921 { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0f9), 994 922 .driver_data = (kernel_ulong_t) &mhi_foxconn_dw5932e_info }, 995 - /* T99W515 (sdx72) */ 923 + /* T99W640 (sdx72) */ 996 924 { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe118), 997 - .driver_data = (kernel_ulong_t) &mhi_foxconn_t99w515_info }, 925 + .driver_data = (kernel_ulong_t) &mhi_foxconn_t99w640_info }, 998 926 /* DW5934e(sdx72), With eSIM */ 999 927 { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe11d), 1000 928 .driver_data = (kernel_ulong_t) &mhi_foxconn_dw5934e_info }, ··· 1378 1306 /* start health check */ 1379 1307 mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD); 1380 1308 1381 - /* Only allow runtime-suspend if PME capable (for wakeup) */ 1382 - if (pci_pme_capable(pdev, PCI_D3hot)) { 1309 + /* Allow runtime suspend only if both PME from D3Hot and M3 are supported */ 1310 + if (pci_pme_capable(pdev, PCI_D3hot) && !(info->no_m3)) { 1383 1311 pm_runtime_set_autosuspend_delay(&pdev->dev, 2000); 1384 1312 pm_runtime_use_autosuspend(&pdev->dev); 1385 1313 pm_runtime_mark_last_busy(&pdev->dev);