diff options
Diffstat (limited to 'drivers/pci/hotplug/pciehp_pci.c')
-rw-r--r-- | drivers/pci/hotplug/pciehp_pci.c | 137 |
1 files changed, 1 insertions, 136 deletions
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 10f9566cceeb..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 | ||
37 | static 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 | |||
76 | static 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, ®16); | ||
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, ®16); | ||
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, ®32); | ||
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, ®32); | ||
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, ®32); | ||
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, ®32); | ||
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 | |||
138 | static 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 | |||
167 | static int __ref pciehp_add_bridge(struct pci_dev *dev) | 37 | static 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 | ||
@@ -285,11 +155,6 @@ int pciehp_unconfigure_device(struct slot *p_slot) | |||
285 | } | 155 | } |
286 | pci_dev_put(temp); | 156 | pci_dev_put(temp); |
287 | } | 157 | } |
288 | /* | ||
289 | * Some PCI Express root ports require fixup after hot-plug operation. | ||
290 | */ | ||
291 | if (pcie_mch_quirk) | ||
292 | pci_fixup_device(pci_fixup_final, p_slot->ctrl->pci_dev); | ||
293 | 158 | ||
294 | return rc; | 159 | return rc; |
295 | } | 160 | } |