platform_driver_register,什么时候调用PROBE函数 注册后如何找到驱动匹配的设备

platform_driver_register,什么时候调用PROBE函数 注册后如何找到驱动匹配的设备kernel_init中do_basic_setup()->driver_init()->platform_bus_init()->…初始化platformbus(虚拟总线)设备向内核注册的时候platform_device_register()->platform_device_add()->…内核把设备挂在虚拟的platformbus下驱动注册…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

kernel_init中do_basic_setup()->driver_init()->platform_bus_init()->…初始化platform bus(虚拟总线)

设备向内核注册的时候platform_device_register()->platform_device_add()->…内核把设备挂在虚拟的platform bus下

驱动注册的时候platform_driver_register()->driver_register()->bus_add_driver()->driver_attach()->bus_for_each_dev()

对每个挂在虚拟的platform bus的设备作__driver_attach()->driver_probe_device()->drv->bus->match()==platform_match()->比较strncmp(pdev->name, drv->name, BUS_ID_SIZE),

如果相符就调用platform_drv_probe()->driver->probe(),如果probe成功则绑定该设备到该驱动.

kernel/init/main.c 

 

static int __init kernel_init(void * unused)

{

/*

 * Wait until kthreadd is all set-up.

 */

wait_for_completion(&kthreadd_done);

/*

 * init can allocate pages on any node

 */

set_mems_allowed(node_states[N_HIGH_MEMORY]);

/*

 * init can run on any cpu.

 */

set_cpus_allowed_ptr(current, cpu_all_mask);

 

cad_pid = task_pid(current);

 

smp_prepare_cpus(setup_max_cpus);

 

do_pre_smp_initcalls();

lockup_detector_init();

 

smp_init();

sched_init_smp();

 

do_basic_setup();

 

/* Open the /dev/console on the rootfs, this should never fail */

if (sys_open((const char __user *) “/dev/console”, O_RDWR, 0) < 0)

printk(KERN_WARNING “Warning: unable to open an initial console.\n”);

 

(void) sys_dup(0);

(void) sys_dup(0);

/*

 * check if there is an early userspace init.  If yes, let it do all

 * the work

 */

 

if (!ramdisk_execute_command)

ramdisk_execute_command = “/init”;

 

if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {

ramdisk_execute_command = NULL;

prepare_namespace();

}

 

/*

 * Ok, we have completed the initial bootup, and

 * we’re essentially up and running. Get rid of the

 * initmem segments and start the user-mode stuff..

 */

 

init_post();

return 0;

}

 

 

static void __init do_basic_setup(void)

{

cpuset_init_smp();

usermodehelper_init();

init_tmpfs();

driver_init();

init_irq_proc();

do_ctors();

do_initcalls();

}

 

kernel/drivers/base/init.c

 

void __init driver_init(void)

{

/* These are the core pieces */

devtmpfs_init();

devices_init();

buses_init();

classes_init();

firmware_init();

hypervisor_init();

 

/* These are also core pieces, but must come after the

 * core core pieces.

 */

platform_bus_init();

system_bus_init();

cpu_dev_init();

memory_dev_init();

}

 

kernel/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;

}

 

 

kernel/drivers/base/platform.c

 

int platform_device_register(struct platform_device *pdev)

{

device_initialize(&pdev->dev);

return platform_device_add(pdev);

}

 

 

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

}

 

kernel/drivers/base/driver.c

 

int driver_register(struct device_driver *drv)

{

int ret;

struct device_driver *other;

 

BUG_ON(!drv->bus->p);

 

if ((drv->bus->probe && drv->probe) ||

    (drv->bus->remove && drv->remove) ||

    (drv->bus->shutdown && drv->shutdown))

printk(KERN_WARNING “Driver ‘%s’ needs updating – please use “

“bus_type methods\n”, drv->name);

 

other = driver_find(drv->name, drv->bus);

if (other) {

put_driver(other);

printk(KERN_ERR “Error: Driver ‘%s’ is already registered, “

“aborting…\n”, drv->name);

return -EBUSY;

}

 

ret = bus_add_driver(drv);

if (ret)

return ret;

ret = driver_add_groups(drv, drv->groups);

if (ret)

bus_remove_driver(drv);

return ret;

}

 

kernel/drivers/base/bus.c

 

int bus_add_driver(struct device_driver *drv)

{

struct bus_type *bus;

struct driver_private *priv;

int error = 0;

 

bus = bus_get(drv->bus);

if (!bus)

return -EINVAL;

 

pr_debug(“bus: ‘%s’: add driver %s\n”, bus->name, drv->name);

 

priv = kzalloc(sizeof(*priv), GFP_KERNEL);

if (!priv) {

error = -ENOMEM;

goto out_put_bus;

}

klist_init(&priv->klist_devices, NULL, NULL);

priv->driver = drv;

drv->p = priv;

priv->kobj.kset = bus->p->drivers_kset;

error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,

     “%s”, drv->name);

if (error)

goto out_unregister;

 

if (drv->bus->p->drivers_autoprobe) {

error = driver_attach(drv);

if (error)

goto out_unregister;

}

klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);

module_add_driver(drv->owner, drv);

 

error = driver_create_file(drv, &driver_attr_uevent);

if (error) {

printk(KERN_ERR “%s: uevent attr (%s) failed\n”,

__func__, drv->name);

}

error = driver_add_attrs(bus, drv);

if (error) {

/* How the hell do we get out of this pickle? Give up */

printk(KERN_ERR “%s: driver_add_attrs(%s) failed\n”,

__func__, drv->name);

}

 

if (!drv->suppress_bind_attrs) {

error = add_bind_files(drv);

if (error) {

/* Ditto */

printk(KERN_ERR “%s: add_bind_files(%s) failed\n”,

__func__, drv->name);

}

}

 

kobject_uevent(&priv->kobj, KOBJ_ADD);

return 0;

 

out_unregister:

kobject_put(&priv->kobj);

kfree(drv->p);

drv->p = NULL;

out_put_bus:

bus_put(bus);

return error;

}

 

kernel/drivers/base/Dd.c

 

int driver_attach(struct device_driver *drv)

{

return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);

}

EXPORT_SYMBOL_GPL(driver_attach);

 

kernel/drivers/base/bus.c

 

int bus_for_each_dev(struct bus_type *bus, struct device *start,

     void *data, int (*fn)(struct device *, void *))

{

struct klist_iter i;

struct device *dev;

int error = 0;

 

if (!bus)

return -EINVAL;

 

klist_iter_init_node(&bus->p->klist_devices, &i,

     (start ? &start->p->knode_bus : NULL));

while ((dev = next_device(&i)) && !error)

error = fn(dev, data);

klist_iter_exit(&i);

return error;

}

EXPORT_SYMBOL_GPL(bus_for_each_dev);

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/158256.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 达芬奇的密码[通俗易懂]

    达芬奇的密码[通俗易懂]写在前面郇山隐修会是一个确实存在的组织,是一个成立于1099年的欧洲秘密社团。1975年巴黎国家图书馆发现了被称作“秘密卷宗”的羊皮纸文献,才知道包括艾撒克。牛顿爵士、波提切利、维克多。雨果和列昂纳多。达。芬奇等众多人物均为郇山隐修会成员。人们所知的“天主事工会”是一个梵蒂冈教派——一个极度虔诚的罗马天主教派。该教派近来引起了诸多争议,因为有报道

  • 新版白话空间统计(8):莫兰指数小结

    新版白话空间统计(8):莫兰指数小结本节对前面写的莫兰指数部分留下的一下小问题进行解答,里面包括一些读者朋友们通过邮件提出的一些问题。Q1:ArcGIS中,计算莫兰指数的工具里面的那个Row(行标准化)是拿来干嘛的?A:…

  • Zuul网关_为什么网关老是断开

    Zuul网关_为什么网关老是断开一、前言Zuul网关是具体核心业务服务的看门神,相比具体实现业务的系统服务来说它是一个边缘服务,主要提供动态路由,监控,弹性,安全性等功能。在分布式的微服务系统中,系统被拆为了多套系统,通过zuul网关来对用户的请求进行路由,转发到具体的后台服务系统中。本Chat主要内容如下:服务网关演化历程。Zuul1.0服务架构与源码剖析。Zuul2.0服务架构新特性。二、服务网关演化历程网关是…

  • a4如何打印双面小册子_a4如何打印双面小册子[通俗易懂]

    a4如何打印双面小册子_a4如何打印双面小册子[通俗易懂]展开全部1、在Word中打开一篇文档,点击“文件”——“打印”菜单项,准备开始打印工作。2、弹出“32313133353236313431303231363533e4b893e5b19e31333433623230打印”对话框,在“打印机”名称框的左侧,点击“属性”按钮,点击此按钮,开始设置小册子打印。3、弹出打印机属性对话框,在“双面打印”部分,点击下拉菜单,选择“双面打印,短边“装订。(目…

  • deepfakes视频的网站_惊了,DeepFakes不仅骗过人,还能骗过人脸识别系统?![通俗易懂]

    deepfakes视频的网站_惊了,DeepFakes不仅骗过人,还能骗过人脸识别系统?![通俗易懂]原标题:惊了,DeepFakes不仅骗过人,还能骗过人脸识别系统?!选自arXiv作者:PavelKorshunov、SebastienMarcel机器之心编辑部今年年初,DeepFakes技术火爆全网,它可以轻松替换视频中的人脸。网络上各种恶搞视频(其中大量是色情视频)让人分不清真真假假,那么人脸识别系统能够检测出哪些是DeepFakes生成的视频吗?这项研究告诉我们不太行……自动视…

  • pytorch 下载安装全流程详细教程

    pytorch 下载安装全流程详细教程强烈推荐,亲测有效,1.查看cuda版本。2.在官网https://pytorch.org/选择对应的版本。3.复制RunthisCommand,直接下载安装(速度还挺快)。完美

    2022年10月31日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号