Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/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
  • Loading branch information
Linus Torvalds committed Nov 23, 2011
2 parents de7badf + 4cac2eb commit 0952157
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 25 deletions.
1 change: 1 addition & 0 deletions drivers/pci/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
29 changes: 24 additions & 5 deletions drivers/pci/hotplug/acpiphp_glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down Expand Up @@ -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 ;
}

Expand Down
3 changes: 0 additions & 3 deletions drivers/pci/hotplug/pciehp_ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
27 changes: 18 additions & 9 deletions drivers/pci/hotplug/pciehp_hpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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;
}

Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/pci/hotplug/shpchp_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions drivers/pci/hotplug/shpchp_hpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions include/linux/pci-ats.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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)
{
Expand All @@ -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

Expand Down
2 changes: 1 addition & 1 deletion include/linux/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down

0 comments on commit 0952157

Please sign in to comment.