Merge tag 'powerpc-4.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
[cascardo/linux.git] / arch / powerpc / platforms / powernv / pci-ioda.c
index d314ecc..d4b33dd 100644 (file)
@@ -133,9 +133,22 @@ static inline bool pnv_pci_is_m64_flags(unsigned long resource_flags)
 
 static struct pnv_ioda_pe *pnv_ioda_init_pe(struct pnv_phb *phb, int pe_no)
 {
+       s64 rc;
+
        phb->ioda.pe_array[pe_no].phb = phb;
        phb->ioda.pe_array[pe_no].pe_number = pe_no;
 
+       /*
+        * Clear the PE frozen state as it might be put into frozen state
+        * in the last PCI remove path. It's not harmful to do so when the
+        * PE is already in unfrozen state.
+        */
+       rc = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no,
+                                      OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
+       if (rc != OPAL_SUCCESS)
+               pr_warn("%s: Error %lld unfreezing PHB#%d-PE#%d\n",
+                       __func__, rc, phb->hose->global_number, pe_no);
+
        return &phb->ioda.pe_array[pe_no];
 }
 
@@ -417,7 +430,7 @@ static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb)
        struct device_node *dn = hose->dn;
        struct resource *res;
        u32 m64_range[2], i;
-       const u32 *r;
+       const __be32 *r;
        u64 pci_addr;
 
        if (phb->type != PNV_PHB_IODA1 && phb->type != PNV_PHB_IODA2) {
@@ -3049,6 +3062,38 @@ static void pnv_ioda_setup_pe_seg(struct pnv_ioda_pe *pe)
        }
 }
 
+#ifdef CONFIG_DEBUG_FS
+static int pnv_pci_diag_data_set(void *data, u64 val)
+{
+       struct pci_controller *hose;
+       struct pnv_phb *phb;
+       s64 ret;
+
+       if (val != 1ULL)
+               return -EINVAL;
+
+       hose = (struct pci_controller *)data;
+       if (!hose || !hose->private_data)
+               return -ENODEV;
+
+       phb = hose->private_data;
+
+       /* Retrieve the diag data from firmware */
+       ret = opal_pci_get_phb_diag_data2(phb->opal_id, phb->diag.blob,
+                                         PNV_PCI_DIAG_BUF_SIZE);
+       if (ret != OPAL_SUCCESS)
+               return -EIO;
+
+       /* Print the diag data to the kernel log */
+       pnv_pci_dump_phb_diag_data(phb->hose, phb->diag.blob);
+       return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(pnv_pci_diag_data_fops, NULL,
+                       pnv_pci_diag_data_set, "%llu\n");
+
+#endif /* CONFIG_DEBUG_FS */
+
 static void pnv_pci_ioda_create_dbgfs(void)
 {
 #ifdef CONFIG_DEBUG_FS
@@ -3064,9 +3109,14 @@ static void pnv_pci_ioda_create_dbgfs(void)
 
                sprintf(name, "PCI%04x", hose->global_number);
                phb->dbgfs = debugfs_create_dir(name, powerpc_debugfs_root);
-               if (!phb->dbgfs)
+               if (!phb->dbgfs) {
                        pr_warning("%s: Error on creating debugfs on PHB#%x\n",
                                __func__, hose->global_number);
+                       continue;
+               }
+
+               debugfs_create_file("dump_diag_regs", 0200, phb->dbgfs, hose,
+                                   &pnv_pci_diag_data_fops);
        }
 #endif /* CONFIG_DEBUG_FS */
 }
@@ -3779,10 +3829,11 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
        if (rc)
                pr_warning("  OPAL Error %ld performing IODA table reset !\n", rc);
 
-       /* If we're running in kdump kerenl, the previous kerenl never
+       /*
+        * If we're running in kdump kernel, the previous kernel never
         * shutdown PCI devices correctly. We already got IODA table
         * cleaned out. So we have to issue PHB reset to stop all PCI
-        * transactions from previous kerenl.
+        * transactions from previous kernel.
         */
        if (is_kdump_kernel()) {
                pr_info("  Issue PHB reset ...\n");