在module_init(s3c_rtc_init); 时,
static int __init s3c_rtc_init(void)
{
printk(banner);
return platform_driver_register(&s3c2410_rtcdrv);
}
系统注册s3c_rtc时,将banner打出来了
static struct platform_driver s3c2410_rtcdrv = {
.probe = s3c_rtc_probe,
.remove = s3c_rtc_remove,
.suspend = s3c_rtc_suspend,
.resume = s3c_rtc_resume,
.driver = {
.name = "s3c2410-rtc",
.owner = THIS_MODULE,
},
};
int platform_driver_register(struct platform_driver *drv)
{
drv->driver.bus = &platform_bus_type; //设置driver的bus type
if (drv->probe) //在platform_driver s3c2410_rtcdrv 定义了.probe = s3c_rtc_probe,
drv->driver.probe = platform_drv_probe; //将drv->driver.probe 设为platform_drv_probe 将drv->driver.probe和drv->probe都设置为platform_driver的probe函数,即是s3c_rtc_probe函数
if (drv->remove)
drv->driver.remove = platform_drv_remove; //同理
if (drv->shutdown)
drv->driver.shutdown = platform_drv_shutdown;
if (drv->suspend)
drv->driver.suspend = platform_drv_suspend;
if (drv->resume)
drv->driver.resume = platform_drv_resume;
return driver_register(&drv->driver); //这里就是关键的注册函数:driver_register
}
/**
* driver_register - register driver with bus
* @drv: driver to register
*
* We pass off most of the work to the bus_add_driver() call,
* since most of the things we have to do deal with the bus
* structures.
*/
int driver_register(struct device_driver *drv)
{
int ret;
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);
ret = bus_add_driver(drv); //We pass off most of the work to the bus_add_driver() call
if (ret)
return ret;
ret = driver_add_groups(drv, drv->groups);
if (ret)
bus_remove_driver(drv);
return ret;
}
/**
* bus_add_driver - Add a driver to the bus.
* @drv: driver.
*/
int bus_add_driver(struct device_driver *drv)
{
struct bus_type *bus;
struct driver_private *priv;
int error = 0;
bus = bus_get(drv->bus); //获取drv的bus tpye ,即bus为platform_bus_type
if (!bus)
return -EINVAL;
pr_debug("bus: '%s': add driver %s/n", bus->name, drv->name);
priv = kzalloc(sizeof(*priv), GFP_KERNEL); //初始化driver_private *priv
if (!priv) {
error = -ENOMEM;
goto out_put_bus;
}
klist_init(&priv->klist_devices, NULL, NULL); //初始化drv结构体下的priv指针的dev设备列表
priv->driver = drv;
drv->p = priv; //这两句将priv结构体指针和drv联系在一起
priv->kobj.kset = bus->p->drivers_kset;
/* 指向bus的drivers_kset容器,该容器的作用与device_kset容器相同,前者是包含所
有注册到该bus的driver,后者是包含所有注册到该bus的device。*/
error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,
"%s", drv->name);
//因为有上面的priv->kobj.kset = bus->p->drivers_kset;,所以这一句在/sys/bus/platform/drivers/下建立了"s3c2410-rtc"(drv->name)目录
if (error)
goto out_unregister;
if (drv->bus->p->drivers_autoprobe) { //因为在bus_register中有priv->drivers_autoprobe = 1;if会执行的
error = driver_attach(drv); //实际就是调用bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
//这个地方和bus_for_each_drv很是类似
//driver_attach-->bus_for_each_dev-->__driver_attach-->driver_probe_device-->really_probe
if (error)
goto out_unregister;
}
klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers); //在bus的drivers列表上添加节点
module_add_driver(drv->owner, drv); //将driver添加到module模块,后面再看
error = driver_create_file(drv, &driver_attr_uevent);
//生成/sys/bus/platform/drivers/s3c2410-rtc/uevent属性文件,其作用与device中的
uevent类似
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed/n",
__FUNCTION__, drv->name);
}
error = driver_add_attrs(bus, drv);
//添加bus的公有属性文件到/sys//sys/bus/platform/drivers/s3c2410-rtc/目录
if (error) {
/* How the hell do we get out of this pickle? Give up */
printk(KERN_ERR "%s: driver_add_attrs(%s) failed/n",
__FUNCTION__, drv->name);
}
error = add_bind_files(drv);
//如果配置了”CONFIG_HOTPLUG",则生成“bind”和"unbind”属性文件,可用于手动匹
配和移除 device与driver之间的关联,见下面的英文注释
/*
* Thanks to drivers making their tables __devinit, we can't allow manual
* bind and unbind from userspace unless CONFIG_HOTPLUG is enabled.
*/
if (error) {
/* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed/n",
__FUNCTION__, drv->name);
}
kobject_uevent(&priv->kobj, KOBJ_ADD);
return error;
out_unregister:
kobject_put(&priv->kobj);
out_put_bus:
bus_put(bus);
return error;
}
void module_add_driver(struct module *mod, struct device_driver *drv)
{
char *driver_name;
int no_warn;
struct module_kobject *mk = NULL;
if (!drv)
return;
if (mod) //因为设置了THIS_MODULE,所以执行
mk = &mod->mkobj;
else if (drv->mod_name) {
struct kobject *mkobj;
/* Lookup built-in module entry in /sys/modules */
mkobj = kset_find_obj(module_kset, drv->mod_name);
if (mkobj) {
mk = container_of(mkobj, struct module_kobject, kobj);
/* remember our module structure */
drv->p->mkobj = mk;
/* kset_find_obj took a reference */
kobject_put(mkobj);
}
}
if (!mk)
return;
/* Don't check return codes; these calls are idempotent */
no_warn = sysfs_create_link(&drv->p->kobj, &mk->kobj, "module");
//在/sys/bus/platform/drivers/s3c2410-rtc/目录下生成名为"module"的链接文件,指
向/sys/modules/rtc-s3c目录
driver_name = make_driver_name(drv);
//将drv->bus->name和 drv->name组合在一起生成driver_name为platform:s3c2410-rtc
if (driver_name) {
module_create_drivers_dir(mk); //生成/sys/modules/rtc-s3c目录下生成drivers目录
no_warn = sysfs_create_link(mk->drivers_dir, &drv->p->kobj,
driver_name);
//在/sys/modules/rtc-s3c/drivers目录下生成名为“platform:s3c2410-rtc”的
链接文件,指向/sys/bus/platform/drivers/s3c2410-rtc/目录
kfree(driver_name);
}
}
这样driver就注册完成了。