aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pcie
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/pcie')
-rw-r--r--drivers/pci/pcie/aer/aerdrv_acpi.c1
-rw-r--r--drivers/pci/pcie/aer/aerdrv_errprint.c2
-rw-r--r--drivers/pci/pcie/aspm.c165
-rw-r--r--drivers/pci/pcie/portdrv_bus.c32
-rw-r--r--drivers/pci/pcie/portdrv_core.c240
-rw-r--r--drivers/pci/pcie/portdrv_pci.c21
6 files changed, 290 insertions, 171 deletions
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c
index 6dd7b13e9808..ebce26c37049 100644
--- a/drivers/pci/pcie/aer/aerdrv_acpi.c
+++ b/drivers/pci/pcie/aer/aerdrv_acpi.c
@@ -38,7 +38,6 @@ int aer_osc_setup(struct pcie_device *pciedev)
38 38
39 handle = acpi_find_root_bridge_handle(pdev); 39 handle = acpi_find_root_bridge_handle(pdev);
40 if (handle) { 40 if (handle) {
41 pcie_osc_support_set(OSC_EXT_PCI_CONFIG_SUPPORT);
42 status = pci_osc_control_set(handle, 41 status = pci_osc_control_set(handle,
43 OSC_PCI_EXPRESS_AER_CONTROL | 42 OSC_PCI_EXPRESS_AER_CONTROL |
44 OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); 43 OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c
index 3933d4f30e8c..0fc29ae80df8 100644
--- a/drivers/pci/pcie/aer/aerdrv_errprint.c
+++ b/drivers/pci/pcie/aer/aerdrv_errprint.c
@@ -233,7 +233,7 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
233 233
234 if (info->flags & AER_TLP_HEADER_VALID_FLAG) { 234 if (info->flags & AER_TLP_HEADER_VALID_FLAG) {
235 unsigned char *tlp = (unsigned char *) &info->tlp; 235 unsigned char *tlp = (unsigned char *) &info->tlp;
236 printk("%sTLB Header:\n", loglevel); 236 printk("%sTLP Header:\n", loglevel);
237 printk("%s%02x%02x%02x%02x %02x%02x%02x%02x" 237 printk("%s%02x%02x%02x%02x %02x%02x%02x%02x"
238 " %02x%02x%02x%02x %02x%02x%02x%02x\n", 238 " %02x%02x%02x%02x %02x%02x%02x%02x\n",
239 loglevel, 239 loglevel,
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 9aad608bcf3f..586b6f75910d 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -17,6 +17,7 @@
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/jiffies.h> 19#include <linux/jiffies.h>
20#include <linux/delay.h>
20#include <linux/pci-aspm.h> 21#include <linux/pci-aspm.h>
21#include "../pci.h" 22#include "../pci.h"
22 23
@@ -33,6 +34,11 @@ struct endpoint_state {
33struct pcie_link_state { 34struct pcie_link_state {
34 struct list_head sibiling; 35 struct list_head sibiling;
35 struct pci_dev *pdev; 36 struct pci_dev *pdev;
37 bool downstream_has_switch;
38
39 struct pcie_link_state *parent;
40 struct list_head children;
41 struct list_head link;
36 42
37 /* ASPM state */ 43 /* ASPM state */
38 unsigned int support_state; 44 unsigned int support_state;
@@ -70,6 +76,8 @@ static const char *policy_str[] = {
70 [POLICY_POWERSAVE] = "powersave" 76 [POLICY_POWERSAVE] = "powersave"
71}; 77};
72 78
79#define LINK_RETRAIN_TIMEOUT HZ
80
73static int policy_to_aspm_state(struct pci_dev *pdev) 81static int policy_to_aspm_state(struct pci_dev *pdev)
74{ 82{
75 struct pcie_link_state *link_state = pdev->link_state; 83 struct pcie_link_state *link_state = pdev->link_state;
@@ -125,7 +133,7 @@ static void pcie_set_clock_pm(struct pci_dev *pdev, int enable)
125 link_state->clk_pm_enabled = !!enable; 133 link_state->clk_pm_enabled = !!enable;
126} 134}
127 135
128static void pcie_check_clock_pm(struct pci_dev *pdev) 136static void pcie_check_clock_pm(struct pci_dev *pdev, int blacklist)
129{ 137{
130 int pos; 138 int pos;
131 u32 reg32; 139 u32 reg32;
@@ -149,10 +157,26 @@ static void pcie_check_clock_pm(struct pci_dev *pdev)
149 if (!(reg16 & PCI_EXP_LNKCTL_CLKREQ_EN)) 157 if (!(reg16 & PCI_EXP_LNKCTL_CLKREQ_EN))
150 enabled = 0; 158 enabled = 0;
151 } 159 }
152 link_state->clk_pm_capable = capable;
153 link_state->clk_pm_enabled = enabled; 160 link_state->clk_pm_enabled = enabled;
154 link_state->bios_clk_state = enabled; 161 link_state->bios_clk_state = enabled;
155 pcie_set_clock_pm(pdev, policy_to_clkpm_state(pdev)); 162 if (!blacklist) {
163 link_state->clk_pm_capable = capable;
164 pcie_set_clock_pm(pdev, policy_to_clkpm_state(pdev));
165 } else {
166 link_state->clk_pm_capable = 0;
167 pcie_set_clock_pm(pdev, 0);
168 }
169}
170
171static bool pcie_aspm_downstream_has_switch(struct pci_dev *pdev)
172{
173 struct pci_dev *child_dev;
174
175 list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) {
176 if (child_dev->pcie_type == PCI_EXP_TYPE_UPSTREAM)
177 return true;
178 }
179 return false;
156} 180}
157 181
158/* 182/*
@@ -217,16 +241,18 @@ static void pcie_aspm_configure_common_clock(struct pci_dev *pdev)
217 pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16); 241 pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
218 242
219 /* Wait for link training end */ 243 /* Wait for link training end */
220 /* break out after waiting for 1 second */ 244 /* break out after waiting for timeout */
221 start_jiffies = jiffies; 245 start_jiffies = jiffies;
222 while ((jiffies - start_jiffies) < HZ) { 246 for (;;) {
223 pci_read_config_word(pdev, pos + PCI_EXP_LNKSTA, &reg16); 247 pci_read_config_word(pdev, pos + PCI_EXP_LNKSTA, &reg16);
224 if (!(reg16 & PCI_EXP_LNKSTA_LT)) 248 if (!(reg16 & PCI_EXP_LNKSTA_LT))
225 break; 249 break;
226 cpu_relax(); 250 if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT))
251 break;
252 msleep(1);
227 } 253 }
228 /* training failed -> recover */ 254 /* training failed -> recover */
229 if ((jiffies - start_jiffies) >= HZ) { 255 if (reg16 & PCI_EXP_LNKSTA_LT) {
230 dev_printk (KERN_ERR, &pdev->dev, "ASPM: Could not configure" 256 dev_printk (KERN_ERR, &pdev->dev, "ASPM: Could not configure"
231 " common clock\n"); 257 " common clock\n");
232 i = 0; 258 i = 0;
@@ -419,9 +445,9 @@ static unsigned int pcie_aspm_check_state(struct pci_dev *pdev,
419{ 445{
420 struct pci_dev *child_dev; 446 struct pci_dev *child_dev;
421 447
422 /* If no child, disable the link */ 448 /* If no child, ignore the link */
423 if (list_empty(&pdev->subordinate->devices)) 449 if (list_empty(&pdev->subordinate->devices))
424 return 0; 450 return state;
425 list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) { 451 list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) {
426 if (child_dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) { 452 if (child_dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) {
427 /* 453 /*
@@ -462,6 +488,9 @@ static void __pcie_aspm_config_link(struct pci_dev *pdev, unsigned int state)
462 int valid = 1; 488 int valid = 1;
463 struct pcie_link_state *link_state = pdev->link_state; 489 struct pcie_link_state *link_state = pdev->link_state;
464 490
491 /* If no child, disable the link */
492 if (list_empty(&pdev->subordinate->devices))
493 state = 0;
465 /* 494 /*
466 * if the downstream component has pci bridge function, don't do ASPM 495 * if the downstream component has pci bridge function, don't do ASPM
467 * now 496 * now
@@ -493,20 +522,52 @@ static void __pcie_aspm_config_link(struct pci_dev *pdev, unsigned int state)
493 link_state->enabled_state = state; 522 link_state->enabled_state = state;
494} 523}
495 524
525static struct pcie_link_state *get_root_port_link(struct pcie_link_state *link)
526{
527 struct pcie_link_state *root_port_link = link;
528 while (root_port_link->parent)
529 root_port_link = root_port_link->parent;
530 return root_port_link;
531}
532
533/* check the whole hierarchy, and configure each link in the hierarchy */
496static void __pcie_aspm_configure_link_state(struct pci_dev *pdev, 534static void __pcie_aspm_configure_link_state(struct pci_dev *pdev,
497 unsigned int state) 535 unsigned int state)
498{ 536{
499 struct pcie_link_state *link_state = pdev->link_state; 537 struct pcie_link_state *link_state = pdev->link_state;
538 struct pcie_link_state *root_port_link = get_root_port_link(link_state);
539 struct pcie_link_state *leaf;
500 540
501 if (link_state->support_state == 0)
502 return;
503 state &= PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1; 541 state &= PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1;
504 542
505 /* state 0 means disabling aspm */ 543 /* check all links who have specific root port link */
506 state = pcie_aspm_check_state(pdev, state); 544 list_for_each_entry(leaf, &link_list, sibiling) {
545 if (!list_empty(&leaf->children) ||
546 get_root_port_link(leaf) != root_port_link)
547 continue;
548 state = pcie_aspm_check_state(leaf->pdev, state);
549 }
550 /* check root port link too in case it hasn't children */
551 state = pcie_aspm_check_state(root_port_link->pdev, state);
552
507 if (link_state->enabled_state == state) 553 if (link_state->enabled_state == state)
508 return; 554 return;
509 __pcie_aspm_config_link(pdev, state); 555
556 /*
557 * we must change the hierarchy. See comments in
558 * __pcie_aspm_config_link for the order
559 **/
560 if (state & PCIE_LINK_STATE_L1) {
561 list_for_each_entry(leaf, &link_list, sibiling) {
562 if (get_root_port_link(leaf) == root_port_link)
563 __pcie_aspm_config_link(leaf->pdev, state);
564 }
565 } else {
566 list_for_each_entry_reverse(leaf, &link_list, sibiling) {
567 if (get_root_port_link(leaf) == root_port_link)
568 __pcie_aspm_config_link(leaf->pdev, state);
569 }
570 }
510} 571}
511 572
512/* 573/*
@@ -570,6 +631,7 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
570 unsigned int state; 631 unsigned int state;
571 struct pcie_link_state *link_state; 632 struct pcie_link_state *link_state;
572 int error = 0; 633 int error = 0;
634 int blacklist;
573 635
574 if (aspm_disabled || !pdev->is_pcie || pdev->link_state) 636 if (aspm_disabled || !pdev->is_pcie || pdev->link_state)
575 return; 637 return;
@@ -580,29 +642,58 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
580 if (list_empty(&pdev->subordinate->devices)) 642 if (list_empty(&pdev->subordinate->devices))
581 goto out; 643 goto out;
582 644
583 if (pcie_aspm_sanity_check(pdev)) 645 blacklist = !!pcie_aspm_sanity_check(pdev);
584 goto out;
585 646
586 mutex_lock(&aspm_lock); 647 mutex_lock(&aspm_lock);
587 648
588 link_state = kzalloc(sizeof(*link_state), GFP_KERNEL); 649 link_state = kzalloc(sizeof(*link_state), GFP_KERNEL);
589 if (!link_state) 650 if (!link_state)
590 goto unlock_out; 651 goto unlock_out;
591 pdev->link_state = link_state;
592 652
593 pcie_aspm_configure_common_clock(pdev); 653 link_state->downstream_has_switch = pcie_aspm_downstream_has_switch(pdev);
654 INIT_LIST_HEAD(&link_state->children);
655 INIT_LIST_HEAD(&link_state->link);
656 if (pdev->bus->self) {/* this is a switch */
657 struct pcie_link_state *parent_link_state;
594 658
595 pcie_aspm_cap_init(pdev); 659 parent_link_state = pdev->bus->parent->self->link_state;
660 if (!parent_link_state) {
661 kfree(link_state);
662 goto unlock_out;
663 }
664 list_add(&link_state->link, &parent_link_state->children);
665 link_state->parent = parent_link_state;
666 }
596 667
597 /* config link state to avoid BIOS error */ 668 pdev->link_state = link_state;
598 state = pcie_aspm_check_state(pdev, policy_to_aspm_state(pdev));
599 __pcie_aspm_config_link(pdev, state);
600 669
601 pcie_check_clock_pm(pdev); 670 if (!blacklist) {
671 pcie_aspm_configure_common_clock(pdev);
672 pcie_aspm_cap_init(pdev);
673 } else {
674 link_state->enabled_state = PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1;
675 link_state->bios_aspm_state = 0;
676 /* Set support state to 0, so we will disable ASPM later */
677 link_state->support_state = 0;
678 }
602 679
603 link_state->pdev = pdev; 680 link_state->pdev = pdev;
604 list_add(&link_state->sibiling, &link_list); 681 list_add(&link_state->sibiling, &link_list);
605 682
683 if (link_state->downstream_has_switch) {
684 /*
685 * If link has switch, delay the link config. The leaf link
686 * initialization will config the whole hierarchy. but we must
687 * make sure BIOS doesn't set unsupported link state
688 **/
689 state = pcie_aspm_check_state(pdev, link_state->bios_aspm_state);
690 __pcie_aspm_config_link(pdev, state);
691 } else
692 __pcie_aspm_configure_link_state(pdev,
693 policy_to_aspm_state(pdev));
694
695 pcie_check_clock_pm(pdev, blacklist);
696
606unlock_out: 697unlock_out:
607 if (error) 698 if (error)
608 free_link_state(pdev); 699 free_link_state(pdev);
@@ -635,6 +726,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
635 /* All functions are removed, so just disable ASPM for the link */ 726 /* All functions are removed, so just disable ASPM for the link */
636 __pcie_aspm_config_one_dev(parent, 0); 727 __pcie_aspm_config_one_dev(parent, 0);
637 list_del(&link_state->sibiling); 728 list_del(&link_state->sibiling);
729 list_del(&link_state->link);
638 /* Clock PM is for endpoint device */ 730 /* Clock PM is for endpoint device */
639 731
640 free_link_state(parent); 732 free_link_state(parent);
@@ -857,24 +949,15 @@ void pcie_no_aspm(void)
857 aspm_disabled = 1; 949 aspm_disabled = 1;
858} 950}
859 951
860#ifdef CONFIG_ACPI 952/**
861#include <acpi/acpi_bus.h> 953 * pcie_aspm_enabled - is PCIe ASPM enabled?
862#include <linux/pci-acpi.h> 954 *
863static void pcie_aspm_platform_init(void) 955 * Returns true if ASPM has not been disabled by the command-line option
864{ 956 * pcie_aspm=off.
865 pcie_osc_support_set(OSC_ACTIVE_STATE_PWR_SUPPORT| 957 **/
866 OSC_CLOCK_PWR_CAPABILITY_SUPPORT); 958int pcie_aspm_enabled(void)
867}
868#else
869static inline void pcie_aspm_platform_init(void) { }
870#endif
871
872static int __init pcie_aspm_init(void)
873{ 959{
874 if (aspm_disabled) 960 return !aspm_disabled;
875 return 0;
876 pcie_aspm_platform_init();
877 return 0;
878} 961}
962EXPORT_SYMBOL(pcie_aspm_enabled);
879 963
880fs_initcall(pcie_aspm_init);
diff --git a/drivers/pci/pcie/portdrv_bus.c b/drivers/pci/pcie/portdrv_bus.c
index 359fe5568df1..eec89b767f9f 100644
--- a/drivers/pci/pcie/portdrv_bus.c
+++ b/drivers/pci/pcie/portdrv_bus.c
@@ -16,14 +16,10 @@
16#include "portdrv.h" 16#include "portdrv.h"
17 17
18static int pcie_port_bus_match(struct device *dev, struct device_driver *drv); 18static int pcie_port_bus_match(struct device *dev, struct device_driver *drv);
19static int pcie_port_bus_suspend(struct device *dev, pm_message_t state);
20static int pcie_port_bus_resume(struct device *dev);
21 19
22struct bus_type pcie_port_bus_type = { 20struct bus_type pcie_port_bus_type = {
23 .name = "pci_express", 21 .name = "pci_express",
24 .match = pcie_port_bus_match, 22 .match = pcie_port_bus_match,
25 .suspend = pcie_port_bus_suspend,
26 .resume = pcie_port_bus_resume,
27}; 23};
28EXPORT_SYMBOL_GPL(pcie_port_bus_type); 24EXPORT_SYMBOL_GPL(pcie_port_bus_type);
29 25
@@ -49,32 +45,12 @@ static int pcie_port_bus_match(struct device *dev, struct device_driver *drv)
49 return 1; 45 return 1;
50} 46}
51 47
52static int pcie_port_bus_suspend(struct device *dev, pm_message_t state) 48int pcie_port_bus_register(void)
53{ 49{
54 struct pcie_device *pciedev; 50 return bus_register(&pcie_port_bus_type);
55 struct pcie_port_service_driver *driver;
56
57 if (!dev || !dev->driver)
58 return 0;
59
60 pciedev = to_pcie_device(dev);
61 driver = to_service_driver(dev->driver);
62 if (driver && driver->suspend)
63 driver->suspend(pciedev, state);
64 return 0;
65} 51}
66 52
67static int pcie_port_bus_resume(struct device *dev) 53void pcie_port_bus_unregister(void)
68{ 54{
69 struct pcie_device *pciedev; 55 bus_unregister(&pcie_port_bus_type);
70 struct pcie_port_service_driver *driver;
71
72 if (!dev || !dev->driver)
73 return 0;
74
75 pciedev = to_pcie_device(dev);
76 driver = to_service_driver(dev->driver);
77 if (driver && driver->resume)
78 driver->resume(pciedev);
79 return 0;
80} 56}
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 2e091e014829..8b3f8c18032f 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -19,91 +19,15 @@
19 19
20extern int pcie_mch_quirk; /* MSI-quirk Indicator */ 20extern int pcie_mch_quirk; /* MSI-quirk Indicator */
21 21
22static int pcie_port_probe_service(struct device *dev) 22/**
23{ 23 * release_pcie_device - free PCI Express port service device structure
24 struct pcie_device *pciedev; 24 * @dev: Port service device to release
25 struct pcie_port_service_driver *driver; 25 *
26 int status; 26 * Invoked automatically when device is being removed in response to
27 27 * device_unregister(dev). Release all resources being claimed.
28 if (!dev || !dev->driver)
29 return -ENODEV;
30
31 driver = to_service_driver(dev->driver);
32 if (!driver || !driver->probe)
33 return -ENODEV;
34
35 pciedev = to_pcie_device(dev);
36 status = driver->probe(pciedev, driver->id_table);
37 if (!status) {
38 dev_printk(KERN_DEBUG, dev, "service driver %s loaded\n",
39 driver->name);
40 get_device(dev);
41 }
42 return status;
43}
44
45static int pcie_port_remove_service(struct device *dev)
46{
47 struct pcie_device *pciedev;
48 struct pcie_port_service_driver *driver;
49
50 if (!dev || !dev->driver)
51 return 0;
52
53 pciedev = to_pcie_device(dev);
54 driver = to_service_driver(dev->driver);
55 if (driver && driver->remove) {
56 dev_printk(KERN_DEBUG, dev, "unloading service driver %s\n",
57 driver->name);
58 driver->remove(pciedev);
59 put_device(dev);
60 }
61 return 0;
62}
63
64static void pcie_port_shutdown_service(struct device *dev) {}
65
66static int pcie_port_suspend_service(struct device *dev, pm_message_t state)
67{
68 struct pcie_device *pciedev;
69 struct pcie_port_service_driver *driver;
70
71 if (!dev || !dev->driver)
72 return 0;
73
74 pciedev = to_pcie_device(dev);
75 driver = to_service_driver(dev->driver);
76 if (driver && driver->suspend)
77 driver->suspend(pciedev, state);
78 return 0;
79}
80
81static int pcie_port_resume_service(struct device *dev)
82{
83 struct pcie_device *pciedev;
84 struct pcie_port_service_driver *driver;
85
86 if (!dev || !dev->driver)
87 return 0;
88
89 pciedev = to_pcie_device(dev);
90 driver = to_service_driver(dev->driver);
91
92 if (driver && driver->resume)
93 driver->resume(pciedev);
94 return 0;
95}
96
97/*
98 * release_pcie_device
99 *
100 * Being invoked automatically when device is being removed
101 * in response to device_unregister(dev) call.
102 * Release all resources being claimed.
103 */ 28 */
104static void release_pcie_device(struct device *dev) 29static void release_pcie_device(struct device *dev)
105{ 30{
106 dev_printk(KERN_DEBUG, dev, "free port service\n");
107 kfree(to_pcie_device(dev)); 31 kfree(to_pcie_device(dev));
108} 32}
109 33
@@ -128,7 +52,16 @@ static int is_msi_quirked(struct pci_dev *dev)
128 } 52 }
129 return quirk; 53 return quirk;
130} 54}
131 55
56/**
57 * assign_interrupt_mode - choose interrupt mode for PCI Express port services
58 * (INTx, MSI-X, MSI) and set up vectors
59 * @dev: PCI Express port to handle
60 * @vectors: Array of interrupt vectors to populate
61 * @mask: Bitmask of port capabilities returned by get_port_device_capability()
62 *
63 * Return value: Interrupt mode associated with the port
64 */
132static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask) 65static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask)
133{ 66{
134 int i, pos, nvec, status = -EINVAL; 67 int i, pos, nvec, status = -EINVAL;
@@ -150,7 +83,6 @@ static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask)
150 if (pos) { 83 if (pos) {
151 struct msix_entry msix_entries[PCIE_PORT_DEVICE_MAXSERVICES] = 84 struct msix_entry msix_entries[PCIE_PORT_DEVICE_MAXSERVICES] =
152 {{0, 0}, {0, 1}, {0, 2}, {0, 3}}; 85 {{0, 0}, {0, 1}, {0, 2}, {0, 3}};
153 dev_info(&dev->dev, "found MSI-X capability\n");
154 status = pci_enable_msix(dev, msix_entries, nvec); 86 status = pci_enable_msix(dev, msix_entries, nvec);
155 if (!status) { 87 if (!status) {
156 int j = 0; 88 int j = 0;
@@ -165,7 +97,6 @@ static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask)
165 if (status) { 97 if (status) {
166 pos = pci_find_capability(dev, PCI_CAP_ID_MSI); 98 pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
167 if (pos) { 99 if (pos) {
168 dev_info(&dev->dev, "found MSI capability\n");
169 status = pci_enable_msi(dev); 100 status = pci_enable_msi(dev);
170 if (!status) { 101 if (!status) {
171 interrupt_mode = PCIE_PORT_MSI_MODE; 102 interrupt_mode = PCIE_PORT_MSI_MODE;
@@ -177,6 +108,16 @@ static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask)
177 return interrupt_mode; 108 return interrupt_mode;
178} 109}
179 110
111/**
112 * get_port_device_capability - discover capabilities of a PCI Express port
113 * @dev: PCI Express port to examine
114 *
115 * The capabilities are read from the port's PCI Express configuration registers
116 * as described in PCI Express Base Specification 1.0a sections 7.8.2, 7.8.9 and
117 * 7.9 - 7.11.
118 *
119 * Return value: Bitmask of discovered port capabilities
120 */
180static int get_port_device_capability(struct pci_dev *dev) 121static int get_port_device_capability(struct pci_dev *dev)
181{ 122{
182 int services = 0, pos; 123 int services = 0, pos;
@@ -204,6 +145,15 @@ static int get_port_device_capability(struct pci_dev *dev)
204 return services; 145 return services;
205} 146}
206 147
148/**
149 * pcie_device_init - initialize PCI Express port service device
150 * @dev: Port service device to initialize
151 * @parent: PCI Express port to associate the service device with
152 * @port_type: Type of the port
153 * @service_type: Type of service to associate with the service device
154 * @irq: Interrupt vector to associate with the service device
155 * @irq_mode: Interrupt mode of the service (INTx, MSI-X, MSI)
156 */
207static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev, 157static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev,
208 int port_type, int service_type, int irq, int irq_mode) 158 int port_type, int service_type, int irq, int irq_mode)
209{ 159{
@@ -224,11 +174,19 @@ static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev,
224 device->driver = NULL; 174 device->driver = NULL;
225 device->driver_data = NULL; 175 device->driver_data = NULL;
226 device->release = release_pcie_device; /* callback to free pcie dev */ 176 device->release = release_pcie_device; /* callback to free pcie dev */
227 snprintf(device->bus_id, sizeof(device->bus_id), "%s:pcie%02x", 177 dev_set_name(device, "%s:pcie%02x",
228 pci_name(parent), get_descriptor_id(port_type, service_type)); 178 pci_name(parent), get_descriptor_id(port_type, service_type));
229 device->parent = &parent->dev; 179 device->parent = &parent->dev;
230} 180}
231 181
182/**
183 * alloc_pcie_device - allocate PCI Express port service device structure
184 * @parent: PCI Express port to associate the service device with
185 * @port_type: Type of the port
186 * @service_type: Type of service to associate with the service device
187 * @irq: Interrupt vector to associate with the service device
188 * @irq_mode: Interrupt mode of the service (INTx, MSI-X, MSI)
189 */
232static struct pcie_device* alloc_pcie_device(struct pci_dev *parent, 190static struct pcie_device* alloc_pcie_device(struct pci_dev *parent,
233 int port_type, int service_type, int irq, int irq_mode) 191 int port_type, int service_type, int irq, int irq_mode)
234{ 192{
@@ -239,10 +197,13 @@ static struct pcie_device* alloc_pcie_device(struct pci_dev *parent,
239 return NULL; 197 return NULL;
240 198
241 pcie_device_init(parent, device, port_type, service_type, irq,irq_mode); 199 pcie_device_init(parent, device, port_type, service_type, irq,irq_mode);
242 dev_printk(KERN_DEBUG, &device->device, "allocate port service\n");
243 return device; 200 return device;
244} 201}
245 202
203/**
204 * pcie_port_device_probe - check if device is a PCI Express port
205 * @dev: Device to check
206 */
246int pcie_port_device_probe(struct pci_dev *dev) 207int pcie_port_device_probe(struct pci_dev *dev)
247{ 208{
248 int pos, type; 209 int pos, type;
@@ -260,6 +221,13 @@ int pcie_port_device_probe(struct pci_dev *dev)
260 return -ENODEV; 221 return -ENODEV;
261} 222}
262 223
224/**
225 * pcie_port_device_register - register PCI Express port
226 * @dev: PCI Express port to register
227 *
228 * Allocate the port extension structure and register services associated with
229 * the port.
230 */
263int pcie_port_device_register(struct pci_dev *dev) 231int pcie_port_device_register(struct pci_dev *dev)
264{ 232{
265 struct pcie_port_device_ext *p_ext; 233 struct pcie_port_device_ext *p_ext;
@@ -323,6 +291,11 @@ static int suspend_iter(struct device *dev, void *data)
323 return 0; 291 return 0;
324} 292}
325 293
294/**
295 * pcie_port_device_suspend - suspend port services associated with a PCIe port
296 * @dev: PCI Express port to handle
297 * @state: Representation of system power management transition in progress
298 */
326int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state) 299int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state)
327{ 300{
328 return device_for_each_child(&dev->dev, &state, suspend_iter); 301 return device_for_each_child(&dev->dev, &state, suspend_iter);
@@ -341,6 +314,10 @@ static int resume_iter(struct device *dev, void *data)
341 return 0; 314 return 0;
342} 315}
343 316
317/**
318 * pcie_port_device_suspend - resume port services associated with a PCIe port
319 * @dev: PCI Express port to handle
320 */
344int pcie_port_device_resume(struct pci_dev *dev) 321int pcie_port_device_resume(struct pci_dev *dev)
345{ 322{
346 return device_for_each_child(&dev->dev, NULL, resume_iter); 323 return device_for_each_child(&dev->dev, NULL, resume_iter);
@@ -363,6 +340,13 @@ static int remove_iter(struct device *dev, void *data)
363 return 0; 340 return 0;
364} 341}
365 342
343/**
344 * pcie_port_device_remove - unregister PCI Express port service devices
345 * @dev: PCI Express port the service devices to unregister are associated with
346 *
347 * Remove PCI Express port service devices associated with given port and
348 * disable MSI-X or MSI for the port.
349 */
366void pcie_port_device_remove(struct pci_dev *dev) 350void pcie_port_device_remove(struct pci_dev *dev)
367{ 351{
368 struct device *device; 352 struct device *device;
@@ -386,16 +370,80 @@ void pcie_port_device_remove(struct pci_dev *dev)
386 pci_disable_msi(dev); 370 pci_disable_msi(dev);
387} 371}
388 372
389int pcie_port_bus_register(void) 373/**
374 * pcie_port_probe_service - probe driver for given PCI Express port service
375 * @dev: PCI Express port service device to probe against
376 *
377 * If PCI Express port service driver is registered with
378 * pcie_port_service_register(), this function will be called by the driver core
379 * whenever match is found between the driver and a port service device.
380 */
381static int pcie_port_probe_service(struct device *dev)
390{ 382{
391 return bus_register(&pcie_port_bus_type); 383 struct pcie_device *pciedev;
384 struct pcie_port_service_driver *driver;
385 int status;
386
387 if (!dev || !dev->driver)
388 return -ENODEV;
389
390 driver = to_service_driver(dev->driver);
391 if (!driver || !driver->probe)
392 return -ENODEV;
393
394 pciedev = to_pcie_device(dev);
395 status = driver->probe(pciedev, driver->id_table);
396 if (!status) {
397 dev_printk(KERN_DEBUG, dev, "service driver %s loaded\n",
398 driver->name);
399 get_device(dev);
400 }
401 return status;
392} 402}
393 403
394void pcie_port_bus_unregister(void) 404/**
405 * pcie_port_remove_service - detach driver from given PCI Express port service
406 * @dev: PCI Express port service device to handle
407 *
408 * If PCI Express port service driver is registered with
409 * pcie_port_service_register(), this function will be called by the driver core
410 * when device_unregister() is called for the port service device associated
411 * with the driver.
412 */
413static int pcie_port_remove_service(struct device *dev)
395{ 414{
396 bus_unregister(&pcie_port_bus_type); 415 struct pcie_device *pciedev;
416 struct pcie_port_service_driver *driver;
417
418 if (!dev || !dev->driver)
419 return 0;
420
421 pciedev = to_pcie_device(dev);
422 driver = to_service_driver(dev->driver);
423 if (driver && driver->remove) {
424 dev_printk(KERN_DEBUG, dev, "unloading service driver %s\n",
425 driver->name);
426 driver->remove(pciedev);
427 put_device(dev);
428 }
429 return 0;
397} 430}
398 431
432/**
433 * pcie_port_shutdown_service - shut down given PCI Express port service
434 * @dev: PCI Express port service device to handle
435 *
436 * If PCI Express port service driver is registered with
437 * pcie_port_service_register(), this function will be called by the driver core
438 * when device_shutdown() is called for the port service device associated
439 * with the driver.
440 */
441static void pcie_port_shutdown_service(struct device *dev) {}
442
443/**
444 * pcie_port_service_register - register PCI Express port service driver
445 * @new: PCI Express port service driver to register
446 */
399int pcie_port_service_register(struct pcie_port_service_driver *new) 447int pcie_port_service_register(struct pcie_port_service_driver *new)
400{ 448{
401 new->driver.name = (char *)new->name; 449 new->driver.name = (char *)new->name;
@@ -403,15 +451,17 @@ int pcie_port_service_register(struct pcie_port_service_driver *new)
403 new->driver.probe = pcie_port_probe_service; 451 new->driver.probe = pcie_port_probe_service;
404 new->driver.remove = pcie_port_remove_service; 452 new->driver.remove = pcie_port_remove_service;
405 new->driver.shutdown = pcie_port_shutdown_service; 453 new->driver.shutdown = pcie_port_shutdown_service;
406 new->driver.suspend = pcie_port_suspend_service;
407 new->driver.resume = pcie_port_resume_service;
408 454
409 return driver_register(&new->driver); 455 return driver_register(&new->driver);
410} 456}
411 457
412void pcie_port_service_unregister(struct pcie_port_service_driver *new) 458/**
459 * pcie_port_service_unregister - unregister PCI Express port service driver
460 * @drv: PCI Express port service driver to unregister
461 */
462void pcie_port_service_unregister(struct pcie_port_service_driver *drv)
413{ 463{
414 driver_unregister(&new->driver); 464 driver_unregister(&drv->driver);
415} 465}
416 466
417EXPORT_SYMBOL(pcie_port_service_register); 467EXPORT_SYMBOL(pcie_port_service_register);
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 584422da8d8b..99a914a027f8 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -41,7 +41,6 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev)
41{ 41{
42 int retval; 42 int retval;
43 43
44 pci_restore_state(dev);
45 retval = pci_enable_device(dev); 44 retval = pci_enable_device(dev);
46 if (retval) 45 if (retval)
47 return retval; 46 return retval;
@@ -52,11 +51,18 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev)
52#ifdef CONFIG_PM 51#ifdef CONFIG_PM
53static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state) 52static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state)
54{ 53{
55 int ret = pcie_port_device_suspend(dev, state); 54 return pcie_port_device_suspend(dev, state);
56 55
57 if (!ret) 56}
58 ret = pcie_portdrv_save_config(dev); 57
59 return ret; 58static int pcie_portdrv_suspend_late(struct pci_dev *dev, pm_message_t state)
59{
60 return pci_save_state(dev);
61}
62
63static int pcie_portdrv_resume_early(struct pci_dev *dev)
64{
65 return pci_restore_state(dev);
60} 66}
61 67
62static int pcie_portdrv_resume(struct pci_dev *dev) 68static int pcie_portdrv_resume(struct pci_dev *dev)
@@ -66,6 +72,8 @@ static int pcie_portdrv_resume(struct pci_dev *dev)
66} 72}
67#else 73#else
68#define pcie_portdrv_suspend NULL 74#define pcie_portdrv_suspend NULL
75#define pcie_portdrv_suspend_late NULL
76#define pcie_portdrv_resume_early NULL
69#define pcie_portdrv_resume NULL 77#define pcie_portdrv_resume NULL
70#endif 78#endif
71 79
@@ -221,6 +229,7 @@ static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev)
221 229
222 /* If fatal, restore cfg space for possible link reset at upstream */ 230 /* If fatal, restore cfg space for possible link reset at upstream */
223 if (dev->error_state == pci_channel_io_frozen) { 231 if (dev->error_state == pci_channel_io_frozen) {
232 pci_restore_state(dev);
224 pcie_portdrv_restore_config(dev); 233 pcie_portdrv_restore_config(dev);
225 pci_enable_pcie_error_reporting(dev); 234 pci_enable_pcie_error_reporting(dev);
226 } 235 }
@@ -283,6 +292,8 @@ static struct pci_driver pcie_portdriver = {
283 .remove = pcie_portdrv_remove, 292 .remove = pcie_portdrv_remove,
284 293
285 .suspend = pcie_portdrv_suspend, 294 .suspend = pcie_portdrv_suspend,
295 .suspend_late = pcie_portdrv_suspend_late,
296 .resume_early = pcie_portdrv_resume_early,
286 .resume = pcie_portdrv_resume, 297 .resume = pcie_portdrv_resume,
287 298
288 .err_handler = &pcie_portdrv_err_handler, 299 .err_handler = &pcie_portdrv_err_handler,