Skip to content

Commit 60c46a0

Browse files
committed
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
2 parents 45e06a9 + 00559ba commit 60c46a0

File tree

6 files changed

+102
-26
lines changed

6 files changed

+102
-26
lines changed

drivers/bus/mhi/host/boot.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ int mhi_rddm_prepare(struct mhi_controller *mhi_cntrl,
3131
int ret;
3232

3333
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);
3636
}
3737

3838
dev_dbg(dev, "BHIe programming for RDDM\n");
@@ -431,8 +431,8 @@ static void mhi_firmware_copy_bhie(struct mhi_controller *mhi_cntrl,
431431
while (remainder) {
432432
to_cpy = min(remainder, mhi_buf->len);
433433
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);
436436

437437
buf += to_cpy;
438438
remainder -= to_cpy;

drivers/bus/mhi/host/debugfs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/list.h>
1111
#include <linux/mhi.h>
1212
#include <linux/module.h>
13+
#include <linux/string_choices.h>
1314
#include "internal.h"
1415

1516
static int mhi_debugfs_states_show(struct seq_file *m, void *d)
@@ -22,7 +23,7 @@ static int mhi_debugfs_states_show(struct seq_file *m, void *d)
2223
mhi_is_active(mhi_cntrl) ? "Active" : "Inactive",
2324
mhi_state_str(mhi_cntrl->dev_state),
2425
TO_MHI_EXEC_STR(mhi_cntrl->ee),
25-
mhi_cntrl->wake_set ? "true" : "false");
26+
str_true_false(mhi_cntrl->wake_set));
2627

2728
/* counters */
2829
seq_printf(m, "M0: %u M2: %u M3: %u", mhi_cntrl->M0, mhi_cntrl->M2,

drivers/bus/mhi/host/init.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ static int mhi_alloc_aligned_ring(struct mhi_controller *mhi_cntrl,
176176
return 0;
177177
}
178178

179-
void mhi_deinit_free_irq(struct mhi_controller *mhi_cntrl)
179+
static void mhi_deinit_free_irq(struct mhi_controller *mhi_cntrl)
180180
{
181181
int i;
182182
struct mhi_event *mhi_event = mhi_cntrl->mhi_event;
@@ -191,7 +191,7 @@ void mhi_deinit_free_irq(struct mhi_controller *mhi_cntrl)
191191
free_irq(mhi_cntrl->irq[0], mhi_cntrl);
192192
}
193193

194-
int mhi_init_irq_setup(struct mhi_controller *mhi_cntrl)
194+
static int mhi_init_irq_setup(struct mhi_controller *mhi_cntrl)
195195
{
196196
struct mhi_event *mhi_event = mhi_cntrl->mhi_event;
197197
struct device *dev = &mhi_cntrl->mhi_dev->dev;
@@ -254,7 +254,7 @@ int mhi_init_irq_setup(struct mhi_controller *mhi_cntrl)
254254
return ret;
255255
}
256256

257-
void mhi_deinit_dev_ctxt(struct mhi_controller *mhi_cntrl)
257+
static void mhi_deinit_dev_ctxt(struct mhi_controller *mhi_cntrl)
258258
{
259259
int i;
260260
struct mhi_ctxt *mhi_ctxt = mhi_cntrl->mhi_ctxt;
@@ -299,7 +299,7 @@ void mhi_deinit_dev_ctxt(struct mhi_controller *mhi_cntrl)
299299
mhi_cntrl->mhi_ctxt = NULL;
300300
}
301301

302-
int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl)
302+
static int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl)
303303
{
304304
struct mhi_ctxt *mhi_ctxt;
305305
struct mhi_chan_ctxt *chan_ctxt;

drivers/bus/mhi/host/internal.h

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ struct mhi_ctxt {
2525
};
2626

2727
struct bhi_vec_entry {
28-
u64 dma_addr;
29-
u64 size;
28+
__le64 dma_addr;
29+
__le64 size;
3030
};
3131

3232
enum mhi_fw_load_type {
@@ -383,19 +383,12 @@ void mhi_ring_chan_db(struct mhi_controller *mhi_cntrl,
383383

384384
/* Initialization methods */
385385
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);
390386
int mhi_rddm_prepare(struct mhi_controller *mhi_cntrl,
391387
struct image_info *img_info);
392388
void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl);
393389

394390
/* Automatically allocate and queue inbound buffers */
395391
#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-
399392
int mhi_init_chan_ctxt(struct mhi_controller *mhi_cntrl,
400393
struct mhi_chan *mhi_chan);
401394
void mhi_deinit_chan_ctxt(struct mhi_controller *mhi_cntrl,

drivers/bus/mhi/host/main.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl,
602602
{
603603
dma_addr_t ptr = MHI_TRE_GET_EV_PTR(event);
604604
struct mhi_ring_element *local_rp, *ev_tre;
605-
void *dev_rp;
605+
void *dev_rp, *next_rp;
606606
struct mhi_buf_info *buf_info;
607607
u16 xfer_len;
608608

@@ -621,6 +621,16 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl,
621621
result.dir = mhi_chan->dir;
622622

623623
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+
624634
while (local_rp != dev_rp) {
625635
buf_info = buf_ring->rp;
626636
/* If it's the last TRE, get length from the event */
@@ -1435,7 +1445,7 @@ static void mhi_unprepare_channel(struct mhi_controller *mhi_cntrl,
14351445
mutex_unlock(&mhi_chan->mutex);
14361446
}
14371447

1438-
int mhi_prepare_channel(struct mhi_controller *mhi_cntrl,
1448+
static int mhi_prepare_channel(struct mhi_controller *mhi_cntrl,
14391449
struct mhi_chan *mhi_chan, unsigned int flags)
14401450
{
14411451
int ret = 0;

drivers/bus/mhi/host/pci_generic.c

Lines changed: 78 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
* @mru_default: default MRU size for MBIM network packets
4444
* @sideband_wake: Devices using dedicated sideband GPIO for wakeup instead
4545
* of inband wake support (such as sdx24)
46+
* @no_m3: M3 not supported
4647
*/
4748
struct mhi_pci_dev_info {
4849
const struct mhi_controller_config *config;
@@ -54,6 +55,7 @@ struct mhi_pci_dev_info {
5455
unsigned int dma_data_width;
5556
unsigned int mru_default;
5657
bool sideband_wake;
58+
bool no_m3;
5759
};
5860

5961
#define MHI_CHANNEL_CONFIG_UL(ch_num, ch_name, el_count, ev_ring) \
@@ -295,6 +297,7 @@ static const struct mhi_pci_dev_info mhi_qcom_qdu100_info = {
295297
.bar_num = MHI_PCI_DEFAULT_BAR_NUM,
296298
.dma_data_width = 32,
297299
.sideband_wake = false,
300+
.no_m3 = true,
298301
};
299302

300303
static const struct mhi_channel_config mhi_qcom_sa8775p_channels[] = {
@@ -490,6 +493,23 @@ static const struct mhi_channel_config mhi_foxconn_sdx55_channels[] = {
490493
MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0_MBIM", 128, 3),
491494
};
492495

496+
static const struct mhi_channel_config mhi_foxconn_sdx61_channels[] = {
497+
MHI_CHANNEL_CONFIG_UL(0, "LOOPBACK", 32, 0),
498+
MHI_CHANNEL_CONFIG_DL(1, "LOOPBACK", 32, 0),
499+
MHI_CHANNEL_CONFIG_UL(4, "DIAG", 32, 1),
500+
MHI_CHANNEL_CONFIG_DL(5, "DIAG", 32, 1),
501+
MHI_CHANNEL_CONFIG_UL(12, "MBIM", 32, 0),
502+
MHI_CHANNEL_CONFIG_DL(13, "MBIM", 32, 0),
503+
MHI_CHANNEL_CONFIG_UL(32, "DUN", 32, 0),
504+
MHI_CHANNEL_CONFIG_DL(33, "DUN", 32, 0),
505+
MHI_CHANNEL_CONFIG_UL_FP(34, "FIREHOSE", 32, 0),
506+
MHI_CHANNEL_CONFIG_DL_FP(35, "FIREHOSE", 32, 0),
507+
MHI_CHANNEL_CONFIG_UL(50, "NMEA", 32, 0),
508+
MHI_CHANNEL_CONFIG_DL(51, "NMEA", 32, 0),
509+
MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0_MBIM", 128, 2),
510+
MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0_MBIM", 128, 3),
511+
};
512+
493513
static struct mhi_event_config mhi_foxconn_sdx55_events[] = {
494514
MHI_EVENT_CONFIG_CTRL(0, 128),
495515
MHI_EVENT_CONFIG_DATA(1, 128),
@@ -506,6 +526,15 @@ static const struct mhi_controller_config modem_foxconn_sdx55_config = {
506526
.event_cfg = mhi_foxconn_sdx55_events,
507527
};
508528

529+
static const struct mhi_controller_config modem_foxconn_sdx61_config = {
530+
.max_channels = 128,
531+
.timeout_ms = 20000,
532+
.num_channels = ARRAY_SIZE(mhi_foxconn_sdx61_channels),
533+
.ch_cfg = mhi_foxconn_sdx61_channels,
534+
.num_events = ARRAY_SIZE(mhi_foxconn_sdx55_events),
535+
.event_cfg = mhi_foxconn_sdx55_events,
536+
};
537+
509538
static const struct mhi_controller_config modem_foxconn_sdx72_config = {
510539
.max_channels = 128,
511540
.timeout_ms = 20000,
@@ -593,8 +622,8 @@ static const struct mhi_pci_dev_info mhi_foxconn_dw5932e_info = {
593622
.sideband_wake = false,
594623
};
595624

596-
static const struct mhi_pci_dev_info mhi_foxconn_t99w515_info = {
597-
.name = "foxconn-t99w515",
625+
static const struct mhi_pci_dev_info mhi_foxconn_t99w640_info = {
626+
.name = "foxconn-t99w640",
598627
.edl = "qcom/sdx72m/foxconn/edl.mbn",
599628
.edl_trigger = true,
600629
.config = &modem_foxconn_sdx72_config,
@@ -615,6 +644,17 @@ static const struct mhi_pci_dev_info mhi_foxconn_dw5934e_info = {
615644
.sideband_wake = false,
616645
};
617646

647+
static const struct mhi_pci_dev_info mhi_foxconn_t99w696_info = {
648+
.name = "foxconn-t99w696",
649+
.edl = "qcom/sdx61/foxconn/prog_firehose_lite.elf",
650+
.edl_trigger = true,
651+
.config = &modem_foxconn_sdx61_config,
652+
.bar_num = MHI_PCI_DEFAULT_BAR_NUM,
653+
.dma_data_width = 32,
654+
.mru_default = 32768,
655+
.sideband_wake = false,
656+
};
657+
618658
static const struct mhi_channel_config mhi_mv3x_channels[] = {
619659
MHI_CHANNEL_CONFIG_UL(0, "LOOPBACK", 64, 0),
620660
MHI_CHANNEL_CONFIG_DL(1, "LOOPBACK", 64, 0),
@@ -695,6 +735,7 @@ static const struct mhi_pci_dev_info mhi_sierra_em919x_info = {
695735
.config = &modem_sierra_em919x_config,
696736
.bar_num = MHI_PCI_DEFAULT_BAR_NUM,
697737
.dma_data_width = 32,
738+
.mru_default = 32768,
698739
.sideband_wake = false,
699740
};
700741

@@ -818,6 +859,16 @@ static const struct mhi_pci_dev_info mhi_telit_fn920c04_info = {
818859
.edl_trigger = true,
819860
};
820861

862+
static const struct mhi_pci_dev_info mhi_telit_fn990b40_info = {
863+
.name = "telit-fn990b40",
864+
.config = &modem_telit_fn920c04_config,
865+
.bar_num = MHI_PCI_DEFAULT_BAR_NUM,
866+
.dma_data_width = 32,
867+
.sideband_wake = false,
868+
.mru_default = 32768,
869+
.edl_trigger = true,
870+
};
871+
821872
static const struct mhi_pci_dev_info mhi_netprisma_lcur57_info = {
822873
.name = "netprisma-lcur57",
823874
.edl = "qcom/prog_firehose_sdx24.mbn",
@@ -852,6 +903,9 @@ static const struct pci_device_id mhi_pci_id_table[] = {
852903
/* EM919x (sdx55), use the same vid:pid as qcom-sdx55m */
853904
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, 0x18d7, 0x0200),
854905
.driver_data = (kernel_ulong_t) &mhi_sierra_em919x_info },
906+
/* EM929x (sdx65), use the same configuration as EM919x */
907+
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, 0x18d7, 0x0301),
908+
.driver_data = (kernel_ulong_t) &mhi_sierra_em919x_info },
855909
/* Telit FN980 hardware revision v1 */
856910
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, 0x1C5D, 0x2000),
857911
.driver_data = (kernel_ulong_t) &mhi_telit_fn980_hw_v1_info },
@@ -863,8 +917,26 @@ static const struct pci_device_id mhi_pci_id_table[] = {
863917
/* Telit FE990A */
864918
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, 0x1c5d, 0x2015),
865919
.driver_data = (kernel_ulong_t) &mhi_telit_fe990a_info },
920+
/* Foxconn T99W696.01, Lenovo Generic SKU */
921+
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, PCI_VENDOR_ID_FOXCONN, 0xe142),
922+
.driver_data = (kernel_ulong_t) &mhi_foxconn_t99w696_info },
923+
/* Foxconn T99W696.02, Lenovo X1 Carbon SKU */
924+
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, PCI_VENDOR_ID_FOXCONN, 0xe143),
925+
.driver_data = (kernel_ulong_t) &mhi_foxconn_t99w696_info },
926+
/* Foxconn T99W696.03, Lenovo X1 2in1 SKU */
927+
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, PCI_VENDOR_ID_FOXCONN, 0xe144),
928+
.driver_data = (kernel_ulong_t) &mhi_foxconn_t99w696_info },
929+
/* Foxconn T99W696.04, Lenovo PRC SKU */
930+
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, PCI_VENDOR_ID_FOXCONN, 0xe145),
931+
.driver_data = (kernel_ulong_t) &mhi_foxconn_t99w696_info },
932+
/* Foxconn T99W696.00, Foxconn SKU */
933+
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, PCI_VENDOR_ID_FOXCONN, 0xe146),
934+
.driver_data = (kernel_ulong_t) &mhi_foxconn_t99w696_info },
866935
{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0308),
867936
.driver_data = (kernel_ulong_t) &mhi_qcom_sdx65_info },
937+
/* Telit FN990B40 (sdx72) */
938+
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0309, 0x1c5d, 0x201a),
939+
.driver_data = (kernel_ulong_t) &mhi_telit_fn990b40_info },
868940
{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0309),
869941
.driver_data = (kernel_ulong_t) &mhi_qcom_sdx75_info },
870942
/* QDU100, x100-DU */
@@ -920,9 +992,9 @@ static const struct pci_device_id mhi_pci_id_table[] = {
920992
/* DW5932e (sdx62), Non-eSIM */
921993
{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0f9),
922994
.driver_data = (kernel_ulong_t) &mhi_foxconn_dw5932e_info },
923-
/* T99W515 (sdx72) */
995+
/* T99W640 (sdx72) */
924996
{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe118),
925-
.driver_data = (kernel_ulong_t) &mhi_foxconn_t99w515_info },
997+
.driver_data = (kernel_ulong_t) &mhi_foxconn_t99w640_info },
926998
/* DW5934e(sdx72), With eSIM */
927999
{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe11d),
9281000
.driver_data = (kernel_ulong_t) &mhi_foxconn_dw5934e_info },
@@ -1306,8 +1378,8 @@ static int mhi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
13061378
/* start health check */
13071379
mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD);
13081380

1309-
/* Only allow runtime-suspend if PME capable (for wakeup) */
1310-
if (pci_pme_capable(pdev, PCI_D3hot)) {
1381+
/* Allow runtime suspend only if both PME from D3Hot and M3 are supported */
1382+
if (pci_pme_capable(pdev, PCI_D3hot) && !(info->no_m3)) {
13111383
pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);
13121384
pm_runtime_use_autosuspend(&pdev->dev);
13131385
pm_runtime_mark_last_busy(&pdev->dev);

0 commit comments

Comments
 (0)