#include "pci_sun4v.h"
 
-#define PGLIST_NENTS   2048
+#define PGLIST_NENTS   (PAGE_SIZE / sizeof(u64))
 
 struct sun4v_pglist {
-       u64     pglist[PGLIST_NENTS];
+       u64     *pglist;
 };
 
 static DEFINE_PER_CPU(struct sun4v_pglist, iommu_pglists);
 {
        struct pcidev_cookie *pcp;
        struct pci_iommu *iommu;
-       unsigned long devhandle, flags, order, first_page, npages, n;
+       unsigned long flags, order, first_page, npages, n;
        void *ret;
        long entry;
        u64 *pglist;
+       u32 devhandle;
        int cpu;
 
        size = IO_PAGE_ALIGN(size);
 
        cpu = get_cpu();
 
-       pglist = &__get_cpu_var(iommu_pglists).pglist[0];
+       pglist = __get_cpu_var(iommu_pglists).pglist;
        for (n = 0; n < npages; n++)
                pglist[n] = first_page + (n * PAGE_SIZE);
 
 {
        struct pcidev_cookie *pcp;
        struct pci_iommu *iommu;
-       unsigned long flags, order, npages, entry, devhandle;
+       unsigned long flags, order, npages, entry;
+       u32 devhandle;
 
        npages = IO_PAGE_ALIGN(size) >> IO_PAGE_SHIFT;
        pcp = pdev->sysdata;
        struct pcidev_cookie *pcp;
        struct pci_iommu *iommu;
        unsigned long flags, npages, oaddr;
-       unsigned long i, base_paddr, devhandle;
-       u32 bus_addr, ret;
+       unsigned long i, base_paddr;
+       u32 devhandle, bus_addr, ret;
        unsigned long prot;
        long entry;
        u64 *pglist;
 
        cpu = get_cpu();
 
-       pglist = &__get_cpu_var(iommu_pglists).pglist[0];
+       pglist = __get_cpu_var(iommu_pglists).pglist;
        for (i = 0; i < npages; i++, base_paddr += IO_PAGE_SIZE)
                pglist[i] = base_paddr;
 
 {
        struct pcidev_cookie *pcp;
        struct pci_iommu *iommu;
-       unsigned long flags, npages, devhandle;
+       unsigned long flags, npages;
        long entry;
+       u32 devhandle;
 
        if (unlikely(direction == PCI_DMA_NONE)) {
                if (printk_ratelimit())
 #define SG_ENT_PHYS_ADDRESS(SG)        \
        (__pa(page_address((SG)->page)) + (SG)->offset)
 
-static inline void fill_sg(long entry, unsigned long devhandle,
+static inline void fill_sg(long entry, u32 devhandle,
                           struct scatterlist *sg,
                           int nused, int nelems, unsigned long prot)
 {
        u64 *pglist;
 
        cpu = get_cpu();
-       pglist = &__get_cpu_var(iommu_pglists).pglist[0];
+       pglist = __get_cpu_var(iommu_pglists).pglist;
        pglist_ent = 0;
        for (i = 0; i < nused; i++) {
                unsigned long pteval = ~0UL;
 {
        struct pcidev_cookie *pcp;
        struct pci_iommu *iommu;
-       unsigned long flags, npages, prot, devhandle;
-       u32 dma_base;
+       unsigned long flags, npages, prot;
+       u32 devhandle, dma_base;
        struct scatterlist *sgtmp;
        long entry;
        int used;
 {
        struct pcidev_cookie *pcp;
        struct pci_iommu *iommu;
-       unsigned long flags, i, npages, devhandle;
+       unsigned long flags, i, npages;
        long entry;
-       u32 bus_addr;
+       u32 devhandle, bus_addr;
 
        if (unlikely(direction == PCI_DMA_NONE)) {
                if (printk_ratelimit())
                                   struct pci_iommu *iommu)
 {
        struct pci_iommu_arena *arena = &iommu->arena;
-       unsigned long i, devhandle;
+       unsigned long i;
+       u32 devhandle;
 
        devhandle = pbm->devhandle;
        for (i = 0; i < arena->limit; i++) {
 
 }
 
-static void pci_sun4v_pbm_init(struct pci_controller_info *p, int prom_node, unsigned int devhandle)
+static void pci_sun4v_pbm_init(struct pci_controller_info *p, int prom_node, u32 devhandle)
 {
        struct pci_pbm_info *pbm;
        int err, i;
        struct pci_controller_info *p;
        struct pci_iommu *iommu;
        struct linux_prom64_registers regs;
-       unsigned int devhandle;
+       u32 devhandle;
+       int i;
 
        prom_getproperty(node, "reg", (char *)®s, sizeof(regs));
        devhandle = (regs.phys_addr >> 32UL) & 0x0fffffff;
                }
        }
 
-       p = kmalloc(sizeof(struct pci_controller_info), GFP_ATOMIC);
-       if (!p) {
-               prom_printf("SUN4V_PCI: Fatal memory allocation error.\n");
-               prom_halt();
+       for (i = 0; i < NR_CPUS; i++) {
+               unsigned long page = get_zeroed_page(GFP_ATOMIC);
+
+               if (!page)
+                       goto fatal_memory_error;
+
+               per_cpu(iommu_pglists, i).pglist = (u64 *) page;
        }
+
+       p = kmalloc(sizeof(struct pci_controller_info), GFP_ATOMIC);
+       if (!p)
+               goto fatal_memory_error;
+
        memset(p, 0, sizeof(*p));
 
        iommu = kmalloc(sizeof(struct pci_iommu), GFP_ATOMIC);
-       if (!iommu) {
-               prom_printf("SCHIZO: Fatal memory allocation error.\n");
-               prom_halt();
-       }
+       if (!iommu)
+               goto fatal_memory_error;
+
        memset(iommu, 0, sizeof(*iommu));
        p->pbm_A.iommu = iommu;
 
        iommu = kmalloc(sizeof(struct pci_iommu), GFP_ATOMIC);
-       if (!iommu) {
-               prom_printf("SCHIZO: Fatal memory allocation error.\n");
-               prom_halt();
-       }
+       if (!iommu)
+               goto fatal_memory_error;
+
        memset(iommu, 0, sizeof(*iommu));
        p->pbm_B.iommu = iommu;
 
        pci_memspace_mask = 0x7fffffffUL;
 
        pci_sun4v_pbm_init(p, node, devhandle);
+       return;
+
+fatal_memory_error:
+       prom_printf("SUN4V_PCI: Fatal memory allocation error.\n");
+       prom_halt();
 }