# Makefile for the linux kernel.
 #
 
-obj-y                  := gpio.o i2c.o pci.o setup.o time.o
+obj-y                  := gpio.o i2c.o pci.o setup.o time.o io.o
 obj-m                  :=
 obj-n                  :=
 obj-                   :=
 
--- /dev/null
+/*
+ * iop3xx custom ioremap implementation
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+void * __iomem __iop3xx_ioremap(unsigned long cookie, size_t size,
+       unsigned long flags)
+{
+       void __iomem * retval;
+
+       switch (cookie) {
+       case IOP3XX_PCI_LOWER_IO_PA ... IOP3XX_PCI_UPPER_IO_PA:
+               retval = (void *) IOP3XX_PCI_IO_PHYS_TO_VIRT(cookie);
+               break;
+       case IOP3XX_PERIPHERAL_PHYS_BASE ... IOP3XX_PERIPHERAL_UPPER_PA:
+               retval = (void *) IOP3XX_PMMR_PHYS_TO_VIRT(cookie);
+               break;
+       default:
+               retval = __ioremap(cookie, size, flags);
+       }
+
+       return retval;
+}
+EXPORT_SYMBOL(__iop3xx_ioremap);
+
+void __iop3xx_iounmap(void __iomem *addr)
+{
+       extern void __iounmap(volatile void __iomem *addr);
+
+       switch ((u32) addr) {
+       case IOP3XX_PCI_LOWER_IO_VA ... IOP3XX_PCI_UPPER_IO_VA:
+       case IOP3XX_PERIPHERAL_VIRT_BASE ... IOP3XX_PERIPHERAL_UPPER_VA:
+               goto skip;
+       }
+       __iounmap(addr);
+
+skip:
+       return;
+}
+EXPORT_SYMBOL(__iop3xx_iounmap);
 
        if (!res)
                panic("PCI: unable to alloc resources");
 
-       res[0].start = IOP3XX_PCI_LOWER_IO_VA;
-       res[0].end   = IOP3XX_PCI_LOWER_IO_VA + IOP3XX_PCI_IO_WINDOW_SIZE - 1;
+       res[0].start = IOP3XX_PCI_LOWER_IO_PA;
+       res[0].end   = IOP3XX_PCI_LOWER_IO_PA + IOP3XX_PCI_IO_WINDOW_SIZE - 1;
        res[0].name  = "IOP3XX PCI I/O Space";
        res[0].flags = IORESOURCE_IO;
        request_resource(&ioport_resource, &res[0]);
        request_resource(&iomem_resource, &res[1]);
 
        sys->mem_offset = IOP3XX_PCI_LOWER_MEM_PA - IOP3XX_PCI_LOWER_MEM_BA;
-       sys->io_offset  = IOP3XX_PCI_LOWER_IO_VA - IOP3XX_PCI_LOWER_IO_BA;
+       sys->io_offset  = IOP3XX_PCI_LOWER_IO_PA - IOP3XX_PCI_LOWER_IO_BA;
 
        sys->resource[0] = &res[0];
        sys->resource[1] = &res[1];
 
 
 #include <asm/hardware.h>
 
-#define IO_SPACE_LIMIT         0xffffffff
+extern void __iomem * __ioremap(unsigned long, size_t, unsigned long);
+extern void __iomem *__iop3xx_ioremap(unsigned long cookie, size_t size,
+       unsigned long flags);
+extern void __iop3xx_iounmap(void __iomem *addr);
 
-#define __io(p)                        ((void __iomem *)(p))
+#define IO_SPACE_LIMIT         0xffffffff
+#define __io(p)                ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p))
 #define __mem_pci(a)           (a)
 
+#define __arch_ioremap(a, s, f) __iop3xx_ioremap(a, s, f)
+#define __arch_iounmap(a)       __iop3xx_iounmap(a)
 
 #endif
 
 
 #include <asm/hardware.h>
 
+extern void __iomem * __ioremap(unsigned long, size_t, unsigned long);
+extern void __iomem *__iop3xx_ioremap(unsigned long cookie, size_t size,
+       unsigned long flags);
+extern void __iop3xx_iounmap(void __iomem *addr);
+
 #define IO_SPACE_LIMIT         0xffffffff
-#define __io(p)                        ((void __iomem *)(p))
+#define __io(p)                ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p))
 #define __mem_pci(a)           (a)
 
+#define __arch_ioremap(a, s, f) __iop3xx_ioremap(a, s, f)
+#define __arch_iounmap(a)       __iop3xx_iounmap(a)
 
 #endif
 
 #define IOP3XX_PERIPHERAL_PHYS_BASE    0xffffe000
 #define IOP3XX_PERIPHERAL_VIRT_BASE    0xfeffe000
 #define IOP3XX_PERIPHERAL_SIZE         0x00002000
+#define IOP3XX_PERIPHERAL_UPPER_PA (IOP3XX_PERIPHERAL_PHYS_BASE +\
+                                       IOP3XX_PERIPHERAL_SIZE - 1)
+#define IOP3XX_PERIPHERAL_UPPER_VA (IOP3XX_PERIPHERAL_VIRT_BASE +\
+                                       IOP3XX_PERIPHERAL_SIZE - 1)
+#define IOP3XX_PMMR_PHYS_TO_VIRT(addr) (u32) ((u32) addr -\
+                                       (IOP3XX_PERIPHERAL_PHYS_BASE\
+                                       - IOP3XX_PERIPHERAL_VIRT_BASE))
 #define IOP3XX_REG_ADDR(reg)           (IOP3XX_PERIPHERAL_VIRT_BASE + (reg))
 
 /* Address Translation Unit  */
 #define IOP3XX_PCI_LOWER_IO_PA         0x90000000
 #define IOP3XX_PCI_LOWER_IO_VA         0xfe000000
 #define IOP3XX_PCI_LOWER_IO_BA         (*IOP3XX_OIOWTVR)
+#define IOP3XX_PCI_UPPER_IO_PA         (IOP3XX_PCI_LOWER_IO_PA +\
+                                       IOP3XX_PCI_IO_WINDOW_SIZE - 1)
+#define IOP3XX_PCI_UPPER_IO_VA         (IOP3XX_PCI_LOWER_IO_VA +\
+                                       IOP3XX_PCI_IO_WINDOW_SIZE - 1)
+#define IOP3XX_PCI_IO_PHYS_TO_VIRT(addr) (((u32) addr -\
+                                       IOP3XX_PCI_LOWER_IO_PA) +\
+                                       IOP3XX_PCI_LOWER_IO_VA)
 
 
 #ifndef __ASSEMBLY__