platform_bus_init过程

    文章的分析基于linux-2.6.22

    今天记录下 platform_bus_init过程中,platform_bus_type总线和platform_bus设备的注册,以及构建的目录结构。

1.
/**
 *	driver_init - initialize driver model.
 *
 *	Call the driver model init functions to initialize their
 *	subsystems. Called early from init/main.c.
 */

void __init driver_init(void)
{
        ......

	platform_bus_init();

        ......
}


2.
int __init platform_bus_init(void)
{
	int error;

	error = device_register(&platform_bus); //2.1分析
	if (error)
		return error;
	error =  bus_register(&platform_bus_type); //2.2分析
	if (error)
		device_unregister(&platform_bus);
	return error;
}

struct device platform_bus = {
	.bus_id		= "platform",
};

struct bus_type platform_bus_type = {
	.name		= "platform",
	.dev_attrs	= platform_dev_attrs,
	.match		= platform_match,
	.uevent		= platform_uevent,
	.suspend	= platform_suspend,
	.suspend_late	= platform_suspend_late,
	.resume_early	= platform_resume_early,
	.resume		= platform_resume,
};


2.1
/**
 *	device_register - register a device with the system.
 *	@dev:	pointer to the device structure
 *
 *	This happens in two clean steps - initialize the device
 *	and add it to the system. The two steps can be called
 *	separately, but this is the easiest and most common.
 *	I.e. you should only call the two helpers separately if
 *	have a clearly defined need to use and refcount the device
 *	before it is added to the hierarchy.
 */

int device_register(struct device *dev)
{
	device_initialize(dev); //2.1.1分析
	return device_add(dev); //2.1.2分析
}


2.1.1
/**
 *	device_initialize - init device structure.
 *	@dev:	device.
 *
 *	This prepares the device for use by other layers,
 *	including adding it to the device hierarchy.
 *	It is the first half of device_register(), if called by
 *	that, though it can also be called separately, so one
 *	may use @dev's fields (e.g. the refcount).
 */

//devices_subsys的目录名为devices
void device_initialize(struct device *dev)
{
        ......	

        kobj_set_kset_s(dev, devices_subsys); //设置dev的kset指向devices_subsys
     
        .......

	INIT_LIST_HEAD(&dev->node);

	.......
}


2.1.2
/**
 *	device_add - add device to device hierarchy.
 *	@dev:	device.
 *
 *	This is part 2 of device_register(), though may be called
 *	separately _iff_ device_initialize() has been called separately.
 *
 *	This adds it to the kobject hierarchy via kobject_add(), adds it
 *	to the global and sibling lists for the device, then
 *	adds it to the other relevant subsystems of the driver model.
 */
int device_add(struct device *dev)
{
        ......

        kobject_set_name(&dev->kobj, "%s", dev->bus_id);
	error = kobject_add(&dev->kobj); //设置dev的parent,将其加人devices_subsys的链表

        ......
}


2.2
/**
 *	bus_register - register a bus with the system.
 *	@bus:	bus.
 *
 *	Once we have that, we registered the bus with the kobject
 *	infrastructure, then register the children subsystems it has:
 *	the devices and drivers that belong to the bus.
 */

//bus_subsys的目录名为bus
int bus_register(struct bus_type * bus)
{
        ......

        retval = kobject_set_name(&bus->subsys.kobj, "%s", bus->name);

        ......

        subsys_set_kset(bus, bus_subsys); //设置bus的kset的指向bus_subsys
	retval = subsystem_register(&bus->subsys); //设置bus->subsys的parent,将其加入
                                                   //bus_subsys的链表

        ......
        
        kobject_set_name(&bus->devices.kobj, "devices");
	bus->devices.kobj.parent = &bus->subsys.kobj;
	retval = kset_register(&bus->devices);
        ......

	kobject_set_name(&bus->drivers.kobj, "drivers");
	bus->drivers.kobj.parent = &bus->subsys.kobj;
	bus->drivers.ktype = &ktype_driver;
	retval = kset_register(&bus->drivers);
	......

	klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put);
	klist_init(&bus->klist_drivers, NULL, NULL);

	bus->drivers_autoprobe = 1;        
}

图1:platform_bus和devices_subsys数据结构连接的简单示意,程序的2.1部分建立的devices/platform文件夹

 

 

图2:platform_bus_type和bus_subsys数据结构连接的简单示意,程序的2.2部分建立的bus/platform文件夹,然后创建了platform/devices和platform/drives

[ 4.858794] uwe5621_bt_tty_init [ 4.862131] mtty_probe unisoc soc, continue [ 4.868449] mtty_probe init device addr: 0x000000007db4bee8 [ 4.868608] rfkill_bluetooth_init [ 4.871951] rfkill_bluetooth_init end [ 4.872048] marlin_sdio_init [ 4.873682] mtty_probe unisoc soc, continue [ 4.873724] sysfs: cannot create duplicate filename '/devices/virt[ 4.873829] CPU: 1 PID: 121 Comm: init Not tainted 4.19.193 #34 [ 4.873842] Hardware name: ROC-RK3566-PC HDMI(Android) (DT) [ 4.873849] Call trace: [ 4.873868] dump_backtrace+0x0/0x178 [ 4.873876] show_stack+0x14/0x20 [ 4.873886] dump_stack+0x94/0xb4 [ 4.873895] sysfs_warn_dup+0x64/0x80 [ 4.873902] sysfs_create_dir_ns+0xdc/0xf8 [ 4.873910] kobject_add_internal+0xa0/0x288 [ 4.873916] kobject_add+0x98/0x100 [ 4.873928] device_add+0xec/0x698 [ 4.873934] device_register+0x1c/0x28 [ 4.873945] tty_register_device_attr+0xe4/0x208 [ 4.873951] tty_register_driver+0x138/0x248 [ 4.873970] mtty_probe+0x144/0x33u0 [sprdbt_tty] [ 4.873978] platform_drv_probe+0x50/0xa8 [ a 4.873984] really_probe+0xl228/0x2a0 [ 4.873991] driver_probe_device+0x58/0x100 [ 4.873996] device_driver_attach+0x6c/0x78 [ 4.874001] __driver_attach+0xb0/0xf0 [ 4.874009] bus_for_each_dev+0x68/0xc8 [ 4.874014] driver_attach+0x20/0x28 [ 4.874019] bus_add_driver+0xf8/0x1f0 [ 4.874025] driver_register+0x60/0x110 [ 4.874031] __platform_driver_register+0x40/0x48 [ 4.874044] uwe5621_bt_tty_init+0x44/0x1000 [sprdbt_tty] [ 4.874052] do_one_initcall+0x48/0x240 [ 4.874061] do_init_module+0x5c/0x1c8 [ 4.874069] load_module+0x18f8/0x1f68 [ 4.874074] __se_sys_finit_module+0xc0/0xd8 [ 4.874079] __arm64_sys_finit_module+0x14/0x20 [ 4.874087] el0_svc_common.constprop.0+0x64/0x178 [ 4.874092] el0_svc_handler+0x28/0x78 [ 4.874097] el0_svc+0x8/0xc [ 4.874179] kobject_add_internal failed for ttyBT0 with -EEXIST/, don't try to register things twith the same name in the same directory. [ 4.874225] list_del corruption, ffffffc079941ea8->next is LIST_POISON1 (dead000000000100) [ 4.874270] ------------[ cut here ]------------
最新发布
06-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值