Commit 2e8b5f62 authored by Bjorn Helgaas's avatar Bjorn Helgaas

Merge branch 'pci/misc' into next

* pci/misc:
  PCI: Remove pcie_cap_has_devctl()
  PCI: Support PCIe Capability Slot registers only for ports with slots
  PCI: Remove PCIe Capability version checks
  PCI: Allow PCIe Capability link-related register access for switches
  PCI: Add offsets of PCIe capability registers
  PCI: Tidy bitmasks and spacing of PCIe capability definitions
  PCI: Remove obsolete comment reference to pci_pcie_cap2()
  PCI: Clarify PCI_EXP_TYPE_PCI_BRIDGE comment
  PCI: Rename PCIe capability definitions to follow convention
  PCI: Disable decoding for BAR sizing only when it was actually enabled
  PCI: Add comment about needing pci_msi_off() even when CONFIG_PCI_MSI=n
  PCI: Add pcibios_pm_ops for optional arch-specific hibernate functionality
parents 07f2daad fed24515
...@@ -44,7 +44,7 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr) ...@@ -44,7 +44,7 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr)
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02);
/* Configure LTR */ /* Configure LTR */
pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &cap); pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &cap);
if (cap & PCI_EXP_LTR_EN) if (cap & PCI_EXP_DEVCTL2_LTR_EN)
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LTR_CTL, 0xFF, 0xA3); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LTR_CTL, 0xFF, 0xA3);
/* Configure OBFF */ /* Configure OBFF */
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OBFF_CFG, 0x03, 0x03); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OBFF_CFG, 0x03, 0x03);
......
...@@ -475,37 +475,33 @@ static inline int pcie_cap_version(const struct pci_dev *dev) ...@@ -475,37 +475,33 @@ static inline int pcie_cap_version(const struct pci_dev *dev)
return pcie_caps_reg(dev) & PCI_EXP_FLAGS_VERS; return pcie_caps_reg(dev) & PCI_EXP_FLAGS_VERS;
} }
static inline bool pcie_cap_has_devctl(const struct pci_dev *dev)
{
return true;
}
static inline bool pcie_cap_has_lnkctl(const struct pci_dev *dev) static inline bool pcie_cap_has_lnkctl(const struct pci_dev *dev)
{ {
int type = pci_pcie_type(dev); int type = pci_pcie_type(dev);
return pcie_cap_version(dev) > 1 || return type == PCI_EXP_TYPE_ENDPOINT ||
type == PCI_EXP_TYPE_LEG_END ||
type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_ROOT_PORT ||
type == PCI_EXP_TYPE_ENDPOINT || type == PCI_EXP_TYPE_UPSTREAM ||
type == PCI_EXP_TYPE_LEG_END; type == PCI_EXP_TYPE_DOWNSTREAM ||
type == PCI_EXP_TYPE_PCI_BRIDGE ||
type == PCI_EXP_TYPE_PCIE_BRIDGE;
} }
static inline bool pcie_cap_has_sltctl(const struct pci_dev *dev) static inline bool pcie_cap_has_sltctl(const struct pci_dev *dev)
{ {
int type = pci_pcie_type(dev); int type = pci_pcie_type(dev);
return pcie_cap_version(dev) > 1 || return (type == PCI_EXP_TYPE_ROOT_PORT ||
type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_DOWNSTREAM) &&
(type == PCI_EXP_TYPE_DOWNSTREAM && pcie_caps_reg(dev) & PCI_EXP_FLAGS_SLOT;
pcie_caps_reg(dev) & PCI_EXP_FLAGS_SLOT);
} }
static inline bool pcie_cap_has_rtctl(const struct pci_dev *dev) static inline bool pcie_cap_has_rtctl(const struct pci_dev *dev)
{ {
int type = pci_pcie_type(dev); int type = pci_pcie_type(dev);
return pcie_cap_version(dev) > 1 || return type == PCI_EXP_TYPE_ROOT_PORT ||
type == PCI_EXP_TYPE_ROOT_PORT ||
type == PCI_EXP_TYPE_RC_EC; type == PCI_EXP_TYPE_RC_EC;
} }
...@@ -520,7 +516,7 @@ static bool pcie_capability_reg_implemented(struct pci_dev *dev, int pos) ...@@ -520,7 +516,7 @@ static bool pcie_capability_reg_implemented(struct pci_dev *dev, int pos)
case PCI_EXP_DEVCAP: case PCI_EXP_DEVCAP:
case PCI_EXP_DEVCTL: case PCI_EXP_DEVCTL:
case PCI_EXP_DEVSTA: case PCI_EXP_DEVSTA:
return pcie_cap_has_devctl(dev); return true;
case PCI_EXP_LNKCAP: case PCI_EXP_LNKCAP:
case PCI_EXP_LNKCTL: case PCI_EXP_LNKCTL:
case PCI_EXP_LNKSTA: case PCI_EXP_LNKSTA:
......
...@@ -763,6 +763,13 @@ static int pci_pm_resume(struct device *dev) ...@@ -763,6 +763,13 @@ static int pci_pm_resume(struct device *dev)
#ifdef CONFIG_HIBERNATE_CALLBACKS #ifdef CONFIG_HIBERNATE_CALLBACKS
/*
* pcibios_pm_ops - provide arch-specific hooks when a PCI device is doing
* a hibernate transition
*/
struct dev_pm_ops __weak pcibios_pm_ops;
static int pci_pm_freeze(struct device *dev) static int pci_pm_freeze(struct device *dev)
{ {
struct pci_dev *pci_dev = to_pci_dev(dev); struct pci_dev *pci_dev = to_pci_dev(dev);
...@@ -786,6 +793,9 @@ static int pci_pm_freeze(struct device *dev) ...@@ -786,6 +793,9 @@ static int pci_pm_freeze(struct device *dev)
return error; return error;
} }
if (pcibios_pm_ops.freeze)
return pcibios_pm_ops.freeze(dev);
return 0; return 0;
} }
...@@ -811,6 +821,9 @@ static int pci_pm_freeze_noirq(struct device *dev) ...@@ -811,6 +821,9 @@ static int pci_pm_freeze_noirq(struct device *dev)
pci_pm_set_unknown_state(pci_dev); pci_pm_set_unknown_state(pci_dev);
if (pcibios_pm_ops.freeze_noirq)
return pcibios_pm_ops.freeze_noirq(dev);
return 0; return 0;
} }
...@@ -820,6 +833,12 @@ static int pci_pm_thaw_noirq(struct device *dev) ...@@ -820,6 +833,12 @@ static int pci_pm_thaw_noirq(struct device *dev)
struct device_driver *drv = dev->driver; struct device_driver *drv = dev->driver;
int error = 0; int error = 0;
if (pcibios_pm_ops.thaw_noirq) {
error = pcibios_pm_ops.thaw_noirq(dev);
if (error)
return error;
}
if (pci_has_legacy_pm_support(pci_dev)) if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_resume_early(dev); return pci_legacy_resume_early(dev);
...@@ -837,6 +856,12 @@ static int pci_pm_thaw(struct device *dev) ...@@ -837,6 +856,12 @@ static int pci_pm_thaw(struct device *dev)
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
int error = 0; int error = 0;
if (pcibios_pm_ops.thaw) {
error = pcibios_pm_ops.thaw(dev);
if (error)
return error;
}
if (pci_has_legacy_pm_support(pci_dev)) if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_resume(dev); return pci_legacy_resume(dev);
...@@ -878,6 +903,9 @@ static int pci_pm_poweroff(struct device *dev) ...@@ -878,6 +903,9 @@ static int pci_pm_poweroff(struct device *dev)
Fixup: Fixup:
pci_fixup_device(pci_fixup_suspend, pci_dev); pci_fixup_device(pci_fixup_suspend, pci_dev);
if (pcibios_pm_ops.poweroff)
return pcibios_pm_ops.poweroff(dev);
return 0; return 0;
} }
...@@ -911,6 +939,9 @@ static int pci_pm_poweroff_noirq(struct device *dev) ...@@ -911,6 +939,9 @@ static int pci_pm_poweroff_noirq(struct device *dev)
if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI) if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI)
pci_write_config_word(pci_dev, PCI_COMMAND, 0); pci_write_config_word(pci_dev, PCI_COMMAND, 0);
if (pcibios_pm_ops.poweroff_noirq)
return pcibios_pm_ops.poweroff_noirq(dev);
return 0; return 0;
} }
...@@ -920,6 +951,12 @@ static int pci_pm_restore_noirq(struct device *dev) ...@@ -920,6 +951,12 @@ static int pci_pm_restore_noirq(struct device *dev)
struct device_driver *drv = dev->driver; struct device_driver *drv = dev->driver;
int error = 0; int error = 0;
if (pcibios_pm_ops.restore_noirq) {
error = pcibios_pm_ops.restore_noirq(dev);
if (error)
return error;
}
pci_pm_default_resume_early(pci_dev); pci_pm_default_resume_early(pci_dev);
if (pci_has_legacy_pm_support(pci_dev)) if (pci_has_legacy_pm_support(pci_dev))
...@@ -937,6 +974,12 @@ static int pci_pm_restore(struct device *dev) ...@@ -937,6 +974,12 @@ static int pci_pm_restore(struct device *dev)
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
int error = 0; int error = 0;
if (pcibios_pm_ops.restore) {
error = pcibios_pm_ops.restore(dev);
if (error)
return error;
}
/* /*
* This is necessary for the hibernation error path in which restore is * This is necessary for the hibernation error path in which restore is
* called without restoring the standard config registers of the device. * called without restoring the standard config registers of the device.
......
...@@ -2116,9 +2116,9 @@ void pci_enable_ido(struct pci_dev *dev, unsigned long type) ...@@ -2116,9 +2116,9 @@ void pci_enable_ido(struct pci_dev *dev, unsigned long type)
u16 ctrl = 0; u16 ctrl = 0;
if (type & PCI_EXP_IDO_REQUEST) if (type & PCI_EXP_IDO_REQUEST)
ctrl |= PCI_EXP_IDO_REQ_EN; ctrl |= PCI_EXP_DEVCTL2_IDO_REQ_EN;
if (type & PCI_EXP_IDO_COMPLETION) if (type & PCI_EXP_IDO_COMPLETION)
ctrl |= PCI_EXP_IDO_CMP_EN; ctrl |= PCI_EXP_DEVCTL2_IDO_CMP_EN;
if (ctrl) if (ctrl)
pcie_capability_set_word(dev, PCI_EXP_DEVCTL2, ctrl); pcie_capability_set_word(dev, PCI_EXP_DEVCTL2, ctrl);
} }
...@@ -2134,9 +2134,9 @@ void pci_disable_ido(struct pci_dev *dev, unsigned long type) ...@@ -2134,9 +2134,9 @@ void pci_disable_ido(struct pci_dev *dev, unsigned long type)
u16 ctrl = 0; u16 ctrl = 0;
if (type & PCI_EXP_IDO_REQUEST) if (type & PCI_EXP_IDO_REQUEST)
ctrl |= PCI_EXP_IDO_REQ_EN; ctrl |= PCI_EXP_DEVCTL2_IDO_REQ_EN;
if (type & PCI_EXP_IDO_COMPLETION) if (type & PCI_EXP_IDO_COMPLETION)
ctrl |= PCI_EXP_IDO_CMP_EN; ctrl |= PCI_EXP_DEVCTL2_IDO_CMP_EN;
if (ctrl) if (ctrl)
pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2, ctrl); pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2, ctrl);
} }
...@@ -2168,7 +2168,7 @@ int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type type) ...@@ -2168,7 +2168,7 @@ int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type type)
int ret; int ret;
pcie_capability_read_dword(dev, PCI_EXP_DEVCAP2, &cap); pcie_capability_read_dword(dev, PCI_EXP_DEVCAP2, &cap);
if (!(cap & PCI_EXP_OBFF_MASK)) if (!(cap & PCI_EXP_DEVCAP2_OBFF_MASK))
return -ENOTSUPP; /* no OBFF support at all */ return -ENOTSUPP; /* no OBFF support at all */
/* Make sure the topology supports OBFF as well */ /* Make sure the topology supports OBFF as well */
...@@ -2179,17 +2179,17 @@ int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type type) ...@@ -2179,17 +2179,17 @@ int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type type)
} }
pcie_capability_read_word(dev, PCI_EXP_DEVCTL2, &ctrl); pcie_capability_read_word(dev, PCI_EXP_DEVCTL2, &ctrl);
if (cap & PCI_EXP_OBFF_WAKE) if (cap & PCI_EXP_DEVCAP2_OBFF_WAKE)
ctrl |= PCI_EXP_OBFF_WAKE_EN; ctrl |= PCI_EXP_DEVCTL2_OBFF_WAKE_EN;
else { else {
switch (type) { switch (type) {
case PCI_EXP_OBFF_SIGNAL_L0: case PCI_EXP_OBFF_SIGNAL_L0:
if (!(ctrl & PCI_EXP_OBFF_WAKE_EN)) if (!(ctrl & PCI_EXP_DEVCTL2_OBFF_WAKE_EN))
ctrl |= PCI_EXP_OBFF_MSGA_EN; ctrl |= PCI_EXP_DEVCTL2_OBFF_MSGA_EN;
break; break;
case PCI_EXP_OBFF_SIGNAL_ALWAYS: case PCI_EXP_OBFF_SIGNAL_ALWAYS:
ctrl &= ~PCI_EXP_OBFF_WAKE_EN; ctrl &= ~PCI_EXP_DEVCTL2_OBFF_WAKE_EN;
ctrl |= PCI_EXP_OBFF_MSGB_EN; ctrl |= PCI_EXP_DEVCTL2_OBFF_MSGB_EN;
break; break;
default: default:
WARN(1, "bad OBFF signal type\n"); WARN(1, "bad OBFF signal type\n");
...@@ -2210,7 +2210,8 @@ EXPORT_SYMBOL(pci_enable_obff); ...@@ -2210,7 +2210,8 @@ EXPORT_SYMBOL(pci_enable_obff);
*/ */
void pci_disable_obff(struct pci_dev *dev) void pci_disable_obff(struct pci_dev *dev)
{ {
pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2, PCI_EXP_OBFF_WAKE_EN); pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2,
PCI_EXP_DEVCTL2_OBFF_WAKE_EN);
} }
EXPORT_SYMBOL(pci_disable_obff); EXPORT_SYMBOL(pci_disable_obff);
...@@ -2258,7 +2259,8 @@ int pci_enable_ltr(struct pci_dev *dev) ...@@ -2258,7 +2259,8 @@ int pci_enable_ltr(struct pci_dev *dev)
return ret; return ret;
} }
return pcie_capability_set_word(dev, PCI_EXP_DEVCTL2, PCI_EXP_LTR_EN); return pcie_capability_set_word(dev, PCI_EXP_DEVCTL2,
PCI_EXP_DEVCTL2_LTR_EN);
} }
EXPORT_SYMBOL(pci_enable_ltr); EXPORT_SYMBOL(pci_enable_ltr);
...@@ -2275,7 +2277,8 @@ void pci_disable_ltr(struct pci_dev *dev) ...@@ -2275,7 +2277,8 @@ void pci_disable_ltr(struct pci_dev *dev)
if (!pci_ltr_supported(dev)) if (!pci_ltr_supported(dev))
return; return;
pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2, PCI_EXP_LTR_EN); pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2,
PCI_EXP_DEVCTL2_LTR_EN);
} }
EXPORT_SYMBOL(pci_disable_ltr); EXPORT_SYMBOL(pci_disable_ltr);
...@@ -3141,18 +3144,23 @@ bool pci_check_and_unmask_intx(struct pci_dev *dev) ...@@ -3141,18 +3144,23 @@ bool pci_check_and_unmask_intx(struct pci_dev *dev)
EXPORT_SYMBOL_GPL(pci_check_and_unmask_intx); EXPORT_SYMBOL_GPL(pci_check_and_unmask_intx);
/** /**
* pci_msi_off - disables any msi or msix capabilities * pci_msi_off - disables any MSI or MSI-X capabilities
* @dev: the PCI device to operate on * @dev: the PCI device to operate on
* *
* If you want to use msi see pci_enable_msi and friends. * If you want to use MSI, see pci_enable_msi() and friends.
* This is a lower level primitive that allows us to disable * This is a lower-level primitive that allows us to disable
* msi operation at the device level. * MSI operation at the device level.
*/ */
void pci_msi_off(struct pci_dev *dev) void pci_msi_off(struct pci_dev *dev)
{ {
int pos; int pos;
u16 control; u16 control;
/*
* This looks like it could go in msi.c, but we need it even when
* CONFIG_PCI_MSI=n. For the same reason, we can't use
* dev->msi_cap or dev->msix_cap here.
*/
pos = pci_find_capability(dev, PCI_CAP_ID_MSI); pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
if (pos) { if (pos) {
pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
......
...@@ -156,6 +156,8 @@ static inline unsigned long decode_bar(struct pci_dev *dev, u32 bar) ...@@ -156,6 +156,8 @@ static inline unsigned long decode_bar(struct pci_dev *dev, u32 bar)
return flags; return flags;
} }
#define PCI_COMMAND_DECODE_ENABLE (PCI_COMMAND_MEMORY | PCI_COMMAND_IO)
/** /**
* pci_read_base - read a PCI BAR * pci_read_base - read a PCI BAR
* @dev: the PCI device * @dev: the PCI device
...@@ -178,8 +180,10 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, ...@@ -178,8 +180,10 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
/* No printks while decoding is disabled! */ /* No printks while decoding is disabled! */
if (!dev->mmio_always_on) { if (!dev->mmio_always_on) {
pci_read_config_word(dev, PCI_COMMAND, &orig_cmd); pci_read_config_word(dev, PCI_COMMAND, &orig_cmd);
pci_write_config_word(dev, PCI_COMMAND, if (orig_cmd & PCI_COMMAND_DECODE_ENABLE) {
orig_cmd & ~(PCI_COMMAND_MEMORY | PCI_COMMAND_IO)); pci_write_config_word(dev, PCI_COMMAND,
orig_cmd & ~PCI_COMMAND_DECODE_ENABLE);
}
} }
res->name = pci_name(dev); res->name = pci_name(dev);
...@@ -293,7 +297,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, ...@@ -293,7 +297,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
fail: fail:
res->flags = 0; res->flags = 0;
out: out:
if (!dev->mmio_always_on) if (!dev->mmio_always_on &&
(orig_cmd & PCI_COMMAND_DECODE_ENABLE))
pci_write_config_word(dev, PCI_COMMAND, orig_cmd); pci_write_config_word(dev, PCI_COMMAND, orig_cmd);
if (bar_too_big) if (bar_too_big)
......
...@@ -1654,6 +1654,10 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, ...@@ -1654,6 +1654,10 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev,
int pcibios_add_device(struct pci_dev *dev); int pcibios_add_device(struct pci_dev *dev);
void pcibios_release_device(struct pci_dev *dev); void pcibios_release_device(struct pci_dev *dev);
#ifdef CONFIG_HIBERNATE_CALLBACKS
extern struct dev_pm_ops pcibios_pm_ops;
#endif
#ifdef CONFIG_PCI_MMCONFIG #ifdef CONFIG_PCI_MMCONFIG
void __init pci_mmcfg_early_init(void); void __init pci_mmcfg_early_init(void);
void __init pci_mmcfg_late_init(void); void __init pci_mmcfg_late_init(void);
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment