#include <linux/bitmap.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#ifdef CONFIG_X86_64
+#include <asm/pat.h>
+#endif
 
 #include "ipath_kernel.h"
 #include "ipath_verbs.h"
        unsigned long long addr;
        u32 bar0 = 0, bar1 = 0;
 
+#ifdef CONFIG_X86_64
+       if (WARN(pat_enabled(),
+                "ipath needs PAT disabled, boot with nopat kernel parameter\n")) {
+               ret = -ENODEV;
+               goto bail;
+       }
+#endif
+
        dd = ipath_alloc_devdata(pdev);
        if (IS_ERR(dd)) {
                ret = PTR_ERR(dd);
        dd->ipath_kregbase = __ioremap(addr, len,
                (_PAGE_NO_CACHE|_PAGE_WRITETHRU));
 #else
+       /* XXX: split this properly to enable on PAT */
        dd->ipath_kregbase = ioremap_nocache(addr, len);
 #endif
 
 
        ret = ipath_enable_wc(dd);
 
-       if (ret) {
-               ipath_dev_err(dd, "Write combining not enabled "
-                             "(err %d): performance may be poor\n",
-                             -ret);
+       if (ret)
                ret = 0;
-       }
 
        ipath_verify_pioperf(dd);
 
 
        /* offset in HT config space of slave/primary interface block */
        u8 ipath_ht_slave_off;
        /* for write combining settings */
-       unsigned long ipath_wc_cookie;
-       unsigned long ipath_wc_base;
-       unsigned long ipath_wc_len;
+       int wc_cookie;
        /* ref count for each pkey */
        atomic_t ipath_pkeyrefs[4];
        /* shadow copy of struct page *'s for exp tid pages */
 
  */
 
 #include <linux/pci.h>
-#include <asm/mtrr.h>
 #include <asm/processor.h>
 
 #include "ipath_kernel.h"
        }
 
        if (!ret) {
-               int cookie;
-               ipath_cdbg(VERBOSE, "Setting mtrr for chip to WC "
-                          "(addr %llx, len=0x%llx)\n",
-                          (unsigned long long) pioaddr,
-                          (unsigned long long) piolen);
-               cookie = mtrr_add(pioaddr, piolen, MTRR_TYPE_WRCOMB, 0);
-               if (cookie < 0) {
-                       {
-                               dev_info(&dd->pcidev->dev,
-                                        "mtrr_add()  WC for PIO bufs "
-                                        "failed (%d)\n",
-                                        cookie);
-                               ret = -EINVAL;
-                       }
-               } else {
-                       ipath_cdbg(VERBOSE, "Set mtrr for chip to WC, "
-                                  "cookie is %d\n", cookie);
-                       dd->ipath_wc_cookie = cookie;
-                       dd->ipath_wc_base = (unsigned long) pioaddr;
-                       dd->ipath_wc_len = (unsigned long) piolen;
-               }
+               dd->wc_cookie = arch_phys_wc_add(pioaddr, piolen);
+               if (dd->wc_cookie < 0) {
+                       ipath_dev_err(dd, "Seting mtrr failed on PIO buffers\n");
+                       ret = -ENODEV;
+               } else if (dd->wc_cookie == 0)
+                       ipath_cdbg(VERBOSE, "Set mtrr for chip to WC not needed\n");
+               else
+                       ipath_cdbg(VERBOSE, "Set mtrr for chip to WC\n");
        }
 
        return ret;
  */
 void ipath_disable_wc(struct ipath_devdata *dd)
 {
-       if (dd->ipath_wc_cookie) {
-               int r;
-               ipath_cdbg(VERBOSE, "undoing WCCOMB on pio buffers\n");
-               r = mtrr_del(dd->ipath_wc_cookie, dd->ipath_wc_base,
-                            dd->ipath_wc_len);
-               if (r < 0)
-                       dev_info(&dd->pcidev->dev,
-                                "mtrr_del(%lx, %lx, %lx) failed: %d\n",
-                                dd->ipath_wc_cookie, dd->ipath_wc_base,
-                                dd->ipath_wc_len, r);
-               dd->ipath_wc_cookie = 0; /* even on failure */
-       }
+       arch_phys_wc_del(dd->wc_cookie);
 }