108 platform:虚拟的平台总线

一、pbus,pdev,pdrv 三者关系

  • platform_device:内部继承 device,关联硬件代码

  • platform_driver:内部继承device_driver,是软件点代码部分,重设probe函数指针

  • platform(bus_type):统一管理、设置match匹配规则(若匹配则会执行 drv->probe,最终会调用 pdrv->probe)

在这里插入图片描述

二、平台总线注册

drivers/base/platform.c

/sys/bus/platform

1、platform_bus_init()函数

struct bus_type platform_bus_type = {
	.name		= "platform",
	.dev_groups	= platform_dev_groups,
	.match		= platform_match,
	.uevent		= platform_uevent,
	.dma_configure	= platform_dma_configure,
	.pm		= &platform_dev_pm_ops,
};

/* 此函数在系统启动时自动执行。 */
int __init platform_bus_init(void)
{
...
	/* 注册平台总线。 */
	error =  bus_register(&platform_bus_type);
...
	return error;
}

2、platform_match()函数

设置匹配规则

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);

	/* When driver_override is set, only bind to the matching driver */
	if (pdev->driver_override)
		return !strcmp(pdev->driver_override, drv->name);

	/* Attempt an OF style match first */
	if (of_driver_match_device(dev, drv))
		return 1;

	/* Then try ACPI style match */
	if (acpi_driver_match_device(dev, drv))
		return 1;

	/* Then try to match against the id table */
	if (pdrv->id_table)
		return platform_match_id(pdrv->id_table, pdev) != NULL;

	/* fall-back to driver name match */
	return (strcmp(pdev->name, drv->name) == 0);
}
  • of_driver_match_device:设备树匹配
  • acpi_driver_match_device:ACPI匹配
  • platform_match_id:id_table匹配
  • strcmp(pdev->name, drv->name):设备名和驱动名匹配

三、平台设备注册

drivers/base/platform.c

1、platform_device_register()函数

想内核注册一个 pdev(在注册之前需要我们向pdev结构体中填充硬件相关信息)

int platform_device_register(struct platform_device *pdev)
  • 继承device

2、resource 结构体

此结构体用来描述驱动的硬件资源

/*
 * Resources are tree-like, allowing
 * nesting etc..
 */
struct resource {
	resource_size_t start;
	resource_size_t end;
	const char *name;
	unsigned long flags;
	struct resource *parent, *sibling, *child;
};
  • start:资源的开始值
  • end:资源的结束值
  • flasg:资源的类型
    • IORESOURCE_MEM:内存地址
    • IORESOURCE_IO:IO端口
    • IORESOURCE_DMA:DMA传输
    • IORESOURCE_IRQ:中断资源

四、平台驱动注册

include/linux/platform_device.h

1、platform_driver_register() 宏

#define platform_driver_register(drv) \
	__platform_driver_register(drv, THIS_MODULE)
extern int __platform_driver_register(struct platform_driver *,
					struct module *);

注意第一个参数 struct platform_driver 关联软件部分的代码,此结构体中最重要的是 probe 成员函数(一定要初始化好在向总线注册),是真正的模块入口。

另外 pdrv->id_table也要初始化好。

2、平台驱动获取资源

drivers/base/platform.c

platform_get_resource()函数

此函数用于在软件模块代码中获取硬件代码的相关数据。

/**
 * platform_get_resource - get a resource for a device
 * @dev: platform device
 * @type: resource type
 * @num: resource index
 */
struct resource *platform_get_resource(struct platform_device *dev,
				       unsigned int type, unsigned int num)
{
	int i;

	for (i = 0; i < dev->num_resources; i++) {
		struct resource *r = &dev->resource[i];

		if (type == resource_type(r) && num-- == 0)
			return r;
	}
	return NULL;
}
EXPORT_SYMBOL_GPL(platform_get_resource);
  • dev:平台设备,就是与 pdrv 匹配的 pdev->dev
  • type:要获取的资源类型
  • num:就是 type 类资源中的第 num 个。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值