diff options
| -rw-r--r-- | arch/powerpc/platforms/powernv/eeh-ioda.c | 235 | ||||
| -rw-r--r-- | arch/powerpc/platforms/powernv/eeh-powernv.c | 225 | ||||
| -rw-r--r-- | arch/powerpc/platforms/powernv/pci-ioda.c | 4 | ||||
| -rw-r--r-- | arch/powerpc/platforms/powernv/pci.h | 3 |
4 files changed, 223 insertions, 244 deletions
diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c index 94d94b4811ad..9fcfc45595ad 100644 --- a/arch/powerpc/platforms/powernv/eeh-ioda.c +++ b/arch/powerpc/platforms/powernv/eeh-ioda.c | |||
| @@ -34,240 +34,5 @@ | |||
| 34 | #include "powernv.h" | 34 | #include "powernv.h" |
| 35 | #include "pci.h" | 35 | #include "pci.h" |
| 36 | 36 | ||
| 37 | static s64 ioda_eeh_phb_poll(struct pnv_phb *phb) | ||
| 38 | { | ||
| 39 | s64 rc = OPAL_HARDWARE; | ||
| 40 | |||
| 41 | while (1) { | ||
| 42 | rc = opal_pci_poll(phb->opal_id); | ||
| 43 | if (rc <= 0) | ||
| 44 | break; | ||
| 45 | |||
| 46 | if (system_state < SYSTEM_RUNNING) | ||
| 47 | udelay(1000 * rc); | ||
| 48 | else | ||
| 49 | msleep(rc); | ||
| 50 | } | ||
| 51 | |||
| 52 | return rc; | ||
| 53 | } | ||
| 54 | |||
| 55 | int ioda_eeh_phb_reset(struct pci_controller *hose, int option) | ||
| 56 | { | ||
| 57 | struct pnv_phb *phb = hose->private_data; | ||
| 58 | s64 rc = OPAL_HARDWARE; | ||
| 59 | |||
| 60 | pr_debug("%s: Reset PHB#%x, option=%d\n", | ||
| 61 | __func__, hose->global_number, option); | ||
| 62 | |||
| 63 | /* Issue PHB complete reset request */ | ||
| 64 | if (option == EEH_RESET_FUNDAMENTAL || | ||
| 65 | option == EEH_RESET_HOT) | ||
| 66 | rc = opal_pci_reset(phb->opal_id, | ||
| 67 | OPAL_RESET_PHB_COMPLETE, | ||
| 68 | OPAL_ASSERT_RESET); | ||
| 69 | else if (option == EEH_RESET_DEACTIVATE) | ||
| 70 | rc = opal_pci_reset(phb->opal_id, | ||
| 71 | OPAL_RESET_PHB_COMPLETE, | ||
| 72 | OPAL_DEASSERT_RESET); | ||
| 73 | if (rc < 0) | ||
| 74 | goto out; | ||
| 75 | |||
| 76 | /* | ||
| 77 | * Poll state of the PHB until the request is done | ||
| 78 | * successfully. The PHB reset is usually PHB complete | ||
| 79 | * reset followed by hot reset on root bus. So we also | ||
| 80 | * need the PCI bus settlement delay. | ||
| 81 | */ | ||
| 82 | rc = ioda_eeh_phb_poll(phb); | ||
| 83 | if (option == EEH_RESET_DEACTIVATE) { | ||
| 84 | if (system_state < SYSTEM_RUNNING) | ||
| 85 | udelay(1000 * EEH_PE_RST_SETTLE_TIME); | ||
| 86 | else | ||
| 87 | msleep(EEH_PE_RST_SETTLE_TIME); | ||
| 88 | } | ||
| 89 | out: | ||
| 90 | if (rc != OPAL_SUCCESS) | ||
| 91 | return -EIO; | ||
| 92 | |||
| 93 | return 0; | ||
| 94 | } | ||
| 95 | |||
| 96 | static int ioda_eeh_root_reset(struct pci_controller *hose, int option) | ||
| 97 | { | ||
| 98 | struct pnv_phb *phb = hose->private_data; | ||
| 99 | s64 rc = OPAL_SUCCESS; | ||
| 100 | |||
| 101 | pr_debug("%s: Reset PHB#%x, option=%d\n", | ||
| 102 | __func__, hose->global_number, option); | ||
| 103 | |||
| 104 | /* | ||
| 105 | * During the reset deassert time, we needn't care | ||
| 106 | * the reset scope because the firmware does nothing | ||
| 107 | * for fundamental or hot reset during deassert phase. | ||
| 108 | */ | ||
| 109 | if (option == EEH_RESET_FUNDAMENTAL) | ||
| 110 | rc = opal_pci_reset(phb->opal_id, | ||
| 111 | OPAL_RESET_PCI_FUNDAMENTAL, | ||
| 112 | OPAL_ASSERT_RESET); | ||
| 113 | else if (option == EEH_RESET_HOT) | ||
| 114 | rc = opal_pci_reset(phb->opal_id, | ||
| 115 | OPAL_RESET_PCI_HOT, | ||
| 116 | OPAL_ASSERT_RESET); | ||
| 117 | else if (option == EEH_RESET_DEACTIVATE) | ||
| 118 | rc = opal_pci_reset(phb->opal_id, | ||
| 119 | OPAL_RESET_PCI_HOT, | ||
| 120 | OPAL_DEASSERT_RESET); | ||
| 121 | if (rc < 0) | ||
| 122 | goto out; | ||
| 123 | |||
| 124 | /* Poll state of the PHB until the request is done */ | ||
| 125 | rc = ioda_eeh_phb_poll(phb); | ||
| 126 | if (option == EEH_RESET_DEACTIVATE) | ||
| 127 | msleep(EEH_PE_RST_SETTLE_TIME); | ||
| 128 | out: | ||
| 129 | if (rc != OPAL_SUCCESS) | ||
| 130 | return -EIO; | ||
| 131 | |||
| 132 | return 0; | ||
| 133 | } | ||
| 134 | |||
| 135 | static int ioda_eeh_bridge_reset(struct pci_dev *dev, int option) | ||
| 136 | |||
| 137 | { | ||
| 138 | struct device_node *dn = pci_device_to_OF_node(dev); | ||
| 139 | struct eeh_dev *edev = of_node_to_eeh_dev(dn); | ||
| 140 | int aer = edev ? edev->aer_cap : 0; | ||
| 141 | u32 ctrl; | ||
| 142 | |||
| 143 | pr_debug("%s: Reset PCI bus %04x:%02x with option %d\n", | ||
| 144 | __func__, pci_domain_nr(dev->bus), | ||
| 145 | dev->bus->number, option); | ||
| 146 | |||
| 147 | switch (option) { | ||
| 148 | case EEH_RESET_FUNDAMENTAL: | ||
| 149 | case EEH_RESET_HOT: | ||
| 150 | /* Don't report linkDown event */ | ||
| 151 | if (aer) { | ||
| 152 | eeh_ops->read_config(dn, aer + PCI_ERR_UNCOR_MASK, | ||
| 153 | 4, &ctrl); | ||
| 154 | ctrl |= PCI_ERR_UNC_SURPDN; | ||
| 155 | eeh_ops->write_config(dn, aer + PCI_ERR_UNCOR_MASK, | ||
| 156 | 4, ctrl); | ||
| 157 | } | ||
| 158 | |||
| 159 | eeh_ops->read_config(dn, PCI_BRIDGE_CONTROL, 2, &ctrl); | ||
| 160 | ctrl |= PCI_BRIDGE_CTL_BUS_RESET; | ||
| 161 | eeh_ops->write_config(dn, PCI_BRIDGE_CONTROL, 2, ctrl); | ||
| 162 | msleep(EEH_PE_RST_HOLD_TIME); | ||
| 163 | |||
| 164 | break; | ||
| 165 | case EEH_RESET_DEACTIVATE: | ||
| 166 | eeh_ops->read_config(dn, PCI_BRIDGE_CONTROL, 2, &ctrl); | ||
| 167 | ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET; | ||
| 168 | eeh_ops->write_config(dn, PCI_BRIDGE_CONTROL, 2, ctrl); | ||
| 169 | msleep(EEH_PE_RST_SETTLE_TIME); | ||
| 170 | |||
| 171 | /* Continue reporting linkDown event */ | ||
| 172 | if (aer) { | ||
| 173 | eeh_ops->read_config(dn, aer + PCI_ERR_UNCOR_MASK, | ||
| 174 | 4, &ctrl); | ||
| 175 | ctrl &= ~PCI_ERR_UNC_SURPDN; | ||
| 176 | eeh_ops->write_config(dn, aer + PCI_ERR_UNCOR_MASK, | ||
| 177 | 4, ctrl); | ||
| 178 | } | ||
| 179 | |||
| 180 | break; | ||
| 181 | } | ||
| 182 | |||
| 183 | return 0; | ||
| 184 | } | ||
| 185 | |||
| 186 | void pnv_pci_reset_secondary_bus(struct pci_dev *dev) | ||
| 187 | { | ||
| 188 | struct pci_controller *hose; | ||
| 189 | |||
| 190 | if (pci_is_root_bus(dev->bus)) { | ||
| 191 | hose = pci_bus_to_host(dev->bus); | ||
| 192 | ioda_eeh_root_reset(hose, EEH_RESET_HOT); | ||
| 193 | ioda_eeh_root_reset(hose, EEH_RESET_DEACTIVATE); | ||
| 194 | } else { | ||
| 195 | ioda_eeh_bridge_reset(dev, EEH_RESET_HOT); | ||
| 196 | ioda_eeh_bridge_reset(dev, EEH_RESET_DEACTIVATE); | ||
| 197 | } | ||
| 198 | } | ||
| 199 | |||
| 200 | /** | ||
| 201 | * ioda_eeh_reset - Reset the indicated PE | ||
| 202 | * @pe: EEH PE | ||
| 203 | * @option: reset option | ||
| 204 | * | ||
| 205 | * Do reset on the indicated PE. For PCI bus sensitive PE, | ||
| 206 | * we need to reset the parent p2p bridge. The PHB has to | ||
| 207 | * be reinitialized if the p2p bridge is root bridge. For | ||
| 208 | * PCI device sensitive PE, we will try to reset the device | ||
| 209 | * through FLR. For now, we don't have OPAL APIs to do HARD | ||
| 210 | * reset yet, so all reset would be SOFT (HOT) reset. | ||
| 211 | */ | ||
| 212 | static int ioda_eeh_reset(struct eeh_pe *pe, int option) | ||
| 213 | { | ||
| 214 | struct pci_controller *hose = pe->phb; | ||
| 215 | struct pci_bus *bus; | ||
| 216 | int ret; | ||
| 217 | |||
| 218 | /* | ||
| 219 | * For PHB reset, we always have complete reset. For those PEs whose | ||
| 220 | * primary bus derived from root complex (root bus) or root port | ||
| 221 | * (usually bus#1), we apply hot or fundamental reset on the root port. | ||
| 222 | * For other PEs, we always have hot reset on the PE primary bus. | ||
| 223 | * | ||
| 224 | * Here, we have different design to pHyp, which always clear the | ||
| 225 | * frozen state during PE reset. However, the good idea here from | ||
| 226 | * benh is to keep frozen state before we get PE reset done completely | ||
| 227 | * (until BAR restore). With the frozen state, HW drops illegal IO | ||
| 228 | * or MMIO access, which can incur recrusive frozen PE during PE | ||
| 229 | * reset. The side effect is that EEH core has to clear the frozen | ||
| 230 | * state explicitly after BAR restore. | ||
| 231 | */ | ||
| 232 | if (pe->type & EEH_PE_PHB) { | ||
| 233 | ret = ioda_eeh_phb_reset(hose, option); | ||
| 234 | } else { | ||
| 235 | struct pnv_phb *phb; | ||
| 236 | s64 rc; | ||
| 237 | |||
| 238 | /* | ||
| 239 | * The frozen PE might be caused by PAPR error injection | ||
| 240 | * registers, which are expected to be cleared after hitting | ||
| 241 | * frozen PE as stated in the hardware spec. Unfortunately, | ||
| 242 | * that's not true on P7IOC. So we have to clear it manually | ||
| 243 | * to avoid recursive EEH errors during recovery. | ||
| 244 | */ | ||
| 245 | phb = hose->private_data; | ||
| 246 | if (phb->model == PNV_PHB_MODEL_P7IOC && | ||
| 247 | (option == EEH_RESET_HOT || | ||
| 248 | option == EEH_RESET_FUNDAMENTAL)) { | ||
| 249 | rc = opal_pci_reset(phb->opal_id, | ||
| 250 | OPAL_RESET_PHB_ERROR, | ||
| 251 | OPAL_ASSERT_RESET); | ||
| 252 | if (rc != OPAL_SUCCESS) { | ||
| 253 | pr_warn("%s: Failure %lld clearing " | ||
| 254 | "error injection registers\n", | ||
| 255 | __func__, rc); | ||
| 256 | return -EIO; | ||
| 257 | } | ||
| 258 | } | ||
| 259 | |||
| 260 | bus = eeh_pe_bus_get(pe); | ||
| 261 | if (pci_is_root_bus(bus) || | ||
| 262 | pci_is_root_bus(bus->parent)) | ||
| 263 | ret = ioda_eeh_root_reset(hose, option); | ||
| 264 | else | ||
| 265 | ret = ioda_eeh_bridge_reset(bus->self, option); | ||
| 266 | } | ||
| 267 | |||
| 268 | return ret; | ||
| 269 | } | ||
| 270 | |||
| 271 | struct pnv_eeh_ops ioda_eeh_ops = { | 37 | struct pnv_eeh_ops ioda_eeh_ops = { |
| 272 | .reset = ioda_eeh_reset, | ||
| 273 | }; | 38 | }; |
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index e51ac2dfde50..ede690630dfc 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c | |||
| @@ -665,21 +665,236 @@ static int pnv_eeh_get_state(struct eeh_pe *pe, int *delay) | |||
| 665 | return ret; | 665 | return ret; |
| 666 | } | 666 | } |
| 667 | 667 | ||
| 668 | static s64 pnv_eeh_phb_poll(struct pnv_phb *phb) | ||
| 669 | { | ||
| 670 | s64 rc = OPAL_HARDWARE; | ||
| 671 | |||
| 672 | while (1) { | ||
| 673 | rc = opal_pci_poll(phb->opal_id); | ||
| 674 | if (rc <= 0) | ||
| 675 | break; | ||
| 676 | |||
| 677 | if (system_state < SYSTEM_RUNNING) | ||
| 678 | udelay(1000 * rc); | ||
| 679 | else | ||
| 680 | msleep(rc); | ||
| 681 | } | ||
| 682 | |||
| 683 | return rc; | ||
| 684 | } | ||
| 685 | |||
| 686 | int pnv_eeh_phb_reset(struct pci_controller *hose, int option) | ||
| 687 | { | ||
| 688 | struct pnv_phb *phb = hose->private_data; | ||
| 689 | s64 rc = OPAL_HARDWARE; | ||
| 690 | |||
| 691 | pr_debug("%s: Reset PHB#%x, option=%d\n", | ||
| 692 | __func__, hose->global_number, option); | ||
| 693 | |||
| 694 | /* Issue PHB complete reset request */ | ||
| 695 | if (option == EEH_RESET_FUNDAMENTAL || | ||
| 696 | option == EEH_RESET_HOT) | ||
| 697 | rc = opal_pci_reset(phb->opal_id, | ||
| 698 | OPAL_RESET_PHB_COMPLETE, | ||
| 699 | OPAL_ASSERT_RESET); | ||
| 700 | else if (option == EEH_RESET_DEACTIVATE) | ||
| 701 | rc = opal_pci_reset(phb->opal_id, | ||
| 702 | OPAL_RESET_PHB_COMPLETE, | ||
| 703 | OPAL_DEASSERT_RESET); | ||
| 704 | if (rc < 0) | ||
| 705 | goto out; | ||
| 706 | |||
| 707 | /* | ||
| 708 | * Poll state of the PHB until the request is done | ||
| 709 | * successfully. The PHB reset is usually PHB complete | ||
| 710 | * reset followed by hot reset on root bus. So we also | ||
| 711 | * need the PCI bus settlement delay. | ||
| 712 | */ | ||
| 713 | rc = pnv_eeh_phb_poll(phb); | ||
| 714 | if (option == EEH_RESET_DEACTIVATE) { | ||
| 715 | if (system_state < SYSTEM_RUNNING) | ||
| 716 | udelay(1000 * EEH_PE_RST_SETTLE_TIME); | ||
| 717 | else | ||
| 718 | msleep(EEH_PE_RST_SETTLE_TIME); | ||
| 719 | } | ||
| 720 | out: | ||
| 721 | if (rc != OPAL_SUCCESS) | ||
| 722 | return -EIO; | ||
| 723 | |||
| 724 | return 0; | ||
| 725 | } | ||
| 726 | |||
| 727 | static int pnv_eeh_root_reset(struct pci_controller *hose, int option) | ||
| 728 | { | ||
| 729 | struct pnv_phb *phb = hose->private_data; | ||
| 730 | s64 rc = OPAL_HARDWARE; | ||
| 731 | |||
| 732 | pr_debug("%s: Reset PHB#%x, option=%d\n", | ||
| 733 | __func__, hose->global_number, option); | ||
| 734 | |||
| 735 | /* | ||
| 736 | * During the reset deassert time, we needn't care | ||
| 737 | * the reset scope because the firmware does nothing | ||
| 738 | * for fundamental or hot reset during deassert phase. | ||
| 739 | */ | ||
| 740 | if (option == EEH_RESET_FUNDAMENTAL) | ||
| 741 | rc = opal_pci_reset(phb->opal_id, | ||
| 742 | OPAL_RESET_PCI_FUNDAMENTAL, | ||
| 743 | OPAL_ASSERT_RESET); | ||
| 744 | else if (option == EEH_RESET_HOT) | ||
| 745 | rc = opal_pci_reset(phb->opal_id, | ||
| 746 | OPAL_RESET_PCI_HOT, | ||
| 747 | OPAL_ASSERT_RESET); | ||
| 748 | else if (option == EEH_RESET_DEACTIVATE) | ||
| 749 | rc = opal_pci_reset(phb->opal_id, | ||
| 750 | OPAL_RESET_PCI_HOT, | ||
| 751 | OPAL_DEASSERT_RESET); | ||
| 752 | if (rc < 0) | ||
| 753 | goto out; | ||
| 754 | |||
| 755 | /* Poll state of the PHB until the request is done */ | ||
| 756 | rc = pnv_eeh_phb_poll(phb); | ||
| 757 | if (option == EEH_RESET_DEACTIVATE) | ||
| 758 | msleep(EEH_PE_RST_SETTLE_TIME); | ||
| 759 | out: | ||
| 760 | if (rc != OPAL_SUCCESS) | ||
| 761 | return -EIO; | ||
| 762 | |||
| 763 | return 0; | ||
| 764 | } | ||
| 765 | |||
| 766 | static int pnv_eeh_bridge_reset(struct pci_dev *dev, int option) | ||
| 767 | { | ||
| 768 | struct device_node *dn = pci_device_to_OF_node(dev); | ||
| 769 | struct eeh_dev *edev = of_node_to_eeh_dev(dn); | ||
| 770 | int aer = edev ? edev->aer_cap : 0; | ||
| 771 | u32 ctrl; | ||
| 772 | |||
| 773 | pr_debug("%s: Reset PCI bus %04x:%02x with option %d\n", | ||
| 774 | __func__, pci_domain_nr(dev->bus), | ||
| 775 | dev->bus->number, option); | ||
| 776 | |||
| 777 | switch (option) { | ||
| 778 | case EEH_RESET_FUNDAMENTAL: | ||
| 779 | case EEH_RESET_HOT: | ||
| 780 | /* Don't report linkDown event */ | ||
| 781 | if (aer) { | ||
| 782 | eeh_ops->read_config(dn, aer + PCI_ERR_UNCOR_MASK, | ||
| 783 | 4, &ctrl); | ||
| 784 | ctrl |= PCI_ERR_UNC_SURPDN; | ||
| 785 | eeh_ops->write_config(dn, aer + PCI_ERR_UNCOR_MASK, | ||
| 786 | 4, ctrl); | ||
| 787 | } | ||
| 788 | |||
| 789 | eeh_ops->read_config(dn, PCI_BRIDGE_CONTROL, 2, &ctrl); | ||
| 790 | ctrl |= PCI_BRIDGE_CTL_BUS_RESET; | ||
| 791 | eeh_ops->write_config(dn, PCI_BRIDGE_CONTROL, 2, ctrl); | ||
| 792 | |||
| 793 | msleep(EEH_PE_RST_HOLD_TIME); | ||
| 794 | break; | ||
| 795 | case EEH_RESET_DEACTIVATE: | ||
| 796 | eeh_ops->read_config(dn, PCI_BRIDGE_CONTROL, 2, &ctrl); | ||
| 797 | ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET; | ||
| 798 | eeh_ops->write_config(dn, PCI_BRIDGE_CONTROL, 2, ctrl); | ||
| 799 | |||
| 800 | msleep(EEH_PE_RST_SETTLE_TIME); | ||
| 801 | |||
| 802 | /* Continue reporting linkDown event */ | ||
| 803 | if (aer) { | ||
| 804 | eeh_ops->read_config(dn, aer + PCI_ERR_UNCOR_MASK, | ||
| 805 | 4, &ctrl); | ||
| 806 | ctrl &= ~PCI_ERR_UNC_SURPDN; | ||
| 807 | eeh_ops->write_config(dn, aer + PCI_ERR_UNCOR_MASK, | ||
| 808 | 4, ctrl); | ||
| 809 | } | ||
| 810 | |||
| 811 | break; | ||
| 812 | } | ||
| 813 | |||
| 814 | return 0; | ||
| 815 | } | ||
| 816 | |||
| 817 | void pnv_pci_reset_secondary_bus(struct pci_dev *dev) | ||
| 818 | { | ||
| 819 | struct pci_controller *hose; | ||
| 820 | |||
| 821 | if (pci_is_root_bus(dev->bus)) { | ||
| 822 | hose = pci_bus_to_host(dev->bus); | ||
| 823 | pnv_eeh_root_reset(hose, EEH_RESET_HOT); | ||
| 824 | pnv_eeh_root_reset(hose, EEH_RESET_DEACTIVATE); | ||
| 825 | } else { | ||
| 826 | pnv_eeh_bridge_reset(dev, EEH_RESET_HOT); | ||
| 827 | pnv_eeh_bridge_reset(dev, EEH_RESET_DEACTIVATE); | ||
| 828 | } | ||
| 829 | } | ||
| 830 | |||
| 668 | /** | 831 | /** |
| 669 | * pnv_eeh_reset - Reset the specified PE | 832 | * pnv_eeh_reset - Reset the specified PE |
| 670 | * @pe: EEH PE | 833 | * @pe: EEH PE |
| 671 | * @option: reset option | 834 | * @option: reset option |
| 672 | * | 835 | * |
| 673 | * Reset the specified PE | 836 | * Do reset on the indicated PE. For PCI bus sensitive PE, |
| 837 | * we need to reset the parent p2p bridge. The PHB has to | ||
| 838 | * be reinitialized if the p2p bridge is root bridge. For | ||
| 839 | * PCI device sensitive PE, we will try to reset the device | ||
| 840 | * through FLR. For now, we don't have OPAL APIs to do HARD | ||
| 841 | * reset yet, so all reset would be SOFT (HOT) reset. | ||
| 674 | */ | 842 | */ |
| 675 | static int pnv_eeh_reset(struct eeh_pe *pe, int option) | 843 | static int pnv_eeh_reset(struct eeh_pe *pe, int option) |
| 676 | { | 844 | { |
| 677 | struct pci_controller *hose = pe->phb; | 845 | struct pci_controller *hose = pe->phb; |
| 678 | struct pnv_phb *phb = hose->private_data; | 846 | struct pci_bus *bus; |
| 679 | int ret = -EEXIST; | 847 | int ret; |
| 848 | |||
| 849 | /* | ||
| 850 | * For PHB reset, we always have complete reset. For those PEs whose | ||
| 851 | * primary bus derived from root complex (root bus) or root port | ||
| 852 | * (usually bus#1), we apply hot or fundamental reset on the root port. | ||
| 853 | * For other PEs, we always have hot reset on the PE primary bus. | ||
| 854 | * | ||
| 855 | * Here, we have different design to pHyp, which always clear the | ||
| 856 | * frozen state during PE reset. However, the good idea here from | ||
| 857 | * benh is to keep frozen state before we get PE reset done completely | ||
| 858 | * (until BAR restore). With the frozen state, HW drops illegal IO | ||
| 859 | * or MMIO access, which can incur recrusive frozen PE during PE | ||
| 860 | * reset. The side effect is that EEH core has to clear the frozen | ||
| 861 | * state explicitly after BAR restore. | ||
| 862 | */ | ||
| 863 | if (pe->type & EEH_PE_PHB) { | ||
| 864 | ret = pnv_eeh_phb_reset(hose, option); | ||
| 865 | } else { | ||
| 866 | struct pnv_phb *phb; | ||
| 867 | s64 rc; | ||
| 680 | 868 | ||
| 681 | if (phb->eeh_ops && phb->eeh_ops->reset) | 869 | /* |
| 682 | ret = phb->eeh_ops->reset(pe, option); | 870 | * The frozen PE might be caused by PAPR error injection |
| 871 | * registers, which are expected to be cleared after hitting | ||
| 872 | * frozen PE as stated in the hardware spec. Unfortunately, | ||
| 873 | * that's not true on P7IOC. So we have to clear it manually | ||
| 874 | * to avoid recursive EEH errors during recovery. | ||
| 875 | */ | ||
| 876 | phb = hose->private_data; | ||
| 877 | if (phb->model == PNV_PHB_MODEL_P7IOC && | ||
| 878 | (option == EEH_RESET_HOT || | ||
| 879 | option == EEH_RESET_FUNDAMENTAL)) { | ||
| 880 | rc = opal_pci_reset(phb->opal_id, | ||
| 881 | OPAL_RESET_PHB_ERROR, | ||
| 882 | OPAL_ASSERT_RESET); | ||
| 883 | if (rc != OPAL_SUCCESS) { | ||
| 884 | pr_warn("%s: Failure %lld clearing " | ||
| 885 | "error injection registers\n", | ||
| 886 | __func__, rc); | ||
| 887 | return -EIO; | ||
| 888 | } | ||
| 889 | } | ||
| 890 | |||
| 891 | bus = eeh_pe_bus_get(pe); | ||
| 892 | if (pci_is_root_bus(bus) || | ||
| 893 | pci_is_root_bus(bus->parent)) | ||
| 894 | ret = pnv_eeh_root_reset(hose, option); | ||
| 895 | else | ||
| 896 | ret = pnv_eeh_bridge_reset(bus->self, option); | ||
| 897 | } | ||
| 683 | 898 | ||
| 684 | return ret; | 899 | return ret; |
| 685 | } | 900 | } |
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 6c9ff2b95119..4e21596bed48 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c | |||
| @@ -2121,8 +2121,8 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np, | |||
| 2121 | */ | 2121 | */ |
| 2122 | if (is_kdump_kernel()) { | 2122 | if (is_kdump_kernel()) { |
| 2123 | pr_info(" Issue PHB reset ...\n"); | 2123 | pr_info(" Issue PHB reset ...\n"); |
| 2124 | ioda_eeh_phb_reset(hose, EEH_RESET_FUNDAMENTAL); | 2124 | pnv_eeh_phb_reset(hose, EEH_RESET_FUNDAMENTAL); |
| 2125 | ioda_eeh_phb_reset(hose, EEH_RESET_DEACTIVATE); | 2125 | pnv_eeh_phb_reset(hose, EEH_RESET_DEACTIVATE); |
| 2126 | } | 2126 | } |
| 2127 | 2127 | ||
| 2128 | /* Remove M64 resource if we can't configure it successfully */ | 2128 | /* Remove M64 resource if we can't configure it successfully */ |
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 5275d8928d94..39f2ca37b19e 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h | |||
| @@ -78,7 +78,6 @@ struct pnv_ioda_pe { | |||
| 78 | /* IOC dependent EEH operations */ | 78 | /* IOC dependent EEH operations */ |
| 79 | #ifdef CONFIG_EEH | 79 | #ifdef CONFIG_EEH |
| 80 | struct pnv_eeh_ops { | 80 | struct pnv_eeh_ops { |
| 81 | int (*reset)(struct eeh_pe *pe, int option); | ||
| 82 | }; | 81 | }; |
| 83 | #endif /* CONFIG_EEH */ | 82 | #endif /* CONFIG_EEH */ |
| 84 | 83 | ||
| @@ -223,6 +222,6 @@ extern void pnv_pci_init_ioda2_phb(struct device_node *np); | |||
| 223 | extern void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl, | 222 | extern void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl, |
| 224 | __be64 *startp, __be64 *endp, bool rm); | 223 | __be64 *startp, __be64 *endp, bool rm); |
| 225 | extern void pnv_pci_reset_secondary_bus(struct pci_dev *dev); | 224 | extern void pnv_pci_reset_secondary_bus(struct pci_dev *dev); |
| 226 | extern int ioda_eeh_phb_reset(struct pci_controller *hose, int option); | 225 | extern int pnv_eeh_phb_reset(struct pci_controller *hose, int option); |
| 227 | 226 | ||
| 228 | #endif /* __POWERNV_PCI_H */ | 227 | #endif /* __POWERNV_PCI_H */ |
