aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2013-08-15 16:41:33 -0400
committerBjorn Helgaas <bhelgaas@google.com>2013-08-15 16:41:33 -0400
commit7d8c4a2c5ae6d76f1142fb052d698b3c40ce518c (patch)
treee5f4d7779bd2e6b4e9ccc3e73d5c40bb537513e8 /drivers
parent63ef41811b86432101b4627ff07c9671f93a483f (diff)
parent9a3d2b9beefd5b07c1d8f70ded01b88f203ee304 (diff)
Merge branch 'pci/aw-reset-v5' into next
* pci/aw-reset-v5: PCI: Add pci_probe_reset_slot() and pci_probe_reset_bus() PCI: Remove aer_do_secondary_bus_reset() PCI: Tune secondary bus reset timing PCI: Wake-up devices before saving config space for reset PCI: Add pci_reset_slot() and pci_reset_bus() PCI: Split out pci_dev lock/unlock and save/restore PCI: Add slot reset option to pci_dev_reset() PCI: pciehp: Add reset_slot() method PCI: Add hotplug_slot_ops.reset_slot() PCI: Add pci_reset_bridge_secondary_bus()
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/hotplug/pciehp.h1
-rw-r--r--drivers/pci/hotplug/pciehp_core.c12
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c31
-rw-r--r--drivers/pci/pci.c373
-rw-r--r--drivers/pci/pcie/aer/aerdrv.c2
-rw-r--r--drivers/pci/pcie/aer/aerdrv.h1
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c35
7 files changed, 393 insertions, 62 deletions
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 7fb326983ed6..541bbe6d5343 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -155,6 +155,7 @@ void pciehp_green_led_off(struct slot *slot);
155void pciehp_green_led_blink(struct slot *slot); 155void pciehp_green_led_blink(struct slot *slot);
156int pciehp_check_link_status(struct controller *ctrl); 156int pciehp_check_link_status(struct controller *ctrl);
157void pciehp_release_ctrl(struct controller *ctrl); 157void pciehp_release_ctrl(struct controller *ctrl);
158int pciehp_reset_slot(struct slot *slot, int probe);
158 159
159static inline const char *slot_name(struct slot *slot) 160static inline const char *slot_name(struct slot *slot)
160{ 161{
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 7d72c5e2eba9..f4a18f51a29c 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -69,6 +69,7 @@ static int get_power_status (struct hotplug_slot *slot, u8 *value);
69static int get_attention_status (struct hotplug_slot *slot, u8 *value); 69static int get_attention_status (struct hotplug_slot *slot, u8 *value);
70static int get_latch_status (struct hotplug_slot *slot, u8 *value); 70static int get_latch_status (struct hotplug_slot *slot, u8 *value);
71static int get_adapter_status (struct hotplug_slot *slot, u8 *value); 71static int get_adapter_status (struct hotplug_slot *slot, u8 *value);
72static int reset_slot (struct hotplug_slot *slot, int probe);
72 73
73/** 74/**
74 * release_slot - free up the memory used by a slot 75 * release_slot - free up the memory used by a slot
@@ -111,6 +112,7 @@ static int init_slot(struct controller *ctrl)
111 ops->disable_slot = disable_slot; 112 ops->disable_slot = disable_slot;
112 ops->get_power_status = get_power_status; 113 ops->get_power_status = get_power_status;
113 ops->get_adapter_status = get_adapter_status; 114 ops->get_adapter_status = get_adapter_status;
115 ops->reset_slot = reset_slot;
114 if (MRL_SENS(ctrl)) 116 if (MRL_SENS(ctrl))
115 ops->get_latch_status = get_latch_status; 117 ops->get_latch_status = get_latch_status;
116 if (ATTN_LED(ctrl)) { 118 if (ATTN_LED(ctrl)) {
@@ -223,6 +225,16 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
223 return pciehp_get_adapter_status(slot, value); 225 return pciehp_get_adapter_status(slot, value);
224} 226}
225 227
228static int reset_slot(struct hotplug_slot *hotplug_slot, int probe)
229{
230 struct slot *slot = hotplug_slot->private;
231
232 ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
233 __func__, slot_name(slot));
234
235 return pciehp_reset_slot(slot, probe);
236}
237
226static int pciehp_probe(struct pcie_device *dev) 238static int pciehp_probe(struct pcie_device *dev)
227{ 239{
228 int rc; 240 int rc;
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index b2255736ac81..51f56ef4ab6f 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -749,6 +749,37 @@ static void pcie_disable_notification(struct controller *ctrl)
749 ctrl_warn(ctrl, "Cannot disable software notification\n"); 749 ctrl_warn(ctrl, "Cannot disable software notification\n");
750} 750}
751 751
752/*
753 * pciehp has a 1:1 bus:slot relationship so we ultimately want a secondary
754 * bus reset of the bridge, but if the slot supports surprise removal we need
755 * to disable presence detection around the bus reset and clear any spurious
756 * events after.
757 */
758int pciehp_reset_slot(struct slot *slot, int probe)
759{
760 struct controller *ctrl = slot->ctrl;
761
762 if (probe)
763 return 0;
764
765 if (HP_SUPR_RM(ctrl)) {
766 pcie_write_cmd(ctrl, 0, PCI_EXP_SLTCTL_PDCE);
767 if (pciehp_poll_mode)
768 del_timer_sync(&ctrl->poll_timer);
769 }
770
771 pci_reset_bridge_secondary_bus(ctrl->pcie->port);
772
773 if (HP_SUPR_RM(ctrl)) {
774 pciehp_writew(ctrl, PCI_EXP_SLTSTA, PCI_EXP_SLTSTA_PDC);
775 pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PDCE, PCI_EXP_SLTCTL_PDCE);
776 if (pciehp_poll_mode)
777 int_poll_timeout(ctrl->poll_timer.data);
778 }
779
780 return 0;
781}
782
752int pcie_init_notification(struct controller *ctrl) 783int pcie_init_notification(struct controller *ctrl)
753{ 784{
754 if (pciehp_request_irq(ctrl)) 785 if (pciehp_request_irq(ctrl))
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 7d6ce2ec04ec..10e3c4e15178 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -22,6 +22,7 @@
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/device.h> 23#include <linux/device.h>
24#include <linux/pm_runtime.h> 24#include <linux/pm_runtime.h>
25#include <linux/pci_hotplug.h>
25#include <asm-generic/pci-bridge.h> 26#include <asm-generic/pci-bridge.h>
26#include <asm/setup.h> 27#include <asm/setup.h>
27#include "pci.h" 28#include "pci.h"
@@ -3288,9 +3289,42 @@ static int pci_pm_reset(struct pci_dev *dev, int probe)
3288 return 0; 3289 return 0;
3289} 3290}
3290 3291
3291static int pci_parent_bus_reset(struct pci_dev *dev, int probe) 3292/**
3293 * pci_reset_bridge_secondary_bus - Reset the secondary bus on a PCI bridge.
3294 * @dev: Bridge device
3295 *
3296 * Use the bridge control register to assert reset on the secondary bus.
3297 * Devices on the secondary bus are left in power-on state.
3298 */
3299void pci_reset_bridge_secondary_bus(struct pci_dev *dev)
3292{ 3300{
3293 u16 ctrl; 3301 u16 ctrl;
3302
3303 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &ctrl);
3304 ctrl |= PCI_BRIDGE_CTL_BUS_RESET;
3305 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ctrl);
3306 /*
3307 * PCI spec v3.0 7.6.4.2 requires minimum Trst of 1ms. Double
3308 * this to 2ms to ensure that we meet the minium requirement.
3309 */
3310 msleep(2);
3311
3312 ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
3313 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ctrl);
3314
3315 /*
3316 * Trhfa for conventional PCI is 2^25 clock cycles.
3317 * Assuming a minimum 33MHz clock this results in a 1s
3318 * delay before we can consider subordinate devices to
3319 * be re-initialized. PCIe has some ways to shorten this,
3320 * but we don't make use of them yet.
3321 */
3322 ssleep(1);
3323}
3324EXPORT_SYMBOL_GPL(pci_reset_bridge_secondary_bus);
3325
3326static int pci_parent_bus_reset(struct pci_dev *dev, int probe)
3327{
3294 struct pci_dev *pdev; 3328 struct pci_dev *pdev;
3295 3329
3296 if (pci_is_root_bus(dev->bus) || dev->subordinate || !dev->bus->self) 3330 if (pci_is_root_bus(dev->bus) || dev->subordinate || !dev->bus->self)
@@ -3303,18 +3337,40 @@ static int pci_parent_bus_reset(struct pci_dev *dev, int probe)
3303 if (probe) 3337 if (probe)
3304 return 0; 3338 return 0;
3305 3339
3306 pci_read_config_word(dev->bus->self, PCI_BRIDGE_CONTROL, &ctrl); 3340 pci_reset_bridge_secondary_bus(dev->bus->self);
3307 ctrl |= PCI_BRIDGE_CTL_BUS_RESET;
3308 pci_write_config_word(dev->bus->self, PCI_BRIDGE_CONTROL, ctrl);
3309 msleep(100);
3310
3311 ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
3312 pci_write_config_word(dev->bus->self, PCI_BRIDGE_CONTROL, ctrl);
3313 msleep(100);
3314 3341
3315 return 0; 3342 return 0;
3316} 3343}
3317 3344
3345static int pci_reset_hotplug_slot(struct hotplug_slot *hotplug, int probe)
3346{
3347 int rc = -ENOTTY;
3348
3349 if (!hotplug || !try_module_get(hotplug->ops->owner))
3350 return rc;
3351
3352 if (hotplug->ops->reset_slot)
3353 rc = hotplug->ops->reset_slot(hotplug, probe);
3354
3355 module_put(hotplug->ops->owner);
3356
3357 return rc;
3358}
3359
3360static int pci_dev_reset_slot_function(struct pci_dev *dev, int probe)
3361{
3362 struct pci_dev *pdev;
3363
3364 if (dev->subordinate || !dev->slot)
3365 return -ENOTTY;
3366
3367 list_for_each_entry(pdev, &dev->bus->devices, bus_list)
3368 if (pdev != dev && pdev->slot == dev->slot)
3369 return -ENOTTY;
3370
3371 return pci_reset_hotplug_slot(dev->slot->hotplug, probe);
3372}
3373
3318static int __pci_dev_reset(struct pci_dev *dev, int probe) 3374static int __pci_dev_reset(struct pci_dev *dev, int probe)
3319{ 3375{
3320 int rc; 3376 int rc;
@@ -3337,27 +3393,65 @@ static int __pci_dev_reset(struct pci_dev *dev, int probe)
3337 if (rc != -ENOTTY) 3393 if (rc != -ENOTTY)
3338 goto done; 3394 goto done;
3339 3395
3396 rc = pci_dev_reset_slot_function(dev, probe);
3397 if (rc != -ENOTTY)
3398 goto done;
3399
3340 rc = pci_parent_bus_reset(dev, probe); 3400 rc = pci_parent_bus_reset(dev, probe);
3341done: 3401done:
3342 return rc; 3402 return rc;
3343} 3403}
3344 3404
3405static void pci_dev_lock(struct pci_dev *dev)
3406{
3407 pci_cfg_access_lock(dev);
3408 /* block PM suspend, driver probe, etc. */
3409 device_lock(&dev->dev);
3410}
3411
3412static void pci_dev_unlock(struct pci_dev *dev)
3413{
3414 device_unlock(&dev->dev);
3415 pci_cfg_access_unlock(dev);
3416}
3417
3418static void pci_dev_save_and_disable(struct pci_dev *dev)
3419{
3420 /*
3421 * Wake-up device prior to save. PM registers default to D0 after
3422 * reset and a simple register restore doesn't reliably return
3423 * to a non-D0 state anyway.
3424 */
3425 pci_set_power_state(dev, PCI_D0);
3426
3427 pci_save_state(dev);
3428 /*
3429 * Disable the device by clearing the Command register, except for
3430 * INTx-disable which is set. This not only disables MMIO and I/O port
3431 * BARs, but also prevents the device from being Bus Master, preventing
3432 * DMA from the device including MSI/MSI-X interrupts. For PCI 2.3
3433 * compliant devices, INTx-disable prevents legacy interrupts.
3434 */
3435 pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE);
3436}
3437
3438static void pci_dev_restore(struct pci_dev *dev)
3439{
3440 pci_restore_state(dev);
3441}
3442
3345static int pci_dev_reset(struct pci_dev *dev, int probe) 3443static int pci_dev_reset(struct pci_dev *dev, int probe)
3346{ 3444{
3347 int rc; 3445 int rc;
3348 3446
3349 if (!probe) { 3447 if (!probe)
3350 pci_cfg_access_lock(dev); 3448 pci_dev_lock(dev);
3351 /* block PM suspend, driver probe, etc. */
3352 device_lock(&dev->dev);
3353 }
3354 3449
3355 rc = __pci_dev_reset(dev, probe); 3450 rc = __pci_dev_reset(dev, probe);
3356 3451
3357 if (!probe) { 3452 if (!probe)
3358 device_unlock(&dev->dev); 3453 pci_dev_unlock(dev);
3359 pci_cfg_access_unlock(dev); 3454
3360 }
3361 return rc; 3455 return rc;
3362} 3456}
3363/** 3457/**
@@ -3448,22 +3542,249 @@ int pci_reset_function(struct pci_dev *dev)
3448 if (rc) 3542 if (rc)
3449 return rc; 3543 return rc;
3450 3544
3451 pci_save_state(dev); 3545 pci_dev_save_and_disable(dev);
3452
3453 /*
3454 * both INTx and MSI are disabled after the Interrupt Disable bit
3455 * is set and the Bus Master bit is cleared.
3456 */
3457 pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE);
3458 3546
3459 rc = pci_dev_reset(dev, 0); 3547 rc = pci_dev_reset(dev, 0);
3460 3548
3461 pci_restore_state(dev); 3549 pci_dev_restore(dev);
3462 3550
3463 return rc; 3551 return rc;
3464} 3552}
3465EXPORT_SYMBOL_GPL(pci_reset_function); 3553EXPORT_SYMBOL_GPL(pci_reset_function);
3466 3554
3555/* Lock devices from the top of the tree down */
3556static void pci_bus_lock(struct pci_bus *bus)
3557{
3558 struct pci_dev *dev;
3559
3560 list_for_each_entry(dev, &bus->devices, bus_list) {
3561 pci_dev_lock(dev);
3562 if (dev->subordinate)
3563 pci_bus_lock(dev->subordinate);
3564 }
3565}
3566
3567/* Unlock devices from the bottom of the tree up */
3568static void pci_bus_unlock(struct pci_bus *bus)
3569{
3570 struct pci_dev *dev;
3571
3572 list_for_each_entry(dev, &bus->devices, bus_list) {
3573 if (dev->subordinate)
3574 pci_bus_unlock(dev->subordinate);
3575 pci_dev_unlock(dev);
3576 }
3577}
3578
3579/* Lock devices from the top of the tree down */
3580static void pci_slot_lock(struct pci_slot *slot)
3581{
3582 struct pci_dev *dev;
3583
3584 list_for_each_entry(dev, &slot->bus->devices, bus_list) {
3585 if (!dev->slot || dev->slot != slot)
3586 continue;
3587 pci_dev_lock(dev);
3588 if (dev->subordinate)
3589 pci_bus_lock(dev->subordinate);
3590 }
3591}
3592
3593/* Unlock devices from the bottom of the tree up */
3594static void pci_slot_unlock(struct pci_slot *slot)
3595{
3596 struct pci_dev *dev;
3597
3598 list_for_each_entry(dev, &slot->bus->devices, bus_list) {
3599 if (!dev->slot || dev->slot != slot)
3600 continue;
3601 if (dev->subordinate)
3602 pci_bus_unlock(dev->subordinate);
3603 pci_dev_unlock(dev);
3604 }
3605}
3606
3607/* Save and disable devices from the top of the tree down */
3608static void pci_bus_save_and_disable(struct pci_bus *bus)
3609{
3610 struct pci_dev *dev;
3611
3612 list_for_each_entry(dev, &bus->devices, bus_list) {
3613 pci_dev_save_and_disable(dev);
3614 if (dev->subordinate)
3615 pci_bus_save_and_disable(dev->subordinate);
3616 }
3617}
3618
3619/*
3620 * Restore devices from top of the tree down - parent bridges need to be
3621 * restored before we can get to subordinate devices.
3622 */
3623static void pci_bus_restore(struct pci_bus *bus)
3624{
3625 struct pci_dev *dev;
3626
3627 list_for_each_entry(dev, &bus->devices, bus_list) {
3628 pci_dev_restore(dev);
3629 if (dev->subordinate)
3630 pci_bus_restore(dev->subordinate);
3631 }
3632}
3633
3634/* Save and disable devices from the top of the tree down */
3635static void pci_slot_save_and_disable(struct pci_slot *slot)
3636{
3637 struct pci_dev *dev;
3638
3639 list_for_each_entry(dev, &slot->bus->devices, bus_list) {
3640 if (!dev->slot || dev->slot != slot)
3641 continue;
3642 pci_dev_save_and_disable(dev);
3643 if (dev->subordinate)
3644 pci_bus_save_and_disable(dev->subordinate);
3645 }
3646}
3647
3648/*
3649 * Restore devices from top of the tree down - parent bridges need to be
3650 * restored before we can get to subordinate devices.
3651 */
3652static void pci_slot_restore(struct pci_slot *slot)
3653{
3654 struct pci_dev *dev;
3655
3656 list_for_each_entry(dev, &slot->bus->devices, bus_list) {
3657 if (!dev->slot || dev->slot != slot)
3658 continue;
3659 pci_dev_restore(dev);
3660 if (dev->subordinate)
3661 pci_bus_restore(dev->subordinate);
3662 }
3663}
3664
3665static int pci_slot_reset(struct pci_slot *slot, int probe)
3666{
3667 int rc;
3668
3669 if (!slot)
3670 return -ENOTTY;
3671
3672 if (!probe)
3673 pci_slot_lock(slot);
3674
3675 might_sleep();
3676
3677 rc = pci_reset_hotplug_slot(slot->hotplug, probe);
3678
3679 if (!probe)
3680 pci_slot_unlock(slot);
3681
3682 return rc;
3683}
3684
3685/**
3686 * pci_probe_reset_slot - probe whether a PCI slot can be reset
3687 * @slot: PCI slot to probe
3688 *
3689 * Return 0 if slot can be reset, negative if a slot reset is not supported.
3690 */
3691int pci_probe_reset_slot(struct pci_slot *slot)
3692{
3693 return pci_slot_reset(slot, 1);
3694}
3695EXPORT_SYMBOL_GPL(pci_probe_reset_slot);
3696
3697/**
3698 * pci_reset_slot - reset a PCI slot
3699 * @slot: PCI slot to reset
3700 *
3701 * A PCI bus may host multiple slots, each slot may support a reset mechanism
3702 * independent of other slots. For instance, some slots may support slot power
3703 * control. In the case of a 1:1 bus to slot architecture, this function may
3704 * wrap the bus reset to avoid spurious slot related events such as hotplug.
3705 * Generally a slot reset should be attempted before a bus reset. All of the
3706 * function of the slot and any subordinate buses behind the slot are reset
3707 * through this function. PCI config space of all devices in the slot and
3708 * behind the slot is saved before and restored after reset.
3709 *
3710 * Return 0 on success, non-zero on error.
3711 */
3712int pci_reset_slot(struct pci_slot *slot)
3713{
3714 int rc;
3715
3716 rc = pci_slot_reset(slot, 1);
3717 if (rc)
3718 return rc;
3719
3720 pci_slot_save_and_disable(slot);
3721
3722 rc = pci_slot_reset(slot, 0);
3723
3724 pci_slot_restore(slot);
3725
3726 return rc;
3727}
3728EXPORT_SYMBOL_GPL(pci_reset_slot);
3729
3730static int pci_bus_reset(struct pci_bus *bus, int probe)
3731{
3732 if (!bus->self)
3733 return -ENOTTY;
3734
3735 if (probe)
3736 return 0;
3737
3738 pci_bus_lock(bus);
3739
3740 might_sleep();
3741
3742 pci_reset_bridge_secondary_bus(bus->self);
3743
3744 pci_bus_unlock(bus);
3745
3746 return 0;
3747}
3748
3749/**
3750 * pci_probe_reset_bus - probe whether a PCI bus can be reset
3751 * @bus: PCI bus to probe
3752 *
3753 * Return 0 if bus can be reset, negative if a bus reset is not supported.
3754 */
3755int pci_probe_reset_bus(struct pci_bus *bus)
3756{
3757 return pci_bus_reset(bus, 1);
3758}
3759EXPORT_SYMBOL_GPL(pci_probe_reset_bus);
3760
3761/**
3762 * pci_reset_bus - reset a PCI bus
3763 * @bus: top level PCI bus to reset
3764 *
3765 * Do a bus reset on the given bus and any subordinate buses, saving
3766 * and restoring state of all devices.
3767 *
3768 * Return 0 on success, non-zero on error.
3769 */
3770int pci_reset_bus(struct pci_bus *bus)
3771{
3772 int rc;
3773
3774 rc = pci_bus_reset(bus, 1);
3775 if (rc)
3776 return rc;
3777
3778 pci_bus_save_and_disable(bus);
3779
3780 rc = pci_bus_reset(bus, 0);
3781
3782 pci_bus_restore(bus);
3783
3784 return rc;
3785}
3786EXPORT_SYMBOL_GPL(pci_reset_bus);
3787
3467/** 3788/**
3468 * pcix_get_max_mmrbc - get PCI-X maximum designed memory read byte count 3789 * pcix_get_max_mmrbc - get PCI-X maximum designed memory read byte count
3469 * @dev: PCI device to query 3790 * @dev: PCI device to query
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index 76ef634caf6f..0bf82a20a0fb 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -352,7 +352,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
352 reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK; 352 reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK;
353 pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, reg32); 353 pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, reg32);
354 354
355 aer_do_secondary_bus_reset(dev); 355 pci_reset_bridge_secondary_bus(dev);
356 dev_printk(KERN_DEBUG, &dev->dev, "Root Port link has been reset\n"); 356 dev_printk(KERN_DEBUG, &dev->dev, "Root Port link has been reset\n");
357 357
358 /* Clear Root Error Status */ 358 /* Clear Root Error Status */
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h
index 90ea3e88041f..84420b7c9456 100644
--- a/drivers/pci/pcie/aer/aerdrv.h
+++ b/drivers/pci/pcie/aer/aerdrv.h
@@ -106,7 +106,6 @@ static inline pci_ers_result_t merge_result(enum pci_ers_result orig,
106} 106}
107 107
108extern struct bus_type pcie_port_bus_type; 108extern struct bus_type pcie_port_bus_type;
109void aer_do_secondary_bus_reset(struct pci_dev *dev);
110int aer_init(struct pcie_device *dev); 109int aer_init(struct pcie_device *dev);
111void aer_isr(struct work_struct *work); 110void aer_isr(struct work_struct *work);
112void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); 111void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 8b68ae59b7b6..85ca36f2136d 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -367,39 +367,6 @@ static pci_ers_result_t broadcast_error_message(struct pci_dev *dev,
367} 367}
368 368
369/** 369/**
370 * aer_do_secondary_bus_reset - perform secondary bus reset
371 * @dev: pointer to bridge's pci_dev data structure
372 *
373 * Invoked when performing link reset at Root Port or Downstream Port.
374 */
375void aer_do_secondary_bus_reset(struct pci_dev *dev)
376{
377 u16 p2p_ctrl;
378
379 /* Assert Secondary Bus Reset */
380 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &p2p_ctrl);
381 p2p_ctrl |= PCI_BRIDGE_CTL_BUS_RESET;
382 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl);
383
384 /*
385 * we should send hot reset message for 2ms to allow it time to
386 * propagate to all downstream ports
387 */
388 msleep(2);
389
390 /* De-assert Secondary Bus Reset */
391 p2p_ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
392 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl);
393
394 /*
395 * System software must wait for at least 100ms from the end
396 * of a reset of one or more device before it is permitted
397 * to issue Configuration Requests to those devices.
398 */
399 msleep(200);
400}
401
402/**
403 * default_reset_link - default reset function 370 * default_reset_link - default reset function
404 * @dev: pointer to pci_dev data structure 371 * @dev: pointer to pci_dev data structure
405 * 372 *
@@ -408,7 +375,7 @@ void aer_do_secondary_bus_reset(struct pci_dev *dev)
408 */ 375 */
409static pci_ers_result_t default_reset_link(struct pci_dev *dev) 376static pci_ers_result_t default_reset_link(struct pci_dev *dev)
410{ 377{
411 aer_do_secondary_bus_reset(dev); 378 pci_reset_bridge_secondary_bus(dev);
412 dev_printk(KERN_DEBUG, &dev->dev, "downstream link has been reset\n"); 379 dev_printk(KERN_DEBUG, &dev->dev, "downstream link has been reset\n");
413 return PCI_ERS_RESULT_RECOVERED; 380 return PCI_ERS_RESULT_RECOVERED;
414} 381}