linux 驱动-匹配2 (amba_bustype)

目录

1.实例分析

   a. 设备树实例

  b. 驱动实例

2. amba匹配流程

 a. 创建amba_device

b. 确定总线以及总线的匹配函数

c. 分析总线的匹配函数


1.实例分析

   a. 设备树实例

serial@7e201000 {
    compatible = "brcm,bcm2835-pl011\0arm,pl011\0arm,primecell"; //创建amba_device
    reg = <0x7e201000 0x200>;
    interrupts = <0x02 0x19>;
    clocks = <0x03 0x13 0x03 0x14>;
    clock-names = "uartclk\0apb_pclk";
    arm,primecell-periphid = <0x241011>; // 用于匹配amba_driver 的id_table
    cts-event-workaround;
    pinctrl-names = "default";
    pinctrl-0 = <0x08 0x09>;
    status = "okay";
    phandle = <0x21>;
};

  b. 驱动实例

 static const struct amba_id pl011_ids[] = {
    {
        .id    = 0x00041011,
        .mask    = 0x000fffff,
        .data    = &vendor_arm,
    },
    { 0, 0 },
};

static struct amba_driver pl011_driver = {
    .drv = {
        .name    = "uart-pl011",
        .pm    = &pl011_dev_pm_ops,
        .suppress_bind_attrs = IS_BUILTIN(CONFIG_SERIAL_AMBA_PL011),
    },
    .id_table    = pl011_ids,
    .probe        = pl011_probe,
    .remove        = pl011_remove,
};

2. amba匹配流程

   总结
        a.创建amba_device,
                并根据设备树的 “arm,primecell-periphid”属性 填充 amba_device 的periphid
        b. 使用amba_device 的periphid 去匹配 amba_driver的id_table

 a. 创建amba_device

b. 确定总线以及总线的匹配函数

a. 确定总线为 amba_bustype
of_amba_device_create
   ->amba_device_alloc
   	->amba_device_initialize
static void amba_device_initialize(struct amba_device *dev, const char *name)

{
	...
	dev->dev.bus = &amba_bustype;

      	....
}
b. 确定amba总线的匹配函数为amba_match	
struct bus_type amba_bustype = {
	...
	.match		= amba_match,
	...
};

c. 分析总线的匹配函数

       使用amba_device->periphid  与 amba_driver->id_table数组进行匹配


static int amba_match(struct device *dev, struct device_driver *drv)
{
	struct amba_device *pcdev = to_amba_device(dev);
	struct amba_driver *pcdrv = to_amba_driver(drv);

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

	return amba_lookup(pcdrv->id_table, pcdev) != NULL;
}

static const struct amba_id *
amba_lookup(const struct amba_id *table, struct amba_device *dev)
{
	int ret = 0;
	while (table->mask) {
		ret = (dev->periphid & table->mask) == table->id;
		if (ret)
			break;
		table++;
	}
	return ret ? table : NULL;
}

  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乐分享-程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值