kobject引用计数

**************************************************************
struct platform_device {
struct device dev;
};
struct device {
struct kobject kobj;
void (*release)(struct device *dev);
}
创建一个平台设备:
static struct platform_device xxx = {
.name = xxx
.resourse =
.dev = {
.release = xxx_release,
}
}
***************************************************************
问题1:xxx_release何时被调用????
当卸载平台设备时,调用:
-------------------------------------------------------------------------------
void platform_device_unregister(struct platform_device *pdev)
{
/* 1.移除平台设备,这个函数将会释放设备占用的所有内存、端口、irq...资源 */
platform_device_del(pdev);

/* 2.减少设备引用次数 */
platform_device_put(pdev);
} \drivers\base\Platform.c

--------------------------------------------------------------------------------
void platform_device_put(struct platform_device *pdev)
{
if (pdev)
put_device(&pdev->dev);
} \drivers\base\Platform.c
--------------------------------------------------------------------------------
void put_device(struct device *dev)
{
/* might_sleep(); */
if (dev)
kobject_put(&dev->kobj);
} \drivers\base\core.c
--------------------------------------------------------------------------------
static void kobject_release(struct kref *kref)
{
kobject_cleanup(container_of(kref, struct kobject, kref));
}
void kobject_put(struct kobject *kobj)
{
if (kobj) {
if (!kobj->state_initialized)
WARN(1, KERN_WARNING "kobject: '%s' (%p): is not "
      "initialized, yet kobject_put() is being "
      "called.\n", kobject_name(kobj), kobj);
kref_put(&kobj->kref, kobject_release);
}
} \lib\Kobject.c

--------------------------------------------------------------------------------
int kref_put(struct kref *kref, void (*release)(struct kref *kref))
{
WARN_ON(release == NULL);
WARN_ON(release == (void (*)(struct kref *))kfree);

/* 从原子变量refcount中减去1,如果refcount为0,返回ture,否则调用release(kref) */

if (atomic_dec_and_test(&kref->refcount)) {
release(kref);
return 1;
}
return 0;
}  \lib\Kref.c
--------------------------------------------------------------------------------
static void kobject_cleanup(struct kobject *kobj)
{
/* 1.获取kobject 的属性值*/
struct kobj_type *t = get_ktype(kobj);

/* 2.如果没有提供release函数则报错 */
if (t && !t->release)
pr_debug("kobject: '%s' (%p): does not have a release() "
"function, it is broken and must be fixed.\n",
kobject_name(kobj), kobj);

/* 3.如果提供了release函数,就调用它 */
if (t && t->release) {
pr_debug("kobject: '%s' (%p): calling ktype release\n",
kobject_name(kobj), kobj);
t->release(kobj);
}

} \lib\Kobject.c
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
struct device {
struct kobject kobj;
void (*release)(struct device *dev);
}

device里的release 函数如何与kobj->kobj_type 里的release函数关联起来的????

int platform_device_register(struct platform_device *pdev)
{
device_initialize(&pdev->dev);
return platform_device_add(pdev);
}
--------------------------------------------------------------
static struct kobj_type device_ktype = {
.release = device_release,
.sysfs_ops = &dev_sysfs_ops,
};
static void device_release(struct kobject *kobj)
{
struct device *dev = to_dev(kobj);
struct device_private *p = dev->p;

if (dev->release)
dev->release(dev);                      //在这里联系起来的
else if (dev->type && dev->type->release)
dev->type->release(dev);
else if (dev->class && dev->class->dev_release)
dev->class->dev_release(dev);
else
WARN(1, KERN_ERR "Device '%s' does not have a release() "
"function, it is broken and must be fixed.\n",
dev_name(dev));
kfree(p);
}

void device_initialize(struct device *dev)
{
kobject_init(&dev->kobj, &device_ktype);
}

void kobject_init(struct kobject *kobj, struct kobj_type *ktype)
{
kobj->ktype = ktype;
}
到这里,我们已经理清了release函数与kobject类型







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值