aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorBjorn Helgaas <bjorn.helgaas@hp.com>2009-09-14 18:35:25 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-09-14 20:39:09 -0400
commitd569c74d78ffcde2f163256e4da934ec3bacff0e (patch)
treea4652df85c274f60b5677ac266e88f99e990f87c /drivers/pci
parent8838400db5193c37588813c2eb1249b821781950 (diff)
PCI hotplug: pciehp: use generic pci_configure_slot()
Use the generic pci_configure_slot() rather than the PCIe-specific program_fw_provided_values(). Unlike the previous pciehp-specific code, we now walk through subordinate devices even if there are no settings for the parent. This should be harmless because we won't change anything unless we discover firmware settings farther down. Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Reviewed-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Acked-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/hotplug/pciehp.h7
-rw-r--r--drivers/pci/hotplug/pciehp_pci.c132
2 files changed, 1 insertions, 138 deletions
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 86cdfd71ed27..36faa9a8e18f 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -237,15 +237,8 @@ static inline int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev)
237 return retval; 237 return retval;
238 return pciehp_acpi_slot_detection_check(dev); 238 return pciehp_acpi_slot_detection_check(dev);
239} 239}
240
241static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
242 struct hotplug_params *hpp)
243{
244 return acpi_get_hp_params_from_firmware(dev, hpp);
245}
246#else 240#else
247#define pciehp_firmware_init() do {} while (0) 241#define pciehp_firmware_init() do {} while (0)
248#define pciehp_get_hp_hw_control_from_firmware(dev) 0 242#define pciehp_get_hp_hw_control_from_firmware(dev) 0
249#define pciehp_get_hp_params_from_firmware(dev, hpp) (-ENODEV)
250#endif /* CONFIG_ACPI */ 243#endif /* CONFIG_ACPI */
251#endif /* _PCIEHP_H */ 244#endif /* _PCIEHP_H */
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index af295d080a00..02e24d63b3ee 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -34,136 +34,6 @@
34#include "../pci.h" 34#include "../pci.h"
35#include "pciehp.h" 35#include "pciehp.h"
36 36
37static void program_hpp_type0(struct pci_dev *dev, struct hpp_type0 *hpp)
38{
39 u16 pci_cmd, pci_bctl;
40
41 if (hpp->revision > 1) {
42 warn("Rev.%d type0 record not supported\n", hpp->revision);
43 return;
44 }
45
46 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp->cache_line_size);
47 pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp->latency_timer);
48 pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
49 if (hpp->enable_serr)
50 pci_cmd |= PCI_COMMAND_SERR;
51 else
52 pci_cmd &= ~PCI_COMMAND_SERR;
53 if (hpp->enable_perr)
54 pci_cmd |= PCI_COMMAND_PARITY;
55 else
56 pci_cmd &= ~PCI_COMMAND_PARITY;
57 pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
58
59 /* Program bridge control value */
60 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
61 pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
62 hpp->latency_timer);
63 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
64 if (hpp->enable_serr)
65 pci_bctl |= PCI_BRIDGE_CTL_SERR;
66 else
67 pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
68 if (hpp->enable_perr)
69 pci_bctl |= PCI_BRIDGE_CTL_PARITY;
70 else
71 pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
72 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
73 }
74}
75
76static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
77{
78 int pos;
79 u16 reg16;
80 u32 reg32;
81
82 if (hpp->revision > 1) {
83 warn("Rev.%d type2 record not supported\n", hpp->revision);
84 return;
85 }
86
87 /* Find PCI Express capability */
88 pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
89 if (!pos)
90 return;
91
92 /* Initialize Device Control Register */
93 pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &reg16);
94 reg16 = (reg16 & hpp->pci_exp_devctl_and) | hpp->pci_exp_devctl_or;
95 pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16);
96
97 /* Initialize Link Control Register */
98 if (dev->subordinate) {
99 pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &reg16);
100 reg16 = (reg16 & hpp->pci_exp_lnkctl_and)
101 | hpp->pci_exp_lnkctl_or;
102 pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, reg16);
103 }
104
105 /* Find Advanced Error Reporting Enhanced Capability */
106 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
107 if (!pos)
108 return;
109
110 /* Initialize Uncorrectable Error Mask Register */
111 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, &reg32);
112 reg32 = (reg32 & hpp->unc_err_mask_and) | hpp->unc_err_mask_or;
113 pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, reg32);
114
115 /* Initialize Uncorrectable Error Severity Register */
116 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &reg32);
117 reg32 = (reg32 & hpp->unc_err_sever_and) | hpp->unc_err_sever_or;
118 pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, reg32);
119
120 /* Initialize Correctable Error Mask Register */
121 pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &reg32);
122 reg32 = (reg32 & hpp->cor_err_mask_and) | hpp->cor_err_mask_or;
123 pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg32);
124
125 /* Initialize Advanced Error Capabilities and Control Register */
126 pci_read_config_dword(dev, pos + PCI_ERR_CAP, &reg32);
127 reg32 = (reg32 & hpp->adv_err_cap_and) | hpp->adv_err_cap_or;
128 pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32);
129
130 /*
131 * FIXME: The following two registers are not supported yet.
132 *
133 * o Secondary Uncorrectable Error Severity Register
134 * o Secondary Uncorrectable Error Mask Register
135 */
136}
137
138static void program_fw_provided_values(struct pci_dev *dev)
139{
140 struct pci_dev *cdev;
141 struct hotplug_params hpp;
142
143 /* Program hpp values for this device */
144 if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
145 (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
146 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
147 return;
148
149 if (pciehp_get_hp_params_from_firmware(dev, &hpp)) {
150 warn("Could not get hotplug parameters\n");
151 return;
152 }
153
154 if (hpp.t2)
155 program_hpp_type2(dev, hpp.t2);
156 if (hpp.t0)
157 program_hpp_type0(dev, hpp.t0);
158
159 /* Program child devices */
160 if (dev->subordinate) {
161 list_for_each_entry(cdev, &dev->subordinate->devices,
162 bus_list)
163 program_fw_provided_values(cdev);
164 }
165}
166
167static int __ref pciehp_add_bridge(struct pci_dev *dev) 37static int __ref pciehp_add_bridge(struct pci_dev *dev)
168{ 38{
169 struct pci_bus *parent = dev->bus; 39 struct pci_bus *parent = dev->bus;
@@ -226,7 +96,7 @@ int pciehp_configure_device(struct slot *p_slot)
226 (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { 96 (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
227 pciehp_add_bridge(dev); 97 pciehp_add_bridge(dev);
228 } 98 }
229 program_fw_provided_values(dev); 99 pci_configure_slot(dev);
230 pci_dev_put(dev); 100 pci_dev_put(dev);
231 } 101 }
232 102