您的位置:首页 > 其它

platform_device驱动模型用到的结构体

2015-08-14 06:28 316 查看
http://my.oschina.net/yuyang/blog/85888

linux platform_device驱动模型详解

platform在linux模型结构中,其实就是一种虚拟总线,没有对应的硬件结构。

其主要用来管理系统的外设资源,比如IO 内存 中断信号......

这样内核就可以假设所有设备都是挂在platform总线上,从而进行整体管理。

linux2.6的设备模型:设备、总线、类和驱动彼此相关的模型结构

首先是总线,bus_type

include/linux/device.h

struct bus_type {

const char *name;

struct bus_attribute *bus_attrs;

struct device_attribute *dev_attrs;

struct driver_attribute *drv_attrs;

int (*match)(struct device *dev, struct device_driver *drv);

int (*uevent)(struct device *dev, struct kobj_uevent_env *env);

int (*probe)(struct device *dev);

int (*remove)(struct device *dev);

void (*shutdown)(struct device *dev);

int (*suspend)(struct device *dev, pm_message_t state);

int (*resume)(struct device *dev);

const struct dev_pm_ops *pm;

struct subsys_private *p;

};

platform的总线定义如下:

struct bus_type platform_bus_type = {

.name = "platform",

.dev_attrs = platform_dev_attrs, //设备属性

.match = platform_match, //match函数这个函数在当属于platform的设备或者驱动注册到内核时就会调用完成设备与驱动的匹配工作

.uevent = platform_uevent, //热插拔操作函数

.pm = &platform_dev_pm_ops,

};

platform_bus_type不是以模块的形势注册到内核中的,它是由init/main.c中的

do_base_setup ---->drivers/base/init.c中driver_init---->

drivers/base/platform.c下的

int __init platform_bus_init(void)

{

int error;

early_platform_cleanup();

error = device_register(&platform_bus);

if (error)

return error;

error = bus_register(&platform_bus_type);

if (error)

device_unregister(&platform_bus);

return error;

}

设备

系统中每个设备都有一个device对象(C语言也可以进行面向对象编程,参考“Linux设备模型理解”)描述,如下

include/linux/device.h

struct device {

struct device *parent;

struct device_private *p;

struct kobject kobj;

const char *init_name; /* initial name of the device */

const struct device_type *type;

struct mutex mutex; /* mutex to synchronize calls to

* its driver.

*/

struct bus_type *bus; /* type of bus device is on */

struct device_driver *driver; /* which driver has allocated this

device */

void *platform_data; /* Platform specific data, device

core doesn't touch it */

struct dev_pm_info power;

struct dev_power_domain *pwr_domain;

#ifdef CONFIG_NUMA

int numa_node; /* NUMA node this device is close to */

#endif

u64 *dma_mask; /* dma mask (if dma'able device) */

u64 coherent_dma_mask;/* Like dma_mask, but for

alloc_coherent mappings as

not all hardware supports

64 bit addresses for consistent

allocations such descriptors. */

struct device_dma_parameters *dma_parms;

struct list_head dma_pools; /* dma pools (if dma'ble) */

struct dma_coherent_mem *dma_mem; /* internal for coherent mem

override */

/* arch specific additions */

struct dev_archdata archdata;

struct device_node *of_node; /* associated device tree node */

dev_t devt; /* dev_t, creates the sysfs "dev" */

dev_t devt; /* dev_t, creates the sysfs "dev" */

spinlock_t devres_lock;

struct list_head devres_head;

struct klist_node knode_class;

struct class *class;

const struct attribute_group **groups; /* optional groups */

void (*release)(struct device *dev);

};

include/linux/platform_device.h中platform_device

struct platform_device {

const char * name;

int id;

struct device dev;

u32 num_resources;

struct resource * resource;

const struct platform_device_id *id_entry;

/* MFD cell pointer */

struct mfd_cell *mfd_cell;

/* arch specific additions */

struct pdev_archdata archdata;

};

resource定义在include/linux/ioport.h下

struct resource {

resource_size_t start;

resource_size_t end;

const char *name;

unsigned long flags;

struct resource *parent, *sibling, *child;

};

设备的注册:

register_device(dev);

int device_register(struct device *dev)

{

device_initialize(dev);

return device_add(dev);

}

对应的platform_device的注册函数为:drivers/base/platform.c下platform_device_register

int platform_device_register(struct device *dev)

{

device_initialize(&pdev->dev);

returnplatform_device_add(pdev);

}

就是mini2440的所有外设资源了,外设的具体定义在

/arch/arm/plat-s3c24xx/devs.c下

驱动

下面是设备驱动定义:

include/linux/device.h

struct device_driver {

const char * name;

struct bus_type * bus;//所属总线

struct completion unloaded;

struct kobject kobj;//代表自身

struct klist klist_devices;//设备列表

struct klist_node knode_bus;

struct module * owner;

int (*probe) (struct device * dev);

int (*remove) (struct device * dev);

void (*shutdown) (struct device * dev);

int (*suspend) (struct device * dev, pm_message_t state);

int (*resume) (struct device * dev);

};

platform_driver的结构如下:

include/linux/platform_device.h

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;

const struct platform_device_id *id_table;

};

驱动注册函数:

drivers/base/driver.c下int driver_register(struct device_driver *drv)

platform_driver的注册函数在drivers/base/platform.c下

int platform_driver_register(struct platform_driver *drv) {

drv->driver.bus = &platform_bus_type;

if (drv->probe)

drv->driver.probe = platform_drv_probe;

if (drv->remove)

drv->driver.remove = platform_drv_remove;

if (drv->shutdown)

drv->driver.shutdown = platform_drv_shutdown;

return driver_register(&drv->driver);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: