platform bus

1. An important thought
on separation: the separation devices and drivers, their management. Added to the bus until the end, to match.
model
2. What is the platform bus?
With respect to USB, PCI, I2C, SPI, etc. for physical bus, the bus is a virtual Platform, abstract bus, in practice there is no such bus. Why need platform bus it? In fact, the Linux device driver model in order to maintain the unity and virtual device drivers out of the bus. Because for usb device, i2c device, pci device, spi equipment, etc., they communicate with the cpu are directly linked to the respective bus following data interaction with our cpu, but in which we embedded systems, not All of these devices are capable of belonging to a common bus, in which embedded systems, system integration SoC independent peripheral controller, attached peripherals SoC memory space is not attached to such bus. So Linux Driver Model For completeness, these devices are hung on a virtual bus (platform bus), which is not such that some devices on the bus, there is no other device on the bus to hang.
platform bus-related code declares: linux / platform_device.h file

3, two key structures platform_device platform_driver platform bus and
to the buses of the two parts by any one of Linux device driver model consisting of: device-related structure described and description of the driving structure is associated platform bus at platform_device and platform_driver, each element is the following two structures were analyzed:
the structure (1) platform_device structure and analysis

struct platform_device {           
      const char * name;      //平台设备的名字
      int id;                 //ID区分设备名字,如果一个驱动对应一个设备,传-1
      struct device dev;      //描述设备信息device结构体
      u32 num_resources;      //资源结构体数量,资源信息结构体数组的大小
      struct resource * resource; //资源结构体,一般定义一个数组
};
struct device {
    struct device_driver *driver;  //设备驱动的结构体指针
    struct device_node *of_node;   //设备树节点
    u32 id;	
    void (*release)(struct device *dev);  //设备端卸载的时候,须调用的函数
};
struct resource {
	resource_size_t start;      //起始地址
	resource_size_t end;        //结束地址
	const char *name;           //资源名字
	unsigned long flags;        //标志 IORESOURCE_IO IORESOURCE_MEM 
                               //IORESOURCE_IRQ
}; 

Device-side call code

int platform_device_register(struct platform_device *pdev);
功能:platfrom平台总线设备注册
参数:
    @pdev    platform平台总线设备端结构体指针
返回值:成功返回0,失败返回负数错误码

void platform_device_unregister(struct platform_device *); 
功能:platfrom平台总线设备卸载
参数:
    @pdev    platform平台总线设备端结构体指针
返回值:成功返回0,失败返回负数错误码

(2) Structure platform_driver structure and Analysis

struct platform_driver {
	int (*probe)(struct platform_device *);   //获取设备信息,在匹配成功调用
	int (*remove)(struct platform_device *);   //在移除的时候调用
	struct device_driver driver;
	const struct platform_device_id *id_table; //id_table表
};

struct device_driver {
	const char		*name;    //名字  匹配
	struct bus_type		*bus;     //总线信息结构体
	struct module		*owner;   //THIS_MODULE
	const struct of_device_id	*of_match_table;    //设备树的相关信息
};

struct platform_device_id {
	char name[PLATFORM_NAME_SIZE];   //名字
	kernel_ulong_t driver_dat;
};

Driver-side call code

int platform_driver_register(struct platform_driver *pdrv);
功能:platform平台总线驱动端注册函数
参数:
    @pdrv   platform平台总线驱动端结构体指针
返回值:成功返回0,失败返回负数错误码    

void platform_driver_unregister(struct platform_driver *);
功能:platform平台总线驱动端卸载函数
参数:
    @pdrv   platform平台总线驱动端结构体指针
返回值:成功返回0,失败返回负数错误码  

Key:
a .platform drive registration process:

platform_driver_register
  --->>>driver_register(&drv->driver);
      --->>>bus_add_driver(drv);
          --->>>driver_attach(drv);   //驱动绑定设备
                  /*遍历设备端的链表,完成匹配*/
              --->>>bus_for_each_dev(drv->bus, NULL, drv,__driver_attach); 
                  --->>>__driver_attach
                      --->>>driver_match_device(drv, dev)
static int platform_match(struct device *dev, struct device_driver *drv)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct platform_driver *pdrv = to_platform_driver(drv);
    /*和设备树进行匹配*/
	if (of_driver_match_device(dev, drv))
		return 1;

	/* 和id_table表进行匹配 */
	if (pdrv->id_table)
		return platform_match_id(pdrv->id_table, pdev) != NULL;

	/* 和名字进行匹配*/
	return (strcmp(pdev->name, drv->name) == 0);
}

Two .platform device-side registration:

platform_device_register
  --->>>platform_device_add(pdev);
    --->>>device_add(&pdev->dev);
       --->>>bus_probe_device(dev);
         --->>>device_attach(dev);
           --->>>bus_for_each_drv(dev->bus, NULL, dev, __device_attach);

Above last call:

**driver_probe_device**

Summary: platform platform bus, devices and drivers in the registration process, the other will traverse the linked list, to find whether there is a match, if there is a match, it calls probe detection function driver acquires device information.

Released three original articles · won praise 22 · views 1158

Guess you like

Origin blog.csdn.net/xjpyinxll/article/details/104522648