LNKW_X8                 = 0x8
 };
 
-static inline int pcie_in_8(const volatile unsigned char __iomem *addr)
+static void pcie_dmer_disable(void)
 {
-       int ret;
-
-       PCIE_IN(lbzx, ret, addr);
-
-       return ret;
-}
-
-static inline int pcie_in_le16(const volatile unsigned short __iomem *addr)
-{
-       int ret;
-
-       PCIE_IN(lhbrx, ret, addr)
-
-       return ret;
+       mtdcr (DCRN_PEGPL_CFG(DCRN_PCIE0_BASE),
+               mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE0_BASE)) | GPL_DMER_MASK_DISA);
+       mtdcr (DCRN_PEGPL_CFG(DCRN_PCIE1_BASE),
+               mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE1_BASE)) | GPL_DMER_MASK_DISA);
+       mtdcr (DCRN_PEGPL_CFG(DCRN_PCIE2_BASE),
+               mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE2_BASE)) | GPL_DMER_MASK_DISA);
 }
 
-static inline unsigned pcie_in_le32(const volatile unsigned __iomem *addr)
+static void pcie_dmer_enable(void)
 {
-       unsigned ret;
-
-       PCIE_IN(lwbrx, ret, addr);
-
-       return ret;
+       mtdcr (DCRN_PEGPL_CFG (DCRN_PCIE0_BASE),
+               mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE0_BASE)) & ~GPL_DMER_MASK_DISA);
+       mtdcr (DCRN_PEGPL_CFG (DCRN_PCIE1_BASE),
+               mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE1_BASE)) & ~GPL_DMER_MASK_DISA);
+       mtdcr (DCRN_PEGPL_CFG (DCRN_PCIE2_BASE),
+               mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE2_BASE)) & ~GPL_DMER_MASK_DISA);
 }
 
 
        devfn = PCI_BDF(0,0,0);
        offset += devfn << 4;
 
+       /*
+        * Reading from configuration space of non-existing device can
+        * generate transaction errors. For the read duration we suppress
+        * assertion of machine check exceptions to avoid those.
+        */
+       pcie_dmer_disable ();
+
        switch (len) {
        case 1:
-               *val = pcie_in_8(hose->cfg_data + offset);
+               *val = in_8(hose->cfg_data + offset);
                break;
        case 2:
-               *val = pcie_in_le16((u16 *)(hose->cfg_data + offset));
+               *val = in_le16((u16 *)(hose->cfg_data + offset));
                break;
        default:
-               *val = pcie_in_le32((u32*)(hose->cfg_data + offset));
+               *val = in_le32((u32*)(hose->cfg_data + offset));
                break;
        }
+
+       pcie_dmer_enable ();
+
        return 0;
 }
 
        devfn = PCI_BDF(0,0,0);
        offset += devfn << 4;
 
+       /*
+        * Suppress MCK exceptions, similar to pcie_read_config()
+        */
+       pcie_dmer_disable ();
+
        switch (len) {
        case 1:
                out_8(hose->cfg_data + offset, val);
                out_le32((u32 *)(hose->cfg_data + offset), val);
                break;
        }
+
+       pcie_dmer_enable ();
+
        return 0;
 }
 
 
 #define DCRN_PEGPL_REGBAL(base)                (base + 0x13)
 #define DCRN_PEGPL_REGMSK(base)                (base + 0x14)
 #define DCRN_PEGPL_SPECIAL(base)       (base + 0x15)
+#define DCRN_PEGPL_CFG(base)           (base + 0x16)
 
 /*
  * System DCRs (SDRs)
        mtdcr(DCRN_SDR0_CFGADDR, offset); \
        mtdcr(DCRN_SDR0_CFGDATA,data);})
 
-#define PCIE_IN(opcode, ret, addr) \
-       __asm__ __volatile__(                   \
-               "sync\n"                        \
-               #opcode " %0,0,%1\n"            \
-               "1: twi 0,%0,0\n"               \
-               "isync\n"                       \
-               "b 3f\n"                        \
-               "2: li %0,-1\n"                 \
-               "3:\n"                          \
-               ".section __ex_table,\"a\"\n"   \
-               ".balign 4\n"                   \
-               ".long 1b,2b\n"                 \
-               ".previous\n"                   \
-               : "=r" (ret) : "r" (addr), "m" (*addr));
+#define GPL_DMER_MASK_DISA     0x02000000
 
 int ppc440spe_init_pcie(void);
 int ppc440spe_init_pcie_rootport(int port);
 
        int uncorr_ecc = 0;
 #endif
 
-       /* Probing PCI(E) using config cycles may cause this exception
-        * when a device is not present. To gracefully recover in such
-        * scenarios config read/write routines need to be instrumented in
-        * order to return via fixup handler. For examples refer to
-        * pcie_in_8(), pcie_in_le16() and pcie_in_le32()
-        */
        if ((fixup = search_exception_table(regs->nip)) != 0) {
                regs->nip = fixup;
                val = mfspr(MCSR);