diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index e3d0a3cbaf94..0277e1ab1198 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -367,7 +367,7 @@ static void mhi_ep_read_completion(struct mhi_ep_buf_info *buf_info) ret = mhi_ep_send_completion_event(mhi_cntrl, ring, el, MHI_TRE_DATA_GET_LEN(el), MHI_EV_CC_EOB); - if (ret < 0) { + if (ret) { dev_err(&mhi_chan->mhi_dev->dev, "Error sending transfer compl. event\n"); goto err_free_tre_buf; @@ -383,7 +383,7 @@ static void mhi_ep_read_completion(struct mhi_ep_buf_info *buf_info) ret = mhi_ep_send_completion_event(mhi_cntrl, ring, el, MHI_TRE_DATA_GET_LEN(el), MHI_EV_CC_EOT); - if (ret < 0) { + if (ret) { dev_err(&mhi_chan->mhi_dev->dev, "Error sending transfer compl. event\n"); goto err_free_tre_buf; @@ -449,7 +449,7 @@ static int mhi_ep_read_channel(struct mhi_ep_cntrl *mhi_cntrl, dev_dbg(dev, "Reading %zd bytes from channel (%u)\n", tr_len, ring->ch_id); ret = mhi_cntrl->read_async(mhi_cntrl, &buf_info); - if (ret < 0) { + if (ret) { dev_err(&mhi_chan->mhi_dev->dev, "Error reading from channel\n"); goto err_free_buf_addr; } @@ -494,7 +494,7 @@ static int mhi_ep_process_ch_ring(struct mhi_ep_ring *ring) } else { /* UL channel */ ret = mhi_ep_read_channel(mhi_cntrl, ring); - if (ret < 0) { + if (ret) { dev_err(&mhi_chan->mhi_dev->dev, "Failed to read channel\n"); return ret; } @@ -591,7 +591,7 @@ int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb) dev_dbg(dev, "Writing %zd bytes to channel (%u)\n", tr_len, ring->ch_id); ret = mhi_cntrl->write_async(mhi_cntrl, &buf_info); - if (ret < 0) { + if (ret) { dev_err(dev, "Error writing to the channel\n"); goto err_exit; } diff --git a/drivers/bus/mhi/ep/ring.c b/drivers/bus/mhi/ep/ring.c index 9375b16ff2a5..405ce16c02a8 100644 --- a/drivers/bus/mhi/ep/ring.c +++ b/drivers/bus/mhi/ep/ring.c @@ -49,7 +49,7 @@ static int __mhi_ep_cache_ring(struct mhi_ep_ring *ring, size_t end) buf_info.dev_addr = &ring->ring_cache[start]; ret = mhi_cntrl->read_sync(mhi_cntrl, &buf_info); - if (ret < 0) + if (ret) return ret; } else { buf_info.size = (ring->ring_size - start) * sizeof(struct mhi_ring_element); @@ -57,7 +57,7 @@ static int __mhi_ep_cache_ring(struct mhi_ep_ring *ring, size_t end) buf_info.dev_addr = &ring->ring_cache[start]; ret = mhi_cntrl->read_sync(mhi_cntrl, &buf_info); - if (ret < 0) + if (ret) return ret; if (end) { @@ -66,7 +66,7 @@ static int __mhi_ep_cache_ring(struct mhi_ep_ring *ring, size_t end) buf_info.size = end * sizeof(struct mhi_ring_element); ret = mhi_cntrl->read_sync(mhi_cntrl, &buf_info); - if (ret < 0) + if (ret) return ret; } } diff --git a/drivers/bus/mhi/host/boot.c b/drivers/bus/mhi/host/boot.c index f16a1e67a667..19c84913cfb9 100644 --- a/drivers/bus/mhi/host/boot.c +++ b/drivers/bus/mhi/host/boot.c @@ -308,7 +308,6 @@ static void mhi_free_bhi_buffer(struct mhi_controller *mhi_cntrl, struct mhi_buf *mhi_buf = image_info->mhi_buf; dma_free_coherent(mhi_cntrl->cntrl_dev, mhi_buf->len, mhi_buf->buf, mhi_buf->dma_addr); - kfree(image_info->mhi_buf); kfree(image_info); } @@ -322,7 +321,6 @@ void mhi_free_bhie_table(struct mhi_controller *mhi_cntrl, dma_free_coherent(mhi_cntrl->cntrl_dev, mhi_buf->len, mhi_buf->buf, mhi_buf->dma_addr); - kfree(image_info->mhi_buf); kfree(image_info); } @@ -333,15 +331,10 @@ static int mhi_alloc_bhi_buffer(struct mhi_controller *mhi_cntrl, struct image_info *img_info; struct mhi_buf *mhi_buf; - img_info = kzalloc_obj(*img_info); + img_info = kzalloc_flex(*img_info, mhi_buf, 1); if (!img_info) return -ENOMEM; - /* Allocate memory for entry */ - img_info->mhi_buf = kzalloc_obj(*img_info->mhi_buf); - if (!img_info->mhi_buf) - goto error_alloc_mhi_buf; - /* Allocate and populate vector table */ mhi_buf = img_info->mhi_buf; @@ -358,8 +351,6 @@ static int mhi_alloc_bhi_buffer(struct mhi_controller *mhi_cntrl, return 0; error_alloc_segment: - kfree(mhi_buf); -error_alloc_mhi_buf: kfree(img_info); return -ENOMEM; @@ -375,14 +366,11 @@ int mhi_alloc_bhie_table(struct mhi_controller *mhi_cntrl, struct image_info *img_info; struct mhi_buf *mhi_buf; - img_info = kzalloc_obj(*img_info); + img_info = kzalloc_flex(*img_info, mhi_buf, segments); if (!img_info) return -ENOMEM; - /* Allocate memory for entries */ - img_info->mhi_buf = kzalloc_objs(*img_info->mhi_buf, segments); - if (!img_info->mhi_buf) - goto error_alloc_mhi_buf; + img_info->entries = segments; /* Allocate and populate vector table */ mhi_buf = img_info->mhi_buf; @@ -402,7 +390,6 @@ int mhi_alloc_bhie_table(struct mhi_controller *mhi_cntrl, } img_info->bhi_vec = img_info->mhi_buf[segments - 1].buf; - img_info->entries = segments; *image_info = img_info; return 0; @@ -411,9 +398,6 @@ int mhi_alloc_bhie_table(struct mhi_controller *mhi_cntrl, for (--i, --mhi_buf; i >= 0; i--, mhi_buf--) dma_free_coherent(mhi_cntrl->cntrl_dev, mhi_buf->len, mhi_buf->buf, mhi_buf->dma_addr); - kfree(img_info->mhi_buf); - -error_alloc_mhi_buf: kfree(img_info); return -ENOMEM; diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_generic.c index 0884a384b77f..750da3dbb4c6 100644 --- a/drivers/bus/mhi/host/pci_generic.c +++ b/drivers/bus/mhi/host/pci_generic.c @@ -253,6 +253,13 @@ static const struct mhi_channel_config mhi_qcom_qdu100_channels[] = { MHI_CHANNEL_CONFIG_DL(41, "MHI_PHC", 32, 4), MHI_CHANNEL_CONFIG_UL(46, "IP_SW0", 256, 5), MHI_CHANNEL_CONFIG_DL(47, "IP_SW0", 256, 5), + MHI_CHANNEL_CONFIG_UL(48, "IP_SW1", 256, 6), + MHI_CHANNEL_CONFIG_DL(49, "IP_SW1", 256, 6), + MHI_CHANNEL_CONFIG_UL(50, "IP_ETH0", 256, 7), + MHI_CHANNEL_CONFIG_DL(51, "IP_ETH0", 256, 7), + MHI_CHANNEL_CONFIG_UL(52, "IP_ETH1", 256, 8), + MHI_CHANNEL_CONFIG_DL(53, "IP_ETH1", 256, 8), + }; static struct mhi_event_config mhi_qcom_qdu100_events[] = { @@ -268,6 +275,7 @@ static struct mhi_event_config mhi_qcom_qdu100_events[] = { MHI_EVENT_CONFIG_SW_DATA(5, 512), MHI_EVENT_CONFIG_SW_DATA(6, 512), MHI_EVENT_CONFIG_SW_DATA(7, 512), + MHI_EVENT_CONFIG_SW_DATA(8, 512), }; static const struct mhi_controller_config mhi_qcom_qdu100_config = { @@ -407,6 +415,16 @@ static const struct mhi_pci_dev_info mhi_qcom_sdx55_info = { .sideband_wake = false, }; +static const struct mhi_pci_dev_info mhi_qcom_sdx35_info = { + .name = "qcom-sdx35m", + .config = &modem_qcom_v2_mhiv_config, + .bar_num = MHI_PCI_DEFAULT_BAR_NUM, + .dma_data_width = 32, + .mru_default = 32768, + .sideband_wake = false, + .edl_trigger = true, +}; + static const struct mhi_pci_dev_info mhi_qcom_sdx24_info = { .name = "qcom-sdx24", .edl = "qcom/prog_firehose_sdx24.mbn", @@ -788,6 +806,8 @@ static const struct mhi_channel_config mhi_telit_fn990_channels[] = { MHI_CHANNEL_CONFIG_DL(33, "DUN", 32, 0), MHI_CHANNEL_CONFIG_UL(92, "DUN2", 32, 1), MHI_CHANNEL_CONFIG_DL(93, "DUN2", 32, 1), + MHI_CHANNEL_CONFIG_UL(94, "NMEA", 32, 1), + MHI_CHANNEL_CONFIG_DL(95, "NMEA", 32, 1), MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0_MBIM", 128, 2), MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0_MBIM", 128, 3), }; @@ -839,6 +859,8 @@ static const struct mhi_channel_config mhi_telit_fn920c04_channels[] = { MHI_CHANNEL_CONFIG_DL_FP(35, "FIREHOSE", 32, 0), MHI_CHANNEL_CONFIG_UL(92, "DUN2", 32, 1), MHI_CHANNEL_CONFIG_DL(93, "DUN2", 32, 1), + MHI_CHANNEL_CONFIG_UL(94, "NMEA", 32, 1), + MHI_CHANNEL_CONFIG_DL(95, "NMEA", 32, 1), MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 128, 2), MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0", 128, 3), }; @@ -882,6 +904,16 @@ static const struct mhi_pci_dev_info mhi_telit_fe990b40_info = { .edl_trigger = true, }; +static const struct mhi_pci_dev_info mhi_telit_fe912c04_info = { + .name = "telit-fe912c04", + .config = &modem_telit_fn920c04_config, + .bar_num = MHI_PCI_DEFAULT_BAR_NUM, + .dma_data_width = 32, + .sideband_wake = false, + .mru_default = 32768, + .edl_trigger = true, +}; + static const struct mhi_pci_dev_info mhi_netprisma_lcur57_info = { .name = "netprisma-lcur57", .edl = "qcom/prog_firehose_sdx24.mbn", @@ -909,6 +941,11 @@ static const struct pci_device_id mhi_pci_id_table[] = { /* Telit FN920C04 (sdx35) */ {PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x011a, 0x1c5d, 0x2020), .driver_data = (kernel_ulong_t) &mhi_telit_fn920c04_info }, + /* Telit FE912C04 (sdx35) */ + { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x011a, 0x1c5d, 0x2045), + .driver_data = (kernel_ulong_t) &mhi_telit_fe912c04_info }, + { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x011a), + .driver_data = (kernel_ulong_t) &mhi_qcom_sdx35_info }, { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0304), .driver_data = (kernel_ulong_t) &mhi_qcom_sdx24_info }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, PCI_VENDOR_ID_QCOM, 0x010c), @@ -1393,7 +1430,7 @@ static int mhi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_unregister; } - err = mhi_sync_power_up(mhi_cntrl); + err = mhi_async_power_up(mhi_cntrl); if (err) { dev_err(&pdev->dev, "failed to power up MHI controller\n"); goto err_unprepare; @@ -1428,6 +1465,7 @@ static void mhi_pci_remove(struct pci_dev *pdev) struct mhi_pci_device *mhi_pdev = pci_get_drvdata(pdev); struct mhi_controller *mhi_cntrl = &mhi_pdev->mhi_cntrl; + pm_runtime_forbid(&pdev->dev); pci_disable_sriov(pdev); if (pdev->is_physfn) diff --git a/include/linux/mhi.h b/include/linux/mhi.h index 88ccb3e14f48..fb3ba639f4f8 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -85,17 +85,33 @@ enum mhi_ch_type { MHI_CH_TYPE_INBOUND_COALESCED = 3, }; +/** + * struct mhi_buf - MHI Buffer description + * @buf: Virtual address of the buffer + * @name: Buffer label. For offload channel, configurations name must be: + * ECA - Event context array data + * CCA - Channel context array data + * @dma_addr: IOMMU address of the buffer + * @len: # of bytes + */ +struct mhi_buf { + void *buf; + const char *name; + dma_addr_t dma_addr; + size_t len; +}; + /** * struct image_info - Firmware and RDDM table * @mhi_buf: Buffer for firmware and RDDM table * @entries: # of entries in table */ struct image_info { - struct mhi_buf *mhi_buf; /* private: from internal.h */ struct bhi_vec_entry *bhi_vec; /* public: */ u32 entries; + struct mhi_buf mhi_buf[] __counted_by(entries); }; /** @@ -488,22 +504,6 @@ struct mhi_result { int transaction_status; }; -/** - * struct mhi_buf - MHI Buffer description - * @buf: Virtual address of the buffer - * @name: Buffer label. For offload channel, configurations name must be: - * ECA - Event context array data - * CCA - Channel context array data - * @dma_addr: IOMMU address of the buffer - * @len: # of bytes - */ -struct mhi_buf { - void *buf; - const char *name; - dma_addr_t dma_addr; - size_t len; -}; - /** * struct mhi_driver - Structure representing a MHI client driver * @probe: CB function for client driver probe function