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
This commit is contained in:
Linus Torvalds 2011-11-23 14:58:46 -08:00
commit 09521577ca
8 changed files with 51 additions and 25 deletions

View File

@ -76,6 +76,7 @@ config PCI_IOV
config PCI_PRI
bool "PCI PRI support"
depends on PCI
select PCI_ATS
help
PRI is the PCI Page Request Interface. It allows PCI devices that are

View File

@ -459,8 +459,17 @@ static int add_bridge(acpi_handle handle)
{
acpi_status status;
unsigned long long tmp;
struct acpi_pci_root *root;
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 */
status = acpi_get_handle(handle, "_STA", &dummy_handle);
if (ACPI_SUCCESS(status)) {
@ -1376,13 +1385,23 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type,
static acpi_status
find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
{
struct acpi_pci_root *root;
int *count = (int *)context;
if (acpi_is_root_bridge(handle)) {
acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
handle_hotplug_event_bridge, NULL);
(*count)++;
}
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,
handle_hotplug_event_bridge, NULL);
return AE_OK ;
}

View File

@ -213,9 +213,6 @@ static int board_added(struct slot *p_slot)
goto err_exit;
}
/* Wait for 1 second after checking link training status */
msleep(1000);
/* Check for a power fault */
if (ctrl->power_fault_detected || pciehp_query_power_fault(p_slot)) {
ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot));

View File

@ -280,6 +280,14 @@ int pciehp_check_link_status(struct controller *ctrl)
else
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);
if (retval) {
ctrl_err(ctrl, "Cannot read LNKSTATUS register\n");
@ -294,6 +302,16 @@ int pciehp_check_link_status(struct controller *ctrl)
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;
}
@ -484,7 +502,6 @@ int pciehp_power_on_slot(struct slot * slot)
u16 slot_cmd;
u16 cmd_mask;
u16 slot_status;
u16 lnk_status;
int retval = 0;
/* Clear sticky power-fault bit from previous power failures */
@ -516,14 +533,6 @@ int pciehp_power_on_slot(struct slot * slot)
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
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;
}

View File

@ -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)
{
if ((dev->vendor == PCI_VENDOR_ID_AMD) || (dev->device ==
PCI_DEVICE_ID_AMD_GOLAM_7450))
if (dev->vendor == PCI_VENDOR_ID_AMD &&
dev->device == PCI_DEVICE_ID_AMD_GOLAM_7450)
return 1;
if (!pci_find_capability(dev, PCI_CAP_ID_SHPC))
return 0;

View File

@ -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_dbg(ctrl, "Hotplug Controller:\n");
if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device ==
PCI_DEVICE_ID_AMD_GOLAM_7450)) {
if (pdev->vendor == PCI_VENDOR_ID_AMD &&
pdev->device == PCI_DEVICE_ID_AMD_GOLAM_7450) {
/* amd shpc driver doesn't use Base Offset; assume 0 */
ctrl->mmio_base = pci_resource_start(pdev, 0);
ctrl->mmio_size = pci_resource_len(pdev, 0);

View File

@ -12,7 +12,7 @@ struct pci_ats {
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 void pci_disable_ats(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;
}
#else /* CONFIG_PCI_IOV */
#else /* CONFIG_PCI_ATS */
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)
return 0;
}
#endif /* CONFIG_PCI_IOV */
#endif /* CONFIG_PCI_ATS */
#ifdef CONFIG_PCI_PRI

View File

@ -338,7 +338,7 @@ struct pci_dev {
struct list_head msi_list;
#endif
struct pci_vpd *vpd;
#ifdef CONFIG_PCI_IOV
#ifdef CONFIG_PCI_ATS
union {
struct pci_sriov *sriov; /* SR-IOV capability related */
struct pci_dev *physfn; /* the PF this VF is associated with */