Commit 26833a5029b710b12f00607fa255ce86909836ad

Authored by Gavin Shan
Committed by Benjamin Herrenschmidt
1 parent fd5cee7ce8

powerpc/eeh: Make the delay for PE reset unified

Basically, we have 3 types of resets to fulfil PE reset: fundamental,
hot and PHB reset. For the later 2 cases, we need PCI bus reset hold
and settlement delay as specified by PCI spec. PowerNV and pSeries
platforms are running on top of different firmware and some of the
delays have been covered by underly firmware (PowerNV).

The patch makes the delays unified to be done in backend, instead of
EEH core.

Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Showing 4 changed files with 30 additions and 15 deletions Side-by-side Diff

arch/powerpc/include/asm/eeh.h
... ... @@ -39,6 +39,16 @@
39 39 #define EEH_PROBE_MODE_DEVTREE 0x8 /* From device tree */
40 40  
41 41 /*
  42 + * Delay for PE reset, all in ms
  43 + *
  44 + * PCI specification has reset hold time of 100 milliseconds.
  45 + * We have 250 milliseconds here. The PCI bus settlement time
  46 + * is specified as 1.5 seconds and we have 1.8 seconds.
  47 + */
  48 +#define EEH_PE_RST_HOLD_TIME 250
  49 +#define EEH_PE_RST_SETTLE_TIME 1800
  50 +
  51 +/*
42 52 * The struct is used to trace PE related EEH functionality.
43 53 * In theory, there will have one instance of the struct to
44 54 * be created against particular PE. In nature, PEs corelate
arch/powerpc/kernel/eeh.c
... ... @@ -639,20 +639,7 @@
639 639 else
640 640 eeh_ops->reset(pe, EEH_RESET_HOT);
641 641  
642   - /* The PCI bus requires that the reset be held high for at least
643   - * a 100 milliseconds. We wait a bit longer 'just in case'.
644   - */
645   -#define PCI_BUS_RST_HOLD_TIME_MSEC 250
646   - msleep(PCI_BUS_RST_HOLD_TIME_MSEC);
647   -
648 642 eeh_ops->reset(pe, EEH_RESET_DEACTIVATE);
649   -
650   - /* After a PCI slot has been reset, the PCI Express spec requires
651   - * a 1.5 second idle time for the bus to stabilize, before starting
652   - * up traffic.
653   - */
654   -#define PCI_BUS_SETTLE_TIME_MSEC 1800
655   - msleep(PCI_BUS_SETTLE_TIME_MSEC);
656 643 }
657 644  
658 645 /**
arch/powerpc/platforms/powernv/eeh-ioda.c
... ... @@ -417,9 +417,13 @@
417 417  
418 418 /*
419 419 * Poll state of the PHB until the request is done
420   - * successfully.
  420 + * successfully. The PHB reset is usually PHB complete
  421 + * reset followed by hot reset on root bus. So we also
  422 + * need the PCI bus settlement delay.
421 423 */
422 424 rc = ioda_eeh_phb_poll(phb);
  425 + if (option == EEH_RESET_DEACTIVATE)
  426 + msleep(EEH_PE_RST_SETTLE_TIME);
423 427 out:
424 428 if (rc != OPAL_SUCCESS)
425 429 return -EIO;
... ... @@ -457,6 +461,8 @@
457 461  
458 462 /* Poll state of the PHB until the request is done */
459 463 rc = ioda_eeh_phb_poll(phb);
  464 + if (option == EEH_RESET_DEACTIVATE)
  465 + msleep(EEH_PE_RST_SETTLE_TIME);
460 466 out:
461 467 if (rc != OPAL_SUCCESS)
462 468 return -EIO;
463 469  
... ... @@ -480,11 +486,15 @@
480 486 eeh_ops->read_config(dn, PCI_BRIDGE_CONTROL, 2, &ctrl);
481 487 ctrl |= PCI_BRIDGE_CTL_BUS_RESET;
482 488 eeh_ops->write_config(dn, PCI_BRIDGE_CONTROL, 2, ctrl);
  489 +
  490 + msleep(EEH_PE_RST_HOLD_TIME);
483 491 break;
484 492 case EEH_RESET_DEACTIVATE:
485 493 eeh_ops->read_config(dn, PCI_BRIDGE_CONTROL, 2, &ctrl);
486 494 ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
487 495 eeh_ops->write_config(dn, PCI_BRIDGE_CONTROL, 2, ctrl);
  496 +
  497 + msleep(EEH_PE_RST_SETTLE_TIME);
488 498 break;
489 499 }
490 500  
arch/powerpc/platforms/pseries/eeh_pseries.c
... ... @@ -532,10 +532,18 @@
532 532 /* If fundamental-reset not supported, try hot-reset */
533 533 if (option == EEH_RESET_FUNDAMENTAL &&
534 534 ret == -8) {
  535 + option = EEH_RESET_HOT;
535 536 ret = rtas_call(ibm_set_slot_reset, 4, 1, NULL,
536 537 config_addr, BUID_HI(pe->phb->buid),
537   - BUID_LO(pe->phb->buid), EEH_RESET_HOT);
  538 + BUID_LO(pe->phb->buid), option);
538 539 }
  540 +
  541 + /* We need reset hold or settlement delay */
  542 + if (option == EEH_RESET_FUNDAMENTAL ||
  543 + option == EEH_RESET_HOT)
  544 + msleep(EEH_PE_RST_HOLD_TIME);
  545 + else
  546 + msleep(EEH_PE_RST_SETTLE_TIME);
539 547  
540 548 return ret;
541 549 }