<span style="font-size:14px;">struct platform_device {   // linux/platform_device.h
	const char	* name;
	int		id;
	struct device	dev;
	u32		num_resources;
	struct resource	* resource;

	struct platform_device_id	*id_entry;

	/* arch specific additions */
	struct pdev_archdata	archdata;
};</span>

还有一个比较重要的结构体resource比较关键,通常定义一个platform_device一般需要初始化两个方面的内容:设备占用的资源resource和设备私有数据dev.platform_data。最重要的是resource,设备占用的资源主要是两个方面:IO内存和irq资源。实际上是对地址范围及其属性的一个描述。最后几个用于树型结构的指针是内核用于管理所有资源的。

struct resource {   //linux/ioports
	resource_size_t start;
	resource_size_t end;
	const char *name;
	unsigned long flags;
	struct resource *parent, *sibling, *child;
};
static struct resource Myled_resource[] = {
        [0] = {
                .start = 0x56000010,
                .end   = 0x56000010 + 16,
                .flags = IORESOURCE_MEM
        },
};
struct platform_driver {
	int (*probe)(struct platform_device *);
	int (*remove)(struct platform_device *);
	void (*shutdown)(struct platform_device *);
	int (*suspend)(struct platform_device *, pm_message_t state);
	int (*resume)(struct platform_device *);
	struct device_driver driver;
	struct platform_device_id *id_table;
};
//系统中为platform总线定义了一个bus_type的实例platform_bus_type,
struct bus_type platform_bus_type = {
    .name = “platform”,
    .dev_attrs = platform_dev_attrs,
    .match = platform_match,
    .uevent = platform_uevent,
    .pm = PLATFORM_PM_OPS_PTR,
};
EXPORT_SYMBOL_GPL(platform_bus_type);
 
//这里要重点关注其match()成员函数,正是此成员表明了platform_device和platform_driver之间如何匹配。
static int platform_match(struct device *dev, struct device_driver *drv)
{
    struct platform_device *pdev;

    pdev = container_of(dev, struct platform_device, dev);
    return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0);
}
//匹配platform_device和platform_driver主要看二者的name字段是否相同。
//对platform_device的定义通常在BSP的板文件中实现,在板文件中,将platform_device归纳为一个数组,最终通过platform_add_devices()函数统一注册。
//platform_add_devices()函数可以将平台设备添加到系统中,这个函数的 原型为:
int platform_add_devices(struct platform_device **devs, int num);
//该函数的第一个参数为平台设备数组的指针,第二个参数为平台设备的数量,它内部调用了platform_device_register()函 数用于注册单个的平台设备。


//example

Myled.c 设备

static struct platform_device Myledplatform_device_led = {
        .name           = "Myled_platform_device_driver",
        .id             = -1,
        .num_resources  = ARRAY_SIZE(Myled_resource),
        .resource       = Myled_resource,
        .dev            = {
              .release  = Myled_platform_device_release,
        },
};
Myled_drv.c 设备驱动
static struct platform_driver Myled_platform_driver = {
	.probe  = Myled_probe,
	.remove = __devexit_p(Myled_remove),
	.driver = {
		.name = "Myled_platform_device_driver",
		.owner = THIS_MODULE,
	}
};

我们只要把platform_device 和 platform_driver 中的driver.name 设置成一样,platform总线的match会自动匹配 platform_device 和 platform_driver。

Logo

更多推荐