--------
 
 - Request power-of-2 MSI vectors from pci_generic driver for sanity.
 
 - Add support for Telit FE910C04 modem based on Qcom SDX35 chipset
 
 - Fix the check used to identify the physical functions to work with both SR-IOV
   and non-SR-IOV devices
 
 MHI Endpoint
 ------------
 
 - Fix a potential deadlock in the mhi_ep_reset_worker() helper
 
 - Add lock around mhi_ep_handle_syserr() in the error path to avoid race in
   setting MHI state in the error path
 
 - Add missing state_lock protection for mhi_state access
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEZ6VDKoFIy9ikWCeXVZ8R5v6RzvUFAmoifS4ACgkQVZ8R5v6R
 zvVpBQf+LlDiVt1mJwA0hiwUwcsitoz83D1jSMbmOwmdH68NuivfnAMbyYDhah8b
 43t9XmCVXq9Cznx5JlB8jss+9DfECbcY+eQwsQp9N9yLb3FyB6D+v+MaaZeiYyDq
 yRPg7Q7gz767iHqf7D6uMS1tsIc6tS7ZU2hOdnTpOjC5tr5no0qr6Dr9SyQDVV40
 7CTlSQJsjHj6VoamDrCB+eEOsvraGOxVpKijHX34Xzu+Tm0qfrDsuP/lKRehFDhw
 vinsY2ihhCuyY8VEIT5rC6vh55ZmNYHInvQ/UfR+UVDxbpXd+PpK57j7kX55eXlv
 Vr0AxwcNc/rVgPUGISfUaQyQYkt2Zg==
 =yy/J
 -----END PGP SIGNATURE-----

Merge tag 'mhi-for-v7.2' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/mani/mhi into char-misc-next

Manivannan writes:

MHI Host
--------

- Request power-of-2 MSI vectors from pci_generic driver for sanity.

- Add support for Telit FE910C04 modem based on Qcom SDX35 chipset

- Fix the check used to identify the physical functions to work with both SR-IOV
  and non-SR-IOV devices

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

- Fix a potential deadlock in the mhi_ep_reset_worker() helper

- Add lock around mhi_ep_handle_syserr() in the error path to avoid race in
  setting MHI state in the error path

- Add missing state_lock protection for mhi_state access

* tag 'mhi-for-v7.2' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/mani/mhi:
  bus: mhi: host: pci_generic: Fix the physical function check
  bus: mhi: ep: Protect mhi_ep_handle_syserr() in the error path
  bus: mhi: host: pci_generic: Add Telit FE910C04 modem support
  bus: mhi: ep: Add missing state_lock protection for mhi_state access
  bus: mhi: ep: Fix potential deadlock in mhi_ep_reset_worker()
  bus: mhi: host: pci_generic: Round up nr_irqs to power of two
This commit is contained in:
Greg Kroah-Hartman 2026-06-08 21:27:34 +02:00
commit 39f9c91bce
2 changed files with 32 additions and 15 deletions

View File

@ -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);

View File

@ -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 */