内核中与驱动相关的内存操作之十一(IO内存)

    设备通常会提供一组寄存器用于控制设备、读定设备和获取设备状态,即控制寄存器、数据寄存器和状态寄存器.这些寄存器可能位于I/O空间,也可能位于内存空间.当位于I/O空间时,通常被称为I/O端口,位于内存空间时,对应的内存空间被称为I/O内存.在嵌入式LINUX,我们接触最多的就是I/O内存:

#define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name), 0)

     向内核申请n个内存地址,这些地址从first开始,name参数为设备的名称.如果分配成功返回值为非NULL,如果返回NULL,则意味着申请I/O内存失败.
  其相反的动作函数为:

int release_resource(struct resource *old)

   这对函数一般用来判断I/O内存是否已经被占用了.它一般配合platform_get_resource()函数来使用.platform_get_resource()用来获取平台设备端的I/O内存地址空间,并以其返回值为参数.如下:

struct resource *platform_get_resource(struct platform_device *dev,unsigned int type, unsigned int num) 

     以S3C2440的RTC为例,简单说明:

1.	static int __devinit s3c_rtc_probe(struct platform_device *pdev)  
2.	{  
3.	    ... ...;  
4.	        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);  
5.	    if (res == NULL) {  
6.	        dev_err(&pdev->dev, "failed to get memory region resource\n");  
7.	        return -ENOENT;  
8.	    }  
9.	  
10.	    s3c_rtc_mem = request_mem_region(res->start,res->end-res->start+1,pdev->name);  
11.	    ... ...;  
12.	}  

    [注:]I/O内存一般只用来判断我们目标操作内存是否被占用,但是这并不是必须的.

         在对I/O内存的存取内核提供了专门的API:

1.	unsigned readb(address);  
2.	unsigned readw(address);  
3.	unsigned readl(address);   
4.	  
5.	void writeb(unsigned value, address);  
6.	void writew(unsigned value, address);  
7.	void writel(unsigned value, address);   
    

   例如S3C2440LCD驱动里面,LCD主控端寄存器的配置:

1.	static int __init s3c24xxfb_probe(struct platform_device *pdev,enum s3c_drv_type drv_type)  
2.	{  
3.	    ... ...;  
4.	    lcdcon1 = readl(info->io + S3C2410_LCDCON1);  
5.	    writel(lcdcon1 & ~S3C2410_LCDCON1_ENVID, info->io + S3C2410_LCDCON1);  
6.	    ... ...;  
7.	}  




 

你可能感兴趣的:(内核中与驱动相关的内存操作之十一(IO内存))