diff options
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r-- | drivers/pci/hotplug/Makefile | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpi_pcihp.c | 251 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 11 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp.h | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_core.c | 7 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 17 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_pci.c | 9 | ||||
-rw-r--r-- | drivers/pci/hotplug/pcihp_slot.c | 180 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_pci.c | 8 |
9 files changed, 23 insertions, 464 deletions
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile index 3e6532b945c1..4a9aa08b08f1 100644 --- a/drivers/pci/hotplug/Makefile +++ b/drivers/pci/hotplug/Makefile | |||
@@ -24,7 +24,7 @@ obj-$(CONFIG_HOTPLUG_PCI_S390) += s390_pci_hpc.o | |||
24 | 24 | ||
25 | obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o | 25 | obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o |
26 | 26 | ||
27 | pci_hotplug-objs := pci_hotplug_core.o pcihp_slot.o | 27 | pci_hotplug-objs := pci_hotplug_core.o |
28 | 28 | ||
29 | ifdef CONFIG_HOTPLUG_PCI_CPCI | 29 | ifdef CONFIG_HOTPLUG_PCI_CPCI |
30 | pci_hotplug-objs += cpci_hotplug_core.o \ | 30 | pci_hotplug-objs += cpci_hotplug_core.o \ |
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index 2cac54802567..876ccc620440 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c | |||
@@ -46,215 +46,6 @@ | |||
46 | 46 | ||
47 | static bool debug_acpi; | 47 | static bool debug_acpi; |
48 | 48 | ||
49 | static acpi_status | ||
50 | decode_type0_hpx_record(union acpi_object *record, struct hotplug_params *hpx) | ||
51 | { | ||
52 | int i; | ||
53 | union acpi_object *fields = record->package.elements; | ||
54 | u32 revision = fields[1].integer.value; | ||
55 | |||
56 | switch (revision) { | ||
57 | case 1: | ||
58 | if (record->package.count != 6) | ||
59 | return AE_ERROR; | ||
60 | for (i = 2; i < 6; i++) | ||
61 | if (fields[i].type != ACPI_TYPE_INTEGER) | ||
62 | return AE_ERROR; | ||
63 | hpx->t0 = &hpx->type0_data; | ||
64 | hpx->t0->revision = revision; | ||
65 | hpx->t0->cache_line_size = fields[2].integer.value; | ||
66 | hpx->t0->latency_timer = fields[3].integer.value; | ||
67 | hpx->t0->enable_serr = fields[4].integer.value; | ||
68 | hpx->t0->enable_perr = fields[5].integer.value; | ||
69 | break; | ||
70 | default: | ||
71 | printk(KERN_WARNING | ||
72 | "%s: Type 0 Revision %d record not supported\n", | ||
73 | __func__, revision); | ||
74 | return AE_ERROR; | ||
75 | } | ||
76 | return AE_OK; | ||
77 | } | ||
78 | |||
79 | static acpi_status | ||
80 | decode_type1_hpx_record(union acpi_object *record, struct hotplug_params *hpx) | ||
81 | { | ||
82 | int i; | ||
83 | union acpi_object *fields = record->package.elements; | ||
84 | u32 revision = fields[1].integer.value; | ||
85 | |||
86 | switch (revision) { | ||
87 | case 1: | ||
88 | if (record->package.count != 5) | ||
89 | return AE_ERROR; | ||
90 | for (i = 2; i < 5; i++) | ||
91 | if (fields[i].type != ACPI_TYPE_INTEGER) | ||
92 | return AE_ERROR; | ||
93 | hpx->t1 = &hpx->type1_data; | ||
94 | hpx->t1->revision = revision; | ||
95 | hpx->t1->max_mem_read = fields[2].integer.value; | ||
96 | hpx->t1->avg_max_split = fields[3].integer.value; | ||
97 | hpx->t1->tot_max_split = fields[4].integer.value; | ||
98 | break; | ||
99 | default: | ||
100 | printk(KERN_WARNING | ||
101 | "%s: Type 1 Revision %d record not supported\n", | ||
102 | __func__, revision); | ||
103 | return AE_ERROR; | ||
104 | } | ||
105 | return AE_OK; | ||
106 | } | ||
107 | |||
108 | static acpi_status | ||
109 | decode_type2_hpx_record(union acpi_object *record, struct hotplug_params *hpx) | ||
110 | { | ||
111 | int i; | ||
112 | union acpi_object *fields = record->package.elements; | ||
113 | u32 revision = fields[1].integer.value; | ||
114 | |||
115 | switch (revision) { | ||
116 | case 1: | ||
117 | if (record->package.count != 18) | ||
118 | return AE_ERROR; | ||
119 | for (i = 2; i < 18; i++) | ||
120 | if (fields[i].type != ACPI_TYPE_INTEGER) | ||
121 | return AE_ERROR; | ||
122 | hpx->t2 = &hpx->type2_data; | ||
123 | hpx->t2->revision = revision; | ||
124 | hpx->t2->unc_err_mask_and = fields[2].integer.value; | ||
125 | hpx->t2->unc_err_mask_or = fields[3].integer.value; | ||
126 | hpx->t2->unc_err_sever_and = fields[4].integer.value; | ||
127 | hpx->t2->unc_err_sever_or = fields[5].integer.value; | ||
128 | hpx->t2->cor_err_mask_and = fields[6].integer.value; | ||
129 | hpx->t2->cor_err_mask_or = fields[7].integer.value; | ||
130 | hpx->t2->adv_err_cap_and = fields[8].integer.value; | ||
131 | hpx->t2->adv_err_cap_or = fields[9].integer.value; | ||
132 | hpx->t2->pci_exp_devctl_and = fields[10].integer.value; | ||
133 | hpx->t2->pci_exp_devctl_or = fields[11].integer.value; | ||
134 | hpx->t2->pci_exp_lnkctl_and = fields[12].integer.value; | ||
135 | hpx->t2->pci_exp_lnkctl_or = fields[13].integer.value; | ||
136 | hpx->t2->sec_unc_err_sever_and = fields[14].integer.value; | ||
137 | hpx->t2->sec_unc_err_sever_or = fields[15].integer.value; | ||
138 | hpx->t2->sec_unc_err_mask_and = fields[16].integer.value; | ||
139 | hpx->t2->sec_unc_err_mask_or = fields[17].integer.value; | ||
140 | break; | ||
141 | default: | ||
142 | printk(KERN_WARNING | ||
143 | "%s: Type 2 Revision %d record not supported\n", | ||
144 | __func__, revision); | ||
145 | return AE_ERROR; | ||
146 | } | ||
147 | return AE_OK; | ||
148 | } | ||
149 | |||
150 | static acpi_status | ||
151 | acpi_run_hpx(acpi_handle handle, struct hotplug_params *hpx) | ||
152 | { | ||
153 | acpi_status status; | ||
154 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
155 | union acpi_object *package, *record, *fields; | ||
156 | u32 type; | ||
157 | int i; | ||
158 | |||
159 | /* Clear the return buffer with zeros */ | ||
160 | memset(hpx, 0, sizeof(struct hotplug_params)); | ||
161 | |||
162 | status = acpi_evaluate_object(handle, "_HPX", NULL, &buffer); | ||
163 | if (ACPI_FAILURE(status)) | ||
164 | return status; | ||
165 | |||
166 | package = (union acpi_object *)buffer.pointer; | ||
167 | if (package->type != ACPI_TYPE_PACKAGE) { | ||
168 | status = AE_ERROR; | ||
169 | goto exit; | ||
170 | } | ||
171 | |||
172 | for (i = 0; i < package->package.count; i++) { | ||
173 | record = &package->package.elements[i]; | ||
174 | if (record->type != ACPI_TYPE_PACKAGE) { | ||
175 | status = AE_ERROR; | ||
176 | goto exit; | ||
177 | } | ||
178 | |||
179 | fields = record->package.elements; | ||
180 | if (fields[0].type != ACPI_TYPE_INTEGER || | ||
181 | fields[1].type != ACPI_TYPE_INTEGER) { | ||
182 | status = AE_ERROR; | ||
183 | goto exit; | ||
184 | } | ||
185 | |||
186 | type = fields[0].integer.value; | ||
187 | switch (type) { | ||
188 | case 0: | ||
189 | status = decode_type0_hpx_record(record, hpx); | ||
190 | if (ACPI_FAILURE(status)) | ||
191 | goto exit; | ||
192 | break; | ||
193 | case 1: | ||
194 | status = decode_type1_hpx_record(record, hpx); | ||
195 | if (ACPI_FAILURE(status)) | ||
196 | goto exit; | ||
197 | break; | ||
198 | case 2: | ||
199 | status = decode_type2_hpx_record(record, hpx); | ||
200 | if (ACPI_FAILURE(status)) | ||
201 | goto exit; | ||
202 | break; | ||
203 | default: | ||
204 | printk(KERN_ERR "%s: Type %d record not supported\n", | ||
205 | __func__, type); | ||
206 | status = AE_ERROR; | ||
207 | goto exit; | ||
208 | } | ||
209 | } | ||
210 | exit: | ||
211 | kfree(buffer.pointer); | ||
212 | return status; | ||
213 | } | ||
214 | |||
215 | static acpi_status | ||
216 | acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) | ||
217 | { | ||
218 | acpi_status status; | ||
219 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
220 | union acpi_object *package, *fields; | ||
221 | int i; | ||
222 | |||
223 | memset(hpp, 0, sizeof(struct hotplug_params)); | ||
224 | |||
225 | status = acpi_evaluate_object(handle, "_HPP", NULL, &buffer); | ||
226 | if (ACPI_FAILURE(status)) | ||
227 | return status; | ||
228 | |||
229 | package = (union acpi_object *) buffer.pointer; | ||
230 | if (package->type != ACPI_TYPE_PACKAGE || | ||
231 | package->package.count != 4) { | ||
232 | status = AE_ERROR; | ||
233 | goto exit; | ||
234 | } | ||
235 | |||
236 | fields = package->package.elements; | ||
237 | for (i = 0; i < 4; i++) { | ||
238 | if (fields[i].type != ACPI_TYPE_INTEGER) { | ||
239 | status = AE_ERROR; | ||
240 | goto exit; | ||
241 | } | ||
242 | } | ||
243 | |||
244 | hpp->t0 = &hpp->type0_data; | ||
245 | hpp->t0->revision = 1; | ||
246 | hpp->t0->cache_line_size = fields[0].integer.value; | ||
247 | hpp->t0->latency_timer = fields[1].integer.value; | ||
248 | hpp->t0->enable_serr = fields[2].integer.value; | ||
249 | hpp->t0->enable_perr = fields[3].integer.value; | ||
250 | |||
251 | exit: | ||
252 | kfree(buffer.pointer); | ||
253 | return status; | ||
254 | } | ||
255 | |||
256 | |||
257 | |||
258 | /* acpi_run_oshp - get control of hotplug from the firmware | 49 | /* acpi_run_oshp - get control of hotplug from the firmware |
259 | * | 50 | * |
260 | * @handle - the handle of the hotplug controller. | 51 | * @handle - the handle of the hotplug controller. |
@@ -283,48 +74,6 @@ static acpi_status acpi_run_oshp(acpi_handle handle) | |||
283 | return status; | 74 | return status; |
284 | } | 75 | } |
285 | 76 | ||
286 | /* pci_get_hp_params | ||
287 | * | ||
288 | * @dev - the pci_dev for which we want parameters | ||
289 | * @hpp - allocated by the caller | ||
290 | */ | ||
291 | int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp) | ||
292 | { | ||
293 | acpi_status status; | ||
294 | acpi_handle handle, phandle; | ||
295 | struct pci_bus *pbus; | ||
296 | |||
297 | handle = NULL; | ||
298 | for (pbus = dev->bus; pbus; pbus = pbus->parent) { | ||
299 | handle = acpi_pci_get_bridge_handle(pbus); | ||
300 | if (handle) | ||
301 | break; | ||
302 | } | ||
303 | |||
304 | /* | ||
305 | * _HPP settings apply to all child buses, until another _HPP is | ||
306 | * encountered. If we don't find an _HPP for the input pci dev, | ||
307 | * look for it in the parent device scope since that would apply to | ||
308 | * this pci dev. | ||
309 | */ | ||
310 | while (handle) { | ||
311 | status = acpi_run_hpx(handle, hpp); | ||
312 | if (ACPI_SUCCESS(status)) | ||
313 | return 0; | ||
314 | status = acpi_run_hpp(handle, hpp); | ||
315 | if (ACPI_SUCCESS(status)) | ||
316 | return 0; | ||
317 | if (acpi_is_root_bridge(handle)) | ||
318 | break; | ||
319 | status = acpi_get_parent(handle, &phandle); | ||
320 | if (ACPI_FAILURE(status)) | ||
321 | break; | ||
322 | handle = phandle; | ||
323 | } | ||
324 | return -ENODEV; | ||
325 | } | ||
326 | EXPORT_SYMBOL_GPL(pci_get_hp_params); | ||
327 | |||
328 | /** | 77 | /** |
329 | * acpi_get_hp_hw_control_from_firmware | 78 | * acpi_get_hp_hw_control_from_firmware |
330 | * @dev: the pci_dev of the bridge that has a hotplug controller | 79 | * @dev: the pci_dev of the bridge that has a hotplug controller |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 70741c8c46a0..a6f8e0ba0bfe 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -61,7 +61,6 @@ static DEFINE_MUTEX(bridge_mutex); | |||
61 | static int acpiphp_hotplug_notify(struct acpi_device *adev, u32 type); | 61 | static int acpiphp_hotplug_notify(struct acpi_device *adev, u32 type); |
62 | static void acpiphp_post_dock_fixup(struct acpi_device *adev); | 62 | static void acpiphp_post_dock_fixup(struct acpi_device *adev); |
63 | static void acpiphp_sanitize_bus(struct pci_bus *bus); | 63 | static void acpiphp_sanitize_bus(struct pci_bus *bus); |
64 | static void acpiphp_set_hpp_values(struct pci_bus *bus); | ||
65 | static void hotplug_event(u32 type, struct acpiphp_context *context); | 64 | static void hotplug_event(u32 type, struct acpiphp_context *context); |
66 | static void free_bridge(struct kref *kref); | 65 | static void free_bridge(struct kref *kref); |
67 | 66 | ||
@@ -510,7 +509,7 @@ static void enable_slot(struct acpiphp_slot *slot) | |||
510 | __pci_bus_assign_resources(bus, &add_list, NULL); | 509 | __pci_bus_assign_resources(bus, &add_list, NULL); |
511 | 510 | ||
512 | acpiphp_sanitize_bus(bus); | 511 | acpiphp_sanitize_bus(bus); |
513 | acpiphp_set_hpp_values(bus); | 512 | pcie_bus_configure_settings(bus); |
514 | acpiphp_set_acpi_region(slot); | 513 | acpiphp_set_acpi_region(slot); |
515 | 514 | ||
516 | list_for_each_entry(dev, &bus->devices, bus_list) { | 515 | list_for_each_entry(dev, &bus->devices, bus_list) { |
@@ -702,14 +701,6 @@ static void acpiphp_check_bridge(struct acpiphp_bridge *bridge) | |||
702 | } | 701 | } |
703 | } | 702 | } |
704 | 703 | ||
705 | static void acpiphp_set_hpp_values(struct pci_bus *bus) | ||
706 | { | ||
707 | struct pci_dev *dev; | ||
708 | |||
709 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
710 | pci_configure_slot(dev); | ||
711 | } | ||
712 | |||
713 | /* | 704 | /* |
714 | * Remove devices for which we could not assign resources, call | 705 | * Remove devices for which we could not assign resources, call |
715 | * arch specific code to fix-up the bus | 706 | * arch specific code to fix-up the bus |
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 9e5a9fbb93d7..b11521953485 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -92,7 +92,7 @@ struct controller { | |||
92 | struct slot *slot; | 92 | struct slot *slot; |
93 | wait_queue_head_t queue; /* sleep & wake process */ | 93 | wait_queue_head_t queue; /* sleep & wake process */ |
94 | u32 slot_cap; | 94 | u32 slot_cap; |
95 | u32 slot_ctrl; | 95 | u16 slot_ctrl; |
96 | struct timer_list poll_timer; | 96 | struct timer_list poll_timer; |
97 | unsigned long cmd_started; /* jiffies */ | 97 | unsigned long cmd_started; /* jiffies */ |
98 | unsigned int cmd_busy:1; | 98 | unsigned int cmd_busy:1; |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 07aa722bb12c..3a5e7e28b874 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -262,6 +262,13 @@ static int pciehp_probe(struct pcie_device *dev) | |||
262 | goto err_out_none; | 262 | goto err_out_none; |
263 | } | 263 | } |
264 | 264 | ||
265 | if (!dev->port->subordinate) { | ||
266 | /* Can happen if we run out of bus numbers during probe */ | ||
267 | dev_err(&dev->device, | ||
268 | "Hotplug bridge without secondary bus, ignoring\n"); | ||
269 | goto err_out_none; | ||
270 | } | ||
271 | |||
265 | ctrl = pcie_init(dev); | 272 | ctrl = pcie_init(dev); |
266 | if (!ctrl) { | 273 | if (!ctrl) { |
267 | dev_err(&dev->device, "Controller initialization failed\n"); | 274 | dev_err(&dev->device, "Controller initialization failed\n"); |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 9da84b8b27d8..f0dc6cb9c5be 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -171,9 +171,9 @@ static void pcie_wait_cmd(struct controller *ctrl) | |||
171 | * interrupts. | 171 | * interrupts. |
172 | */ | 172 | */ |
173 | if (!rc) | 173 | if (!rc) |
174 | ctrl_info(ctrl, "Timeout on hotplug command %#010x (issued %u msec ago)\n", | 174 | ctrl_info(ctrl, "Timeout on hotplug command %#06x (issued %u msec ago)\n", |
175 | ctrl->slot_ctrl, | 175 | ctrl->slot_ctrl, |
176 | jiffies_to_msecs(now - ctrl->cmd_started)); | 176 | jiffies_to_msecs(jiffies - ctrl->cmd_started)); |
177 | } | 177 | } |
178 | 178 | ||
179 | /** | 179 | /** |
@@ -422,9 +422,9 @@ void pciehp_set_attention_status(struct slot *slot, u8 value) | |||
422 | default: | 422 | default: |
423 | return; | 423 | return; |
424 | } | 424 | } |
425 | pcie_write_cmd(ctrl, slot_cmd, PCI_EXP_SLTCTL_AIC); | ||
425 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | 426 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
426 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); | 427 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
427 | pcie_write_cmd(ctrl, slot_cmd, PCI_EXP_SLTCTL_AIC); | ||
428 | } | 428 | } |
429 | 429 | ||
430 | void pciehp_green_led_on(struct slot *slot) | 430 | void pciehp_green_led_on(struct slot *slot) |
@@ -602,6 +602,8 @@ void pcie_enable_notification(struct controller *ctrl) | |||
602 | PCI_EXP_SLTCTL_DLLSCE); | 602 | PCI_EXP_SLTCTL_DLLSCE); |
603 | 603 | ||
604 | pcie_write_cmd(ctrl, cmd, mask); | 604 | pcie_write_cmd(ctrl, cmd, mask); |
605 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | ||
606 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, cmd); | ||
605 | } | 607 | } |
606 | 608 | ||
607 | static void pcie_disable_notification(struct controller *ctrl) | 609 | static void pcie_disable_notification(struct controller *ctrl) |
@@ -613,6 +615,8 @@ static void pcie_disable_notification(struct controller *ctrl) | |||
613 | PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE | | 615 | PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE | |
614 | PCI_EXP_SLTCTL_DLLSCE); | 616 | PCI_EXP_SLTCTL_DLLSCE); |
615 | pcie_write_cmd(ctrl, 0, mask); | 617 | pcie_write_cmd(ctrl, 0, mask); |
618 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | ||
619 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, 0); | ||
616 | } | 620 | } |
617 | 621 | ||
618 | /* | 622 | /* |
@@ -640,6 +644,8 @@ int pciehp_reset_slot(struct slot *slot, int probe) | |||
640 | stat_mask |= PCI_EXP_SLTSTA_DLLSC; | 644 | stat_mask |= PCI_EXP_SLTSTA_DLLSC; |
641 | 645 | ||
642 | pcie_write_cmd(ctrl, 0, ctrl_mask); | 646 | pcie_write_cmd(ctrl, 0, ctrl_mask); |
647 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | ||
648 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, 0); | ||
643 | if (pciehp_poll_mode) | 649 | if (pciehp_poll_mode) |
644 | del_timer_sync(&ctrl->poll_timer); | 650 | del_timer_sync(&ctrl->poll_timer); |
645 | 651 | ||
@@ -647,6 +653,8 @@ int pciehp_reset_slot(struct slot *slot, int probe) | |||
647 | 653 | ||
648 | pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, stat_mask); | 654 | pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, stat_mask); |
649 | pcie_write_cmd(ctrl, ctrl_mask, ctrl_mask); | 655 | pcie_write_cmd(ctrl, ctrl_mask, ctrl_mask); |
656 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | ||
657 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, ctrl_mask); | ||
650 | if (pciehp_poll_mode) | 658 | if (pciehp_poll_mode) |
651 | int_poll_timeout(ctrl->poll_timer.data); | 659 | int_poll_timeout(ctrl->poll_timer.data); |
652 | 660 | ||
@@ -785,9 +793,6 @@ struct controller *pcie_init(struct pcie_device *dev) | |||
785 | PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC | | 793 | PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC | |
786 | PCI_EXP_SLTSTA_CC | PCI_EXP_SLTSTA_DLLSC); | 794 | PCI_EXP_SLTSTA_CC | PCI_EXP_SLTSTA_DLLSC); |
787 | 795 | ||
788 | /* Disable software notification */ | ||
789 | pcie_disable_notification(ctrl); | ||
790 | |||
791 | ctrl_info(ctrl, "Slot #%d AttnBtn%c AttnInd%c PwrInd%c PwrCtrl%c MRL%c Interlock%c NoCompl%c LLActRep%c\n", | 796 | ctrl_info(ctrl, "Slot #%d AttnBtn%c AttnInd%c PwrInd%c PwrCtrl%c MRL%c Interlock%c NoCompl%c LLActRep%c\n", |
792 | (slot_cap & PCI_EXP_SLTCAP_PSN) >> 19, | 797 | (slot_cap & PCI_EXP_SLTCAP_PSN) >> 19, |
793 | FLAG(slot_cap, PCI_EXP_SLTCAP_ABP), | 798 | FLAG(slot_cap, PCI_EXP_SLTCAP_ABP), |
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 5f871f4c4af1..9e69403be632 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c | |||
@@ -65,14 +65,7 @@ int pciehp_configure_device(struct slot *p_slot) | |||
65 | pci_hp_add_bridge(dev); | 65 | pci_hp_add_bridge(dev); |
66 | 66 | ||
67 | pci_assign_unassigned_bridge_resources(bridge); | 67 | pci_assign_unassigned_bridge_resources(bridge); |
68 | 68 | pcie_bus_configure_settings(parent); | |
69 | list_for_each_entry(dev, &parent->devices, bus_list) { | ||
70 | if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) | ||
71 | continue; | ||
72 | |||
73 | pci_configure_slot(dev); | ||
74 | } | ||
75 | |||
76 | pci_bus_add_devices(parent); | 69 | pci_bus_add_devices(parent); |
77 | 70 | ||
78 | out: | 71 | out: |
diff --git a/drivers/pci/hotplug/pcihp_slot.c b/drivers/pci/hotplug/pcihp_slot.c deleted file mode 100644 index e246a10a0d2c..000000000000 --- a/drivers/pci/hotplug/pcihp_slot.c +++ /dev/null | |||
@@ -1,180 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1995,2001 Compaq Computer Corporation | ||
3 | * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) | ||
4 | * Copyright (C) 2001 IBM Corp. | ||
5 | * Copyright (C) 2003-2004 Intel Corporation | ||
6 | * (c) Copyright 2009 Hewlett-Packard Development Company, L.P. | ||
7 | * | ||
8 | * All rights reserved. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or (at | ||
13 | * your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, but | ||
16 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
18 | * NON INFRINGEMENT. See the GNU General Public License for more | ||
19 | * details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
24 | */ | ||
25 | |||
26 | #include <linux/pci.h> | ||
27 | #include <linux/export.h> | ||
28 | #include <linux/pci_hotplug.h> | ||
29 | |||
30 | static struct hpp_type0 pci_default_type0 = { | ||
31 | .revision = 1, | ||
32 | .cache_line_size = 8, | ||
33 | .latency_timer = 0x40, | ||
34 | .enable_serr = 0, | ||
35 | .enable_perr = 0, | ||
36 | }; | ||
37 | |||
38 | static void program_hpp_type0(struct pci_dev *dev, struct hpp_type0 *hpp) | ||
39 | { | ||
40 | u16 pci_cmd, pci_bctl; | ||
41 | |||
42 | if (!hpp) { | ||
43 | /* | ||
44 | * Perhaps we *should* use default settings for PCIe, but | ||
45 | * pciehp didn't, so we won't either. | ||
46 | */ | ||
47 | if (pci_is_pcie(dev)) | ||
48 | return; | ||
49 | dev_info(&dev->dev, "using default PCI settings\n"); | ||
50 | hpp = &pci_default_type0; | ||
51 | } | ||
52 | |||
53 | if (hpp->revision > 1) { | ||
54 | dev_warn(&dev->dev, | ||
55 | "PCI settings rev %d not supported; using defaults\n", | ||
56 | hpp->revision); | ||
57 | hpp = &pci_default_type0; | ||
58 | } | ||
59 | |||
60 | pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp->cache_line_size); | ||
61 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp->latency_timer); | ||
62 | pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); | ||
63 | if (hpp->enable_serr) | ||
64 | pci_cmd |= PCI_COMMAND_SERR; | ||
65 | else | ||
66 | pci_cmd &= ~PCI_COMMAND_SERR; | ||
67 | if (hpp->enable_perr) | ||
68 | pci_cmd |= PCI_COMMAND_PARITY; | ||
69 | else | ||
70 | pci_cmd &= ~PCI_COMMAND_PARITY; | ||
71 | pci_write_config_word(dev, PCI_COMMAND, pci_cmd); | ||
72 | |||
73 | /* Program bridge control value */ | ||
74 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { | ||
75 | pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, | ||
76 | hpp->latency_timer); | ||
77 | pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl); | ||
78 | if (hpp->enable_serr) | ||
79 | pci_bctl |= PCI_BRIDGE_CTL_SERR; | ||
80 | else | ||
81 | pci_bctl &= ~PCI_BRIDGE_CTL_SERR; | ||
82 | if (hpp->enable_perr) | ||
83 | pci_bctl |= PCI_BRIDGE_CTL_PARITY; | ||
84 | else | ||
85 | pci_bctl &= ~PCI_BRIDGE_CTL_PARITY; | ||
86 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | static void program_hpp_type1(struct pci_dev *dev, struct hpp_type1 *hpp) | ||
91 | { | ||
92 | if (hpp) | ||
93 | dev_warn(&dev->dev, "PCI-X settings not supported\n"); | ||
94 | } | ||
95 | |||
96 | static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) | ||
97 | { | ||
98 | int pos; | ||
99 | u32 reg32; | ||
100 | |||
101 | if (!hpp) | ||
102 | return; | ||
103 | |||
104 | if (hpp->revision > 1) { | ||
105 | dev_warn(&dev->dev, "PCIe settings rev %d not supported\n", | ||
106 | hpp->revision); | ||
107 | return; | ||
108 | } | ||
109 | |||
110 | /* Initialize Device Control Register */ | ||
111 | pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL, | ||
112 | ~hpp->pci_exp_devctl_and, hpp->pci_exp_devctl_or); | ||
113 | |||
114 | /* Initialize Link Control Register */ | ||
115 | if (dev->subordinate) | ||
116 | pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL, | ||
117 | ~hpp->pci_exp_lnkctl_and, hpp->pci_exp_lnkctl_or); | ||
118 | |||
119 | /* Find Advanced Error Reporting Enhanced Capability */ | ||
120 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | ||
121 | if (!pos) | ||
122 | return; | ||
123 | |||
124 | /* Initialize Uncorrectable Error Mask Register */ | ||
125 | pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, ®32); | ||
126 | reg32 = (reg32 & hpp->unc_err_mask_and) | hpp->unc_err_mask_or; | ||
127 | pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, reg32); | ||
128 | |||
129 | /* Initialize Uncorrectable Error Severity Register */ | ||
130 | pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, ®32); | ||
131 | reg32 = (reg32 & hpp->unc_err_sever_and) | hpp->unc_err_sever_or; | ||
132 | pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, reg32); | ||
133 | |||
134 | /* Initialize Correctable Error Mask Register */ | ||
135 | pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, ®32); | ||
136 | reg32 = (reg32 & hpp->cor_err_mask_and) | hpp->cor_err_mask_or; | ||
137 | pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg32); | ||
138 | |||
139 | /* Initialize Advanced Error Capabilities and Control Register */ | ||
140 | pci_read_config_dword(dev, pos + PCI_ERR_CAP, ®32); | ||
141 | reg32 = (reg32 & hpp->adv_err_cap_and) | hpp->adv_err_cap_or; | ||
142 | pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32); | ||
143 | |||
144 | /* | ||
145 | * FIXME: The following two registers are not supported yet. | ||
146 | * | ||
147 | * o Secondary Uncorrectable Error Severity Register | ||
148 | * o Secondary Uncorrectable Error Mask Register | ||
149 | */ | ||
150 | } | ||
151 | |||
152 | void pci_configure_slot(struct pci_dev *dev) | ||
153 | { | ||
154 | struct pci_dev *cdev; | ||
155 | struct hotplug_params hpp; | ||
156 | int ret; | ||
157 | |||
158 | if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL || | ||
159 | (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && | ||
160 | (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI))) | ||
161 | return; | ||
162 | |||
163 | pcie_bus_configure_settings(dev->bus); | ||
164 | |||
165 | memset(&hpp, 0, sizeof(hpp)); | ||
166 | ret = pci_get_hp_params(dev, &hpp); | ||
167 | if (ret) | ||
168 | dev_warn(&dev->dev, "no hotplug settings from platform\n"); | ||
169 | |||
170 | program_hpp_type2(dev, hpp.t2); | ||
171 | program_hpp_type1(dev, hpp.t1); | ||
172 | program_hpp_type0(dev, hpp.t0); | ||
173 | |||
174 | if (dev->subordinate) { | ||
175 | list_for_each_entry(cdev, &dev->subordinate->devices, | ||
176 | bus_list) | ||
177 | pci_configure_slot(cdev); | ||
178 | } | ||
179 | } | ||
180 | EXPORT_SYMBOL_GPL(pci_configure_slot); | ||
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index 469454e0cc48..f8cd3a27e351 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c | |||
@@ -69,13 +69,7 @@ int shpchp_configure_device(struct slot *p_slot) | |||
69 | } | 69 | } |
70 | 70 | ||
71 | pci_assign_unassigned_bridge_resources(bridge); | 71 | pci_assign_unassigned_bridge_resources(bridge); |
72 | 72 | pcie_bus_configure_settings(parent); | |
73 | list_for_each_entry(dev, &parent->devices, bus_list) { | ||
74 | if (PCI_SLOT(dev->devfn) != p_slot->device) | ||
75 | continue; | ||
76 | pci_configure_slot(dev); | ||
77 | } | ||
78 | |||
79 | pci_bus_add_devices(parent); | 73 | pci_bus_add_devices(parent); |
80 | 74 | ||
81 | out: | 75 | out: |