Commit 09521577 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci:
  PCI hotplug: shpchp: don't blindly claim non-AMD 0x7450 device IDs
  PCI: pciehp: wait 100 ms after Link Training check
  PCI: pciehp: wait 1000 ms before Link Training check
  PCI: pciehp: Retrieve link speed after link is trained
  PCI: Let PCI_PRI depend on PCI
  PCI: Fix compile errors with PCI_ATS and !PCI_IOV
  PCI / ACPI: Make acpiphp ignore root bridges using PCIe native hotplug
parents de7badf1 4cac2eb1
...@@ -76,6 +76,7 @@ config PCI_IOV ...@@ -76,6 +76,7 @@ config PCI_IOV
config PCI_PRI config PCI_PRI
bool "PCI PRI support" bool "PCI PRI support"
depends on PCI
select PCI_ATS select PCI_ATS
help help
PRI is the PCI Page Request Interface. It allows PCI devices that are PRI is the PCI Page Request Interface. It allows PCI devices that are
......
...@@ -459,8 +459,17 @@ static int add_bridge(acpi_handle handle) ...@@ -459,8 +459,17 @@ static int add_bridge(acpi_handle handle)
{ {
acpi_status status; acpi_status status;
unsigned long long tmp; unsigned long long tmp;
struct acpi_pci_root *root;
acpi_handle dummy_handle; acpi_handle dummy_handle;
/*
* We shouldn't use this bridge if PCIe native hotplug control has been
* granted by the BIOS for it.
*/
root = acpi_pci_find_root(handle);
if (root && (root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL))
return -ENODEV;
/* if the bridge doesn't have _STA, we assume it is always there */ /* if the bridge doesn't have _STA, we assume it is always there */
status = acpi_get_handle(handle, "_STA", &dummy_handle); status = acpi_get_handle(handle, "_STA", &dummy_handle);
if (ACPI_SUCCESS(status)) { if (ACPI_SUCCESS(status)) {
...@@ -1376,13 +1385,23 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, ...@@ -1376,13 +1385,23 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type,
static acpi_status static acpi_status
find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
{ {
struct acpi_pci_root *root;
int *count = (int *)context; int *count = (int *)context;
if (acpi_is_root_bridge(handle)) { if (!acpi_is_root_bridge(handle))
return AE_OK;
root = acpi_pci_find_root(handle);
if (!root)
return AE_OK;
if (root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)
return AE_OK;
(*count)++;
acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
handle_hotplug_event_bridge, NULL); handle_hotplug_event_bridge, NULL);
(*count)++;
}
return AE_OK ; return AE_OK ;
} }
......
...@@ -213,9 +213,6 @@ static int board_added(struct slot *p_slot) ...@@ -213,9 +213,6 @@ static int board_added(struct slot *p_slot)
goto err_exit; goto err_exit;
} }
/* Wait for 1 second after checking link training status */
msleep(1000);
/* Check for a power fault */ /* Check for a power fault */
if (ctrl->power_fault_detected || pciehp_query_power_fault(p_slot)) { if (ctrl->power_fault_detected || pciehp_query_power_fault(p_slot)) {
ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot)); ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot));
......
...@@ -280,6 +280,14 @@ int pciehp_check_link_status(struct controller *ctrl) ...@@ -280,6 +280,14 @@ int pciehp_check_link_status(struct controller *ctrl)
else else
msleep(1000); msleep(1000);
/*
* Need to wait for 1000 ms after Data Link Layer Link Active
* (DLLLA) bit reads 1b before sending configuration request.
* We need it before checking Link Training (LT) bit becuase
* LT is still set even after DLLLA bit is set on some platform.
*/
msleep(1000);
retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status);
if (retval) { if (retval) {
ctrl_err(ctrl, "Cannot read LNKSTATUS register\n"); ctrl_err(ctrl, "Cannot read LNKSTATUS register\n");
...@@ -294,6 +302,16 @@ int pciehp_check_link_status(struct controller *ctrl) ...@@ -294,6 +302,16 @@ int pciehp_check_link_status(struct controller *ctrl)
return retval; return retval;
} }
/*
* If the port supports Link speeds greater than 5.0 GT/s, we
* must wait for 100 ms after Link training completes before
* sending configuration request.
*/
if (ctrl->pcie->port->subordinate->max_bus_speed > PCIE_SPEED_5_0GT)
msleep(100);
pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status);
return retval; return retval;
} }
...@@ -484,7 +502,6 @@ int pciehp_power_on_slot(struct slot * slot) ...@@ -484,7 +502,6 @@ int pciehp_power_on_slot(struct slot * slot)
u16 slot_cmd; u16 slot_cmd;
u16 cmd_mask; u16 cmd_mask;
u16 slot_status; u16 slot_status;
u16 lnk_status;
int retval = 0; int retval = 0;
/* Clear sticky power-fault bit from previous power failures */ /* Clear sticky power-fault bit from previous power failures */
...@@ -516,14 +533,6 @@ int pciehp_power_on_slot(struct slot * slot) ...@@ -516,14 +533,6 @@ int pciehp_power_on_slot(struct slot * slot)
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status);
if (retval) {
ctrl_err(ctrl, "%s: Cannot read LNKSTA register\n",
__func__);
return retval;
}
pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status);
return retval; return retval;
} }
......
...@@ -278,8 +278,8 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value) ...@@ -278,8 +278,8 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
static int is_shpc_capable(struct pci_dev *dev) static int is_shpc_capable(struct pci_dev *dev)
{ {
if ((dev->vendor == PCI_VENDOR_ID_AMD) || (dev->device == if (dev->vendor == PCI_VENDOR_ID_AMD &&
PCI_DEVICE_ID_AMD_GOLAM_7450)) dev->device == PCI_DEVICE_ID_AMD_GOLAM_7450)
return 1; return 1;
if (!pci_find_capability(dev, PCI_CAP_ID_SHPC)) if (!pci_find_capability(dev, PCI_CAP_ID_SHPC))
return 0; return 0;
......
...@@ -944,8 +944,8 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) ...@@ -944,8 +944,8 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev)
ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */ ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */
ctrl_dbg(ctrl, "Hotplug Controller:\n"); ctrl_dbg(ctrl, "Hotplug Controller:\n");
if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device == if (pdev->vendor == PCI_VENDOR_ID_AMD &&
PCI_DEVICE_ID_AMD_GOLAM_7450)) { pdev->device == PCI_DEVICE_ID_AMD_GOLAM_7450) {
/* amd shpc driver doesn't use Base Offset; assume 0 */ /* amd shpc driver doesn't use Base Offset; assume 0 */
ctrl->mmio_base = pci_resource_start(pdev, 0); ctrl->mmio_base = pci_resource_start(pdev, 0);
ctrl->mmio_size = pci_resource_len(pdev, 0); ctrl->mmio_size = pci_resource_len(pdev, 0);
......
...@@ -12,7 +12,7 @@ struct pci_ats { ...@@ -12,7 +12,7 @@ struct pci_ats {
unsigned int is_enabled:1; /* Enable bit is set */ unsigned int is_enabled:1; /* Enable bit is set */
}; };
#ifdef CONFIG_PCI_IOV #ifdef CONFIG_PCI_ATS
extern int pci_enable_ats(struct pci_dev *dev, int ps); extern int pci_enable_ats(struct pci_dev *dev, int ps);
extern void pci_disable_ats(struct pci_dev *dev); extern void pci_disable_ats(struct pci_dev *dev);
...@@ -29,7 +29,7 @@ static inline int pci_ats_enabled(struct pci_dev *dev) ...@@ -29,7 +29,7 @@ static inline int pci_ats_enabled(struct pci_dev *dev)
return dev->ats && dev->ats->is_enabled; return dev->ats && dev->ats->is_enabled;
} }
#else /* CONFIG_PCI_IOV */ #else /* CONFIG_PCI_ATS */
static inline int pci_enable_ats(struct pci_dev *dev, int ps) static inline int pci_enable_ats(struct pci_dev *dev, int ps)
{ {
...@@ -50,7 +50,7 @@ static inline int pci_ats_enabled(struct pci_dev *dev) ...@@ -50,7 +50,7 @@ static inline int pci_ats_enabled(struct pci_dev *dev)
return 0; return 0;
} }
#endif /* CONFIG_PCI_IOV */ #endif /* CONFIG_PCI_ATS */
#ifdef CONFIG_PCI_PRI #ifdef CONFIG_PCI_PRI
......
...@@ -338,7 +338,7 @@ struct pci_dev { ...@@ -338,7 +338,7 @@ struct pci_dev {
struct list_head msi_list; struct list_head msi_list;
#endif #endif
struct pci_vpd *vpd; struct pci_vpd *vpd;
#ifdef CONFIG_PCI_IOV #ifdef CONFIG_PCI_ATS
union { union {
struct pci_sriov *sriov; /* SR-IOV capability related */ struct pci_sriov *sriov; /* SR-IOV capability related */
struct pci_dev *physfn; /* the PF this VF is associated with */ struct pci_dev *physfn; /* the PF this VF is associated with */
......
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