Pull thermal into release branch
[linux-drm-fsl-dcu.git] / arch / mips / lib / iomap.c
index 7e2ced715cfbdc4e1f925898a5df1c177b8bf005..e3acb2dad33ad38585d2d8e195385af3e74f54d8 100644 (file)
 /*
- *  iomap.c, Memory Mapped I/O routines for MIPS architecture.
+ * Implement the default iomap interfaces
  *
- *  This code is based on lib/iomap.c, by Linus Torvalds.
- *
- *  Copyright (C) 2004-2005  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
+ * (C) Copyright 2004 Linus Torvalds
+ * (C) Copyright 2006 Ralf Baechle <ralf@linux-mips.org>
+ * (C) Copyright 2007 MIPS Technologies, Inc.
+ *     written by Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/module.h>
+#include <asm/io.h>
+
+/*
+ * Read/write from/to an (offsettable) iomem cookie. It might be a PIO
+ * access or a MMIO access, these functions don't care. The info is
+ * encoded in the hardware mapping set up by the mapping functions
+ * (or the cookie itself, depending on implementation and hw).
  *
- *  This program is distributed in the hope that 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.
+ * The generic routines don't assume any hardware mappings, and just
+ * encode the PIO/MMIO as part of the cookie. They coldly assume that
+ * the MMIO IO mappings are not in the low address range.
  *
- *  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
+ * Architectures for which this is not true can't use this generic
+ * implementation and should do their own copy.
  */
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/pci.h>
 
-#include <asm/io.h>
+#define PIO_MASK       0x0ffffUL
 
-void __iomem *ioport_map(unsigned long port, unsigned int nr)
+unsigned int ioread8(void __iomem *addr)
 {
-       unsigned long end;
+       return readb(addr);
+}
 
-       end = port + nr - 1UL;
-       if (ioport_resource.start > port ||
-           ioport_resource.end < end || port > end)
-               return NULL;
+EXPORT_SYMBOL(ioread8);
 
-       return (void __iomem *)(mips_io_port_base + port);
+unsigned int ioread16(void __iomem *addr)
+{
+       return readw(addr);
 }
 
-void ioport_unmap(void __iomem *addr)
+EXPORT_SYMBOL(ioread16);
+
+unsigned int ioread16be(void __iomem *addr)
 {
+       return be16_to_cpu(__raw_readw(addr));
 }
-EXPORT_SYMBOL(ioport_map);
-EXPORT_SYMBOL(ioport_unmap);
 
-void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
+EXPORT_SYMBOL(ioread16be);
+
+unsigned int ioread32(void __iomem *addr)
 {
-       unsigned long start, len, flags;
+       return readl(addr);
+}
 
-       if (dev == NULL)
-               return NULL;
+EXPORT_SYMBOL(ioread32);
 
-       start = pci_resource_start(dev, bar);
-       len = pci_resource_len(dev, bar);
-       if (!start || !len)
-               return NULL;
+unsigned int ioread32be(void __iomem *addr)
+{
+       return be32_to_cpu(__raw_readl(addr));
+}
+
+EXPORT_SYMBOL(ioread32be);
+
+void iowrite8(u8 val, void __iomem *addr)
+{
+       writeb(val, addr);
+}
 
-       if (maxlen != 0 && len > maxlen)
-               len = maxlen;
+EXPORT_SYMBOL(iowrite8);
 
-       flags = pci_resource_flags(dev, bar);
-       if (flags & IORESOURCE_IO)
-               return ioport_map(start, len);
-       if (flags & IORESOURCE_MEM) {
-               if (flags & IORESOURCE_CACHEABLE)
-                       return ioremap_cacheable_cow(start, len);
-               return ioremap_nocache(start, len);
+void iowrite16(u16 val, void __iomem *addr)
+{
+       writew(val, addr);
+}
+
+EXPORT_SYMBOL(iowrite16);
+
+void iowrite16be(u16 val, void __iomem *addr)
+{
+       __raw_writew(cpu_to_be16(val), addr);
+}
+
+EXPORT_SYMBOL(iowrite16be);
+
+void iowrite32(u32 val, void __iomem *addr)
+{
+       writel(val, addr);
+}
+
+EXPORT_SYMBOL(iowrite32);
+
+void iowrite32be(u32 val, void __iomem *addr)
+{
+       __raw_writel(cpu_to_be32(val), addr);
+}
+
+EXPORT_SYMBOL(iowrite32be);
+
+/*
+ * These are the "repeat MMIO read/write" functions.
+ * Note the "__raw" accesses, since we don't want to
+ * convert to CPU byte order. We write in "IO byte
+ * order" (we also don't have IO barriers).
+ */
+static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
+{
+       while (--count >= 0) {
+               u8 data = __raw_readb(addr);
+               *dst = data;
+               dst++;
        }
+}
 
-       return NULL;
+static inline void mmio_insw(void __iomem *addr, u16 *dst, int count)
+{
+       while (--count >= 0) {
+               u16 data = __raw_readw(addr);
+               *dst = data;
+               dst++;
+       }
+}
+
+static inline void mmio_insl(void __iomem *addr, u32 *dst, int count)
+{
+       while (--count >= 0) {
+               u32 data = __raw_readl(addr);
+               *dst = data;
+               dst++;
+       }
 }
 
-void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
+static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
 {
-       iounmap(addr);
+       while (--count >= 0) {
+               __raw_writeb(*src, addr);
+               src++;
+       }
 }
-EXPORT_SYMBOL(pci_iomap);
-EXPORT_SYMBOL(pci_iounmap);
+
+static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count)
+{
+       while (--count >= 0) {
+               __raw_writew(*src, addr);
+               src++;
+       }
+}
+
+static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count)
+{
+       while (--count >= 0) {
+               __raw_writel(*src, addr);
+               src++;
+       }
+}
+
+void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+       mmio_insb(addr, dst, count);
+}
+
+EXPORT_SYMBOL(ioread8_rep);
+
+void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+       mmio_insw(addr, dst, count);
+}
+
+EXPORT_SYMBOL(ioread16_rep);
+
+void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+       mmio_insl(addr, dst, count);
+}
+
+EXPORT_SYMBOL(ioread32_rep);
+
+void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+       mmio_outsb(addr, src, count);
+}
+
+EXPORT_SYMBOL(iowrite8_rep);
+
+void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+       mmio_outsw(addr, src, count);
+}
+
+EXPORT_SYMBOL(iowrite16_rep);
+
+void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+       mmio_outsl(addr, src, count);
+}
+
+EXPORT_SYMBOL(iowrite32_rep);
+
+/*
+ * Create a virtual mapping cookie for an IO port range
+ *
+ * This uses the same mapping are as the in/out family which has to be setup
+ * by the platform initialization code.
+ *
+ * Just to make matters somewhat more interesting on MIPS systems with
+ * multiple host bridge each will have it's own ioport address space.
+ */
+static void __iomem *ioport_map_legacy(unsigned long port, unsigned int nr)
+{
+       return (void __iomem *) (mips_io_port_base + port);
+}
+
+void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+       if (port > PIO_MASK)
+               return NULL;
+
+       return ioport_map_legacy(port, nr);
+}
+
+EXPORT_SYMBOL(ioport_map);
+
+void ioport_unmap(void __iomem *addr)
+{
+       /* Nothing to do */
+}
+
+EXPORT_SYMBOL(ioport_unmap);