2005-04-16 15:20:36 -07:00
/*
2008-08-02 10:55:55 +01:00
* arch / arm / include / asm / io . h
2005-04-16 15:20:36 -07:00
*
* Copyright ( C ) 1996 - 2000 Russell King
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
* Modifications :
* 16 - Sep - 1996 RMK Inlined the inx / outx functions & optimised for both
* constant addresses and variable addresses .
* 04 - Dec - 1997 RMK Moved a lot of this stuff to the new architecture
* specific IO header files .
* 27 - Mar - 1999 PJB Second parameter of memcpy_toio is const . .
* 04 - Apr - 1999 PJB Added check_signature .
* 12 - Dec - 1999 RMK More cleanups
* 18 - Jun - 2000 RMK Removed virt_to_ * and friends definitions
* 05 - Oct - 2004 BJD Moved memory string functions to use void __iomem
*/
# ifndef __ASM_ARM_IO_H
# define __ASM_ARM_IO_H
# ifdef __KERNEL__
# include <linux/types.h>
2013-10-25 10:33:26 +00:00
# include <linux/blk_types.h>
2005-04-16 15:20:36 -07:00
# include <asm/byteorder.h>
# include <asm/memory.h>
2011-11-24 20:57:23 +02:00
# include <asm-generic/pci_iomap.h>
2013-10-25 10:33:26 +00:00
# include <xen/xen.h>
2005-04-16 15:20:36 -07:00
/*
* ISA I / O bus memory addresses are 1 : 1 with the physical address .
*/
# define isa_virt_to_bus virt_to_phys
# define isa_page_to_bus page_to_phys
# define isa_bus_to_virt phys_to_virt
2013-12-18 23:08:52 +01:00
/*
* Atomic MMIO - wide IO modify
*/
extern void atomic_io_modify ( void __iomem * reg , u32 mask , u32 set ) ;
extern void atomic_io_modify_relaxed ( void __iomem * reg , u32 mask , u32 set ) ;
2005-04-16 15:20:36 -07:00
/*
* Generic IO read / write . These perform native - endian accesses . Note
* that some architectures will want to re - define __raw_ { read , write } w .
*/
extern void __raw_writesb ( void __iomem * addr , const void * data , int bytelen ) ;
extern void __raw_writesw ( void __iomem * addr , const void * data , int wordlen ) ;
extern void __raw_writesl ( void __iomem * addr , const void * data , int longlen ) ;
2005-12-05 10:54:59 +00:00
extern void __raw_readsb ( const void __iomem * addr , void * data , int bytelen ) ;
extern void __raw_readsw ( const void __iomem * addr , void * data , int wordlen ) ;
extern void __raw_readsl ( const void __iomem * addr , void * data , int longlen ) ;
2005-04-16 15:20:36 -07:00
2012-08-24 15:18:45 +01:00
# if __LINUX_ARM_ARCH__ < 6
/*
* Half - word accesses are problematic with RiscPC due to limitations of
* the bus . Rather than special - case the machine , just let the compiler
* generate the access for CPUs prior to ARMv6 .
*/
# define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a))
# define __raw_writew(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v)))
# else
/*
* When running under a hypervisor , we want to avoid I / O accesses with
* writeback addressing modes as these incur a significant performance
* overhead ( the address generation must be emulated in software ) .
*/
static inline void __raw_writew ( u16 val , volatile void __iomem * addr )
{
asm volatile ( " strh %1, %0 "
2012-10-26 18:42:08 +01:00
: " +Q " ( * ( volatile u16 __force * ) addr )
2012-08-24 15:18:45 +01:00
: " r " ( val ) ) ;
}
static inline u16 __raw_readw ( const volatile void __iomem * addr )
{
u16 val ;
asm volatile ( " ldrh %1, %0 "
2012-10-26 18:42:08 +01:00
: " +Q " ( * ( volatile u16 __force * ) addr ) ,
2012-08-24 15:18:45 +01:00
" =r " ( val ) ) ;
return val ;
}
# endif
static inline void __raw_writeb ( u8 val , volatile void __iomem * addr )
{
asm volatile ( " strb %1, %0 "
: " +Qo " ( * ( volatile u8 __force * ) addr )
: " r " ( val ) ) ;
}
static inline void __raw_writel ( u32 val , volatile void __iomem * addr )
{
asm volatile ( " str %1, %0 "
: " +Qo " ( * ( volatile u32 __force * ) addr )
: " r " ( val ) ) ;
}
static inline u8 __raw_readb ( const volatile void __iomem * addr )
{
u8 val ;
asm volatile ( " ldrb %1, %0 "
: " +Qo " ( * ( volatile u8 __force * ) addr ) ,
" =r " ( val ) ) ;
return val ;
}
2005-04-16 15:20:36 -07:00
2012-08-24 15:18:45 +01:00
static inline u32 __raw_readl ( const volatile void __iomem * addr )
{
u32 val ;
asm volatile ( " ldr %1, %0 "
: " +Qo " ( * ( volatile u32 __force * ) addr ) ,
" =r " ( val ) ) ;
return val ;
}
2005-04-16 15:20:36 -07:00
2005-11-17 16:48:00 +00:00
/*
* Architecture ioremap implementation .
*/
2007-05-05 20:59:27 +01:00
# define MT_DEVICE 0
# define MT_DEVICE_NONSHARED 1
# define MT_DEVICE_CACHED 2
2008-09-07 12:42:51 +01:00
# define MT_DEVICE_WC 3
2007-05-05 20:59:27 +01:00
/*
2008-09-07 12:42:51 +01:00
* types 4 onwards can be found in asm / mach / map . h and are undefined
2007-05-05 20:59:27 +01:00
* for ioremap
*/
/*
* __arm_ioremap takes CPU physical address .
* __arm_ioremap_pfn takes a Page Frame Number and an offset into that page
2009-12-18 11:10:03 +00:00
* The _caller variety takes a __builtin_return_address ( 0 ) value for
* / proc / vmalloc to use - and should only be used in non - inline functions .
2007-05-05 20:59:27 +01:00
*/
2009-12-18 11:10:03 +00:00
extern void __iomem * __arm_ioremap_pfn_caller ( unsigned long , unsigned long ,
size_t , unsigned int , void * ) ;
2013-05-16 19:40:22 +01:00
extern void __iomem * __arm_ioremap_caller ( phys_addr_t , size_t , unsigned int ,
2009-12-18 11:10:03 +00:00
void * ) ;
extern void __iomem * __arm_ioremap_pfn ( unsigned long , unsigned long , size_t , unsigned int ) ;
2013-05-16 19:40:22 +01:00
extern void __iomem * __arm_ioremap ( phys_addr_t , size_t , unsigned int ) ;
extern void __iomem * __arm_ioremap_exec ( phys_addr_t , size_t , bool cached ) ;
2006-10-09 02:09:49 +01:00
extern void __iounmap ( volatile void __iomem * addr ) ;
2012-02-10 17:05:13 -06:00
extern void __arm_iounmap ( volatile void __iomem * addr ) ;
2013-05-16 19:40:22 +01:00
extern void __iomem * ( * arch_ioremap_caller ) ( phys_addr_t , size_t ,
2012-02-10 17:05:13 -06:00
unsigned int , void * ) ;
extern void ( * arch_iounmap ) ( volatile void __iomem * ) ;
2005-11-17 16:48:00 +00:00
2005-04-16 15:20:36 -07:00
/*
* Bad read / write accesses . . .
*/
extern void __readwrite_bug ( const char * fn ) ;
2008-11-30 11:45:54 +00:00
/*
* A typesafe __io ( ) helper
*/
static inline void __iomem * __typesafe_io ( unsigned long addr )
{
return ( void __iomem * ) addr ;
}
2012-03-10 10:30:31 -06:00
# define IOMEM(x) ((void __force __iomem *)(x))
2011-01-30 11:29:40 +00:00
/* IO barriers */
# ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
2012-03-28 18:30:01 +01:00
# include <asm/barrier.h>
2011-01-30 11:29:40 +00:00
# define __iormb() rmb()
# define __iowmb() wmb()
# else
# define __iormb() do { } while (0)
# define __iowmb() do { } while (0)
# endif
2012-02-29 18:10:58 -06:00
/* PCI fixed i/o mapping */
# define PCI_IO_VIRT_BASE 0xfee00000
extern int pci_ioremap_io ( unsigned int offset , phys_addr_t phys_addr ) ;
2005-04-16 15:20:36 -07:00
/*
* Now , pick up the machine - defined IO definitions
*/
2012-03-04 22:03:33 -06:00
# ifdef CONFIG_NEED_MACH_IO_H
2008-08-05 16:14:15 +01:00
# include <mach/io.h>
2012-02-29 18:10:58 -06:00
# elif defined(CONFIG_PCI)
# define IO_SPACE_LIMIT ((resource_size_t)0xfffff)
# define __io(a) __typesafe_io(PCI_IO_VIRT_BASE + ((a) & IO_SPACE_LIMIT))
2012-03-04 22:03:33 -06:00
# else
2012-04-04 17:48:04 -05:00
# define __io(a) __typesafe_io((a) & IO_SPACE_LIMIT)
2012-03-04 22:03:33 -06:00
# endif
2005-04-16 15:20:36 -07:00
2011-07-06 12:49:59 +01:00
/*
* This is the limit of PC card / PCI / ISA IO space , which is by default
* 64 K if we have PC card , PCI or ISA support . Otherwise , default to
* zero to prevent ISA / PCI drivers claiming IO space ( and potentially
* oopsing . )
*
* Only set this larger if you really need inb ( ) et . al . to operate over
* a larger address space . Note that SOC_COMMON ioremaps each sockets
* IO space area , and so inb ( ) et . al . must be defined to operate as per
* readb ( ) et . al . on such platforms .
*/
# ifndef IO_SPACE_LIMIT
# if defined(CONFIG_PCMCIA_SOC_COMMON) || defined(CONFIG_PCMCIA_SOC_COMMON_MODULE)
# define IO_SPACE_LIMIT ((resource_size_t)0xffffffff)
# elif defined(CONFIG_PCI) || defined(CONFIG_ISA) || defined(CONFIG_PCCARD)
# define IO_SPACE_LIMIT ((resource_size_t)0xffff)
# else
# define IO_SPACE_LIMIT ((resource_size_t)0)
# endif
# endif
2005-04-16 15:20:36 -07:00
/*
* IO port access primitives
* - - - - - - - - - - - - - - - - - - - - - - - - -
*
* The ARM 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
2005-06-27 14:23:38 +01:00
* big endian mode connectivity is in place , as described by numerous
2005-04-16 15:20:36 -07:00
* ARM documents :
*
* PCI : D0 - D7 D8 - D15 D16 - D23 D24 - D31
* ARM : D24 - D31 D16 - D23 D8 - D15 D0 - D7
*
* 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 .
*/
# ifdef __io
2011-01-30 11:29:40 +00:00
# define outb(v,p) ({ __iowmb(); __raw_writeb(v,__io(p)); })
# define outw(v,p) ({ __iowmb(); __raw_writew((__force __u16) \
cpu_to_le16 ( v ) , __io ( p ) ) ; } )
# define outl(v,p) ({ __iowmb(); __raw_writel((__force __u32) \
cpu_to_le32 ( v ) , __io ( p ) ) ; } )
2005-04-16 15:20:36 -07:00
2011-01-30 11:29:40 +00:00
# define inb(p) ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
2005-04-29 22:08:34 +01:00
# define inw(p) ({ __u16 __v = le16_to_cpu((__force __le16) \
2011-01-30 11:29:40 +00:00
__raw_readw ( __io ( p ) ) ) ; __iormb ( ) ; __v ; } )
2005-04-29 22:08:34 +01:00
# define inl(p) ({ __u32 __v = le32_to_cpu((__force __le32) \
2011-01-30 11:29:40 +00:00
__raw_readl ( __io ( p ) ) ) ; __iormb ( ) ; __v ; } )
2005-04-16 15:20:36 -07:00
# define outsb(p,d,l) __raw_writesb(__io(p),d,l)
# define outsw(p,d,l) __raw_writesw(__io(p),d,l)
# define outsl(p,d,l) __raw_writesl(__io(p),d,l)
# define insb(p,d,l) __raw_readsb(__io(p),d,l)
# define insw(p,d,l) __raw_readsw(__io(p),d,l)
# define insl(p,d,l) __raw_readsl(__io(p),d,l)
# endif
# define outb_p(val,port) outb((val),(port))
# define outw_p(val,port) outw((val),(port))
# define outl_p(val,port) outl((val),(port))
# define inb_p(port) inb((port))
# define inw_p(port) inw((port))
# define inl_p(port) inl((port))
# define outsb_p(port,from,len) outsb(port,from,len)
# define outsw_p(port,from,len) outsw(port,from,len)
# define outsl_p(port,from,len) outsl(port,from,len)
# define insb_p(port,to,len) insb(port,to,len)
# define insw_p(port,to,len) insw(port,to,len)
# define insl_p(port,to,len) insl(port,to,len)
/*
* String version of IO memory access ops :
*/
2005-09-24 10:42:06 +01:00
extern void _memcpy_fromio ( void * , const volatile void __iomem * , size_t ) ;
extern void _memcpy_toio ( volatile void __iomem * , const void * , size_t ) ;
extern void _memset_io ( volatile void __iomem * , int , size_t ) ;
2005-04-16 15:20:36 -07:00
# define mmiowb()
/*
* Memory access primitives
* - - - - - - - - - - - - - - - - - - - - - - - -
*
* These perform PCI memory accesses via an ioremap region . They don ' t
* take an address as such , but a cookie .
*
* Again , this are defined to perform little endian accesses . See the
* IO port primitives for more information .
*/
2012-02-10 20:04:56 -06:00
# ifndef readl
# define readb_relaxed(c) ({ u8 __r = __raw_readb(c); __r; })
2011-10-04 03:44:07 +01:00
# define readw_relaxed(c) ({ u16 __r = le16_to_cpu((__force __le16) \
2012-02-10 20:04:56 -06:00
__raw_readw ( c ) ) ; __r ; } )
2011-10-04 03:44:07 +01:00
# define readl_relaxed(c) ({ u32 __r = le32_to_cpu((__force __le32) \
2012-02-10 20:04:56 -06:00
__raw_readl ( c ) ) ; __r ; } )
2010-07-28 22:00:54 +01:00
2012-05-25 08:39:25 +01:00
# define writeb_relaxed(v,c) __raw_writeb(v,c)
# define writew_relaxed(v,c) __raw_writew((__force u16) cpu_to_le16(v),c)
# define writel_relaxed(v,c) __raw_writel((__force u32) cpu_to_le32(v),c)
2010-07-28 22:00:54 +01:00
2010-07-29 11:38:05 +01:00
# define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; })
# define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; })
# define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; })
# define writeb(v,c) ({ __iowmb(); writeb_relaxed(v,c); })
# define writew(v,c) ({ __iowmb(); writew_relaxed(v,c); })
# define writel(v,c) ({ __iowmb(); writel_relaxed(v,c); })
2012-02-10 20:04:56 -06:00
# define readsb(p,d,l) __raw_readsb(p,d,l)
# define readsw(p,d,l) __raw_readsw(p,d,l)
# define readsl(p,d,l) __raw_readsl(p,d,l)
2005-04-16 15:20:36 -07:00
2012-02-10 20:04:56 -06:00
# define writesb(p,d,l) __raw_writesb(p,d,l)
# define writesw(p,d,l) __raw_writesw(p,d,l)
# define writesl(p,d,l) __raw_writesl(p,d,l)
2005-04-16 15:20:36 -07:00
2012-02-10 20:04:56 -06:00
# define memset_io(c,v,l) _memset_io(c,(v),(l))
# define memcpy_fromio(a,c,l) _memcpy_fromio((a),c,(l))
# define memcpy_toio(c,a,l) _memcpy_toio(c,(a),(l))
2005-04-16 15:20:36 -07:00
2012-02-10 20:04:56 -06:00
# endif /* readl */
2005-04-16 15:20:36 -07:00
/*
* ioremap and friends .
*
* ioremap takes a PCI memory address , as specified in
2011-08-15 02:02:26 +02:00
* Documentation / io - mapping . txt .
2006-01-09 19:23:11 +00:00
*
2005-04-16 15:20:36 -07:00
*/
2012-03-06 15:21:45 -06:00
# define ioremap(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE)
# define ioremap_nocache(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE)
2013-11-22 20:14:49 +01:00
# define ioremap_cache(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE_CACHED)
2012-03-06 15:21:45 -06:00
# define ioremap_wc(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE_WC)
# define iounmap __arm_iounmap
2005-04-16 15:20:36 -07:00
2005-06-20 18:44:37 +01:00
/*
* io { read , write } { 8 , 16 , 32 } macros
*/
2005-06-24 23:11:31 +01:00
# ifndef ioread8
2010-07-29 11:38:05 +01:00
# define ioread8(p) ({ unsigned int __v = __raw_readb(p); __iormb(); __v; })
# define ioread16(p) ({ unsigned int __v = le16_to_cpu((__force __le16)__raw_readw(p)); __iormb(); __v; })
# define ioread32(p) ({ unsigned int __v = le32_to_cpu((__force __le32)__raw_readl(p)); __iormb(); __v; })
2005-06-20 18:44:37 +01:00
2011-09-03 17:54:44 +02:00
# define ioread16be(p) ({ unsigned int __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(); __v; })
# define ioread32be(p) ({ unsigned int __v = be32_to_cpu((__force __be32)__raw_readl(p)); __iormb(); __v; })
2012-05-25 08:39:25 +01:00
# define iowrite8(v,p) ({ __iowmb(); __raw_writeb(v, p); })
# define iowrite16(v,p) ({ __iowmb(); __raw_writew((__force __u16)cpu_to_le16(v), p); })
# define iowrite32(v,p) ({ __iowmb(); __raw_writel((__force __u32)cpu_to_le32(v), p); })
2005-06-20 18:44:37 +01:00
2012-05-25 08:39:25 +01:00
# define iowrite16be(v,p) ({ __iowmb(); __raw_writew((__force __u16)cpu_to_be16(v), p); })
# define iowrite32be(v,p) ({ __iowmb(); __raw_writel((__force __u32)cpu_to_be32(v), p); })
2011-09-03 17:54:44 +02:00
2005-06-20 18:44:37 +01:00
# define ioread8_rep(p,d,c) __raw_readsb(p,d,c)
# define ioread16_rep(p,d,c) __raw_readsw(p,d,c)
# define ioread32_rep(p,d,c) __raw_readsl(p,d,c)
# define iowrite8_rep(p,s,c) __raw_writesb(p,s,c)
# define iowrite16_rep(p,s,c) __raw_writesw(p,s,c)
# define iowrite32_rep(p,s,c) __raw_writesl(p,s,c)
extern void __iomem * ioport_map ( unsigned long port , unsigned int nr ) ;
extern void ioport_unmap ( void __iomem * addr ) ;
2005-06-24 23:11:31 +01:00
# endif
2005-06-20 18:44:37 +01:00
struct pci_dev ;
extern void pci_iounmap ( struct pci_dev * dev , void __iomem * addr ) ;
2005-04-16 15:20:36 -07:00
/*
* can the hardware map this into one segment or not , given no other
* constraints .
*/
# define BIOVEC_MERGEABLE(vec1, vec2) \
( ( bvec_to_phys ( ( vec1 ) ) + ( vec1 ) - > bv_len ) = = bvec_to_phys ( ( vec2 ) ) )
2013-11-06 12:38:28 +00:00
struct bio_vec ;
2013-10-25 10:33:26 +00:00
extern bool xen_biovec_phys_mergeable ( const struct bio_vec * vec1 ,
const struct bio_vec * vec2 ) ;
# define BIOVEC_PHYS_MERGEABLE(vec1, vec2) \
( __BIOVEC_PHYS_MERGEABLE ( vec1 , vec2 ) & & \
( ! xen_domain ( ) | | xen_biovec_phys_mergeable ( vec1 , vec2 ) ) )
2007-05-17 06:22:41 +01:00
# ifdef CONFIG_MMU
2006-09-16 10:50:22 +01:00
# define ARCH_HAS_VALID_PHYS_ADDR_RANGE
2012-09-12 14:05:58 -04:00
extern int valid_phys_addr_range ( phys_addr_t addr , size_t size ) ;
2006-09-16 10:50:22 +01:00
extern int valid_mmap_phys_addr_range ( unsigned long pfn , size_t size ) ;
2010-09-22 18:34:36 -04:00
extern int devmem_is_allowed ( unsigned long pfn ) ;
2007-05-17 06:22:41 +01:00
# endif
2006-09-16 10:50:22 +01:00
2005-04-16 15:20:36 -07:00
/*
* Convert a physical pointer to a virtual kernel pointer for / dev / mem
* access
*/
# define xlate_dev_mem_ptr(p) __va(p)
/*
* Convert a virtual cached pointer to an uncached pointer
*/
# define xlate_dev_kmem_ptr(p) p
2006-08-28 12:45:16 +01:00
/*
* Register ISA memory and port locations for glibc iopl / inb / outb
* emulation .
*/
extern void register_isa_ports ( unsigned int mmio , unsigned int io ,
unsigned int io_shift ) ;
2005-04-16 15:20:36 -07:00
# endif /* __KERNEL__ */
# endif /* __ASM_ARM_IO_H */