generic: implement __fls on all 64-bit archs
[safe/jmp/linux-2.6] / include / asm-sh / io.h
index 894e64b..356e50d 100644 (file)
@@ -38,6 +38,7 @@
  */
 #define __IO_PREFIX    generic
 #include <asm/io_generic.h>
+#include <asm/io_trapped.h>
 
 #define maybebadio(port) \
   printk(KERN_ERR "bad PC-like io %s:%u for port 0x%lx at 0x%08x\n", \
 #define __raw_writew(v, a)     __writew(v, (void __iomem *)(a))
 #define __raw_writel(v, a)     __writel(v, (void __iomem *)(a))
 
+void __raw_writesl(unsigned long addr, const void *data, int longlen);
+void __raw_readsl(unsigned long addr, void *data, int longlen);
+
 /*
  * The platform header files may define some of these macros to use
  * the inlined versions where appropriate.  These macros may also be
  * redefined by userlevel programs.
  */
 #ifdef __readb
-# define readb(a)      ({ unsigned long r_ = __raw_readb(a); mb(); r_; })
+# define readb(a)      ({ unsigned int r_ = __raw_readb(a); mb(); r_; })
 #endif
 #ifdef __raw_readw
-# define readw(a)      ({ unsigned long r_ = __raw_readw(a); mb(); r_; })
+# define readw(a)      ({ unsigned int r_ = __raw_readw(a); mb(); r_; })
 #endif
 #ifdef __raw_readl
-# define readl(a)      ({ unsigned long r_ = __raw_readl(a); mb(); r_; })
+# define readl(a)      ({ unsigned int r_ = __raw_readl(a); mb(); r_; })
 #endif
 
 #ifdef __raw_writeb
 # define writel(v,a)   ({ __raw_writel((v),(a)); mb(); })
 #endif
 
+#define __BUILD_MEMORY_STRING(bwlq, type)                              \
+                                                                       \
+static inline void writes##bwlq(volatile void __iomem *mem,            \
+                               const void *addr, unsigned int count)   \
+{                                                                      \
+       const volatile type *__addr = addr;                             \
+                                                                       \
+       while (count--) {                                               \
+               __raw_write##bwlq(*__addr, mem);                        \
+               __addr++;                                               \
+       }                                                               \
+}                                                                      \
+                                                                       \
+static inline void reads##bwlq(volatile void __iomem *mem, void *addr, \
+                              unsigned int count)                      \
+{                                                                      \
+       volatile type *__addr = addr;                                   \
+                                                                       \
+       while (count--) {                                               \
+               *__addr = __raw_read##bwlq(mem);                        \
+               __addr++;                                               \
+       }                                                               \
+}
+
+__BUILD_MEMORY_STRING(b, u8)
+__BUILD_MEMORY_STRING(w, u16)
+#define writesl __raw_writesl
+#define readsl  __raw_readsl
+
 #define readb_relaxed(a) readb(a)
 #define readw_relaxed(a) readw(a)
 #define readl_relaxed(a) readl(a)
 #define iowrite32(v,a)         writel((v),(a))
 #define iowrite32be(v,a)       __raw_writel(cpu_to_be32((v)),(a))
 
-#define ioread8_rep(a,d,c)     insb((a),(d),(c))
-#define ioread16_rep(a,d,c)    insw((a),(d),(c))
-#define ioread32_rep(a,d,c)    insl((a),(d),(c))
+#define ioread8_rep(a, d, c)   readsb((a), (d), (c))
+#define ioread16_rep(a, d, c)  readsw((a), (d), (c))
+#define ioread32_rep(a, d, c)  readsl((a), (d), (c))
 
-#define iowrite8_rep(a,s,c)    outsb((a),(s),(c))
-#define iowrite16_rep(a,s,c)   outsw((a),(s),(c))
-#define iowrite32_rep(a,s,c)   outsl((a),(s),(c))
+#define iowrite8_rep(a, s, c)  writesb((a), (s), (c))
+#define iowrite16_rep(a, s, c) writesw((a), (s), (c))
+#define iowrite32_rep(a, s, c) writesl((a), (s), (c))
 
 #define mmiowb()       wmb()   /* synco on SH-4A, otherwise a nop */
 
+#define IO_SPACE_LIMIT 0xffffffff
+
 /*
  * This function provides a method for the generic case where a board-specific
  * ioport_map simply needs to return the port + some arbitrary port base.
@@ -173,6 +208,8 @@ static inline void __set_io_port_base(unsigned long pbase)
        generic_io_base = pbase;
 }
 
+#define __ioport_map(p, n) sh_mv.mv_ioport_map((p), (n))
+
 /* We really want to try and get these to memcpy etc */
 extern void memcpy_fromio(void *, volatile void __iomem *, unsigned long);
 extern void memcpy_toio(volatile void __iomem *, const void *, unsigned long);
@@ -194,6 +231,11 @@ static inline unsigned int ctrl_inl(unsigned long addr)
        return *(volatile unsigned long*)addr;
 }
 
+static inline unsigned long long ctrl_inq(unsigned long addr)
+{
+       return *(volatile unsigned long long*)addr;
+}
+
 static inline void ctrl_outb(unsigned char b, unsigned long addr)
 {
        *(volatile unsigned char*)addr = b;
@@ -209,43 +251,52 @@ static inline void ctrl_outl(unsigned int b, unsigned long addr)
         *(volatile unsigned long*)addr = b;
 }
 
-#define IO_SPACE_LIMIT 0xffffffff
-
-/*
- * Change virtual addresses to physical addresses and vv.
- * These are trivial on the 1:1 Linux/SuperH mapping
- */
-static inline unsigned long virt_to_phys(volatile void *address)
+static inline void ctrl_outq(unsigned long long b, unsigned long addr)
 {
-       return PHYSADDR(address);
+       *(volatile unsigned long long*)addr = b;
 }
 
-static inline void *phys_to_virt(unsigned long address)
+static inline void ctrl_delay(void)
 {
-       return (void *)P1SEGADDR(address);
+#ifdef P2SEG
+       ctrl_inw(P2SEG);
+#endif
 }
 
-#define virt_to_bus virt_to_phys
-#define bus_to_virt phys_to_virt
-#define page_to_bus page_to_phys
+/* Quad-word real-mode I/O, don't ask.. */
+unsigned long long peek_real_address_q(unsigned long long addr);
+unsigned long long poke_real_address_q(unsigned long long addr,
+                                      unsigned long long val);
+
+/* arch/sh/mm/ioremap_64.c */
+unsigned long onchip_remap(unsigned long addr, unsigned long size,
+                          const char *name);
+extern void onchip_unmap(unsigned long vaddr);
+
+#if !defined(CONFIG_MMU)
+#define virt_to_phys(address)  ((unsigned long)(address))
+#define phys_to_virt(address)  ((void *)(address))
+#else
+#define virt_to_phys(address)  (__pa(address))
+#define phys_to_virt(address)  (__va(address))
+#endif
 
 /*
- * readX/writeX() are used to access memory mapped devices. On some
- * architectures the memory mapped IO stuff needs to be accessed
- * differently. On the x86 architecture, we just read/write the
- * memory location directly.
+ * On 32-bit SH, we traditionally have the whole physical address space
+ * mapped at all times (as MIPS does), so "ioremap()" and "iounmap()" do
+ * not need to do anything but place the address in the proper segment.
+ * This is true for P1 and P2 addresses, as well as some P3 ones.
+ * However, most of the P3 addresses and newer cores using extended
+ * addressing need to map through page tables, so the ioremap()
+ * implementation becomes a bit more complicated.
  *
- * On SH, we traditionally have the whole physical address space mapped
- * at all times (as MIPS does), so "ioremap()" and "iounmap()" do not
- * need to do anything but place the address in the proper segment. This
- * is true for P1 and P2 addresses, as well as some P3 ones. However,
- * most of the P3 addresses and newer cores using extended addressing
- * need to map through page tables, so the ioremap() implementation
- * becomes a bit more complicated. See arch/sh/mm/ioremap.c for
- * additional notes on this.
+ * See arch/sh/mm/ioremap.c for additional notes on this.
  *
  * We cheat a bit and always return uncachable areas until we've fixed
  * the drivers to handle caching properly.
+ *
+ * On the SH-5 the concept of segmentation in the 1:1 PXSEG sense simply
+ * doesn't exist, so everything must go through page tables.
  */
 #ifdef CONFIG_MMU
 void __iomem *__ioremap(unsigned long offset, unsigned long size,
@@ -259,8 +310,16 @@ void __iounmap(void __iomem *addr);
 static inline void __iomem *
 __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
 {
+#ifdef CONFIG_SUPERH32
        unsigned long last_addr = offset + size - 1;
+#endif
+       void __iomem *ret;
+
+       ret = __ioremap_trapped(offset, size);
+       if (ret)
+               return ret;
 
+#ifdef CONFIG_SUPERH32
        /*
         * For P1 and P2 space this is trivial, as everything is already
         * mapped. Uncached access for P1 addresses are done through P2.
@@ -273,6 +332,7 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
 
                return (void __iomem *)P2SEGADDR(offset);
        }
+#endif
 
        return __ioremap(offset, size, flags);
 }
@@ -288,47 +348,6 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
 #define iounmap(addr)                                  \
        __iounmap((addr))
 
-static inline int check_signature(char __iomem *io_addr,
-                       const unsigned char *signature, int length)
-{
-       int retval = 0;
-       do {
-               if (readb(io_addr) != *signature)
-                       goto out;
-               io_addr++;
-               signature++;
-               length--;
-       } while (length);
-       retval = 1;
-out:
-       return retval;
-}
-
-/*
- * The caches on some architectures aren't dma-coherent and have need to
- * handle this in software.  There are three types of operations that
- * can be applied to dma buffers.
- *
- *  - dma_cache_wback_inv(start, size) makes caches and RAM coherent by
- *    writing the content of the caches back to memory, if necessary.
- *    The function also invalidates the affected part of the caches as
- *    necessary before DMA transfers from outside to memory.
- *  - dma_cache_inv(start, size) invalidates the affected parts of the
- *    caches.  Dirty lines of the caches may be written back or simply
- *    be discarded.  This operation is necessary before dma operations
- *    to the memory.
- *  - dma_cache_wback(start, size) writes back any dirty lines but does
- *    not invalidate the cache.  This can be used before DMA reads from
- *    memory,
- */
-
-#define dma_cache_wback_inv(_start,_size) \
-    __flush_purge_region(_start,_size)
-#define dma_cache_inv(_start,_size) \
-    __flush_invalidate_region(_start,_size)
-#define dma_cache_wback(_start,_size) \
-    __flush_wback_region(_start,_size)
-
 /*
  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
  * access