免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2245 | 回复: 0
打印 上一主题 下一主题

io_remap的实现 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-01-05 18:04 |只看该作者 |倒序浏览
驱动程序:
#include  是在linux-2.6.29/include/linux下面寻找源文件。
#include  是在linux-2.6.29/arch/arm/include/asm下面寻找源文件。
#include  是在linux-2.6.29/arch/arm/mach-s3c2410/include/mach下面寻找源文件。
#include   //最基本的文件,支持动态添加和卸载模块。Hello World驱动要这一个文件就可以了
#include   //包含了文件操作相关struct的定义,例如大名鼎鼎的struct file_operations
#include   //包含了对返回值的宏定义,这样用户程序可以用perror输出错误信息。
#include   //对一些特殊类型的定义,例如dev_t, off_t, pid_t.其实这些类型大部分都是unsigned int型通过一连串的typedef变过来的,只是为了方便阅读。
#include   //对字符设备结构cdev以及一系列的操作函数的定义。
#include   //等代队列相关头文件
应用程序:
#include  //包含了open()函数的flags,mode参数的宏定义。
本文来自CSDN博客,转载请标明出处:
http://blog.csdn.net/dearjianfei/archive/2009/11/28/4894122.aspx



in file arch/arm/inclue/asm/io.h

#include
/*
*  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
* big endian mode connectivity is in place, as described by numerous
* 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
#define outb(v,p)  __raw_writeb(v,__io(p))
#define outw(v,p)  __raw_writew((__force __u16) \
     cpu_to_le16(v),__io(p))
#define outl(v,p)  __raw_writel((__force __u32) \
     cpu_to_le32(v),__io(p))
#define inb(p) ({ __u8 __v = __raw_readb(__io(p)); __v; })
#define inw(p) ({ __u16 __v = le16_to_cpu((__force __le16) \
   __raw_readw(__io(p))); __v; })
#define inl(p) ({ __u32 __v = le32_to_cpu((__force __le32) \
   __raw_readl(__io(p))); __v; })
#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:
*/
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);
#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.
*/
#ifdef __mem_pci
#define readb(c) ({ __u8  __v = __raw_readb(__mem_pci(c)); __v; })
#define readw(c) ({ __u16 __v = le16_to_cpu((__force __le16) \
     __raw_readw(__mem_pci(c))); __v; })
#define readl(c) ({ __u32 __v = le32_to_cpu((__force __le32) \
     __raw_readl(__mem_pci(c))); __v; })
#define readb_relaxed(addr) readb(addr)
#define readw_relaxed(addr) readw(addr)
#define readl_relaxed(addr) readl(addr)
#define readsb(p,d,l)  __raw_readsb(__mem_pci(p),d,l)
#define readsw(p,d,l)  __raw_readsw(__mem_pci(p),d,l)
#define readsl(p,d,l)  __raw_readsl(__mem_pci(p),d,l)
#define writeb(v,c)  __raw_writeb(v,__mem_pci(c))
#define writew(v,c)  __raw_writew((__force __u16) \
     cpu_to_le16(v),__mem_pci(c))
#define writel(v,c)  __raw_writel((__force __u32) \
     cpu_to_le32(v),__mem_pci(c))
#define writesb(p,d,l)  __raw_writesb(__mem_pci(p),d,l)
#define writesw(p,d,l)  __raw_writesw(__mem_pci(p),d,l)
#define writesl(p,d,l)  __raw_writesl(__mem_pci(p),d,l)
#define memset_io(c,v,l) _memset_io(__mem_pci(c),(v),(l))
#define memcpy_fromio(a,c,l) _memcpy_fromio((a),__mem_pci(c),(l))
#define memcpy_toio(c,a,l) _memcpy_toio(__mem_pci(c),(a),(l))
#elif !defined(readb)
#define readb(c)   (__readwrite_bug("readb"),0)
#define readw(c)   (__readwrite_bug("readw"),0)
#define readl(c)   (__readwrite_bug("readl"),0)
#define writeb(v,c)   __readwrite_bug("writeb")
#define writew(v,c)   __readwrite_bug("writew")
#define writel(v,c)   __readwrite_bug("writel")
#define check_signature(io,sig,len) (0)
#endif /* __mem_pci */

#ifndef __arch_ioremap
#define ioremap(cookie,size)  __arm_ioremap(cookie, size, MT_DEVICE)
#define ioremap_nocache(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE)
#define ioremap_cached(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE_CACHED)
#define ioremap_wc(cookie,size)  __arm_ioremap(cookie, size, MT_DEVICE_WC)
#define iounmap(cookie)   __iounmap(cookie)
#else
#define ioremap(cookie,size)  __arch_ioremap((cookie), (size), MT_DEVICE)
#define ioremap_nocache(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE)
#define ioremap_cached(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE_CACHED)
#define ioremap_wc(cookie,size)  __arch_ioremap((cookie), (size), MT_DEVICE_WC)
#define iounmap(cookie)   __arch_iounmap(cookie)
#endif

in file arch/arm/plat-omap/include/mach/io.h 被上面的头文件包含,在这个文件里定义了
__arch_ioremap(p,s,t) 所以不会用到__arm_ioremap这个为所有平台提供的函数。实现了编译时
的多态。

#define __io(a)  __typesafe_io(a)
#define __mem_pci(a) (a)
/*
* ----------------------------------------------------------------------------
* I/O mapping
* ----------------------------------------------------------------------------
*/
#if defined(CONFIG_ARCH_OMAP1)
#define IO_PHYS   0xFFFB0000
#define IO_OFFSET  0x01000000 /* Virtual IO = 0xfefb0000 */
#define IO_SIZE   0x40000
#define IO_VIRT   (IO_PHYS - IO_OFFSET)
#define __IO_ADDRESS(pa) ((pa) - IO_OFFSET)
#define __OMAP1_IO_ADDRESS(pa) ((pa) - IO_OFFSET)
#define io_v2p(va)  ((va) + IO_OFFSET)
#elif defined(CONFIG_ARCH_OMAP2)
/* We map both L3 and L4 on OMAP2 */
#define L3_24XX_PHYS L3_24XX_BASE /* 0x68000000 */
#define L3_24XX_VIRT 0xf8000000
#define L3_24XX_SIZE SZ_1M  /* 44kB of 128MB used, want 1MB sect */
#define L4_24XX_PHYS L4_24XX_BASE /* 0x48000000 */
#define L4_24XX_VIRT 0xd8000000
#define L4_24XX_SIZE SZ_1M  /* 1MB of 128MB used, want 1MB sect */
#define L4_WK_243X_PHYS  L4_WK_243X_BASE  /* 0x49000000 */
#define L4_WK_243X_VIRT  0xd9000000
#define L4_WK_243X_SIZE  SZ_1M
#define OMAP243X_GPMC_PHYS OMAP243X_GPMC_BASE /* 0x49000000 */
#define OMAP243X_GPMC_VIRT 0xFE000000
#define OMAP243X_GPMC_SIZE SZ_1M
#define OMAP243X_SDRC_PHYS OMAP243X_SDRC_BASE
#define OMAP243X_SDRC_VIRT 0xFD000000
#define OMAP243X_SDRC_SIZE SZ_1M
#define OMAP243X_SMS_PHYS OMAP243X_SMS_BASE
#define OMAP243X_SMS_VIRT 0xFC000000
#define OMAP243X_SMS_SIZE SZ_1M
#define IO_OFFSET  0x90000000
#define __IO_ADDRESS(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */
#define __OMAP2_IO_ADDRESS(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */
#define io_v2p(va)  ((va) - IO_OFFSET) /* Works for L3 and L4 */
/* DSP */
#define DSP_MEM_24XX_PHYS OMAP2420_DSP_MEM_BASE /* 0x58000000 */
#define DSP_MEM_24XX_VIRT 0xe0000000
#define DSP_MEM_24XX_SIZE 0x28000
#define DSP_IPI_24XX_PHYS OMAP2420_DSP_IPI_BASE /* 0x59000000 */
#define DSP_IPI_24XX_VIRT 0xe1000000
#define DSP_IPI_24XX_SIZE SZ_4K
#define DSP_MMU_24XX_PHYS OMAP2420_DSP_MMU_BASE /* 0x5a000000 */
#define DSP_MMU_24XX_VIRT 0xe2000000
#define DSP_MMU_24XX_SIZE SZ_4K
#elif defined(CONFIG_ARCH_OMAP3)
/* We map both L3 and L4 on OMAP3 */
#define L3_34XX_PHYS  L3_34XX_BASE /* 0x68000000 */
#define L3_34XX_VIRT  0xf8000000
#define L3_34XX_SIZE  SZ_1M   /* 44kB of 128MB used, want 1MB sect */
#define L4_34XX_PHYS  L4_34XX_BASE /* 0x48000000 */
#define L4_34XX_VIRT  0xd8000000
#define L4_34XX_SIZE  SZ_4M   /* 1MB of 128MB used, want 1MB sect */
/*
* Need to look at the Size 4M for L4.
* VPOM3430 was not working for Int controller
*/
#define L4_WK_34XX_PHYS  L4_WK_34XX_BASE /* 0x48300000 */
#define L4_WK_34XX_VIRT  0xd8300000
#define L4_WK_34XX_SIZE  SZ_1M
#define L4_PER_34XX_PHYS L4_PER_34XX_BASE /* 0x49000000 */
#define L4_PER_34XX_VIRT 0xd9000000
#define L4_PER_34XX_SIZE SZ_1M
#define L4_EMU_34XX_PHYS L4_EMU_34XX_BASE /* 0x54000000 */
#define L4_EMU_34XX_VIRT 0xe4000000
#define L4_EMU_34XX_SIZE SZ_64M
#define OMAP34XX_GPMC_PHYS OMAP34XX_GPMC_BASE /* 0x6E000000 */
#define OMAP34XX_GPMC_VIRT 0xFE000000
#define OMAP34XX_GPMC_SIZE SZ_1M
#define OMAP343X_SMS_PHYS OMAP343X_SMS_BASE /* 0x6C000000 */
#define OMAP343X_SMS_VIRT 0xFC000000
#define OMAP343X_SMS_SIZE SZ_1M
#define OMAP343X_SDRC_PHYS OMAP343X_SDRC_BASE /* 0x6D000000 */
#define OMAP343X_SDRC_VIRT 0xFD000000
#define OMAP343X_SDRC_SIZE SZ_1M
#define IO_OFFSET  0x90000000
#define __IO_ADDRESS(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */
#define __OMAP2_IO_ADDRESS(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */
#define io_v2p(va)  ((va) - IO_OFFSET)/* Works for L3 and L4 */
/* DSP */
#define DSP_MEM_34XX_PHYS OMAP34XX_DSP_MEM_BASE /* 0x58000000 */
#define DSP_MEM_34XX_VIRT 0xe0000000
#define DSP_MEM_34XX_SIZE 0x28000
#define DSP_IPI_34XX_PHYS OMAP34XX_DSP_IPI_BASE /* 0x59000000 */
#define DSP_IPI_34XX_VIRT 0xe1000000
#define DSP_IPI_34XX_SIZE SZ_4K
#define DSP_MMU_34XX_PHYS OMAP34XX_DSP_MMU_BASE /* 0x5a000000 */
#define DSP_MMU_34XX_VIRT 0xe2000000
#define DSP_MMU_34XX_SIZE SZ_4K
#endif
#define IO_ADDRESS(pa)  IOMEM(__IO_ADDRESS(pa))
#define OMAP1_IO_ADDRESS(pa) IOMEM(__OMAP1_IO_ADDRESS(pa))
#define OMAP2_IO_ADDRESS(pa) IOMEM(__OMAP2_IO_ADDRESS(pa))
#ifdef __ASSEMBLER__
#define IOMEM(x)  x
#else
#define IOMEM(x)  ((void __force __iomem *)(x))
/*
* Functions to access the OMAP IO region
*
* NOTE: - Use omap_read/write[bwl] for physical register addresses
*  - Use __raw_read/write[bwl]() for virtual register addresses
*  - Use IO_ADDRESS(phys_addr) to convert registers to virtual addresses
*  - DO NOT use hardcoded virtual addresses to allow changing the
*    IO address space again if needed
*/
#define omap_readb(a)  __raw_readb(IO_ADDRESS(a))
#define omap_readw(a)  __raw_readw(IO_ADDRESS(a))
#define omap_readl(a)  __raw_readl(IO_ADDRESS(a))
#define omap_writeb(v,a) __raw_writeb(v, IO_ADDRESS(a))
#define omap_writew(v,a) __raw_writew(v, IO_ADDRESS(a))
#define omap_writel(v,a) __raw_writel(v, IO_ADDRESS(a))
extern void omap1_map_common_io(void);
extern void omap1_init_common_hw(void);
extern void omap2_map_common_io(void);
extern void omap2_init_common_hw(void);
#define __arch_ioremap(p,s,t) omap_ioremap(p,s,t)
#define __arch_iounmap(v) omap_iounmap(v)

void __iomem *omap_ioremap(unsigned long phys, size_t size, unsigned int type);
void omap_iounmap(volatile void __iomem *addr);



本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/96265/showart_2140354.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP