diff options
Diffstat (limited to 'drivers/pci/pci.c')
| -rw-r--r-- | drivers/pci/pci.c | 559 |
1 files changed, 318 insertions, 241 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 7c1b362f599a..fcfaadc774ee 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -197,8 +197,8 @@ EXPORT_SYMBOL_GPL(pci_ioremap_wc_bar); /** * pci_dev_str_match_path - test if a path string matches a device - * @dev: the PCI device to test - * @path: string to match the device against + * @dev: the PCI device to test + * @path: string to match the device against * @endptr: pointer to the string after the match * * Test if a string (typically from a kernel parameter) formatted as a @@ -280,8 +280,8 @@ free_and_exit: /** * pci_dev_str_match - test if a string matches a device - * @dev: the PCI device to test - * @p: string to match the device against + * @dev: the PCI device to test + * @p: string to match the device against * @endptr: pointer to the string after the match * * Test if a string (typically from a kernel parameter) matches a specified @@ -341,7 +341,7 @@ static int pci_dev_str_match(struct pci_dev *dev, const char *p, } else { /* * PCI Bus, Device, Function IDs are specified - * (optionally, may include a path of devfns following it) + * (optionally, may include a path of devfns following it) */ ret = pci_dev_str_match_path(dev, p, &p); if (ret < 0) @@ -425,7 +425,7 @@ static int __pci_bus_find_cap_start(struct pci_bus *bus, * Tell if a device supports a given PCI capability. * Returns the address of the requested capability structure within the * device's PCI configuration space or 0 in case the device does not - * support it. Possible values for @cap: + * support it. Possible values for @cap include: * * %PCI_CAP_ID_PM Power Management * %PCI_CAP_ID_AGP Accelerated Graphics Port @@ -450,11 +450,11 @@ EXPORT_SYMBOL(pci_find_capability); /** * pci_bus_find_capability - query for devices' capabilities - * @bus: the PCI bus to query + * @bus: the PCI bus to query * @devfn: PCI device to query - * @cap: capability code + * @cap: capability code * - * Like pci_find_capability() but works for pci devices that do not have a + * Like pci_find_capability() but works for PCI devices that do not have a * pci_dev structure set up yet. * * Returns the address of the requested capability structure within the @@ -535,7 +535,7 @@ EXPORT_SYMBOL_GPL(pci_find_next_ext_capability); * * Returns the address of the requested extended capability structure * within the device's PCI configuration space or 0 if the device does - * not support it. Possible values for @cap: + * not support it. Possible values for @cap include: * * %PCI_EXT_CAP_ID_ERR Advanced Error Reporting * %PCI_EXT_CAP_ID_VC Virtual Channel @@ -618,12 +618,13 @@ int pci_find_ht_capability(struct pci_dev *dev, int ht_cap) EXPORT_SYMBOL_GPL(pci_find_ht_capability); /** - * pci_find_parent_resource - return resource region of parent bus of given region + * pci_find_parent_resource - return resource region of parent bus of given + * region * @dev: PCI device structure contains resources to be searched * @res: child resource record for which parent is sought * - * For given resource region of given device, return the resource - * region of parent bus the given region is contained in. + * For given resource region of given device, return the resource region of + * parent bus the given region is contained in. */ struct resource *pci_find_parent_resource(const struct pci_dev *dev, struct resource *res) @@ -776,6 +777,12 @@ static inline pci_power_t platform_pci_get_power_state(struct pci_dev *dev) return pci_platform_pm ? pci_platform_pm->get_state(dev) : PCI_UNKNOWN; } +static inline void platform_pci_refresh_power_state(struct pci_dev *dev) +{ + if (pci_platform_pm && pci_platform_pm->refresh_state) + pci_platform_pm->refresh_state(dev); +} + static inline pci_power_t platform_pci_choose_state(struct pci_dev *dev) { return pci_platform_pm ? @@ -800,7 +807,7 @@ static inline bool platform_pci_bridge_d3(struct pci_dev *dev) /** * pci_raw_set_power_state - Use PCI PM registers to set the power state of - * given PCI device + * given PCI device * @dev: PCI device to handle. * @state: PCI power state (D0, D1, D2, D3hot) to put the device into. * @@ -826,7 +833,8 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) if (state < PCI_D0 || state > PCI_D3hot) return -EINVAL; - /* Validate current state: + /* + * Validate current state: * Can enter D0 from any state, but if we can only go deeper * to sleep if we're already in a low power state */ @@ -837,14 +845,15 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) return -EINVAL; } - /* check if this device supports the desired state */ + /* Check if this device supports the desired state */ if ((state == PCI_D1 && !dev->d1_support) || (state == PCI_D2 && !dev->d2_support)) return -EIO; pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); - /* If we're (effectively) in D3, force entire word to 0. + /* + * If we're (effectively) in D3, force entire word to 0. * This doesn't affect PME_Status, disables PME_En, and * sets PowerState to 0. */ @@ -867,11 +876,13 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) break; } - /* enter specified state */ + /* Enter specified state */ pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr); - /* Mandatory power management transition delays */ - /* see PCI PM 1.1 5.6.1 table 18 */ + /* + * Mandatory power management transition delays; see PCI PM 1.1 + * 5.6.1 table 18 + */ if (state == PCI_D3hot || dev->current_state == PCI_D3hot) pci_dev_d3_sleep(dev); else if (state == PCI_D2 || dev->current_state == PCI_D2) @@ -879,8 +890,8 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); - if (dev->current_state != state && printk_ratelimit()) - pci_info(dev, "Refused to change power state, currently in D%d\n", + if (dev->current_state != state) + pci_info_ratelimited(dev, "Refused to change power state, currently in D%d\n", dev->current_state); /* @@ -933,16 +944,18 @@ void pci_update_current_state(struct pci_dev *dev, pci_power_t state) } /** - * pci_power_up - Put the given device into D0 forcibly - * @dev: PCI device to power up + * pci_refresh_power_state - Refresh the given device's power state data + * @dev: Target PCI device. + * + * Ask the platform to refresh the devices power state information and invoke + * pci_update_current_state() to update its current PCI power state. */ -void pci_power_up(struct pci_dev *dev) +void pci_refresh_power_state(struct pci_dev *dev) { if (platform_pci_power_manageable(dev)) - platform_pci_set_power_state(dev, PCI_D0); + platform_pci_refresh_power_state(dev); - pci_raw_set_power_state(dev, PCI_D0); - pci_update_current_state(dev, PCI_D0); + pci_update_current_state(dev, dev->current_state); } /** @@ -1085,16 +1098,18 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) { int error; - /* bound the state we're entering */ + /* Bound the state we're entering */ if (state > PCI_D3cold) state = PCI_D3cold; else if (state < PCI_D0) state = PCI_D0; else if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev)) + /* - * If the device or the parent bridge do not support PCI PM, - * ignore the request if we're doing anything other than putting - * it into D0 (which would only happen on boot). + * If the device or the parent bridge do not support PCI + * PM, ignore the request if we're doing anything other + * than putting it into D0 (which would only happen on + * boot). */ return 0; @@ -1104,8 +1119,10 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) __pci_start_power_transition(dev, state); - /* This device is quirked not to be put into D3, so - don't put it in D3 */ + /* + * This device is quirked not to be put into D3, so don't put it in + * D3 + */ if (state >= PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3)) return 0; @@ -1124,15 +1141,25 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) EXPORT_SYMBOL(pci_set_power_state); /** + * pci_power_up - Put the given device into D0 forcibly + * @dev: PCI device to power up + */ +void pci_power_up(struct pci_dev *dev) +{ + __pci_start_power_transition(dev, PCI_D0); + pci_raw_set_power_state(dev, PCI_D0); + pci_update_current_state(dev, PCI_D0); +} + +/** * pci_choose_state - Choose the power state of a PCI device * @dev: PCI device to be suspended * @state: target sleep state for the whole system. This is the value - * that is passed to suspend() function. + * that is passed to suspend() function. * * Returns PCI power state suitable for given device and given system * message. */ - pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state) { pci_power_t ret; @@ -1310,8 +1337,9 @@ static void pci_restore_ltr_state(struct pci_dev *dev) } /** - * pci_save_state - save the PCI configuration space of a device before suspending - * @dev: - PCI device that we're dealing with + * pci_save_state - save the PCI configuration space of a device before + * suspending + * @dev: PCI device that we're dealing with */ int pci_save_state(struct pci_dev *dev) { @@ -1413,7 +1441,7 @@ static void pci_restore_rebar_state(struct pci_dev *pdev) pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl); bar_idx = ctrl & PCI_REBAR_CTRL_BAR_IDX; res = pdev->resource + bar_idx; - size = order_base_2((resource_size(res) >> 20) | 1) - 1; + size = ilog2(resource_size(res)) - 20; ctrl &= ~PCI_REBAR_CTRL_BAR_SIZE; ctrl |= size << PCI_REBAR_CTRL_BAR_SHIFT; pci_write_config_dword(pdev, pos + PCI_REBAR_CTRL, ctrl); @@ -1422,7 +1450,7 @@ static void pci_restore_rebar_state(struct pci_dev *pdev) /** * pci_restore_state - Restore the saved state of a PCI device - * @dev: - PCI device that we're dealing with + * @dev: PCI device that we're dealing with */ void pci_restore_state(struct pci_dev *dev) { @@ -1599,8 +1627,8 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars) * pci_reenable_device - Resume abandoned device * @dev: PCI device to be resumed * - * Note this function is a backend of pci_default_resume and is not supposed - * to be called by normal code, write proper resume handler and use it instead. + * NOTE: This function is a backend of pci_default_resume() and is not supposed + * to be called by normal code, write proper resume handler and use it instead. */ int pci_reenable_device(struct pci_dev *dev) { @@ -1675,9 +1703,9 @@ static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags) * pci_enable_device_io - Initialize a device for use with IO space * @dev: PCI device to be initialized * - * Initialize device before it's used by a driver. Ask low-level code - * to enable I/O resources. Wake up the device if it was suspended. - * Beware, this function can fail. + * Initialize device before it's used by a driver. Ask low-level code + * to enable I/O resources. Wake up the device if it was suspended. + * Beware, this function can fail. */ int pci_enable_device_io(struct pci_dev *dev) { @@ -1689,9 +1717,9 @@ EXPORT_SYMBOL(pci_enable_device_io); * pci_enable_device_mem - Initialize a device for use with Memory space * @dev: PCI device to be initialized * - * Initialize device before it's used by a driver. Ask low-level code - * to enable Memory resources. Wake up the device if it was suspended. - * Beware, this function can fail. + * Initialize device before it's used by a driver. Ask low-level code + * to enable Memory resources. Wake up the device if it was suspended. + * Beware, this function can fail. */ int pci_enable_device_mem(struct pci_dev *dev) { @@ -1703,12 +1731,12 @@ EXPORT_SYMBOL(pci_enable_device_mem); * pci_enable_device - Initialize device before it's used by a driver. * @dev: PCI device to be initialized * - * Initialize device before it's used by a driver. Ask low-level code - * to enable I/O and memory. Wake up the device if it was suspended. - * Beware, this function can fail. + * Initialize device before it's used by a driver. Ask low-level code + * to enable I/O and memory. Wake up the device if it was suspended. + * Beware, this function can fail. * - * Note we don't actually enable the device many times if we call - * this function repeatedly (we just increment the count). + * Note we don't actually enable the device many times if we call + * this function repeatedly (we just increment the count). */ int pci_enable_device(struct pci_dev *dev) { @@ -1717,8 +1745,8 @@ int pci_enable_device(struct pci_dev *dev) EXPORT_SYMBOL(pci_enable_device); /* - * Managed PCI resources. This manages device on/off, intx/msi/msix - * on/off and BAR regions. pci_dev itself records msi/msix status, so + * Managed PCI resources. This manages device on/off, INTx/MSI/MSI-X + * on/off and BAR regions. pci_dev itself records MSI/MSI-X status, so * there's no need to track it separately. pci_devres is initialized * when a device is enabled using managed PCI device enable interface. */ @@ -1836,7 +1864,8 @@ int __weak pcibios_add_device(struct pci_dev *dev) } /** - * pcibios_release_device - provide arch specific hooks when releasing device dev + * pcibios_release_device - provide arch specific hooks when releasing + * device dev * @dev: the PCI device being released * * Permits the platform to provide architecture specific functionality when @@ -1927,8 +1956,7 @@ EXPORT_SYMBOL(pci_disable_device); * @dev: the PCIe device reset * @state: Reset state to enter into * - * - * Sets the PCIe reset state for the device. This is the default + * Set the PCIe reset state for the device. This is the default * implementation. Architecture implementations can override this. */ int __weak pcibios_set_pcie_reset_state(struct pci_dev *dev, @@ -1942,7 +1970,6 @@ int __weak pcibios_set_pcie_reset_state(struct pci_dev *dev, * @dev: the PCIe device reset * @state: Reset state to enter into * - * * Sets the PCI reset state for the device. */ int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state) @@ -2057,6 +2084,13 @@ static void pci_pme_list_scan(struct work_struct *work) */ if (bridge && bridge->current_state != PCI_D0) continue; + /* + * If the device is in D3cold it should not be + * polled either. + */ + if (pme_dev->dev->current_state == PCI_D3cold) + continue; + pci_pme_wakeup(pme_dev->dev, NULL); } else { list_del(&pme_dev->list); @@ -2339,7 +2373,8 @@ static pci_power_t pci_target_state(struct pci_dev *dev, bool wakeup) } /** - * pci_prepare_to_sleep - prepare PCI device for system-wide transition into a sleep state + * pci_prepare_to_sleep - prepare PCI device for system-wide transition + * into a sleep state * @dev: Device to handle. * * Choose the power state appropriate for the device depending on whether @@ -2367,7 +2402,8 @@ int pci_prepare_to_sleep(struct pci_dev *dev) EXPORT_SYMBOL(pci_prepare_to_sleep); /** - * pci_back_from_sleep - turn PCI device on during system-wide transition into working state + * pci_back_from_sleep - turn PCI device on during system-wide transition + * into working state * @dev: Device to handle. * * Disable device's system wake-up capability and put it into D0. @@ -2449,45 +2485,56 @@ bool pci_dev_run_wake(struct pci_dev *dev) EXPORT_SYMBOL_GPL(pci_dev_run_wake); /** - * pci_dev_keep_suspended - Check if the device can stay in the suspended state. + * pci_dev_need_resume - Check if it is necessary to resume the device. * @pci_dev: Device to check. * - * Return 'true' if the device is runtime-suspended, it doesn't have to be + * Return 'true' if the device is not runtime-suspended or it has to be * reconfigured due to wakeup settings difference between system and runtime - * suspend and the current power state of it is suitable for the upcoming - * (system) transition. - * - * If the device is not configured for system wakeup, disable PME for it before - * returning 'true' to prevent it from waking up the system unnecessarily. + * suspend, or the current power state of it is not suitable for the upcoming + * (system-wide) transition. */ -bool pci_dev_keep_suspended(struct pci_dev *pci_dev) +bool pci_dev_need_resume(struct pci_dev *pci_dev) { struct device *dev = &pci_dev->dev; - bool wakeup = device_may_wakeup(dev); + pci_power_t target_state; - if (!pm_runtime_suspended(dev) - || pci_target_state(pci_dev, wakeup) != pci_dev->current_state - || platform_pci_need_resume(pci_dev)) - return false; + if (!pm_runtime_suspended(dev) || platform_pci_need_resume(pci_dev)) + return true; + + target_state = pci_target_state(pci_dev, device_may_wakeup(dev)); /* - * At this point the device is good to go unless it's been configured - * to generate PME at the runtime suspend time, but it is not supposed - * to wake up the system. In that case, simply disable PME for it - * (it will have to be re-enabled on exit from system resume). - * - * If the device's power state is D3cold and the platform check above - * hasn't triggered, the device's configuration is suitable and we don't - * need to manipulate it at all. + * If the earlier platform check has not triggered, D3cold is just power + * removal on top of D3hot, so no need to resume the device in that + * case. */ + return target_state != pci_dev->current_state && + target_state != PCI_D3cold && + pci_dev->current_state != PCI_D3hot; +} + +/** + * pci_dev_adjust_pme - Adjust PME setting for a suspended device. + * @pci_dev: Device to check. + * + * If the device is suspended and it is not configured for system wakeup, + * disable PME for it to prevent it from waking up the system unnecessarily. + * + * Note that if the device's power state is D3cold and the platform check in + * pci_dev_need_resume() has not triggered, the device's configuration need not + * be changed. + */ +void pci_dev_adjust_pme(struct pci_dev *pci_dev) +{ + struct device *dev = &pci_dev->dev; + spin_lock_irq(&dev->power.lock); - if (pm_runtime_suspended(dev) && pci_dev->current_state < PCI_D3cold && - !wakeup) + if (pm_runtime_suspended(dev) && !device_may_wakeup(dev) && + pci_dev->current_state < PCI_D3cold) __pci_pme_active(pci_dev, false); spin_unlock_irq(&dev->power.lock); - return true; } /** @@ -2777,14 +2824,14 @@ void pci_pm_init(struct pci_dev *dev) dev->d2_support = true; if (dev->d1_support || dev->d2_support) - pci_printk(KERN_DEBUG, dev, "supports%s%s\n", + pci_info(dev, "supports%s%s\n", dev->d1_support ? " D1" : "", dev->d2_support ? " D2" : ""); } pmc &= PCI_PM_CAP_PME_MASK; if (pmc) { - pci_printk(KERN_DEBUG, dev, "PME# supported from%s%s%s%s%s\n", + pci_info(dev, "PME# supported from%s%s%s%s%s\n", (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "", (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "", (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "", @@ -2952,16 +2999,16 @@ static int pci_ea_read(struct pci_dev *dev, int offset) res->flags = flags; if (bei <= PCI_EA_BEI_BAR5) - pci_printk(KERN_DEBUG, dev, "BAR %d: %pR (from Enhanced Allocation, properties %#02x)\n", + pci_info(dev, "BAR %d: %pR (from Enhanced Allocation, properties %#02x)\n", bei, res, prop); else if (bei == PCI_EA_BEI_ROM) - pci_printk(KERN_DEBUG, dev, "ROM: %pR (from Enhanced Allocation, properties %#02x)\n", + pci_info(dev, "ROM: %pR (from Enhanced Allocation, properties %#02x)\n", res, prop); else if (bei >= PCI_EA_BEI_VF_BAR0 && bei <= PCI_EA_BEI_VF_BAR5) - pci_printk(KERN_DEBUG, dev, "VF BAR %d: %pR (from Enhanced Allocation, properties %#02x)\n", + pci_info(dev, "VF BAR %d: %pR (from Enhanced Allocation, properties %#02x)\n", bei - PCI_EA_BEI_VF_BAR0, res, prop); else - pci_printk(KERN_DEBUG, dev, "BEI %d res: %pR (from Enhanced Allocation, properties %#02x)\n", + pci_info(dev, "BEI %d res: %pR (from Enhanced Allocation, properties %#02x)\n", bei, res, prop); out: @@ -3005,7 +3052,7 @@ static void pci_add_saved_cap(struct pci_dev *pci_dev, /** * _pci_add_cap_save_buffer - allocate buffer for saving given - * capability registers + * capability registers * @dev: the PCI device * @cap: the capability to allocate the buffer for * @extended: Standard or Extended capability ID @@ -3186,7 +3233,7 @@ static void pci_disable_acs_redir(struct pci_dev *dev) } /** - * pci_std_enable_acs - enable ACS on devices using standard ACS capabilites + * pci_std_enable_acs - enable ACS on devices using standard ACS capabilities * @dev: the PCI device */ static void pci_std_enable_acs(struct pci_dev *dev) @@ -3532,7 +3579,7 @@ int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask) } /* Ensure upstream ports don't block AtomicOps on egress */ - if (!bridge->has_secondary_link) { + if (pci_pcie_type(bridge) == PCI_EXP_TYPE_UPSTREAM) { pcie_capability_read_dword(bridge, PCI_EXP_DEVCTL2, &ctl2); if (ctl2 & PCI_EXP_DEVCTL2_ATOMIC_EGRESS_BLOCK) @@ -3609,13 +3656,14 @@ u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp) EXPORT_SYMBOL_GPL(pci_common_swizzle); /** - * pci_release_region - Release a PCI bar - * @pdev: PCI device whose resources were previously reserved by pci_request_region - * @bar: BAR to release + * pci_release_region - Release a PCI bar + * @pdev: PCI device whose resources were previously reserved by + * pci_request_region() + * @bar: BAR to release * - * Releases the PCI I/O and memory resources previously reserved by a - * successful call to pci_request_region. Call this function only - * after all use of the PCI regions has ceased. + * Releases the PCI I/O and memory resources previously reserved by a + * successful call to pci_request_region(). Call this function only + * after all use of the PCI regions has ceased. */ void pci_release_region(struct pci_dev *pdev, int bar) { @@ -3637,23 +3685,23 @@ void pci_release_region(struct pci_dev *pdev, int bar) EXPORT_SYMBOL(pci_release_region); /** - * __pci_request_region - Reserved PCI I/O and memory resource - * @pdev: PCI device whose resources are to be reserved - * @bar: BAR to be reserved - * @res_name: Name to be associated with resource. - * @exclusive: whether the region access is exclusive or not + * __pci_request_region - Reserved PCI I/O and memory resource + * @pdev: PCI device whose resources are to be reserved + * @bar: BAR to be reserved + * @res_name: Name to be associated with resource. + * @exclusive: whether the region access is exclusive or not * - * Mark the PCI region associated with PCI device @pdev BR @bar as - * being reserved by owner @res_name. Do not access any - * address inside the PCI regions unless this call returns - * successfully. + * Mark the PCI region associated with PCI device @pdev BAR @bar as + * being reserved by owner @res_name. Do not access any + * address inside the PCI regions unless this call returns + * successfully. * - * If @exclusive is set, then the region is marked so that userspace - * is explicitly not allowed to map the resource via /dev/mem or - * sysfs MMIO access. + * If @exclusive is set, then the region is marked so that userspace + * is explicitly not allowed to map the resource via /dev/mem or + * sysfs MMIO access. * - * Returns 0 on success, or %EBUSY on error. A warning - * message is also printed on failure. + * Returns 0 on success, or %EBUSY on error. A warning + * message is also printed on failure. */ static int __pci_request_region(struct pci_dev *pdev, int bar, const char *res_name, int exclusive) @@ -3687,18 +3735,18 @@ err_out: } /** - * pci_request_region - Reserve PCI I/O and memory resource - * @pdev: PCI device whose resources are to be reserved - * @bar: BAR to be reserved - * @res_name: Name to be associated with resource + * pci_request_region - Reserve PCI I/O and memory resource + * @pdev: PCI device whose resources are to be reserved + * @bar: BAR to be reserved + * @res_name: Name to be associated with resource * - * Mark the PCI region associated with PCI device @pdev BAR @bar as - * being reserved by owner @res_name. Do not access any - * address inside the PCI regions unless this call returns - * successfully. + * Mark the PCI region associated with PCI device @pdev BAR @bar as + * being reserved by owner @res_name. Do not access any + * address inside the PCI regions unless this call returns + * successfully. * - * Returns 0 on success, or %EBUSY on error. A warning - * message is also printed on failure. + * Returns 0 on success, or %EBUSY on error. A warning + * message is also printed on failure. */ int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name) { @@ -3707,31 +3755,6 @@ int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name) EXPORT_SYMBOL(pci_request_region); /** - * pci_request_region_exclusive - Reserved PCI I/O and memory resource - * @pdev: PCI device whose resources are to be reserved - * @bar: BAR to be reserved - * @res_name: Name to be associated with resource. - * - * Mark the PCI region associated with PCI device @pdev BR @bar as - * being reserved by owner @res_name. Do not access any - * address inside the PCI regions unless this call returns - * successfully. - * - * Returns 0 on success, or %EBUSY on error. A warning - * message is also printed on failure. - * - * The key difference that _exclusive makes it that userspace is - * explicitly not allowed to map the resource via /dev/mem or - * sysfs. - */ -int pci_request_region_exclusive(struct pci_dev *pdev, int bar, - const char *res_name) -{ - return __pci_request_region(pdev, bar, res_name, IORESOURCE_EXCLUSIVE); -} -EXPORT_SYMBOL(pci_request_region_exclusive); - -/** * pci_release_selected_regions - Release selected PCI I/O and memory resources * @pdev: PCI device whose resources were previously reserved * @bars: Bitmask of BARs to be released @@ -3791,12 +3814,13 @@ int pci_request_selected_regions_exclusive(struct pci_dev *pdev, int bars, EXPORT_SYMBOL(pci_request_selected_regions_exclusive); /** - * pci_release_regions - Release reserved PCI I/O and memory resources - * @pdev: PCI device whose resources were previously reserved by pci_request_regions + * pci_release_regions - Release reserved PCI I/O and memory resources + * @pdev: PCI device whose resources were previously reserved by + * pci_request_regions() * - * Releases all PCI I/O and memory resources previously reserved by a - * successful call to pci_request_regions. Call this function only - * after all use of the PCI regions has ceased. + * Releases all PCI I/O and memory resources previously reserved by a + * successful call to pci_request_regions(). Call this function only + * after all use of the PCI regions has ceased. */ void pci_release_regions(struct pci_dev *pdev) @@ -3806,17 +3830,17 @@ void pci_release_regions(struct pci_dev *pdev) EXPORT_SYMBOL(pci_release_regions); /** - * pci_request_regions - Reserved PCI I/O and memory resources - * @pdev: PCI device whose resources are to be reserved - * @res_name: Name to be associated with resource. + * pci_request_regions - Reserve PCI I/O and memory resources + * @pdev: PCI device whose resources are to be reserved + * @res_name: Name to be associated with resource. * - * Mark all PCI regions associated with PCI device @pdev as - * being reserved by owner @res_name. Do not access any - * address inside the PCI regions unless this call returns - * successfully. + * Mark all PCI regions associated with PCI device @pdev as + * being reserved by owner @res_name. Do not access any + * address inside the PCI regions unless this call returns + * successfully. * - * Returns 0 on success, or %EBUSY on error. A warning - * message is also printed on failure. + * Returns 0 on success, or %EBUSY on error. A warning + * message is also printed on failure. */ int pci_request_regions(struct pci_dev *pdev, const char *res_name) { @@ -3825,20 +3849,19 @@ int pci_request_regions(struct pci_dev *pdev, const char *res_name) EXPORT_SYMBOL(pci_request_regions); /** - * pci_request_regions_exclusive - Reserved PCI I/O and memory resources - * @pdev: PCI device whose resources are to be reserved - * @res_name: Name to be associated with resource. + * pci_request_regions_exclusive - Reserve PCI I/O and memory resources + * @pdev: PCI device whose resources are to be reserved + * @res_name: Name to be associated with resource. * - * Mark all PCI regions associated with PCI device @pdev as - * being reserved by owner @res_name. Do not access any - * address inside the PCI regions unless this call returns - * successfully. + * Mark all PCI regions associated with PCI device @pdev as being reserved + * by owner @res_name. Do not access any address inside the PCI regions + * unless this call returns successfully. * - * pci_request_regions_exclusive() will mark the region so that - * /dev/mem and the sysfs MMIO access will not be allowed. + * pci_request_regions_exclusive() will mark the region so that /dev/mem + * and the sysfs MMIO access will not be allowed. * - * Returns 0 on success, or %EBUSY on error. A warning - * message is also printed on failure. + * Returns 0 on success, or %EBUSY on error. A warning message is also + * printed on failure. */ int pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_name) { @@ -3849,7 +3872,7 @@ EXPORT_SYMBOL(pci_request_regions_exclusive); /* * Record the PCI IO range (expressed as CPU physical address + size). - * Return a negative value if an error has occured, zero otherwise + * Return a negative value if an error has occurred, zero otherwise */ int pci_register_io_range(struct fwnode_handle *fwnode, phys_addr_t addr, resource_size_t size) @@ -3905,14 +3928,14 @@ unsigned long __weak pci_address_to_pio(phys_addr_t address) } /** - * pci_remap_iospace - Remap the memory mapped I/O space - * @res: Resource describing the I/O space - * @phys_addr: physical address of range to be mapped + * pci_remap_iospace - Remap the memory mapped I/O space + * @res: Resource describing the I/O space + * @phys_addr: physical address of range to be mapped * - * Remap the memory mapped I/O space described by the @res - * and the CPU physical address @phys_addr into virtual address space. - * Only architectures that have memory mapped IO functions defined - * (and the PCI_IOBASE value defined) should call this function. + * Remap the memory mapped I/O space described by the @res and the CPU + * physical address @phys_addr into virtual address space. Only + * architectures that have memory mapped IO functions defined (and the + * PCI_IOBASE value defined) should call this function. */ int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr) { @@ -3928,8 +3951,10 @@ int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr) return ioremap_page_range(vaddr, vaddr + resource_size(res), phys_addr, pgprot_device(PAGE_KERNEL)); #else - /* this architecture does not have memory mapped I/O space, - so this function should never be called */ + /* + * This architecture does not have memory mapped I/O space, + * so this function should never be called + */ WARN_ONCE(1, "This architecture does not support memory mapped I/O\n"); return -ENODEV; #endif @@ -3937,12 +3962,12 @@ int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr) EXPORT_SYMBOL(pci_remap_iospace); /** - * pci_unmap_iospace - Unmap the memory mapped I/O space - * @res: resource to be unmapped + * pci_unmap_iospace - Unmap the memory mapped I/O space + * @res: resource to be unmapped * - * Unmap the CPU virtual address @res from virtual address space. - * Only architectures that have memory mapped IO functions defined - * (and the PCI_IOBASE value defined) should call this function. + * Unmap the CPU virtual address @res from virtual address space. Only + * architectures that have memory mapped IO functions defined (and the + * PCI_IOBASE value defined) should call this function. */ void pci_unmap_iospace(struct resource *res) { @@ -4185,7 +4210,7 @@ int pci_set_cacheline_size(struct pci_dev *dev) if (cacheline_size == pci_cache_line_size) return 0; - pci_printk(KERN_DEBUG, dev, "cache line size of %d is not supported\n", + pci_info(dev, "cache line size of %d is not supported\n", pci_cache_line_size << 2); return -EINVAL; @@ -4288,7 +4313,7 @@ EXPORT_SYMBOL(pci_clear_mwi); * @pdev: the PCI device to operate on * @enable: boolean: whether to enable or disable PCI INTx * - * Enables/disables PCI INTx for device dev + * Enables/disables PCI INTx for device @pdev */ void pci_intx(struct pci_dev *pdev, int enable) { @@ -4364,9 +4389,8 @@ done: * pci_check_and_mask_intx - mask INTx on pending interrupt * @dev: the PCI device to operate on * - * Check if the device dev has its INTx line asserted, mask it and - * return true in that case. False is returned if no interrupt was - * pending. + * Check if the device dev has its INTx line asserted, mask it and return + * true in that case. False is returned if no interrupt was pending. */ bool pci_check_and_mask_intx(struct pci_dev *dev) { @@ -4378,9 +4402,9 @@ EXPORT_SYMBOL_GPL(pci_check_and_mask_intx); * pci_check_and_unmask_intx - unmask INTx if no interrupt is pending * @dev: the PCI device to operate on * - * Check if the device dev has its INTx line asserted, unmask it if not - * and return true. False is returned and the mask remains active if - * there was still an interrupt pending. + * Check if the device dev has its INTx line asserted, unmask it if not and + * return true. False is returned and the mask remains active if there was + * still an interrupt pending. */ bool pci_check_and_unmask_intx(struct pci_dev *dev) { @@ -4389,7 +4413,7 @@ bool pci_check_and_unmask_intx(struct pci_dev *dev) EXPORT_SYMBOL_GPL(pci_check_and_unmask_intx); /** - * pci_wait_for_pending_transaction - waits for pending transaction + * pci_wait_for_pending_transaction - wait for pending transaction * @dev: the PCI device to operate on * * Return 0 if transaction is pending 1 otherwise. @@ -4447,7 +4471,7 @@ static int pci_dev_wait(struct pci_dev *dev, char *reset_type, int timeout) /** * pcie_has_flr - check if a device supports function level resets - * @dev: device to check + * @dev: device to check * * Returns true if the device advertises support for PCIe function level * resets. @@ -4466,7 +4490,7 @@ EXPORT_SYMBOL_GPL(pcie_has_flr); /** * pcie_flr - initiate a PCIe function level reset - * @dev: device to reset + * @dev: device to reset * * Initiate a function level reset on @dev. The caller should ensure the * device supports FLR before calling this function, e.g. by using the @@ -4514,7 +4538,7 @@ static int pci_af_flr(struct pci_dev *dev, int probe) /* * Wait for Transaction Pending bit to clear. A word-aligned test - * is used, so we use the conrol offset rather than status and shift + * is used, so we use the control offset rather than status and shift * the test bit to match. */ if (!pci_wait_for_pending(dev, pos + PCI_AF_CTRL, @@ -4810,6 +4834,7 @@ static void pci_dev_restore(struct pci_dev *dev) * * The device function is presumed to be unused and the caller is holding * the device mutex lock when this function is called. + * * Resetting the device will make the contents of PCI configuration space * random, so any caller of this must be prepared to reinitialise the * device including MSI, bus mastering, BARs, decoding IO and memory spaces, @@ -5373,8 +5398,8 @@ EXPORT_SYMBOL_GPL(pci_reset_bus); * pcix_get_max_mmrbc - get PCI-X maximum designed memory read byte count * @dev: PCI device to query * - * Returns mmrbc: maximum designed memory read count in bytes - * or appropriate error value. + * Returns mmrbc: maximum designed memory read count in bytes or + * appropriate error value. */ int pcix_get_max_mmrbc(struct pci_dev *dev) { @@ -5396,8 +5421,8 @@ EXPORT_SYMBOL(pcix_get_max_mmrbc); * pcix_get_mmrbc - get PCI-X maximum memory read byte count * @dev: PCI device to query * - * Returns mmrbc: maximum memory read count in bytes - * or appropriate error value. + * Returns mmrbc: maximum memory read count in bytes or appropriate error + * value. */ int pcix_get_mmrbc(struct pci_dev *dev) { @@ -5421,7 +5446,7 @@ EXPORT_SYMBOL(pcix_get_mmrbc); * @mmrbc: maximum memory read count in bytes * valid values are 512, 1024, 2048, 4096 * - * If possible sets maximum memory read byte count, some bridges have erratas + * If possible sets maximum memory read byte count, some bridges have errata * that prevent this. */ int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) @@ -5466,8 +5491,7 @@ EXPORT_SYMBOL(pcix_set_mmrbc); * pcie_get_readrq - get PCI Express read request size * @dev: PCI device to query * - * Returns maximum memory read request in bytes - * or appropriate error value. + * Returns maximum memory read request in bytes or appropriate error value. */ int pcie_get_readrq(struct pci_dev *dev) { @@ -5495,10 +5519,9 @@ int pcie_set_readrq(struct pci_dev *dev, int rq) return -EINVAL; /* - * If using the "performance" PCIe config, we clamp the - * read rq size to the max packet size to prevent the - * host bridge generating requests larger than we can - * cope with + * If using the "performance" PCIe config, we clamp the read rq + * size to the max packet size to keep the host bridge from + * generating requests larger than we can cope with. */ if (pcie_bus_config == PCIE_BUS_PERFORMANCE) { int mps = pcie_get_mps(dev); @@ -5635,7 +5658,9 @@ enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev) */ pcie_capability_read_dword(dev, PCI_EXP_LNKCAP2, &lnkcap2); if (lnkcap2) { /* PCIe r3.0-compliant */ - if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_16_0GB) + if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_32_0GB) + return PCIE_SPEED_32_0GT; + else if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_16_0GB) return PCIE_SPEED_16_0GT; else if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_8_0GB) return PCIE_SPEED_8_0GT; @@ -5829,6 +5854,24 @@ int pci_set_vga_state(struct pci_dev *dev, bool decode, return 0; } +#ifdef CONFIG_ACPI +bool pci_pr3_present(struct pci_dev *pdev) +{ + struct acpi_device *adev; + + if (acpi_disabled) + return false; + + adev = ACPI_COMPANION(&pdev->dev); + if (!adev) + return false; + + return adev->power.flags.power_resources && + acpi_has_method(adev->handle, "_PR3"); +} +EXPORT_SYMBOL_GPL(pci_pr3_present); +#endif + /** * pci_add_dma_alias - Add a DMA devfn alias for a device * @dev: the PCI device for which alias is added @@ -5896,8 +5939,19 @@ resource_size_t __weak pcibios_default_alignment(void) return 0; } -#define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE -static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0}; +/* + * Arches that don't want to expose struct resource to userland as-is in + * sysfs and /proc can implement their own pci_resource_to_user(). + */ +void __weak pci_resource_to_user(const struct pci_dev *dev, int bar, + const struct resource *rsrc, + resource_size_t *start, resource_size_t *end) +{ + *start = rsrc->start; + *end = rsrc->end; +} + +static char *resource_alignment_param; static DEFINE_SPINLOCK(resource_alignment_lock); /** @@ -5918,7 +5972,7 @@ static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev, spin_lock(&resource_alignment_lock); p = resource_alignment_param; - if (!*p && !align) + if (!p || !*p) goto out; if (pci_has_flag(PCI_PROBE_ONLY)) { align = 0; @@ -6082,35 +6136,41 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev) } } -static ssize_t pci_set_resource_alignment_param(const char *buf, size_t count) +static ssize_t resource_alignment_show(struct bus_type *bus, char *buf) { - if (count > RESOURCE_ALIGNMENT_PARAM_SIZE - 1) - count = RESOURCE_ALIGNMENT_PARAM_SIZE - 1; - spin_lock(&resource_alignment_lock); - strncpy(resource_alignment_param, buf, count); - resource_alignment_param[count] = '\0'; - spin_unlock(&resource_alignment_lock); - return count; -} + size_t count = 0; -static ssize_t pci_get_resource_alignment_param(char *buf, size_t size) -{ - size_t count; spin_lock(&resource_alignment_lock); - count = snprintf(buf, size, "%s", resource_alignment_param); + if (resource_alignment_param) + count = snprintf(buf, PAGE_SIZE, "%s", resource_alignment_param); spin_unlock(&resource_alignment_lock); - return count; -} -static ssize_t resource_alignment_show(struct bus_type *bus, char *buf) -{ - return pci_get_resource_alignment_param(buf, PAGE_SIZE); + /* + * When set by the command line, resource_alignment_param will not + * have a trailing line feed, which is ugly. So conditionally add + * it here. + */ + if (count >= 2 && buf[count - 2] != '\n' && count < PAGE_SIZE - 1) { + buf[count - 1] = '\n'; + buf[count++] = 0; + } + + return count; } static ssize_t resource_alignment_store(struct bus_type *bus, const char *buf, size_t count) { - return pci_set_resource_alignment_param(buf, count); + char *param = kstrndup(buf, count, GFP_KERNEL); + + if (!param) + return -ENOMEM; + + spin_lock(&resource_alignment_lock); + kfree(resource_alignment_param); + resource_alignment_param = param; + spin_unlock(&resource_alignment_lock); + return count; } static BUS_ATTR_RW(resource_alignment); @@ -6144,6 +6204,7 @@ static int of_pci_bus_find_domain_nr(struct device *parent) if (parent) domain = of_get_pci_domain_nr(parent->of_node); + /* * Check DT domain and use_dt_domains values. * @@ -6238,8 +6299,7 @@ static int __init pci_setup(char *str) } else if (!strncmp(str, "cbmemsize=", 10)) { pci_cardbus_mem_size = memparse(str + 10, &str); } else if (!strncmp(str, "resource_alignment=", 19)) { - pci_set_resource_alignment_param(str + 19, - strlen(str + 19)); + resource_alignment_param = str + 19; } else if (!strncmp(str, "ecrc=", 5)) { pcie_ecrc_get_policy(str + 5); } else if (!strncmp(str, "hpiosize=", 9)) { @@ -6262,11 +6322,9 @@ static int __init pci_setup(char *str) } else if (!strncmp(str, "pcie_scan_all", 13)) { pci_add_flags(PCI_SCAN_ALL_PCIE_DEVS); } else if (!strncmp(str, "disable_acs_redir=", 18)) { - disable_acs_redir_param = - kstrdup(str + 18, GFP_KERNEL); + disable_acs_redir_param = str + 18; } else { - printk(KERN_ERR "PCI: Unknown option `%s'\n", - str); + pr_err("PCI: Unknown option `%s'\n", str); } } str = k; @@ -6274,3 +6332,22 @@ static int __init pci_setup(char *str) return 0; } early_param("pci", pci_setup); + +/* + * 'resource_alignment_param' and 'disable_acs_redir_param' are initialized + * in pci_setup(), above, to point to data in the __initdata section which + * will be freed after the init sequence is complete. We can't allocate memory + * in pci_setup() because some architectures do not have any memory allocation + * service available during an early_param() call. So we allocate memory and + * copy the variable here before the init section is freed. + * + */ +static int __init pci_realloc_setup_params(void) +{ + resource_alignment_param = kstrdup(resource_alignment_param, + GFP_KERNEL); + disable_acs_redir_param = kstrdup(disable_acs_redir_param, GFP_KERNEL); + + return 0; +} +pure_initcall(pci_realloc_setup_params); |