Skip to content

Commit b4d01c5

Browse files
Vivek PernamittaManivannan Sadhasivam
authored andcommitted
bus: mhi: host: pci_generic: Read SUBSYSTEM_VENDOR_ID for VF's to check status
In SR-IOV enabled devices, reading the VF DEVICE/VENDOR ID register returns `FFFFh`, as specified in section 3.4.1.1 of the PCIe SR-IOV spec. To accurately determine device activity, read the PCIe VENDOR_ID of the Physical Function (PF) instead. Health check monitoring for Virtual Functions (VFs) has been disabled, since VFs are not physical functions and lack direct hardware control. This change prevents unnecessary CPU cycles from being consumed by VF health checks, which are both unintended and non-functional. Signed-off-by: Vivek Pernamitta <[email protected]> Signed-off-by: Manivannan Sadhasivam <[email protected]> Reviewed-by: Krishna Chaitanya Chundru <[email protected]> Link: https://patch.msgid.link/[email protected]
1 parent a9e3d5a commit b4d01c5

File tree

1 file changed

+24
-10
lines changed

1 file changed

+24
-10
lines changed

drivers/bus/mhi/host/pci_generic.c

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,7 @@ static bool mhi_pci_is_alive(struct mhi_controller *mhi_cntrl)
10821082
struct pci_dev *pdev = to_pci_dev(mhi_cntrl->cntrl_dev);
10831083
u16 vendor = 0;
10841084

1085-
if (pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor))
1085+
if (pci_read_config_word(pci_physfn(pdev), PCI_VENDOR_ID, &vendor))
10861086
return false;
10871087

10881088
if (vendor == (u16) ~0 || vendor == 0)
@@ -1193,7 +1193,9 @@ static void mhi_pci_recovery_work(struct work_struct *work)
11931193

11941194
dev_warn(&pdev->dev, "device recovery started\n");
11951195

1196-
timer_delete(&mhi_pdev->health_check_timer);
1196+
if (pdev->is_physfn)
1197+
timer_delete(&mhi_pdev->health_check_timer);
1198+
11971199
pm_runtime_forbid(&pdev->dev);
11981200

11991201
/* Clean up MHI state */
@@ -1220,7 +1222,10 @@ static void mhi_pci_recovery_work(struct work_struct *work)
12201222
dev_dbg(&pdev->dev, "Recovery completed\n");
12211223

12221224
set_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status);
1223-
mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD);
1225+
1226+
if (pdev->is_physfn)
1227+
mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD);
1228+
12241229
return;
12251230

12261231
err_unprepare:
@@ -1307,7 +1312,9 @@ static int mhi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
13071312
else
13081313
mhi_cntrl_config = info->config;
13091314

1310-
timer_setup(&mhi_pdev->health_check_timer, health_check, 0);
1315+
/* Initialize health check monitor only for Physical functions */
1316+
if (pdev->is_physfn)
1317+
timer_setup(&mhi_pdev->health_check_timer, health_check, 0);
13111318

13121319
mhi_cntrl = &mhi_pdev->mhi_cntrl;
13131320

@@ -1371,7 +1378,8 @@ static int mhi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
13711378
set_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status);
13721379

13731380
/* start health check */
1374-
mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD);
1381+
if (pdev->is_physfn)
1382+
mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD);
13751383

13761384
/* Allow runtime suspend only if both PME from D3Hot and M3 are supported */
13771385
if (pci_pme_capable(pdev, PCI_D3hot) && !(info->no_m3)) {
@@ -1396,7 +1404,8 @@ static void mhi_pci_remove(struct pci_dev *pdev)
13961404
struct mhi_pci_device *mhi_pdev = pci_get_drvdata(pdev);
13971405
struct mhi_controller *mhi_cntrl = &mhi_pdev->mhi_cntrl;
13981406

1399-
timer_delete_sync(&mhi_pdev->health_check_timer);
1407+
if (pdev->is_physfn)
1408+
timer_delete_sync(&mhi_pdev->health_check_timer);
14001409
cancel_work_sync(&mhi_pdev->recovery_work);
14011410

14021411
if (test_and_clear_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status)) {
@@ -1424,7 +1433,8 @@ static void mhi_pci_reset_prepare(struct pci_dev *pdev)
14241433

14251434
dev_info(&pdev->dev, "reset\n");
14261435

1427-
timer_delete(&mhi_pdev->health_check_timer);
1436+
if (pdev->is_physfn)
1437+
timer_delete(&mhi_pdev->health_check_timer);
14281438

14291439
/* Clean up MHI state */
14301440
if (test_and_clear_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status)) {
@@ -1469,7 +1479,8 @@ static void mhi_pci_reset_done(struct pci_dev *pdev)
14691479
}
14701480

14711481
set_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status);
1472-
mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD);
1482+
if (pdev->is_physfn)
1483+
mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD);
14731484
}
14741485

14751486
static pci_ers_result_t mhi_pci_error_detected(struct pci_dev *pdev,
@@ -1534,7 +1545,9 @@ static int __maybe_unused mhi_pci_runtime_suspend(struct device *dev)
15341545
if (test_and_set_bit(MHI_PCI_DEV_SUSPENDED, &mhi_pdev->status))
15351546
return 0;
15361547

1537-
timer_delete(&mhi_pdev->health_check_timer);
1548+
if (pdev->is_physfn)
1549+
timer_delete(&mhi_pdev->health_check_timer);
1550+
15381551
cancel_work_sync(&mhi_pdev->recovery_work);
15391552

15401553
if (!test_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status) ||
@@ -1585,7 +1598,8 @@ static int __maybe_unused mhi_pci_runtime_resume(struct device *dev)
15851598
}
15861599

15871600
/* Resume health check */
1588-
mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD);
1601+
if (pdev->is_physfn)
1602+
mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD);
15891603

15901604
/* It can be a remote wakeup (no mhi runtime_get), update access time */
15911605
pm_runtime_mark_last_busy(dev);

0 commit comments

Comments
 (0)