平台总线设备除了用前面的platform_device_register函数去注册之外,经常会在平台下面看到platform_add_devices这样一个函数,platform_add_devices也是用于平台设备注册的,它是注册一组平台设备,函数原型如下:
int platform_add_devices(struct platform_device **devs, int num);
大家也可以去看看这个函数,其本质还是依次调用platform_device_register函数去注册这组平台设备。
上面已经为平台设备定义好了资源信息,那么在平台驱动中如何去获取这些资源信息为驱动所用呢?那就是通过platform_get_resource去获取平台设备的资源信息,原型如下:
struct resource *platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num);
参数dev为平台设备,type为前面的资源信息类型,比如IORESOURCE_MEM或IORESOURCE_IRQ,num为同类型资源信息中的一个索引号,比如有多个IORESOURCE_MEM类型的资源信息,那以什么去区分呢,就是这个索引号,可以先看一个例子:
int platform_get_irq(struct platform_device *dev, unsigned int num);
其本质依然是调用platform_get_resource函数去获取资源信息,只是资源信息的类型指定为IORESOURCE_IRQ,在获取到资源信息之后,返回中断号。
int platform_add_devices(struct platform_device **devs, int num);
大家也可以去看看这个函数,其本质还是依次调用platform_device_register函数去注册这组平台设备。
很多时候呢,平台设备会关联一些资源信息,比如IO基地址,中断号等等。Linux中使用struct resource去描述资源信息,需要包含头文件linux/ioport.h,struct resource结构体定义如下:
struct resource {
resource_size_t start;
resource_size_t end;
const char *name;
unsigned long flags;
struct resource *parent, *sibling, *child;
};
先看一个例子:
static struct resource s3c_wdt_resource[] = {
[0] = {
.start = S3C24XX_PA_WATCHDOG,
.end = S3C24XX_PA_WATCHDOG + S3C24XX_SZ_WATCHDOG - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_WDT,
.end = IRQ_WDT,
.flags = IORESOURCE_IRQ,
}
};
这里定义了两组资源信息,一个是IO基地址,另一个是中断号,常用的也就这两种,start为起始值,end为结束值。定义好资源信息之后,还需要将它们赋值给平台设备,例如:
struct platform_device s3c_device_wdt = {
.name = "s3c2410-wdt",
.id = -1,
.num_resources = ARRAY_SIZE(s3c_wdt_resource),
.resource = s3c_wdt_resource,
};
其中num_resources为资源的个数。
上面已经为平台设备定义好了资源信息,那么在平台驱动中如何去获取这些资源信息为驱动所用呢?那就是通过platform_get_resource去获取平台设备的资源信息,原型如下:
struct resource *platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num);
参数dev为平台设备,type为前面的资源信息类型,比如IORESOURCE_MEM或IORESOURCE_IRQ,num为同类型资源信息中的一个索引号,比如有多个IORESOURCE_MEM类型的资源信息,那以什么去区分呢,就是这个索引号,可以先看一个例子:
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
再看一个例子:
static struct resource *wdt_irq;
wdt_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
对于中断号除了用platform_get_resource函数去获取之外,Linux还提供了另外一个函数platform_get_irq,原型如下:
int platform_get_irq(struct platform_device *dev, unsigned int num);
其本质依然是调用platform_get_resource函数去获取资源信息,只是资源信息的类型指定为IORESOURCE_IRQ,在获取到资源信息之后,返回中断号。