mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-05-26 11:40:24 +02:00
Merge branch 'pci/ptm'
- Leave Precision Time Measurement disabled until a driver enables it to avoid PCIe errors (Mika Westerberg) * pci/ptm: PCI/PTM: Do not enable PTM automatically for Root and Switch Upstream Ports PCI/PTM: Drop pci_enable_ptm() granularity parameter
This commit is contained in:
@@ -5028,7 +5028,7 @@ static int ice_init(struct ice_pf *pf)
|
||||
}
|
||||
|
||||
if (pf->hw.mac_type == ICE_MAC_E830) {
|
||||
err = pci_enable_ptm(pf->pdev, NULL);
|
||||
err = pci_enable_ptm(pf->pdev);
|
||||
if (err)
|
||||
dev_dbg(dev, "PCIe PTM not supported by PCIe bus/controller\n");
|
||||
}
|
||||
|
||||
@@ -257,7 +257,7 @@ static int idpf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
err = pci_enable_ptm(pdev, NULL);
|
||||
err = pci_enable_ptm(pdev);
|
||||
if (err)
|
||||
pci_dbg(pdev, "PCIe PTM is not supported by PCIe bus/controller\n");
|
||||
|
||||
|
||||
@@ -7123,7 +7123,7 @@ static int igc_probe(struct pci_dev *pdev,
|
||||
if (err)
|
||||
goto err_pci_reg;
|
||||
|
||||
err = pci_enable_ptm(pdev, NULL);
|
||||
err = pci_enable_ptm(pdev);
|
||||
if (err < 0)
|
||||
dev_info(&pdev->dev, "PCIe PTM not supported by PCIe bus/controller\n");
|
||||
|
||||
|
||||
@@ -960,7 +960,7 @@ static int mlx5_pci_init(struct mlx5_core_dev *dev, struct pci_dev *pdev,
|
||||
|
||||
mlx5_pci_vsc_init(dev);
|
||||
|
||||
pci_enable_ptm(pdev, NULL);
|
||||
pci_enable_ptm(pdev);
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
+41
-36
@@ -52,6 +52,7 @@ void pci_ptm_init(struct pci_dev *dev)
|
||||
return;
|
||||
|
||||
dev->ptm_cap = ptm;
|
||||
atomic_set(&dev->ptm_enable_cnt, 0);
|
||||
pci_add_ext_cap_save_buffer(dev, PCI_EXT_CAP_ID_PTM, sizeof(u32));
|
||||
|
||||
pci_read_config_dword(dev, ptm + PCI_PTM_CAP, &cap);
|
||||
@@ -85,10 +86,6 @@ void pci_ptm_init(struct pci_dev *dev)
|
||||
dev->ptm_responder = 1;
|
||||
if (cap & PCI_PTM_CAP_REQ)
|
||||
dev->ptm_requester = 1;
|
||||
|
||||
if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
|
||||
pci_pcie_type(dev) == PCI_EXP_TYPE_UPSTREAM)
|
||||
pci_enable_ptm(dev, NULL);
|
||||
}
|
||||
|
||||
void pci_save_ptm_state(struct pci_dev *dev)
|
||||
@@ -129,26 +126,11 @@ void pci_restore_ptm_state(struct pci_dev *dev)
|
||||
static int __pci_enable_ptm(struct pci_dev *dev)
|
||||
{
|
||||
u16 ptm = dev->ptm_cap;
|
||||
struct pci_dev *ups;
|
||||
u32 ctrl;
|
||||
|
||||
if (!ptm)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* A device uses local PTM Messages to request time information
|
||||
* from a PTM Root that's farther upstream. Every device along the
|
||||
* path must support PTM and have it enabled so it can handle the
|
||||
* messages. Therefore, if this device is not a PTM Root, the
|
||||
* upstream link partner must have PTM enabled before we can enable
|
||||
* PTM.
|
||||
*/
|
||||
if (!dev->ptm_root) {
|
||||
ups = pci_upstream_ptm(dev);
|
||||
if (!ups || !ups->ptm_enabled)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (pci_pcie_type(dev)) {
|
||||
case PCI_EXP_TYPE_ROOT_PORT:
|
||||
if (!dev->ptm_root)
|
||||
@@ -182,27 +164,46 @@ static int __pci_enable_ptm(struct pci_dev *dev)
|
||||
/**
|
||||
* pci_enable_ptm() - Enable Precision Time Measurement
|
||||
* @dev: PCI device
|
||||
* @granularity: pointer to return granularity
|
||||
*
|
||||
* Enable Precision Time Measurement for @dev. If successful and
|
||||
* @granularity is non-NULL, return the Effective Granularity.
|
||||
* Enable Precision Time Measurement for @dev.
|
||||
*
|
||||
* Return: zero if successful, or -EINVAL if @dev lacks a PTM Capability or
|
||||
* is not a PTM Root and lacks an upstream path of PTM-enabled devices.
|
||||
*/
|
||||
int pci_enable_ptm(struct pci_dev *dev, u8 *granularity)
|
||||
int pci_enable_ptm(struct pci_dev *dev)
|
||||
{
|
||||
int rc;
|
||||
char clock_desc[8];
|
||||
|
||||
/*
|
||||
* A device uses local PTM Messages to request time information
|
||||
* from a PTM Root that's farther upstream. Every device along
|
||||
* the path must support PTM and have it enabled so it can
|
||||
* handle the messages. Therefore, if this device is not a PTM
|
||||
* Root, the upstream link partner must have PTM enabled before
|
||||
* we can enable PTM.
|
||||
*/
|
||||
if (!dev->ptm_root) {
|
||||
struct pci_dev *parent;
|
||||
|
||||
parent = pci_upstream_ptm(dev);
|
||||
if (!parent)
|
||||
return -EINVAL;
|
||||
/* Enable PTM for the parent */
|
||||
rc = pci_enable_ptm(parent);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Already enabled? */
|
||||
if (atomic_inc_return(&dev->ptm_enable_cnt) > 1)
|
||||
return 0;
|
||||
|
||||
rc = __pci_enable_ptm(dev);
|
||||
if (rc)
|
||||
if (rc) {
|
||||
atomic_dec(&dev->ptm_enable_cnt);
|
||||
return rc;
|
||||
|
||||
dev->ptm_enabled = 1;
|
||||
|
||||
if (granularity)
|
||||
*granularity = dev->ptm_granularity;
|
||||
}
|
||||
|
||||
switch (dev->ptm_granularity) {
|
||||
case 0:
|
||||
@@ -244,27 +245,31 @@ static void __pci_disable_ptm(struct pci_dev *dev)
|
||||
*/
|
||||
void pci_disable_ptm(struct pci_dev *dev)
|
||||
{
|
||||
if (dev->ptm_enabled) {
|
||||
struct pci_dev *parent;
|
||||
|
||||
if (atomic_dec_and_test(&dev->ptm_enable_cnt))
|
||||
__pci_disable_ptm(dev);
|
||||
dev->ptm_enabled = 0;
|
||||
}
|
||||
|
||||
parent = pci_upstream_ptm(dev);
|
||||
if (parent)
|
||||
pci_disable_ptm(parent);
|
||||
}
|
||||
EXPORT_SYMBOL(pci_disable_ptm);
|
||||
|
||||
/*
|
||||
* Disable PTM, but preserve dev->ptm_enabled so we silently re-enable it on
|
||||
* Disable PTM, but preserve dev->ptm_enable_cnt so we silently re-enable it on
|
||||
* resume if necessary.
|
||||
*/
|
||||
void pci_suspend_ptm(struct pci_dev *dev)
|
||||
{
|
||||
if (dev->ptm_enabled)
|
||||
if (atomic_read(&dev->ptm_enable_cnt))
|
||||
__pci_disable_ptm(dev);
|
||||
}
|
||||
|
||||
/* If PTM was enabled before suspend, re-enable it when resuming */
|
||||
void pci_resume_ptm(struct pci_dev *dev)
|
||||
{
|
||||
if (dev->ptm_enabled)
|
||||
if (atomic_read(&dev->ptm_enable_cnt))
|
||||
__pci_enable_ptm(dev);
|
||||
}
|
||||
|
||||
@@ -273,7 +278,7 @@ bool pcie_ptm_enabled(struct pci_dev *dev)
|
||||
if (!dev)
|
||||
return false;
|
||||
|
||||
return dev->ptm_enabled;
|
||||
return atomic_read(&dev->ptm_enable_cnt);
|
||||
}
|
||||
EXPORT_SYMBOL(pcie_ptm_enabled);
|
||||
|
||||
|
||||
+3
-3
@@ -518,7 +518,7 @@ struct pci_dev {
|
||||
unsigned int ptm_root:1;
|
||||
unsigned int ptm_responder:1;
|
||||
unsigned int ptm_requester:1;
|
||||
unsigned int ptm_enabled:1;
|
||||
atomic_t ptm_enable_cnt;
|
||||
u8 ptm_granularity;
|
||||
#endif
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
@@ -1973,11 +1973,11 @@ struct pci_ptm_debugfs {
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PCIE_PTM
|
||||
int pci_enable_ptm(struct pci_dev *dev, u8 *granularity);
|
||||
int pci_enable_ptm(struct pci_dev *dev);
|
||||
void pci_disable_ptm(struct pci_dev *dev);
|
||||
bool pcie_ptm_enabled(struct pci_dev *dev);
|
||||
#else
|
||||
static inline int pci_enable_ptm(struct pci_dev *dev, u8 *granularity)
|
||||
static inline int pci_enable_ptm(struct pci_dev *dev)
|
||||
{ return -EINVAL; }
|
||||
static inline void pci_disable_ptm(struct pci_dev *dev) { }
|
||||
static inline bool pcie_ptm_enabled(struct pci_dev *dev)
|
||||
|
||||
Reference in New Issue
Block a user