linux 起步走 platform_driver_register

linux 起步走 platform_driver_registerstaticstructplatform_drivermxc_v4l2_driver={.driver={.name=“mxc_v4l2_capture”,.owner=THIS_MODULE,.of_match_table=mxc_v4l2_dt_ids,}

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

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

static struct platform_driver mxc_v4l2_driver = {
.driver = {
.name = “mxc_v4l2_capture”,
.owner = THIS_MODULE,
.of_match_table = mxc_v4l2_dt_ids,
},
.id_table = imx_v4l2_devtype,
.probe = mxc_v4l2_probe,
.remove = mxc_v4l2_remove,
.suspend = mxc_v4l2_suspend,
.resume = mxc_v4l2_resume,
.shutdown = NULL,
};

int platform_driver_register(struct platform_driver *drv)
{
    drv->driver.bus = &platform_bus_type; //这个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);
}

static int platform_drv_probe(struct device *_dev)
{
    struct platform_driver *drv = to_platform_driver(_dev->driver);
    struct platform_device *dev = to_platform_device(_dev);
    int ret;

    if (ACPI_HANDLE(_dev))
        acpi_dev_pm_attach(_dev, true);

    ret = drv->probe(dev);
    if (ret && ACPI_HANDLE(_dev))
        acpi_dev_pm_detach(_dev, true);

    return ret;
}
#define to_platform_driver(drv) (container_of((drv), struct platform_driver, driver))
//这里platform_drv_probe调用时就会调用drv->probe(dev)也就是mxc_v4l2_probe,其它几个类似
struct bus_type platform_bus_type = {
    .name       = "platform",
    .dev_attrs  = platform_dev_attrs,
    .match      = platform_match,
    .uevent     = platform_uevent,
    .pm     = &platform_dev_pm_ops,
};
//继续往下看return driver_register(&drv->driver);
int driver_register(struct device_driver *drv)
{
    int ret;
    struct device_driver *other;

    BUG_ON(!drv->bus->p);  //这里的bus就是platform_bus_type,这个也有初始化

    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) {
        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;
    }
    kobject_uevent(&drv->p->kobj, KOBJ_ADD);

    return ret;
}
int bus_register(struct bus_type *bus)// platform_bus_init会调用这个初始化platform_bus_type
{
    int retval;
    struct subsys_private *priv;
    struct lock_class_key *key = &bus->lock_key;

    priv = kzalloc(sizeof(struct subsys_private), GFP_KERNEL);
    if (!priv)
        return -ENOMEM;

    priv->bus = bus;
    bus->p = priv;

    BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);

    retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);//name = "platform"
    if (retval)
        goto out;

    priv->subsys.kobj.kset = bus_kset;
    priv->subsys.kobj.ktype = &bus_ktype;
    priv->drivers_autoprobe = 1;

    retval = kset_register(&priv->subsys);
    if (retval)
        goto out;

    retval = bus_create_file(bus, &bus_attr_uevent);
    if (retval)
        goto bus_uevent_fail;

    priv->devices_kset = kset_create_and_add("devices", NULL,
                         &priv->subsys.kobj);
    if (!priv->devices_kset) {
        retval = -ENOMEM;
        goto bus_devices_fail;
    }

    priv->drivers_kset = kset_create_and_add("drivers", NULL,
                         &priv->subsys.kobj);
    if (!priv->drivers_kset) {
        retval = -ENOMEM;
        goto bus_drivers_fail;
    }

    INIT_LIST_HEAD(&priv->interfaces);
    __mutex_init(&priv->mutex, "subsys mutex", key);
    klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);
    klist_init(&priv->klist_drivers, NULL, NULL);

    retval = add_probe_files(bus);
    if (retval)
        goto bus_probe_files_fail;

    retval = bus_add_attrs(bus);
    if (retval)
        goto bus_attrs_fail;

    pr_debug("bus: '%s': registered\n", bus->name);
    return 0;

bus_attrs_fail:
    remove_probe_files(bus);
bus_probe_files_fail:
    kset_unregister(bus->p->drivers_kset);
bus_drivers_fail:
    kset_unregister(bus->p->devices_kset);
bus_devices_fail:
    bus_remove_file(bus, &bus_attr_uevent);
bus_uevent_fail:
    kset_unregister(&bus->p->subsys);
out:
    kfree(bus->p);
    bus->p = NULL;
    return retval;
}
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;

    klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
    if (drv->bus->p->drivers_autoprobe) {
        error = driver_attach(drv);
        if (error)
            goto out_unregister;
    }
    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);
        }
    }

    return 0;

out_unregister:
    kobject_put(&priv->kobj);
    kfree(drv->p);
    drv->p = NULL;
out_put_bus:
    bus_put(bus);
    return error;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/158263.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • pycharm怎么更新包_python 开发web项目

    pycharm怎么更新包_python 开发web项目运行环境使用的是python2.5,想在项目中换成python3.6,安装完Python3.6后。打开Pycharm:File->Settings->找到project:*******->ProjectInterpreter,然后直接在下拉框里选择你已经安装的好的版本(只要在系统里安装好python版本,配置好环境变量,Pycharm会自动加载)。确认即可统一…

    2022年8月29日
    2
  • ARM开发环境搭建

    ARM开发环境搭建1.下载E:\ARM开发\工具软件\ARM裸机开发工具\Yagarto工具包路径下两个程序2.下载E:\ARM开发\工具软件\USB转串口驱动\CH3403.下载E:\ARM开发\工具软件\ARM裸机开发工具\JRE4.打开设备管理器->右键->更新5.6.选择E:\ARM开发\工具软件\ARM裸机开发工具\DRIVER目录下的(注意:此操作win7环境下,win7以上还要有点其他步骤)选择好就点你下一步7.出现红色弹窗点8.完成9.在E:\ARM开发\工具

    2022年5月29日
    37
  • 【Python数据可视化】超星学习通助手后台数据的可视化处理

    【Python数据可视化】超星学习通助手后台数据的可视化处理Python数据可视化。

    2022年6月21日
    33
  • 如何使 WebAPI 自动生成漂亮又实用在线API文档「建议收藏」

    如何使 WebAPI 自动生成漂亮又实用在线API文档

    2022年2月23日
    44
  • 大数据建模流程之数据处理[通俗易懂]

    大数据建模流程之数据处理[通俗易懂]原文链接数据是建模的基础,也是研究事物发展规律的材料。数据本身的可信度和处理的方式将直接决定模型的天花板在何处。一个太过杂乱的数据,无论用多么精炼的模型都无法解决数据的本质问题,也就造成了模型的效果不理想的效果。这也是我们目前所要攻克的壁垒。但是,目前我们市场对的数据或者科研的数据并不是完全杂乱无章的,基本都是有规律可循的,因此,用模型算法去进行科学的分析,可以主观情绪对决策的影响。所以数据是非常重要的一部分。那么,接下来我们就详细说一下数据的处理与分析。一.数据的基本特征当看到数据的时候,首要做的并

    2022年6月8日
    42
  • androidrepublic_android develop

    androidrepublic_android developPreferenceFragment用来显示首选项的设置,效果图如下:主布局文件:<RelativeLayoutxmlns:android=”http://schemas.android.com/apk/res/android”xmlns:tools=”http://schemas.android.com/tools”android:…

    2022年9月6日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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