Skip to content

Commit 8b52451

Browse files
committed
Merge branch 'pci/pcie-rmw'
- Add locking for read/modify/write PCIe Capability Register accessors for Link Control and Root Control (Ilpo Järvinen) - Use PCIe RMW accessors for Link Control updates in PCI core, pciehp, amdgpu, radeon, mlx5, ath10k, ath11k, ath12k (Ilpo Järvinen) - Convert PCIBIOS error values in mlx5 to generic errnos (Ilpo Järvinen) - Simplify pcie_capability_clear_and_set_word() control flow (Bjorn Helgaas) * pci/pcie-rmw: PCI: Simplify pcie_capability_clear_and_set_word() control flow net/mlx5: Convert PCI error values to generic errnos PCI: Document the Capability accessor RMW improvements wifi: ath10k: Use RMW accessors for changing LNKCTL wifi: ath12k: Use RMW accessors for changing LNKCTL wifi: ath11k: Use RMW accessors for changing LNKCTL net/mlx5: Use RMW accessors for changing LNKCTL drm/radeon: Use RMW accessors for changing LNKCTL drm/amdgpu: Use RMW accessors for changing LNKCTL PCI/ASPM: Use RMW accessors for changing LNKCTL PCI: pciehp: Use RMW accessors for changing LNKCTL PCI: Make link retraining use RMW accessors for changing LNKCTL PCI: Add locking to RMW PCI Express Capability Register accessors
2 parents d4a0f52 + 294c1e4 commit 8b52451

File tree

15 files changed

+151
-183
lines changed

15 files changed

+151
-183
lines changed

Documentation/PCI/pciebus-howto.rst

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,12 @@ PCI Config Registers
213213
--------------------
214214

215215
Each service driver runs its PCI config operations on its own
216-
capability structure except the PCI Express capability structure, in
217-
which Root Control register and Device Control register are shared
218-
between PME and AER. This patch assumes that all service drivers
219-
will be well behaved and not overwrite other service driver's
220-
configuration settings.
216+
capability structure except the PCI Express capability structure,
217+
that is shared between many drivers including the service drivers.
218+
RMW Capability accessors (pcie_capability_clear_and_set_word(),
219+
pcie_capability_set_word(), and pcie_capability_clear_word()) protect
220+
a selected set of PCI Express Capability Registers (Link Control
221+
Register and Root Control Register). Any change to those registers
222+
should be performed using RMW accessors to avoid problems due to
223+
concurrent updates. For the up-to-date list of protected registers,
224+
see pcie_capability_clear_and_set_word().

drivers/gpu/drm/amd/amdgpu/cik.c

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1574,17 +1574,8 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev)
15741574
u16 bridge_cfg2, gpu_cfg2;
15751575
u32 max_lw, current_lw, tmp;
15761576

1577-
pcie_capability_read_word(root, PCI_EXP_LNKCTL,
1578-
&bridge_cfg);
1579-
pcie_capability_read_word(adev->pdev, PCI_EXP_LNKCTL,
1580-
&gpu_cfg);
1581-
1582-
tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD;
1583-
pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16);
1584-
1585-
tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD;
1586-
pcie_capability_write_word(adev->pdev, PCI_EXP_LNKCTL,
1587-
tmp16);
1577+
pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
1578+
pcie_capability_set_word(adev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
15881579

15891580
tmp = RREG32_PCIE(ixPCIE_LC_STATUS1);
15901581
max_lw = (tmp & PCIE_LC_STATUS1__LC_DETECTED_LINK_WIDTH_MASK) >>
@@ -1637,21 +1628,14 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev)
16371628
msleep(100);
16381629

16391630
/* linkctl */
1640-
pcie_capability_read_word(root, PCI_EXP_LNKCTL,
1641-
&tmp16);
1642-
tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
1643-
tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD);
1644-
pcie_capability_write_word(root, PCI_EXP_LNKCTL,
1645-
tmp16);
1646-
1647-
pcie_capability_read_word(adev->pdev,
1648-
PCI_EXP_LNKCTL,
1649-
&tmp16);
1650-
tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
1651-
tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD);
1652-
pcie_capability_write_word(adev->pdev,
1653-
PCI_EXP_LNKCTL,
1654-
tmp16);
1631+
pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL,
1632+
PCI_EXP_LNKCTL_HAWD,
1633+
bridge_cfg &
1634+
PCI_EXP_LNKCTL_HAWD);
1635+
pcie_capability_clear_and_set_word(adev->pdev, PCI_EXP_LNKCTL,
1636+
PCI_EXP_LNKCTL_HAWD,
1637+
gpu_cfg &
1638+
PCI_EXP_LNKCTL_HAWD);
16551639

16561640
/* linkctl2 */
16571641
pcie_capability_read_word(root, PCI_EXP_LNKCTL2,

drivers/gpu/drm/amd/amdgpu/si.c

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2276,17 +2276,8 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev)
22762276
u16 bridge_cfg2, gpu_cfg2;
22772277
u32 max_lw, current_lw, tmp;
22782278

2279-
pcie_capability_read_word(root, PCI_EXP_LNKCTL,
2280-
&bridge_cfg);
2281-
pcie_capability_read_word(adev->pdev, PCI_EXP_LNKCTL,
2282-
&gpu_cfg);
2283-
2284-
tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD;
2285-
pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16);
2286-
2287-
tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD;
2288-
pcie_capability_write_word(adev->pdev, PCI_EXP_LNKCTL,
2289-
tmp16);
2279+
pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
2280+
pcie_capability_set_word(adev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
22902281

22912282
tmp = RREG32_PCIE(PCIE_LC_STATUS1);
22922283
max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT;
@@ -2331,21 +2322,14 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev)
23312322

23322323
mdelay(100);
23332324

2334-
pcie_capability_read_word(root, PCI_EXP_LNKCTL,
2335-
&tmp16);
2336-
tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
2337-
tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD);
2338-
pcie_capability_write_word(root, PCI_EXP_LNKCTL,
2339-
tmp16);
2340-
2341-
pcie_capability_read_word(adev->pdev,
2342-
PCI_EXP_LNKCTL,
2343-
&tmp16);
2344-
tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
2345-
tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD);
2346-
pcie_capability_write_word(adev->pdev,
2347-
PCI_EXP_LNKCTL,
2348-
tmp16);
2325+
pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL,
2326+
PCI_EXP_LNKCTL_HAWD,
2327+
bridge_cfg &
2328+
PCI_EXP_LNKCTL_HAWD);
2329+
pcie_capability_clear_and_set_word(adev->pdev, PCI_EXP_LNKCTL,
2330+
PCI_EXP_LNKCTL_HAWD,
2331+
gpu_cfg &
2332+
PCI_EXP_LNKCTL_HAWD);
23492333

23502334
pcie_capability_read_word(root, PCI_EXP_LNKCTL2,
23512335
&tmp16);

drivers/gpu/drm/radeon/cik.c

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9534,17 +9534,8 @@ static void cik_pcie_gen3_enable(struct radeon_device *rdev)
95349534
u16 bridge_cfg2, gpu_cfg2;
95359535
u32 max_lw, current_lw, tmp;
95369536

9537-
pcie_capability_read_word(root, PCI_EXP_LNKCTL,
9538-
&bridge_cfg);
9539-
pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL,
9540-
&gpu_cfg);
9541-
9542-
tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD;
9543-
pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16);
9544-
9545-
tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD;
9546-
pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL,
9547-
tmp16);
9537+
pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
9538+
pcie_capability_set_word(rdev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
95489539

95499540
tmp = RREG32_PCIE_PORT(PCIE_LC_STATUS1);
95509541
max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT;
@@ -9591,21 +9582,14 @@ static void cik_pcie_gen3_enable(struct radeon_device *rdev)
95919582
msleep(100);
95929583

95939584
/* linkctl */
9594-
pcie_capability_read_word(root, PCI_EXP_LNKCTL,
9595-
&tmp16);
9596-
tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
9597-
tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD);
9598-
pcie_capability_write_word(root, PCI_EXP_LNKCTL,
9599-
tmp16);
9600-
9601-
pcie_capability_read_word(rdev->pdev,
9602-
PCI_EXP_LNKCTL,
9603-
&tmp16);
9604-
tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
9605-
tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD);
9606-
pcie_capability_write_word(rdev->pdev,
9607-
PCI_EXP_LNKCTL,
9608-
tmp16);
9585+
pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL,
9586+
PCI_EXP_LNKCTL_HAWD,
9587+
bridge_cfg &
9588+
PCI_EXP_LNKCTL_HAWD);
9589+
pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL,
9590+
PCI_EXP_LNKCTL_HAWD,
9591+
gpu_cfg &
9592+
PCI_EXP_LNKCTL_HAWD);
96099593

96109594
/* linkctl2 */
96119595
pcie_capability_read_word(root, PCI_EXP_LNKCTL2,

drivers/gpu/drm/radeon/si.c

Lines changed: 10 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7131,17 +7131,8 @@ static void si_pcie_gen3_enable(struct radeon_device *rdev)
71317131
u16 bridge_cfg2, gpu_cfg2;
71327132
u32 max_lw, current_lw, tmp;
71337133

7134-
pcie_capability_read_word(root, PCI_EXP_LNKCTL,
7135-
&bridge_cfg);
7136-
pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL,
7137-
&gpu_cfg);
7138-
7139-
tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD;
7140-
pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16);
7141-
7142-
tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD;
7143-
pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL,
7144-
tmp16);
7134+
pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
7135+
pcie_capability_set_word(rdev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
71457136

71467137
tmp = RREG32_PCIE(PCIE_LC_STATUS1);
71477138
max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT;
@@ -7188,22 +7179,14 @@ static void si_pcie_gen3_enable(struct radeon_device *rdev)
71887179
msleep(100);
71897180

71907181
/* linkctl */
7191-
pcie_capability_read_word(root, PCI_EXP_LNKCTL,
7192-
&tmp16);
7193-
tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
7194-
tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD);
7195-
pcie_capability_write_word(root,
7196-
PCI_EXP_LNKCTL,
7197-
tmp16);
7198-
7199-
pcie_capability_read_word(rdev->pdev,
7200-
PCI_EXP_LNKCTL,
7201-
&tmp16);
7202-
tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
7203-
tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD);
7204-
pcie_capability_write_word(rdev->pdev,
7205-
PCI_EXP_LNKCTL,
7206-
tmp16);
7182+
pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL,
7183+
PCI_EXP_LNKCTL_HAWD,
7184+
bridge_cfg &
7185+
PCI_EXP_LNKCTL_HAWD);
7186+
pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL,
7187+
PCI_EXP_LNKCTL_HAWD,
7188+
gpu_cfg &
7189+
PCI_EXP_LNKCTL_HAWD);
72077190

72087191
/* linkctl2 */
72097192
pcie_capability_read_word(root, PCI_EXP_LNKCTL2,

drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ static int mlx5_check_dev_ids(struct mlx5_core_dev *dev, u16 dev_id)
311311
list_for_each_entry(sdev, &bridge_bus->devices, bus_list) {
312312
err = pci_read_config_word(sdev, PCI_DEVICE_ID, &sdev_id);
313313
if (err)
314-
return err;
314+
return pcibios_err_to_errno(err);
315315
if (sdev_id != dev_id) {
316316
mlx5_core_warn(dev, "unrecognized dev_id (0x%x)\n", sdev_id);
317317
return -EPERM;
@@ -371,7 +371,7 @@ static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev)
371371

372372
err = pci_read_config_word(dev->pdev, PCI_DEVICE_ID, &dev_id);
373373
if (err)
374-
return err;
374+
return pcibios_err_to_errno(err);
375375
err = mlx5_check_dev_ids(dev, dev_id);
376376
if (err)
377377
return err;
@@ -384,18 +384,13 @@ static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev)
384384
pci_cfg_access_lock(sdev);
385385
}
386386
/* PCI link toggle */
387-
err = pci_read_config_word(bridge, cap + PCI_EXP_LNKCTL, &reg16);
388-
if (err)
389-
return err;
390-
reg16 |= PCI_EXP_LNKCTL_LD;
391-
err = pci_write_config_word(bridge, cap + PCI_EXP_LNKCTL, reg16);
387+
err = pcie_capability_set_word(bridge, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_LD);
392388
if (err)
393-
return err;
389+
return pcibios_err_to_errno(err);
394390
msleep(500);
395-
reg16 &= ~PCI_EXP_LNKCTL_LD;
396-
err = pci_write_config_word(bridge, cap + PCI_EXP_LNKCTL, reg16);
391+
err = pcie_capability_clear_word(bridge, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_LD);
397392
if (err)
398-
return err;
393+
return pcibios_err_to_errno(err);
399394

400395
/* Check link */
401396
if (!bridge->link_active_reporting) {
@@ -408,7 +403,7 @@ static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev)
408403
do {
409404
err = pci_read_config_word(bridge, cap + PCI_EXP_LNKSTA, &reg16);
410405
if (err)
411-
return err;
406+
return pcibios_err_to_errno(err);
412407
if (reg16 & PCI_EXP_LNKSTA_DLLLA)
413408
break;
414409
msleep(20);
@@ -426,7 +421,7 @@ static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev)
426421
do {
427422
err = pci_read_config_word(dev->pdev, PCI_DEVICE_ID, &reg16);
428423
if (err)
429-
return err;
424+
return pcibios_err_to_errno(err);
430425
if (reg16 == dev_id)
431426
break;
432427
msleep(20);

drivers/net/wireless/ath/ath10k/pci.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1963,8 +1963,9 @@ static int ath10k_pci_hif_start(struct ath10k *ar)
19631963
ath10k_pci_irq_enable(ar);
19641964
ath10k_pci_rx_post(ar);
19651965

1966-
pcie_capability_write_word(ar_pci->pdev, PCI_EXP_LNKCTL,
1967-
ar_pci->link_ctl);
1966+
pcie_capability_clear_and_set_word(ar_pci->pdev, PCI_EXP_LNKCTL,
1967+
PCI_EXP_LNKCTL_ASPMC,
1968+
ar_pci->link_ctl & PCI_EXP_LNKCTL_ASPMC);
19681969

19691970
return 0;
19701971
}
@@ -2821,8 +2822,8 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar,
28212822

28222823
pcie_capability_read_word(ar_pci->pdev, PCI_EXP_LNKCTL,
28232824
&ar_pci->link_ctl);
2824-
pcie_capability_write_word(ar_pci->pdev, PCI_EXP_LNKCTL,
2825-
ar_pci->link_ctl & ~PCI_EXP_LNKCTL_ASPMC);
2825+
pcie_capability_clear_word(ar_pci->pdev, PCI_EXP_LNKCTL,
2826+
PCI_EXP_LNKCTL_ASPMC);
28262827

28272828
/*
28282829
* Bring the target up cleanly.

drivers/net/wireless/ath/ath11k/pci.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -581,17 +581,19 @@ static void ath11k_pci_aspm_disable(struct ath11k_pci *ab_pci)
581581
u16_get_bits(ab_pci->link_ctl, PCI_EXP_LNKCTL_ASPM_L1));
582582

583583
/* disable L0s and L1 */
584-
pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL,
585-
ab_pci->link_ctl & ~PCI_EXP_LNKCTL_ASPMC);
584+
pcie_capability_clear_word(ab_pci->pdev, PCI_EXP_LNKCTL,
585+
PCI_EXP_LNKCTL_ASPMC);
586586

587587
set_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags);
588588
}
589589

590590
static void ath11k_pci_aspm_restore(struct ath11k_pci *ab_pci)
591591
{
592592
if (test_and_clear_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags))
593-
pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL,
594-
ab_pci->link_ctl);
593+
pcie_capability_clear_and_set_word(ab_pci->pdev, PCI_EXP_LNKCTL,
594+
PCI_EXP_LNKCTL_ASPMC,
595+
ab_pci->link_ctl &
596+
PCI_EXP_LNKCTL_ASPMC);
595597
}
596598

597599
static int ath11k_pci_power_up(struct ath11k_base *ab)

drivers/net/wireless/ath/ath12k/pci.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -794,17 +794,19 @@ static void ath12k_pci_aspm_disable(struct ath12k_pci *ab_pci)
794794
u16_get_bits(ab_pci->link_ctl, PCI_EXP_LNKCTL_ASPM_L1));
795795

796796
/* disable L0s and L1 */
797-
pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL,
798-
ab_pci->link_ctl & ~PCI_EXP_LNKCTL_ASPMC);
797+
pcie_capability_clear_word(ab_pci->pdev, PCI_EXP_LNKCTL,
798+
PCI_EXP_LNKCTL_ASPMC);
799799

800800
set_bit(ATH12K_PCI_ASPM_RESTORE, &ab_pci->flags);
801801
}
802802

803803
static void ath12k_pci_aspm_restore(struct ath12k_pci *ab_pci)
804804
{
805805
if (test_and_clear_bit(ATH12K_PCI_ASPM_RESTORE, &ab_pci->flags))
806-
pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL,
807-
ab_pci->link_ctl);
806+
pcie_capability_clear_and_set_word(ab_pci->pdev, PCI_EXP_LNKCTL,
807+
PCI_EXP_LNKCTL_ASPMC,
808+
ab_pci->link_ctl &
809+
PCI_EXP_LNKCTL_ASPMC);
808810
}
809811

810812
static void ath12k_pci_kill_tasklets(struct ath12k_base *ab)

0 commit comments

Comments
 (0)