aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r--drivers/pci/hotplug/Makefile2
-rw-r--r--drivers/pci/hotplug/acpi_pcihp.c117
-rw-r--r--drivers/pci/hotplug/acpiphp.h3
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c187
-rw-r--r--drivers/pci/hotplug/pci_hotplug_core.c3
-rw-r--r--drivers/pci/hotplug/pciehp.h9
-rw-r--r--drivers/pci/hotplug/pciehp_acpi.c7
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c5
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c10
-rw-r--r--drivers/pci/hotplug/pciehp_pci.c137
-rw-r--r--drivers/pci/hotplug/pcihp_slot.c187
-rw-r--r--drivers/pci/hotplug/shpchp.h9
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c62
13 files changed, 271 insertions, 467 deletions
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile
index 2aa117c8cd87..3625b094bf7e 100644
--- a/drivers/pci/hotplug/Makefile
+++ b/drivers/pci/hotplug/Makefile
@@ -22,7 +22,7 @@ obj-$(CONFIG_HOTPLUG_PCI_SGI) += sgi_hotplug.o
22# Link this last so it doesn't claim devices that have a real hotplug driver 22# Link this last so it doesn't claim devices that have a real hotplug driver
23obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o 23obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o
24 24
25pci_hotplug-objs := pci_hotplug_core.o 25pci_hotplug-objs := pci_hotplug_core.o pcihp_slot.o
26 26
27ifdef CONFIG_HOTPLUG_PCI_CPCI 27ifdef CONFIG_HOTPLUG_PCI_CPCI
28pci_hotplug-objs += cpci_hotplug_core.o \ 28pci_hotplug-objs += cpci_hotplug_core.o \
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c
index eb159587d0bf..a73028ec52e5 100644
--- a/drivers/pci/hotplug/acpi_pcihp.c
+++ b/drivers/pci/hotplug/acpi_pcihp.c
@@ -41,7 +41,6 @@
41#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg) 41#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
42 42
43#define METHOD_NAME__SUN "_SUN" 43#define METHOD_NAME__SUN "_SUN"
44#define METHOD_NAME__HPP "_HPP"
45#define METHOD_NAME_OSHP "OSHP" 44#define METHOD_NAME_OSHP "OSHP"
46 45
47static int debug_acpi; 46static int debug_acpi;
@@ -215,80 +214,41 @@ acpi_run_hpx(acpi_handle handle, struct hotplug_params *hpx)
215static acpi_status 214static acpi_status
216acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) 215acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
217{ 216{
218 acpi_status status; 217 acpi_status status;
219 u8 nui[4]; 218 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
220 struct acpi_buffer ret_buf = { 0, NULL}; 219 union acpi_object *package, *fields;
221 struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; 220 int i;
222 union acpi_object *ext_obj, *package;
223 int i, len = 0;
224
225 acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
226 221
227 /* Clear the return buffer with zeros */
228 memset(hpp, 0, sizeof(struct hotplug_params)); 222 memset(hpp, 0, sizeof(struct hotplug_params));
229 223
230 /* get _hpp */ 224 status = acpi_evaluate_object(handle, "_HPP", NULL, &buffer);
231 status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf); 225 if (ACPI_FAILURE(status))
232 switch (status) { 226 return status;
233 case AE_BUFFER_OVERFLOW:
234 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
235 if (!ret_buf.pointer) {
236 printk(KERN_ERR "%s:%s alloc for _HPP fail\n",
237 __func__, (char *)string.pointer);
238 kfree(string.pointer);
239 return AE_NO_MEMORY;
240 }
241 status = acpi_evaluate_object(handle, METHOD_NAME__HPP,
242 NULL, &ret_buf);
243 if (ACPI_SUCCESS(status))
244 break;
245 default:
246 if (ACPI_FAILURE(status)) {
247 pr_debug("%s:%s _HPP fail=0x%x\n", __func__,
248 (char *)string.pointer, status);
249 kfree(string.pointer);
250 return status;
251 }
252 }
253 227
254 ext_obj = (union acpi_object *) ret_buf.pointer; 228 package = (union acpi_object *) buffer.pointer;
255 if (ext_obj->type != ACPI_TYPE_PACKAGE) { 229 if (package->type != ACPI_TYPE_PACKAGE ||
256 printk(KERN_ERR "%s:%s _HPP obj not a package\n", __func__, 230 package->package.count != 4) {
257 (char *)string.pointer);
258 status = AE_ERROR; 231 status = AE_ERROR;
259 goto free_and_return; 232 goto exit;
260 } 233 }
261 234
262 len = ext_obj->package.count; 235 fields = package->package.elements;
263 package = (union acpi_object *) ret_buf.pointer; 236 for (i = 0; i < 4; i++) {
264 for ( i = 0; (i < len) || (i < 4); i++) { 237 if (fields[i].type != ACPI_TYPE_INTEGER) {
265 ext_obj = (union acpi_object *) &package->package.elements[i];
266 switch (ext_obj->type) {
267 case ACPI_TYPE_INTEGER:
268 nui[i] = (u8)ext_obj->integer.value;
269 break;
270 default:
271 printk(KERN_ERR "%s:%s _HPP obj type incorrect\n",
272 __func__, (char *)string.pointer);
273 status = AE_ERROR; 238 status = AE_ERROR;
274 goto free_and_return; 239 goto exit;
275 } 240 }
276 } 241 }
277 242
278 hpp->t0 = &hpp->type0_data; 243 hpp->t0 = &hpp->type0_data;
279 hpp->t0->cache_line_size = nui[0]; 244 hpp->t0->revision = 1;
280 hpp->t0->latency_timer = nui[1]; 245 hpp->t0->cache_line_size = fields[0].integer.value;
281 hpp->t0->enable_serr = nui[2]; 246 hpp->t0->latency_timer = fields[1].integer.value;
282 hpp->t0->enable_perr = nui[3]; 247 hpp->t0->enable_serr = fields[2].integer.value;
283 248 hpp->t0->enable_perr = fields[3].integer.value;
284 pr_debug(" _HPP: cache_line_size=0x%x\n", hpp->t0->cache_line_size);
285 pr_debug(" _HPP: latency timer =0x%x\n", hpp->t0->latency_timer);
286 pr_debug(" _HPP: enable SERR =0x%x\n", hpp->t0->enable_serr);
287 pr_debug(" _HPP: enable PERR =0x%x\n", hpp->t0->enable_perr);
288 249
289free_and_return: 250exit:
290 kfree(string.pointer); 251 kfree(buffer.pointer);
291 kfree(ret_buf.pointer);
292 return status; 252 return status;
293} 253}
294 254
@@ -322,20 +282,19 @@ static acpi_status acpi_run_oshp(acpi_handle handle)
322 return status; 282 return status;
323} 283}
324 284
325/* acpi_get_hp_params_from_firmware 285/* pci_get_hp_params
326 * 286 *
327 * @bus - the pci_bus of the bus on which the device is newly added 287 * @dev - the pci_dev for which we want parameters
328 * @hpp - allocated by the caller 288 * @hpp - allocated by the caller
329 */ 289 */
330acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus, 290int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp)
331 struct hotplug_params *hpp)
332{ 291{
333 acpi_status status = AE_NOT_FOUND; 292 acpi_status status;
334 acpi_handle handle, phandle; 293 acpi_handle handle, phandle;
335 struct pci_bus *pbus; 294 struct pci_bus *pbus;
336 295
337 handle = NULL; 296 handle = NULL;
338 for (pbus = bus; pbus; pbus = pbus->parent) { 297 for (pbus = dev->bus; pbus; pbus = pbus->parent) {
339 handle = acpi_pci_get_bridge_handle(pbus); 298 handle = acpi_pci_get_bridge_handle(pbus);
340 if (handle) 299 if (handle)
341 break; 300 break;
@@ -345,15 +304,15 @@ acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus,
345 * _HPP settings apply to all child buses, until another _HPP is 304 * _HPP settings apply to all child buses, until another _HPP is
346 * encountered. If we don't find an _HPP for the input pci dev, 305 * encountered. If we don't find an _HPP for the input pci dev,
347 * look for it in the parent device scope since that would apply to 306 * look for it in the parent device scope since that would apply to
348 * this pci dev. If we don't find any _HPP, use hardcoded defaults 307 * this pci dev.
349 */ 308 */
350 while (handle) { 309 while (handle) {
351 status = acpi_run_hpx(handle, hpp); 310 status = acpi_run_hpx(handle, hpp);
352 if (ACPI_SUCCESS(status)) 311 if (ACPI_SUCCESS(status))
353 break; 312 return 0;
354 status = acpi_run_hpp(handle, hpp); 313 status = acpi_run_hpp(handle, hpp);
355 if (ACPI_SUCCESS(status)) 314 if (ACPI_SUCCESS(status))
356 break; 315 return 0;
357 if (acpi_is_root_bridge(handle)) 316 if (acpi_is_root_bridge(handle))
358 break; 317 break;
359 status = acpi_get_parent(handle, &phandle); 318 status = acpi_get_parent(handle, &phandle);
@@ -361,9 +320,9 @@ acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus,
361 break; 320 break;
362 handle = phandle; 321 handle = phandle;
363 } 322 }
364 return status; 323 return -ENODEV;
365} 324}
366EXPORT_SYMBOL_GPL(acpi_get_hp_params_from_firmware); 325EXPORT_SYMBOL_GPL(pci_get_hp_params);
367 326
368/** 327/**
369 * acpi_get_hp_hw_control_from_firmware 328 * acpi_get_hp_hw_control_from_firmware
@@ -500,18 +459,18 @@ check_hotplug(acpi_handle handle, u32 lvl, void *context, void **rv)
500 459
501/** 460/**
502 * acpi_pci_detect_ejectable - check if the PCI bus has ejectable slots 461 * acpi_pci_detect_ejectable - check if the PCI bus has ejectable slots
503 * @pbus - PCI bus to scan 462 * @handle - handle of the PCI bus to scan
504 * 463 *
505 * Returns 1 if the PCI bus has ACPI based ejectable slots, 0 otherwise. 464 * Returns 1 if the PCI bus has ACPI based ejectable slots, 0 otherwise.
506 */ 465 */
507int acpi_pci_detect_ejectable(struct pci_bus *pbus) 466int acpi_pci_detect_ejectable(acpi_handle handle)
508{ 467{
509 acpi_handle handle;
510 int found = 0; 468 int found = 0;
511 469
512 if (!(handle = acpi_pci_get_bridge_handle(pbus))) 470 if (!handle)
513 return 0; 471 return found;
514 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, 472
473 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
515 check_hotplug, (void *)&found, NULL); 474 check_hotplug, (void *)&found, NULL);
516 return found; 475 return found;
517} 476}
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index e68d5f20ffb3..7d938df79206 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -91,9 +91,6 @@ struct acpiphp_bridge {
91 /* PCI-to-PCI bridge device */ 91 /* PCI-to-PCI bridge device */
92 struct pci_dev *pci_dev; 92 struct pci_dev *pci_dev;
93 93
94 /* ACPI 2.0 _HPP parameters */
95 struct hotplug_params hpp;
96
97 spinlock_t res_lock; 94 spinlock_t res_lock;
98}; 95};
99 96
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 0cb0f830a993..58d25a163a8b 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -59,7 +59,7 @@ static DEFINE_SPINLOCK(ioapic_list_lock);
59 59
60static void handle_hotplug_event_bridge (acpi_handle, u32, void *); 60static void handle_hotplug_event_bridge (acpi_handle, u32, void *);
61static void acpiphp_sanitize_bus(struct pci_bus *bus); 61static void acpiphp_sanitize_bus(struct pci_bus *bus);
62static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus); 62static void acpiphp_set_hpp_values(struct pci_bus *bus);
63static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context); 63static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context);
64 64
65/* callback routine to check for the existence of a pci dock device */ 65/* callback routine to check for the existence of a pci dock device */
@@ -261,51 +261,21 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
261 261
262 262
263/* see if it's worth looking at this bridge */ 263/* see if it's worth looking at this bridge */
264static int detect_ejectable_slots(struct pci_bus *pbus) 264static int detect_ejectable_slots(acpi_handle handle)
265{ 265{
266 int found = acpi_pci_detect_ejectable(pbus); 266 int found = acpi_pci_detect_ejectable(handle);
267 if (!found) { 267 if (!found) {
268 acpi_handle bridge_handle = acpi_pci_get_bridge_handle(pbus); 268 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
269 if (!bridge_handle)
270 return 0;
271 acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle, (u32)1,
272 is_pci_dock_device, (void *)&found, NULL); 269 is_pci_dock_device, (void *)&found, NULL);
273 } 270 }
274 return found; 271 return found;
275} 272}
276 273
277
278/* decode ACPI 2.0 _HPP hot plug parameters */
279static void decode_hpp(struct acpiphp_bridge *bridge)
280{
281 acpi_status status;
282
283 status = acpi_get_hp_params_from_firmware(bridge->pci_bus, &bridge->hpp);
284 if (ACPI_FAILURE(status) ||
285 !bridge->hpp.t0 || (bridge->hpp.t0->revision > 1)) {
286 /* use default numbers */
287 printk(KERN_WARNING
288 "%s: Could not get hotplug parameters. Use defaults\n",
289 __func__);
290 bridge->hpp.t0 = &bridge->hpp.type0_data;
291 bridge->hpp.t0->revision = 0;
292 bridge->hpp.t0->cache_line_size = 0x10;
293 bridge->hpp.t0->latency_timer = 0x40;
294 bridge->hpp.t0->enable_serr = 0;
295 bridge->hpp.t0->enable_perr = 0;
296 }
297}
298
299
300
301/* initialize miscellaneous stuff for both root and PCI-to-PCI bridge */ 274/* initialize miscellaneous stuff for both root and PCI-to-PCI bridge */
302static void init_bridge_misc(struct acpiphp_bridge *bridge) 275static void init_bridge_misc(struct acpiphp_bridge *bridge)
303{ 276{
304 acpi_status status; 277 acpi_status status;
305 278
306 /* decode ACPI 2.0 _HPP (hot plug parameters) */
307 decode_hpp(bridge);
308
309 /* must be added to the list prior to calling register_slot */ 279 /* must be added to the list prior to calling register_slot */
310 list_add(&bridge->list, &bridge_list); 280 list_add(&bridge->list, &bridge_list);
311 281
@@ -399,9 +369,10 @@ static inline void config_p2p_bridge_flags(struct acpiphp_bridge *bridge)
399 369
400 370
401/* allocate and initialize host bridge data structure */ 371/* allocate and initialize host bridge data structure */
402static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus) 372static void add_host_bridge(acpi_handle *handle)
403{ 373{
404 struct acpiphp_bridge *bridge; 374 struct acpiphp_bridge *bridge;
375 struct acpi_pci_root *root = acpi_pci_find_root(handle);
405 376
406 bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); 377 bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
407 if (bridge == NULL) 378 if (bridge == NULL)
@@ -410,7 +381,7 @@ static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus)
410 bridge->type = BRIDGE_TYPE_HOST; 381 bridge->type = BRIDGE_TYPE_HOST;
411 bridge->handle = handle; 382 bridge->handle = handle;
412 383
413 bridge->pci_bus = pci_bus; 384 bridge->pci_bus = root->bus;
414 385
415 spin_lock_init(&bridge->res_lock); 386 spin_lock_init(&bridge->res_lock);
416 387
@@ -419,7 +390,7 @@ static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus)
419 390
420 391
421/* allocate and initialize PCI-to-PCI bridge data structure */ 392/* allocate and initialize PCI-to-PCI bridge data structure */
422static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev) 393static void add_p2p_bridge(acpi_handle *handle)
423{ 394{
424 struct acpiphp_bridge *bridge; 395 struct acpiphp_bridge *bridge;
425 396
@@ -433,8 +404,8 @@ static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev)
433 bridge->handle = handle; 404 bridge->handle = handle;
434 config_p2p_bridge_flags(bridge); 405 config_p2p_bridge_flags(bridge);
435 406
436 bridge->pci_dev = pci_dev_get(pci_dev); 407 bridge->pci_dev = acpi_get_pci_dev(handle);
437 bridge->pci_bus = pci_dev->subordinate; 408 bridge->pci_bus = bridge->pci_dev->subordinate;
438 if (!bridge->pci_bus) { 409 if (!bridge->pci_bus) {
439 err("This is not a PCI-to-PCI bridge!\n"); 410 err("This is not a PCI-to-PCI bridge!\n");
440 goto err; 411 goto err;
@@ -451,7 +422,7 @@ static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev)
451 init_bridge_misc(bridge); 422 init_bridge_misc(bridge);
452 return; 423 return;
453 err: 424 err:
454 pci_dev_put(pci_dev); 425 pci_dev_put(bridge->pci_dev);
455 kfree(bridge); 426 kfree(bridge);
456 return; 427 return;
457} 428}
@@ -462,39 +433,21 @@ static acpi_status
462find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) 433find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
463{ 434{
464 acpi_status status; 435 acpi_status status;
465 acpi_handle dummy_handle;
466 unsigned long long tmp;
467 int device, function;
468 struct pci_dev *dev; 436 struct pci_dev *dev;
469 struct pci_bus *pci_bus = context;
470
471 status = acpi_get_handle(handle, "_ADR", &dummy_handle);
472 if (ACPI_FAILURE(status))
473 return AE_OK; /* continue */
474
475 status = acpi_evaluate_integer(handle, "_ADR", NULL, &tmp);
476 if (ACPI_FAILURE(status)) {
477 dbg("%s: _ADR evaluation failure\n", __func__);
478 return AE_OK;
479 }
480
481 device = (tmp >> 16) & 0xffff;
482 function = tmp & 0xffff;
483
484 dev = pci_get_slot(pci_bus, PCI_DEVFN(device, function));
485 437
438 dev = acpi_get_pci_dev(handle);
486 if (!dev || !dev->subordinate) 439 if (!dev || !dev->subordinate)
487 goto out; 440 goto out;
488 441
489 /* check if this bridge has ejectable slots */ 442 /* check if this bridge has ejectable slots */
490 if ((detect_ejectable_slots(dev->subordinate) > 0)) { 443 if ((detect_ejectable_slots(handle) > 0)) {
491 dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev)); 444 dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev));
492 add_p2p_bridge(handle, dev); 445 add_p2p_bridge(handle);
493 } 446 }
494 447
495 /* search P2P bridges under this p2p bridge */ 448 /* search P2P bridges under this p2p bridge */
496 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, 449 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
497 find_p2p_bridge, dev->subordinate, NULL); 450 find_p2p_bridge, NULL, NULL);
498 if (ACPI_FAILURE(status)) 451 if (ACPI_FAILURE(status))
499 warn("find_p2p_bridge failed (error code = 0x%x)\n", status); 452 warn("find_p2p_bridge failed (error code = 0x%x)\n", status);
500 453
@@ -509,9 +462,7 @@ static int add_bridge(acpi_handle handle)
509{ 462{
510 acpi_status status; 463 acpi_status status;
511 unsigned long long tmp; 464 unsigned long long tmp;
512 int seg, bus;
513 acpi_handle dummy_handle; 465 acpi_handle dummy_handle;
514 struct pci_bus *pci_bus;
515 466
516 /* if the bridge doesn't have _STA, we assume it is always there */ 467 /* if the bridge doesn't have _STA, we assume it is always there */
517 status = acpi_get_handle(handle, "_STA", &dummy_handle); 468 status = acpi_get_handle(handle, "_STA", &dummy_handle);
@@ -526,36 +477,15 @@ static int add_bridge(acpi_handle handle)
526 return 0; 477 return 0;
527 } 478 }
528 479
529 /* get PCI segment number */
530 status = acpi_evaluate_integer(handle, "_SEG", NULL, &tmp);
531
532 seg = ACPI_SUCCESS(status) ? tmp : 0;
533
534 /* get PCI bus number */
535 status = acpi_evaluate_integer(handle, "_BBN", NULL, &tmp);
536
537 if (ACPI_SUCCESS(status)) {
538 bus = tmp;
539 } else {
540 warn("can't get bus number, assuming 0\n");
541 bus = 0;
542 }
543
544 pci_bus = pci_find_bus(seg, bus);
545 if (!pci_bus) {
546 err("Can't find bus %04x:%02x\n", seg, bus);
547 return 0;
548 }
549
550 /* check if this bridge has ejectable slots */ 480 /* check if this bridge has ejectable slots */
551 if (detect_ejectable_slots(pci_bus) > 0) { 481 if (detect_ejectable_slots(handle) > 0) {
552 dbg("found PCI host-bus bridge with hot-pluggable slots\n"); 482 dbg("found PCI host-bus bridge with hot-pluggable slots\n");
553 add_host_bridge(handle, pci_bus); 483 add_host_bridge(handle);
554 } 484 }
555 485
556 /* search P2P bridges under this host bridge */ 486 /* search P2P bridges under this host bridge */
557 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, 487 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
558 find_p2p_bridge, pci_bus, NULL); 488 find_p2p_bridge, NULL, NULL);
559 489
560 if (ACPI_FAILURE(status)) 490 if (ACPI_FAILURE(status))
561 warn("find_p2p_bridge failed (error code = 0x%x)\n", status); 491 warn("find_p2p_bridge failed (error code = 0x%x)\n", status);
@@ -1083,7 +1013,7 @@ static int __ref enable_device(struct acpiphp_slot *slot)
1083 1013
1084 pci_bus_assign_resources(bus); 1014 pci_bus_assign_resources(bus);
1085 acpiphp_sanitize_bus(bus); 1015 acpiphp_sanitize_bus(bus);
1086 acpiphp_set_hpp_values(slot->bridge->handle, bus); 1016 acpiphp_set_hpp_values(bus);
1087 list_for_each_entry(func, &slot->funcs, sibling) 1017 list_for_each_entry(func, &slot->funcs, sibling)
1088 acpiphp_configure_ioapics(func->handle); 1018 acpiphp_configure_ioapics(func->handle);
1089 pci_enable_bridges(bus); 1019 pci_enable_bridges(bus);
@@ -1294,70 +1224,12 @@ static int acpiphp_check_bridge(struct acpiphp_bridge *bridge)
1294 return retval; 1224 return retval;
1295} 1225}
1296 1226
1297static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge) 1227static void acpiphp_set_hpp_values(struct pci_bus *bus)
1298{ 1228{
1299 u16 pci_cmd, pci_bctl;
1300 struct pci_dev *cdev;
1301
1302 /* Program hpp values for this device */
1303 if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
1304 (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
1305 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
1306 return;
1307
1308 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST)
1309 return;
1310
1311 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
1312 bridge->hpp.t0->cache_line_size);
1313 pci_write_config_byte(dev, PCI_LATENCY_TIMER,
1314 bridge->hpp.t0->latency_timer);
1315 pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
1316 if (bridge->hpp.t0->enable_serr)
1317 pci_cmd |= PCI_COMMAND_SERR;
1318 else
1319 pci_cmd &= ~PCI_COMMAND_SERR;
1320 if (bridge->hpp.t0->enable_perr)
1321 pci_cmd |= PCI_COMMAND_PARITY;
1322 else
1323 pci_cmd &= ~PCI_COMMAND_PARITY;
1324 pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
1325
1326 /* Program bridge control value and child devices */
1327 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
1328 pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
1329 bridge->hpp.t0->latency_timer);
1330 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
1331 if (bridge->hpp.t0->enable_serr)
1332 pci_bctl |= PCI_BRIDGE_CTL_SERR;
1333 else
1334 pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
1335 if (bridge->hpp.t0->enable_perr)
1336 pci_bctl |= PCI_BRIDGE_CTL_PARITY;
1337 else
1338 pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
1339 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
1340 if (dev->subordinate) {
1341 list_for_each_entry(cdev, &dev->subordinate->devices,
1342 bus_list)
1343 program_hpp(cdev, bridge);
1344 }
1345 }
1346}
1347
1348static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus)
1349{
1350 struct acpiphp_bridge bridge;
1351 struct pci_dev *dev; 1229 struct pci_dev *dev;
1352 1230
1353 memset(&bridge, 0, sizeof(bridge));
1354 bridge.handle = handle;
1355 bridge.pci_bus = bus;
1356 bridge.pci_dev = bus->self;
1357 decode_hpp(&bridge);
1358 list_for_each_entry(dev, &bus->devices, bus_list) 1231 list_for_each_entry(dev, &bus->devices, bus_list)
1359 program_hpp(dev, &bridge); 1232 pci_configure_slot(dev);
1360
1361} 1233}
1362 1234
1363/* 1235/*
@@ -1387,24 +1259,23 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus)
1387/* Program resources in newly inserted bridge */ 1259/* Program resources in newly inserted bridge */
1388static int acpiphp_configure_bridge (acpi_handle handle) 1260static int acpiphp_configure_bridge (acpi_handle handle)
1389{ 1261{
1390 struct pci_dev *dev;
1391 struct pci_bus *bus; 1262 struct pci_bus *bus;
1392 1263
1393 dev = acpi_get_pci_dev(handle); 1264 if (acpi_is_root_bridge(handle)) {
1394 if (!dev) { 1265 struct acpi_pci_root *root = acpi_pci_find_root(handle);
1395 err("cannot get PCI domain and bus number for bridge\n"); 1266 bus = root->bus;
1396 return -EINVAL; 1267 } else {
1268 struct pci_dev *pdev = acpi_get_pci_dev(handle);
1269 bus = pdev->subordinate;
1270 pci_dev_put(pdev);
1397 } 1271 }
1398 1272
1399 bus = dev->bus;
1400
1401 pci_bus_size_bridges(bus); 1273 pci_bus_size_bridges(bus);
1402 pci_bus_assign_resources(bus); 1274 pci_bus_assign_resources(bus);
1403 acpiphp_sanitize_bus(bus); 1275 acpiphp_sanitize_bus(bus);
1404 acpiphp_set_hpp_values(handle, bus); 1276 acpiphp_set_hpp_values(bus);
1405 pci_enable_bridges(bus); 1277 pci_enable_bridges(bus);
1406 acpiphp_configure_ioapics(handle); 1278 acpiphp_configure_ioapics(handle);
1407 pci_dev_put(dev);
1408 return 0; 1279 return 0;
1409} 1280}
1410 1281
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
index 5c5043f239cf..0325d989bb46 100644
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -86,7 +86,8 @@ static char *pci_bus_speed_strings[] = {
86 "66 MHz PCIX 533", /* 0x11 */ 86 "66 MHz PCIX 533", /* 0x11 */
87 "100 MHz PCIX 533", /* 0x12 */ 87 "100 MHz PCIX 533", /* 0x12 */
88 "133 MHz PCIX 533", /* 0x13 */ 88 "133 MHz PCIX 533", /* 0x13 */
89 "25 GBps PCI-E", /* 0x14 */ 89 "2.5 GT/s PCI-E", /* 0x14 */
90 "5.0 GT/s PCI-E", /* 0x15 */
90}; 91};
91 92
92#ifdef CONFIG_HOTPLUG_PCI_CPCI 93#ifdef CONFIG_HOTPLUG_PCI_CPCI
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index e6cf096498be..36faa9a8e18f 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -237,17 +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 if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev->bus, hpp)))
245 return -ENODEV;
246 return 0;
247}
248#else 240#else
249#define pciehp_firmware_init() do {} while (0) 241#define pciehp_firmware_init() do {} while (0)
250#define pciehp_get_hp_hw_control_from_firmware(dev) 0 242#define pciehp_get_hp_hw_control_from_firmware(dev) 0
251#define pciehp_get_hp_params_from_firmware(dev, hpp) (-ENODEV)
252#endif /* CONFIG_ACPI */ 243#endif /* CONFIG_ACPI */
253#endif /* _PCIEHP_H */ 244#endif /* _PCIEHP_H */
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c
index 96048010e7d9..7163e6a6cfae 100644
--- a/drivers/pci/hotplug/pciehp_acpi.c
+++ b/drivers/pci/hotplug/pciehp_acpi.c
@@ -47,7 +47,7 @@ int pciehp_acpi_slot_detection_check(struct pci_dev *dev)
47{ 47{
48 if (slot_detection_mode != PCIEHP_DETECT_ACPI) 48 if (slot_detection_mode != PCIEHP_DETECT_ACPI)
49 return 0; 49 return 0;
50 if (acpi_pci_detect_ejectable(dev->subordinate)) 50 if (acpi_pci_detect_ejectable(DEVICE_ACPI_HANDLE(&dev->dev)))
51 return 0; 51 return 0;
52 return -ENODEV; 52 return -ENODEV;
53} 53}
@@ -76,9 +76,9 @@ static int __init dummy_probe(struct pcie_device *dev)
76{ 76{
77 int pos; 77 int pos;
78 u32 slot_cap; 78 u32 slot_cap;
79 acpi_handle handle;
79 struct slot *slot, *tmp; 80 struct slot *slot, *tmp;
80 struct pci_dev *pdev = dev->port; 81 struct pci_dev *pdev = dev->port;
81 struct pci_bus *pbus = pdev->subordinate;
82 /* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */ 82 /* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */
83 if (pciehp_get_hp_hw_control_from_firmware(pdev)) 83 if (pciehp_get_hp_hw_control_from_firmware(pdev))
84 return -ENODEV; 84 return -ENODEV;
@@ -94,7 +94,8 @@ static int __init dummy_probe(struct pcie_device *dev)
94 dup_slot_id++; 94 dup_slot_id++;
95 } 95 }
96 list_add_tail(&slot->slot_list, &dummy_slots); 96 list_add_tail(&slot->slot_list, &dummy_slots);
97 if (!acpi_slot_detected && acpi_pci_detect_ejectable(pbus)) 97 handle = DEVICE_ACPI_HANDLE(&pdev->dev);
98 if (!acpi_slot_detected && acpi_pci_detect_ejectable(handle))
98 acpi_slot_detected = 1; 99 acpi_slot_detected = 1;
99 return -ENODEV; /* dummy driver always returns error */ 100 return -ENODEV; /* dummy driver always returns error */
100} 101}
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 8aab8edf123e..b97cb4c3e0fe 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -246,11 +246,6 @@ static int board_added(struct slot *p_slot)
246 goto err_exit; 246 goto err_exit;
247 } 247 }
248 248
249 /*
250 * Some PCI Express root ports require fixup after hot-plug operation.
251 */
252 if (pcie_mch_quirk)
253 pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
254 if (PWR_LED(ctrl)) 249 if (PWR_LED(ctrl))
255 p_slot->hpc_ops->green_led_on(p_slot); 250 p_slot->hpc_ops->green_led_on(p_slot);
256 251
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 52813257e5bf..271f917b6f2c 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -693,7 +693,10 @@ static int hpc_get_max_lnk_speed(struct slot *slot, enum pci_bus_speed *value)
693 693
694 switch (lnk_cap & 0x000F) { 694 switch (lnk_cap & 0x000F) {
695 case 1: 695 case 1:
696 lnk_speed = PCIE_2PT5GB; 696 lnk_speed = PCIE_2_5GB;
697 break;
698 case 2:
699 lnk_speed = PCIE_5_0GB;
697 break; 700 break;
698 default: 701 default:
699 lnk_speed = PCIE_LNK_SPEED_UNKNOWN; 702 lnk_speed = PCIE_LNK_SPEED_UNKNOWN;
@@ -772,7 +775,10 @@ static int hpc_get_cur_lnk_speed(struct slot *slot, enum pci_bus_speed *value)
772 775
773 switch (lnk_status & PCI_EXP_LNKSTA_CLS) { 776 switch (lnk_status & PCI_EXP_LNKSTA_CLS) {
774 case 1: 777 case 1:
775 lnk_speed = PCIE_2PT5GB; 778 lnk_speed = PCIE_2_5GB;
779 break;
780 case 2:
781 lnk_speed = PCIE_5_0GB;
776 break; 782 break;
777 default: 783 default:
778 lnk_speed = PCIE_LNK_SPEED_UNKNOWN; 784 lnk_speed = PCIE_LNK_SPEED_UNKNOWN;
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
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
@@ -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}
diff --git a/drivers/pci/hotplug/pcihp_slot.c b/drivers/pci/hotplug/pcihp_slot.c
new file mode 100644
index 000000000000..cc8ec3aa41a7
--- /dev/null
+++ b/drivers/pci/hotplug/pcihp_slot.c
@@ -0,0 +1,187 @@
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/pci_hotplug.h>
28
29static struct hpp_type0 pci_default_type0 = {
30 .revision = 1,
31 .cache_line_size = 8,
32 .latency_timer = 0x40,
33 .enable_serr = 0,
34 .enable_perr = 0,
35};
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) {
42 /*
43 * Perhaps we *should* use default settings for PCIe, but
44 * pciehp didn't, so we won't either.
45 */
46 if (dev->is_pcie)
47 return;
48 dev_info(&dev->dev, "using default PCI settings\n");
49 hpp = &pci_default_type0;
50 }
51
52 if (hpp->revision > 1) {
53 dev_warn(&dev->dev,
54 "PCI settings rev %d not supported; using defaults\n",
55 hpp->revision);
56 hpp = &pci_default_type0;
57 }
58
59 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp->cache_line_size);
60 pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp->latency_timer);
61 pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
62 if (hpp->enable_serr)
63 pci_cmd |= PCI_COMMAND_SERR;
64 else
65 pci_cmd &= ~PCI_COMMAND_SERR;
66 if (hpp->enable_perr)
67 pci_cmd |= PCI_COMMAND_PARITY;
68 else
69 pci_cmd &= ~PCI_COMMAND_PARITY;
70 pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
71
72 /* Program bridge control value */
73 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
74 pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
75 hpp->latency_timer);
76 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
77 if (hpp->enable_serr)
78 pci_bctl |= PCI_BRIDGE_CTL_SERR;
79 else
80 pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
81 if (hpp->enable_perr)
82 pci_bctl |= PCI_BRIDGE_CTL_PARITY;
83 else
84 pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
85 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
86 }
87}
88
89static void program_hpp_type1(struct pci_dev *dev, struct hpp_type1 *hpp)
90{
91 if (hpp)
92 dev_warn(&dev->dev, "PCI-X settings not supported\n");
93}
94
95static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
96{
97 int pos;
98 u16 reg16;
99 u32 reg32;
100
101 if (!hpp)
102 return;
103
104 /* Find PCI Express capability */
105 pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
106 if (!pos)
107 return;
108
109 if (hpp->revision > 1) {
110 dev_warn(&dev->dev, "PCIe settings rev %d not supported\n",
111 hpp->revision);
112 return;
113 }
114
115 /* Initialize Device Control Register */
116 pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &reg16);
117 reg16 = (reg16 & hpp->pci_exp_devctl_and) | hpp->pci_exp_devctl_or;
118 pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16);
119
120 /* Initialize Link Control Register */
121 if (dev->subordinate) {
122 pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &reg16);
123 reg16 = (reg16 & hpp->pci_exp_lnkctl_and)
124 | hpp->pci_exp_lnkctl_or;
125 pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, reg16);
126 }
127
128 /* Find Advanced Error Reporting Enhanced Capability */
129 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
130 if (!pos)
131 return;
132
133 /* Initialize Uncorrectable Error Mask Register */
134 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, &reg32);
135 reg32 = (reg32 & hpp->unc_err_mask_and) | hpp->unc_err_mask_or;
136 pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, reg32);
137
138 /* Initialize Uncorrectable Error Severity Register */
139 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &reg32);
140 reg32 = (reg32 & hpp->unc_err_sever_and) | hpp->unc_err_sever_or;
141 pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, reg32);
142
143 /* Initialize Correctable Error Mask Register */
144 pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &reg32);
145 reg32 = (reg32 & hpp->cor_err_mask_and) | hpp->cor_err_mask_or;
146 pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg32);
147
148 /* Initialize Advanced Error Capabilities and Control Register */
149 pci_read_config_dword(dev, pos + PCI_ERR_CAP, &reg32);
150 reg32 = (reg32 & hpp->adv_err_cap_and) | hpp->adv_err_cap_or;
151 pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32);
152
153 /*
154 * FIXME: The following two registers are not supported yet.
155 *
156 * o Secondary Uncorrectable Error Severity Register
157 * o Secondary Uncorrectable Error Mask Register
158 */
159}
160
161void pci_configure_slot(struct pci_dev *dev)
162{
163 struct pci_dev *cdev;
164 struct hotplug_params hpp;
165 int ret;
166
167 if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
168 (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
169 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
170 return;
171
172 memset(&hpp, 0, sizeof(hpp));
173 ret = pci_get_hp_params(dev, &hpp);
174 if (ret)
175 dev_warn(&dev->dev, "no hotplug settings from platform\n");
176
177 program_hpp_type2(dev, hpp.t2);
178 program_hpp_type1(dev, hpp.t1);
179 program_hpp_type0(dev, hpp.t0);
180
181 if (dev->subordinate) {
182 list_for_each_entry(cdev, &dev->subordinate->devices,
183 bus_list)
184 pci_configure_slot(cdev);
185 }
186}
187EXPORT_SYMBOL_GPL(pci_configure_slot);
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index 974e924ca96d..bd588eb8e922 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -188,21 +188,12 @@ static inline const char *slot_name(struct slot *slot)
188 188
189#ifdef CONFIG_ACPI 189#ifdef CONFIG_ACPI
190#include <linux/pci-acpi.h> 190#include <linux/pci-acpi.h>
191static inline int get_hp_params_from_firmware(struct pci_dev *dev,
192 struct hotplug_params *hpp)
193{
194 if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev->bus, hpp)))
195 return -ENODEV;
196 return 0;
197}
198
199static inline int get_hp_hw_control_from_firmware(struct pci_dev *dev) 191static inline int get_hp_hw_control_from_firmware(struct pci_dev *dev)
200{ 192{
201 u32 flags = OSC_SHPC_NATIVE_HP_CONTROL; 193 u32 flags = OSC_SHPC_NATIVE_HP_CONTROL;
202 return acpi_get_hp_hw_control_from_firmware(dev, flags); 194 return acpi_get_hp_hw_control_from_firmware(dev, flags);
203} 195}
204#else 196#else
205#define get_hp_params_from_firmware(dev, hpp) (-ENODEV)
206#define get_hp_hw_control_from_firmware(dev) (0) 197#define get_hp_hw_control_from_firmware(dev) (0)
207#endif 198#endif
208 199
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index aa315e52529b..8c3d3219f227 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -34,66 +34,6 @@
34#include "../pci.h" 34#include "../pci.h"
35#include "shpchp.h" 35#include "shpchp.h"
36 36
37static void program_fw_provided_values(struct pci_dev *dev)
38{
39 u16 pci_cmd, pci_bctl;
40 struct pci_dev *cdev;
41 struct hotplug_params hpp;
42
43 /* Program hpp values for this device */
44 if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
45 (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
46 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
47 return;
48
49 /* use default values if we can't get them from firmware */
50 if (get_hp_params_from_firmware(dev, &hpp) ||
51 !hpp.t0 || (hpp.t0->revision > 1)) {
52 warn("Could not get hotplug parameters. Use defaults\n");
53 hpp.t0 = &hpp.type0_data;
54 hpp.t0->revision = 0;
55 hpp.t0->cache_line_size = 8;
56 hpp.t0->latency_timer = 0x40;
57 hpp.t0->enable_serr = 0;
58 hpp.t0->enable_perr = 0;
59 }
60
61 pci_write_config_byte(dev,
62 PCI_CACHE_LINE_SIZE, hpp.t0->cache_line_size);
63 pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp.t0->latency_timer);
64 pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
65 if (hpp.t0->enable_serr)
66 pci_cmd |= PCI_COMMAND_SERR;
67 else
68 pci_cmd &= ~PCI_COMMAND_SERR;
69 if (hpp.t0->enable_perr)
70 pci_cmd |= PCI_COMMAND_PARITY;
71 else
72 pci_cmd &= ~PCI_COMMAND_PARITY;
73 pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
74
75 /* Program bridge control value and child devices */
76 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
77 pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
78 hpp.t0->latency_timer);
79 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
80 if (hpp.t0->enable_serr)
81 pci_bctl |= PCI_BRIDGE_CTL_SERR;
82 else
83 pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
84 if (hpp.t0->enable_perr)
85 pci_bctl |= PCI_BRIDGE_CTL_PARITY;
86 else
87 pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
88 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
89 if (dev->subordinate) {
90 list_for_each_entry(cdev, &dev->subordinate->devices,
91 bus_list)
92 program_fw_provided_values(cdev);
93 }
94 }
95}
96
97int __ref shpchp_configure_device(struct slot *p_slot) 37int __ref shpchp_configure_device(struct slot *p_slot)
98{ 38{
99 struct pci_dev *dev; 39 struct pci_dev *dev;
@@ -153,7 +93,7 @@ int __ref shpchp_configure_device(struct slot *p_slot)
153 child->subordinate = pci_do_scan_bus(child); 93 child->subordinate = pci_do_scan_bus(child);
154 pci_bus_size_bridges(child); 94 pci_bus_size_bridges(child);
155 } 95 }
156 program_fw_provided_values(dev); 96 pci_configure_slot(dev);
157 pci_dev_put(dev); 97 pci_dev_put(dev);
158 } 98 }
159 99