[PATCH 4/6] AVR32: Add I/O port access primitives

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This adds definitions of inb, outb and friends to include/asm-avr32/io.h

I'm still not sure about the best way to emulate I/O port access on
AVR32, but we should be able to override the __io() macro from
platform-specific headers in the future when we know better what the
requirements really are.

Signed-off-by: Haavard Skinnemoen <[email protected]>
---
 include/asm-avr32/io.h |   84 ++++++++++++++++++++++++++----------------------
 1 files changed, 45 insertions(+), 39 deletions(-)

diff --git a/include/asm-avr32/io.h b/include/asm-avr32/io.h
index 8633e49..30d7340 100644
--- a/include/asm-avr32/io.h
+++ b/include/asm-avr32/io.h
@@ -5,6 +5,24 @@ #include <linux/string.h>
 
 #ifdef __KERNEL__
 
+#include <asm/addrspace.h>
+
+/* virt_to_phys will only work when address is in P1 or P2 */
+static __inline__ unsigned long virt_to_phys(volatile void *address)
+{
+	return PHYSADDR(address);
+}
+
+static __inline__ void * phys_to_virt(unsigned long address)
+{
+	return (void *)P1SEGADDR(address);
+}
+
+#define cached_to_phys(addr)	((unsigned long)PHYSADDR(addr))
+#define uncached_to_phys(addr)	((unsigned long)PHYSADDR(addr))
+#define phys_to_cached(addr)	((void *)P1SEGADDR(addr))
+#define phys_to_uncached(addr)	((void *)P2SEGADDR(addr))
+
 /*
  * Generic IO read/write.  These perform native-endian accesses.  Note
  * that some architectures will want to re-define __raw_{read,write}w.
@@ -17,17 +35,6 @@ extern void __raw_readsb(unsigned int ad
 extern void __raw_readsw(unsigned int addr, void *data, int wordlen);
 extern void __raw_readsl(unsigned int addr, void *data, int longlen);
 
-#ifdef PCMCIA_HSMC_IO_HACK
-#error Needs updating
-/* The HMATRIX tries to byteswap the address for us, so we have to swap it back. */
-#define __raw_writeb(v,a)	(*(volatile unsigned char *)((unsigned long)(a) ^ 3UL) = (v))
-#define __raw_writew(v,a)	(*(volatile unsigned short *)((unsigned long)(a) ^ 2UL) = (v))
-#define __raw_writel(v,a)	(*(volatile unsigned int   *)(a) = (v))
-
-#define __raw_readb(a)		(*(volatile unsigned char *)((unsigned long)(a) ^ 3UL))
-#define __raw_readw(a)		(*(volatile unsigned short *)((unsigned long)(a) ^ 2UL))
-#define __raw_readl(a)		(*(volatile unsigned int *)(a))
-#else
 static inline void writeb(unsigned char b, volatile void __iomem *addr)
 {
 	*(volatile unsigned char __force *)addr = b;
@@ -59,7 +66,6 @@ static inline unsigned int readl(const v
 #define __raw_readb readb
 #define __raw_readw readw
 #define __raw_readl readl
-#endif
 
 #define writesb(p, d, l)	__raw_writesb((unsigned int)p, d, l)
 #define writesw(p, d, l)	__raw_writesw((unsigned int)p, d, l)
@@ -109,18 +115,36 @@ extern void __readwrite_bug(const char *
 
 #define IO_SPACE_LIMIT	0xffffffff
 
+/* Convert I/O port address to virtual address */
+#define __io(p)		((void __iomem *)phys_to_uncached(p))
+
 /*
- * All I/O is memory mapped, so these macros don't make very much
- * sense.  They are needed for PCMCIA support, however, so we'll have
- * to implement them somehow.  For now, they will cause linker errors.
+ *  IO port access primitives
+ *  -------------------------
+ *
+ * The AVR32 doesn't have special IO access instructions; all IO is memory
+ * mapped. Note that these are defined to perform little endian accesses
+ * only. Their primary purpose is to access PCI and ISA peripherals.
+ *
+ * Note that for a big endian machine, this implies that the following
+ * big endian mode connectivity is in place.
+ *
+ * The machine specific io.h include defines __io to translate an "IO"
+ * address to a memory address.
+ *
+ * Note that we prevent GCC re-ordering or caching values in expressions
+ * by introducing sequence points into the in*() definitions.  Note that
+ * __raw_* do not guarantee this behaviour.
+ *
+ * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space.
  */
-extern void outb(unsigned char value, unsigned long port);
-extern void outw(unsigned short value, unsigned long port);
-extern void outl(unsigned long value, unsigned long port);
+#define outb(v, p)		__raw_writeb(v, __io(p))
+#define outw(v, p)		__raw_writew(cpu_to_le16(v), __io(p))
+#define outl(v, p)		__raw_writel(cpu_to_le32(v), __io(p))
 
-extern unsigned char inb(unsigned long port);
-extern unsigned short inw(unsigned long port);
-extern unsigned long inl(unsigned long port);
+#define inb(p)			__raw_readb(__io(p))
+#define inw(p)			le16_to_cpu(__raw_readw(__io(p)))
+#define inl(p)			le32_to_cpu(__raw_readl(__io(p)))
 
 static inline void __outsb(unsigned long port, void *addr, unsigned int count)
 {
@@ -197,24 +221,6 @@ #define ioremap(offset, size)			\
 #define iounmap(addr)				\
 	__iounmap(addr)
 
-#include <asm/addrspace.h>
-
-/* virt_to_phys will only work when address is in P1 or P2 */
-static __inline__ unsigned long virt_to_phys(volatile void *address)
-{
-	return PHYSADDR(address);
-}
-
-static __inline__ void * phys_to_virt(unsigned long address)
-{
-	return (void *)P1SEGADDR(address);
-}
-
-#define cached_to_phys(addr)	((unsigned long)PHYSADDR(addr))
-#define uncached_to_phys(addr)	((unsigned long)PHYSADDR(addr))
-#define phys_to_cached(addr)	((void *)P1SEGADDR(addr))
-#define phys_to_uncached(addr)	((void *)P2SEGADDR(addr))
-
 #define cached(addr) P1SEGADDR(addr)
 #define uncached(addr) P2SEGADDR(addr)
 
-- 
1.4.0

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux