aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
authorMark Brown <broonie@kernel.org>2026-05-29 23:14:29 +0100
committerMark Brown <broonie@kernel.org>2026-05-29 23:14:29 +0100
commit49bf47149d56f7e634c3afbe6f83c16bc79f105e (patch)
tree9471f54b1ae0939548eaa5c08a78e497b8d5de8f /drivers
parent1f9d2bb17bb99d112326875efdeefddb3487fe44 (diff)
parent32845111e8ea6ef5e837b6d25080e69e99bd4561 (diff)
downloadlinux-next-history-49bf47149d56f7e634c3afbe6f83c16bc79f105e.tar.gz
Merge branch 'mhi-next' of https://git.kernel.org/pub/scm/linux/kernel/git/mani/mhi.git
Diffstat (limited to 'drivers')
-rw-r--r--drivers/bus/mhi/ep/main.c11
-rw-r--r--drivers/bus/mhi/host/pci_generic.c36
2 files changed, 32 insertions, 15 deletions
diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c
index 0277e1ab11988..9db2a2a2c9134 100644
--- a/drivers/bus/mhi/ep/main.c
+++ b/drivers/bus/mhi/ep/main.c
@@ -232,7 +232,9 @@ static int mhi_ep_process_cmd_ring(struct mhi_ep_ring *ring, struct mhi_ring_ele
ret = mhi_ep_create_device(mhi_cntrl, ch_id);
if (ret) {
dev_err(dev, "Error creating device for channel (%u)\n", ch_id);
+ mutex_lock(&mhi_cntrl->state_lock);
mhi_ep_handle_syserr(mhi_cntrl);
+ mutex_unlock(&mhi_cntrl->state_lock);
return ret;
}
}
@@ -1087,11 +1089,12 @@ static void mhi_ep_reset_worker(struct work_struct *work)
mhi_ep_power_down(mhi_cntrl);
- mutex_lock(&mhi_cntrl->state_lock);
-
/* Reset MMIO to signal host that the MHI_RESET is completed in endpoint */
mhi_ep_mmio_reset(mhi_cntrl);
+
+ mutex_lock(&mhi_cntrl->state_lock);
cur_state = mhi_cntrl->mhi_state;
+ mutex_unlock(&mhi_cntrl->state_lock);
/*
* Only proceed further if the reset is due to SYS_ERR. The host will
@@ -1100,8 +1103,6 @@ static void mhi_ep_reset_worker(struct work_struct *work)
*/
if (cur_state == MHI_STATE_SYS_ERR)
mhi_ep_power_up(mhi_cntrl);
-
- mutex_unlock(&mhi_cntrl->state_lock);
}
/*
@@ -1148,7 +1149,9 @@ int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl)
for (i = 0; i < mhi_cntrl->event_rings; i++)
mhi_ep_ring_init(&mhi_cntrl->mhi_event[i].ring, RING_TYPE_ER, i);
+ mutex_lock(&mhi_cntrl->state_lock);
mhi_cntrl->mhi_state = MHI_STATE_RESET;
+ mutex_unlock(&mhi_cntrl->state_lock);
/* Set AMSS EE before signaling ready state */
mhi_ep_mmio_set_env(mhi_cntrl, MHI_EE_AMSS);
diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_generic.c
index 750da3dbb4c6e..0d0d9c7ffa4bf 100644
--- a/drivers/bus/mhi/host/pci_generic.c
+++ b/drivers/bus/mhi/host/pci_generic.c
@@ -914,6 +914,16 @@ static const struct mhi_pci_dev_info mhi_telit_fe912c04_info = {
.edl_trigger = true,
};
+static const struct mhi_pci_dev_info mhi_telit_fe910c04_info = {
+ .name = "telit-fe910c04",
+ .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",
@@ -941,6 +951,9 @@ 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 FE910C04 (sdx35) */
+ {PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x011a, 0x1c5d, 0x202a),
+ .driver_data = (kernel_ulong_t) &mhi_telit_fe910c04_info },
/* Telit FE912C04 (sdx35) */
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x011a, 0x1c5d, 0x2045),
.driver_data = (kernel_ulong_t) &mhi_telit_fe912c04_info },
@@ -1189,7 +1202,8 @@ static int mhi_pci_get_irqs(struct mhi_controller *mhi_cntrl,
*/
mhi_cntrl->nr_irqs = 1 + mhi_cntrl_config->num_events;
- nr_vectors = pci_alloc_irq_vectors(pdev, 1, mhi_cntrl->nr_irqs, PCI_IRQ_MSIX | PCI_IRQ_MSI);
+ nr_vectors = pci_alloc_irq_vectors(pdev, 1, roundup_pow_of_two(mhi_cntrl->nr_irqs),
+ PCI_IRQ_MSIX | PCI_IRQ_MSI);
if (nr_vectors < 0) {
dev_err(&pdev->dev, "Error allocating MSI vectors %d\n",
nr_vectors);
@@ -1247,7 +1261,7 @@ static void mhi_pci_recovery_work(struct work_struct *work)
dev_warn(&pdev->dev, "device recovery started\n");
- if (pdev->is_physfn)
+ if (!pdev->is_virtfn)
timer_delete(&mhi_pdev->health_check_timer);
pm_runtime_forbid(&pdev->dev);
@@ -1277,7 +1291,7 @@ static void mhi_pci_recovery_work(struct work_struct *work)
set_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status);
- if (pdev->is_physfn)
+ if (!pdev->is_virtfn)
mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD);
return;
@@ -1368,7 +1382,7 @@ static int mhi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
mhi_cntrl_config = info->config;
/* Initialize health check monitor only for Physical functions */
- if (pdev->is_physfn)
+ if (!pdev->is_virtfn)
timer_setup(&mhi_pdev->health_check_timer, health_check, 0);
mhi_cntrl = &mhi_pdev->mhi_cntrl;
@@ -1390,7 +1404,7 @@ static int mhi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
mhi_cntrl->mru = info->mru_default;
mhi_cntrl->name = info->name;
- if (pdev->is_physfn)
+ if (!pdev->is_virtfn)
mhi_pdev->reset_on_remove = info->reset_on_remove;
if (info->edl_trigger)
@@ -1439,7 +1453,7 @@ static int mhi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
set_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status);
/* start health check */
- if (pdev->is_physfn)
+ if (!pdev->is_virtfn)
mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD);
/* Allow runtime suspend only if both PME from D3Hot and M3 are supported */
@@ -1468,7 +1482,7 @@ static void mhi_pci_remove(struct pci_dev *pdev)
pm_runtime_forbid(&pdev->dev);
pci_disable_sriov(pdev);
- if (pdev->is_physfn)
+ if (!pdev->is_virtfn)
timer_delete_sync(&mhi_pdev->health_check_timer);
cancel_work_sync(&mhi_pdev->recovery_work);
@@ -1500,7 +1514,7 @@ static void mhi_pci_reset_prepare(struct pci_dev *pdev)
dev_info(&pdev->dev, "reset\n");
- if (pdev->is_physfn)
+ if (!pdev->is_virtfn)
timer_delete(&mhi_pdev->health_check_timer);
/* Clean up MHI state */
@@ -1546,7 +1560,7 @@ static void mhi_pci_reset_done(struct pci_dev *pdev)
}
set_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status);
- if (pdev->is_physfn)
+ if (!pdev->is_virtfn)
mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD);
}
@@ -1612,7 +1626,7 @@ static int __maybe_unused mhi_pci_runtime_suspend(struct device *dev)
if (test_and_set_bit(MHI_PCI_DEV_SUSPENDED, &mhi_pdev->status))
return 0;
- if (pdev->is_physfn)
+ if (!pdev->is_virtfn)
timer_delete(&mhi_pdev->health_check_timer);
cancel_work_sync(&mhi_pdev->recovery_work);
@@ -1665,7 +1679,7 @@ static int __maybe_unused mhi_pci_runtime_resume(struct device *dev)
}
/* Resume health check */
- if (pdev->is_physfn)
+ if (!pdev->is_virtfn)
mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD);
/* It can be a remote wakeup (no mhi runtime_get), update access time */