rs5c372驱动加载问题,klist_next返回NULL的问题
时间:2010-07-24
来源:互联网
本帖最后由 joey_chow 于 2010-07-24 17:28 编辑
在使用内核提供的rs5c372的驱动时,驱动了麻烦,不能加载,在rs5c372执行init函数后,并没有执行probe函数,
追踪后发现,在匹配设备时,klist_next查找时返回了NULL,详细的追踪过程如下:
我的追踪过程如下:
//in rtc-rs5c372.c
static __init int rs5c372_init(void)
{
printk("Chow:rs5c372_init\n");
return i2c_add_driver(&rs5c372_driver);
}
//in i2c.h
static inline int i2c_add_driver(struct i2c_driver *driver)
{
return i2c_register_driver(THIS_MODULE, driver);
}
//in i2c-core.c
int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
{
int res;
/* new style driver methods can't mix with legacy ones */
if (is_newstyle_driver(driver)) {
if (driver->attach_adapter || driver->detach_adapter
|| driver->detach_client) {
printk(KERN_WARNING
"i2c-core: driver [%s] is confused\n",
driver->driver.name);
return -EINVAL;
}
}
/* add the driver to the list of i2c drivers in the driver core */
driver->driver.owner = owner;
driver->driver.bus = &i2c_bus_type;
/* for new style drivers, when registration returns the driver core
* will have called probe() for all matching-but-unbound devices.
*/
res = driver_register(&driver->driver); //继续追踪driver_register
if (res)
return res;
pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
printk("chow:i2c-core: driver [%s] registered\n", driver->driver.name);
INIT_LIST_HEAD(&driver->list);
/* Walk the adapters that are already present */
mutex_lock(&core_lists);
printk("chow: bus for each dev\n");
bus_for_each_dev(&i2c_bus_type, NULL, driver, __process_new_driver);
//bus_for_each_dev(&i2c_bus_type, NULL, driver, NULL);
mutex_unlock(&core_lists);
printk("chow:leav for i2c register driver\n");
return 0;
}
//in driver.c
int driver_register(struct device_driver * drv)
{
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);
}
printk("chow : Driver '%s' is register\n", drv->name);
klist_init(&drv->klist_devices, NULL, NULL);
return bus_add_driver(drv);//由此处追踪}
//in bus.c
int bus_add_driver(struct device_driver *drv)
{
struct bus_type * bus = bus_get(drv->bus);
int error = 0;
if (!bus)
return -EINVAL;
pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
error = kobject_set_name(&drv->kobj, "%s", drv->name);
if (error)
goto out_put_bus;
printk("chow: 1\n");
drv->kobj.kset = &bus->drivers;
error = kobject_register(&drv->kobj);
if (error)
goto out_put_bus;
printk("chow: 2\n");
printk("chow: drv->bus->drivers_autoprobe[%s]=%d \n", drv->name, drv->bus->drivers_autoprobe);
if (drv->bus->drivers_autoprobe) {
error = driver_attach(drv);// 探测驱动,由此处追踪
if (error)
goto out_unregister;
printk("chow: 3\n");
}
klist_add_tail(&drv->knode_bus, &bus->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",
__FUNCTION__, 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",
__FUNCTION__, drv->name);
}
error = add_bind_files(drv);
if (error) {
/* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__FUNCTION__, drv->name);
}
printk("chow:error=%d\n", error);
return error;
out_unregister:
printk("chow: out_unregister\n");
kobject_unregister(&drv->kobj);
out_put_bus:
printk("chow: out_put_bus\n");
bus_put(bus);
return error;
}
//in dd.c
int driver_attach(struct device_driver * drv)
{
printk("chow: drv[%s]\n", drv->name);
return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
}
//in 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;
printk("chow:bus_for_each_dev[] bus[%s] \n", bus->name);
if (!bus)
return -EINVAL;
printk("chow next device\n");
klist_iter_init_node(&bus->klist_devices, &i,
(start ? &start->knode_bus : NULL));
while ((dev = next_device(&i)) && !error)//追踪 next_device
error = fn(dev, data);
klist_iter_exit(&i);
printk("chow:bus for dev :%d\n", error);
return error;
}
//in bus.c
static struct device * next_device(struct klist_iter * i)
{
/*
struct klist_node * n = klist_next(i);
return n ? container_of(n, struct device, knode_bus) : NULL;
*/
struct klist_node *n = klist_next(i); //追踪 klist_next
struct device *dev = NULL;
//struct device *dev_prv;
if (n) { // 发现 n == 0,直接return了
printk("chow: n\n");
dev = to_device_private_bus(n);
//dev = dev_prv->device;
}
return dev;
}
//in klist.c
struct klist_node * klist_next(struct klist_iter * i)
{
struct list_head * next;
struct klist_node * lnode = i->i_cur;
struct klist_node * knode = NULL;
void (*put)(struct klist_node *) = i->i_klist->put;
spin_lock(&i->i_klist->k_lock);
printk("chow: inode=%d\n", lnode);
if (lnode) { //发现lnode==0
next = lnode->n_node.next;
if (!klist_dec_and_del(lnode))
put = NULL;
} else
next = i->i_head->next;
printk("chow: net=%d i->i_head=%d\n\n", next, i->i_head);
/*此处的打印信息如下:
chow next device
chow: inode=0
chow: next=-1609140780 i->i_head=-1609140780 这两个值相等,其它正常的驱动,都不相等的,why???
chow: knode=0
*/
if (next != i->i_head) { //问题可能出在此处,从打印信息中发现,这两个值相等,因此knode == null,
knode = to_klist_node(next);
printk("chow: knode1=%d\n", knode);
kref_get(&knode->n_ref);
}
i->i_cur = knode;
spin_unlock(&i->i_klist->k_lock);
if (put && lnode)
put(lnode);
printk("chow: knode=%d\n", knode);
return knode;
}
详细的打印信息如下:
Chow:rs5c372_init
chow : Driver 'rtc-rs5c372' is register
chow: 1
chow: 2
chow: drv->bus->drivers_autoprobe[rtc-rs5c372]=1
chow: drv[rtc-rs5c372]
chow:bus_for_each_dev[] bus[i2c]
chow next device
chow: inode=0
chow: next=-1609140780 i->i_head=-1609140780
chow: knode=0
chow:bus for dev :0
chow: 3
chow:error=0
chow:i2c-core: driver [rtc-rs5c372] registered
chow: bus for each dev
chow:bus_for_each_dev[] bus[i2c]
chow next device
chow: inode=0
chow: net=-1609140780 i->i_head=-1609140780
chow: knode=0
chow:bus for dev :0
chow:leav for i2c register driver
chow : Driver 'lpc22xx-i2c' is register
chow: 1
chow: 2
chow: drv->bus->drivers_autoprobe[lpc22xx-i2c]=1
chow: drv[lpc22xx-i2c]
chow:bus_for_each_dev[] bus[platform]
chow next device
chow: inode=0
chow: net=-1609190084 i->i_head=-1609144760//正确加载的都不相等
chow: knode1=-1609190088
chow: knode=-1609190088
chow: n
chow:__driver_attach
chow: driver_probe_device
chow:platform: try du match lpc22xx-global with Driver lpc22xx-i2c
chow: inode=-1609190088
chow: net=-1609189724 i->i_head=-1609144760
chow: knode1=-1609189728
chow: knode=-1609189728
chow: n
chow:__driver_attach
chow: driver_probe_device
chow:platform: try du match lpc22xx-gpio with Driver lpc22xx-i2c
chow: inode=-1609189728
chow: net=-1609189392 i->i_head=-1609144760
chow: knode1=-1609189396
chow: knode=-1609189396
chow: n
chow:__driver_attach
chow: driver_probe_device
chow:platform: try du match lpc22xx-timer with Driver lpc22xx-i2c
chow: inode=-1609189396
chow: net=-1609189088 i->i_head=-1609144760
chow: knode1=-1609189092
chow: knode=-1609189092
chow: n
chow:__driver_attach
chow: inode=-1609189092
chow: net=-1609188672 i->i_head=-1609144760
chow: knode1=-1609188676
chow: knode=-1609188676
chow: n
chow:__driver_attach
chow: driver_probe_device
chow:platform: try du match nvram with Driver lpc22xx-i2c
chow: inode=-1609188676
chow: net=-1609188368 i->i_head=-1609144760
chow: knode1=-1609188372
chow: knode=-1609188372
chow: n
chow:__driver_attach
chow: driver_probe_device
chow:platform: try du match lpc22xx-i2c.0 with Driver lpc22xx-i2c
chow:platform: Matched Device lpc22xx-i2c.0 with Driver lpc22xx-i2c
chow: really_probe
lpc22xx_i2c_probe base=e005c000 irq=19
Division by zero in kernel.
Function entered at [<a0020500>] from [<a0020d3c>]
Function entered at [<a0020d24>] from [<a00cbaa8>]
Function entered at [<a011e0f4>] from [<a0018f5c>]
r5:a015bba4 r4:a030f800
Function entered at [<a0018e54>] from [<a0103908>]
r7:00000000 r6:a015bc2c r5:a015bba4 r4:a01676d4
Function entered at [<a01038e8>] from [<a010198c>]
Function entered at [<a0101800>] from [<a0101bec>]
Function entered at [<a0101afc>] from [<a0100ab4>]
r6:a01676d4 r5:a01b7ee8 r4:00000000
Function entered at [<a0100a4c>] from [<a0101c24>]
r8:a01b6000 r7:a01676dc r6:a01665b0 r5:00000000 r4:a01676d4
Function entered at [<a0101bf4>] from [<a01010a8>]
r4:a01676d4
Function entered at [<a0100f40>] from [<a0102094>]
Function entered at [<a0102038>] from [<a0103a1c>]
r4:00000000
Function entered at [<a01039b0>] from [<a0019018>]
Function entered at [<a0019004>] from [<a0008ba4>]
Function entered at [<a0008b00>] from [<a0031c9c>]
=== lpc22xx_pca_init
Chow: i2c probe
chow: inode=-1609188372
chow: net=-1609188036 i->i_head=-1609144760
chow: knode1=-1609188040
chow: knode=-1609188040
chow: n
chow:__driver_attach
chow: driver_probe_device
chow:platform: try du match lpc22xx-usb.0 with Driver lpc22xx-i2c
chow: inode=-1609188040
chow: net=-1609187704 i->i_head=-1609144760
chow: knode1=-1609187708
chow: knode=-1609187708
chow: n
chow:__driver_attach
chow: driver_probe_device
chow:platform: try du match lpc22xx-can.0 with Driver lpc22xx-i2c
chow: inode=-1609187708
chow: net=-1609187316 i->i_head=-1609144760
chow: knode1=-1609187320
chow: knode=-1609187320
chow: n
chow:__driver_attach
chow: driver_probe_device
chow:platform: try du match lpc2468-ea-flash with Driver lpc22xx-i2c
chow: inode=-1609187320
chow: net=-1608527788 i->i_head=-1609144760
chow: knode1=-1608527792
chow: knode=-1608527792
chow: n
chow:__driver_attach
chow: inode=-1608527792
chow: net=-1607466412 i->i_head=-1609144760
chow: knode1=-1607466416
chow: knode=-1607466416
chow: n
chow:__driver_attach
chow: inode=-1607466416
chow: net=-1609144760 i->i_head=-1609144760
chow: knode=0
chow:bus for dev :0
chow: 3
chow:error=0
Chow:rtc_class_open rtc0: rtc_class=1
drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
VFS: Mounted root (jffs2 filesystem).
init started: BusyBox v1.00 (2010.06.01-15:23+0000) multi-call binary
init started: BusyBox v1.00 (2010.06.01-15:23+0000) multi-call binary
Starting pid 18, console : '/etc/rc'
Welcome to
____ _ _
/ __| ||_|
_ _| | | | _ ____ _ _ _ _
| | | | | | || | _ \| | | |\ \/ /
| |_| | |__| || | | | | |_| |/ \
| ___\____|_||_|_| |_|\____|\_/\_/
| |
|_|
For further information check:
http://www.uclinux.org/
http://www.olimex.com/dev/
Starting pid 30, console : '/bin/sh'
BusyBox v1.00 (2010.06.01-16:26+0000) Built-in shell (msh)
Enter 'help' for a list of built-in commands.
#
在使用内核提供的rs5c372的驱动时,驱动了麻烦,不能加载,在rs5c372执行init函数后,并没有执行probe函数,
追踪后发现,在匹配设备时,klist_next查找时返回了NULL,详细的追踪过程如下:
我的追踪过程如下:
//in rtc-rs5c372.c
static __init int rs5c372_init(void)
{
printk("Chow:rs5c372_init\n");
return i2c_add_driver(&rs5c372_driver);
}
//in i2c.h
static inline int i2c_add_driver(struct i2c_driver *driver)
{
return i2c_register_driver(THIS_MODULE, driver);
}
//in i2c-core.c
int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
{
int res;
/* new style driver methods can't mix with legacy ones */
if (is_newstyle_driver(driver)) {
if (driver->attach_adapter || driver->detach_adapter
|| driver->detach_client) {
printk(KERN_WARNING
"i2c-core: driver [%s] is confused\n",
driver->driver.name);
return -EINVAL;
}
}
/* add the driver to the list of i2c drivers in the driver core */
driver->driver.owner = owner;
driver->driver.bus = &i2c_bus_type;
/* for new style drivers, when registration returns the driver core
* will have called probe() for all matching-but-unbound devices.
*/
res = driver_register(&driver->driver); //继续追踪driver_register
if (res)
return res;
pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
printk("chow:i2c-core: driver [%s] registered\n", driver->driver.name);
INIT_LIST_HEAD(&driver->list);
/* Walk the adapters that are already present */
mutex_lock(&core_lists);
printk("chow: bus for each dev\n");
bus_for_each_dev(&i2c_bus_type, NULL, driver, __process_new_driver);
//bus_for_each_dev(&i2c_bus_type, NULL, driver, NULL);
mutex_unlock(&core_lists);
printk("chow:leav for i2c register driver\n");
return 0;
}
//in driver.c
int driver_register(struct device_driver * drv)
{
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);
}
printk("chow : Driver '%s' is register\n", drv->name);
klist_init(&drv->klist_devices, NULL, NULL);
return bus_add_driver(drv);//由此处追踪}
//in bus.c
int bus_add_driver(struct device_driver *drv)
{
struct bus_type * bus = bus_get(drv->bus);
int error = 0;
if (!bus)
return -EINVAL;
pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
error = kobject_set_name(&drv->kobj, "%s", drv->name);
if (error)
goto out_put_bus;
printk("chow: 1\n");
drv->kobj.kset = &bus->drivers;
error = kobject_register(&drv->kobj);
if (error)
goto out_put_bus;
printk("chow: 2\n");
printk("chow: drv->bus->drivers_autoprobe[%s]=%d \n", drv->name, drv->bus->drivers_autoprobe);
if (drv->bus->drivers_autoprobe) {
error = driver_attach(drv);// 探测驱动,由此处追踪
if (error)
goto out_unregister;
printk("chow: 3\n");
}
klist_add_tail(&drv->knode_bus, &bus->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",
__FUNCTION__, 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",
__FUNCTION__, drv->name);
}
error = add_bind_files(drv);
if (error) {
/* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__FUNCTION__, drv->name);
}
printk("chow:error=%d\n", error);
return error;
out_unregister:
printk("chow: out_unregister\n");
kobject_unregister(&drv->kobj);
out_put_bus:
printk("chow: out_put_bus\n");
bus_put(bus);
return error;
}
//in dd.c
int driver_attach(struct device_driver * drv)
{
printk("chow: drv[%s]\n", drv->name);
return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
}
//in 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;
printk("chow:bus_for_each_dev[] bus[%s] \n", bus->name);
if (!bus)
return -EINVAL;
printk("chow next device\n");
klist_iter_init_node(&bus->klist_devices, &i,
(start ? &start->knode_bus : NULL));
while ((dev = next_device(&i)) && !error)//追踪 next_device
error = fn(dev, data);
klist_iter_exit(&i);
printk("chow:bus for dev :%d\n", error);
return error;
}
//in bus.c
static struct device * next_device(struct klist_iter * i)
{
/*
struct klist_node * n = klist_next(i);
return n ? container_of(n, struct device, knode_bus) : NULL;
*/
struct klist_node *n = klist_next(i); //追踪 klist_next
struct device *dev = NULL;
//struct device *dev_prv;
if (n) { // 发现 n == 0,直接return了
printk("chow: n\n");
dev = to_device_private_bus(n);
//dev = dev_prv->device;
}
return dev;
}
//in klist.c
struct klist_node * klist_next(struct klist_iter * i)
{
struct list_head * next;
struct klist_node * lnode = i->i_cur;
struct klist_node * knode = NULL;
void (*put)(struct klist_node *) = i->i_klist->put;
spin_lock(&i->i_klist->k_lock);
printk("chow: inode=%d\n", lnode);
if (lnode) { //发现lnode==0
next = lnode->n_node.next;
if (!klist_dec_and_del(lnode))
put = NULL;
} else
next = i->i_head->next;
printk("chow: net=%d i->i_head=%d\n\n", next, i->i_head);
/*此处的打印信息如下:
chow next device
chow: inode=0
chow: next=-1609140780 i->i_head=-1609140780 这两个值相等,其它正常的驱动,都不相等的,why???
chow: knode=0
*/
if (next != i->i_head) { //问题可能出在此处,从打印信息中发现,这两个值相等,因此knode == null,
knode = to_klist_node(next);
printk("chow: knode1=%d\n", knode);
kref_get(&knode->n_ref);
}
i->i_cur = knode;
spin_unlock(&i->i_klist->k_lock);
if (put && lnode)
put(lnode);
printk("chow: knode=%d\n", knode);
return knode;
}
详细的打印信息如下:
Chow:rs5c372_init
chow : Driver 'rtc-rs5c372' is register
chow: 1
chow: 2
chow: drv->bus->drivers_autoprobe[rtc-rs5c372]=1
chow: drv[rtc-rs5c372]
chow:bus_for_each_dev[] bus[i2c]
chow next device
chow: inode=0
chow: next=-1609140780 i->i_head=-1609140780
chow: knode=0
chow:bus for dev :0
chow: 3
chow:error=0
chow:i2c-core: driver [rtc-rs5c372] registered
chow: bus for each dev
chow:bus_for_each_dev[] bus[i2c]
chow next device
chow: inode=0
chow: net=-1609140780 i->i_head=-1609140780
chow: knode=0
chow:bus for dev :0
chow:leav for i2c register driver
chow : Driver 'lpc22xx-i2c' is register
chow: 1
chow: 2
chow: drv->bus->drivers_autoprobe[lpc22xx-i2c]=1
chow: drv[lpc22xx-i2c]
chow:bus_for_each_dev[] bus[platform]
chow next device
chow: inode=0
chow: net=-1609190084 i->i_head=-1609144760//正确加载的都不相等
chow: knode1=-1609190088
chow: knode=-1609190088
chow: n
chow:__driver_attach
chow: driver_probe_device
chow:platform: try du match lpc22xx-global with Driver lpc22xx-i2c
chow: inode=-1609190088
chow: net=-1609189724 i->i_head=-1609144760
chow: knode1=-1609189728
chow: knode=-1609189728
chow: n
chow:__driver_attach
chow: driver_probe_device
chow:platform: try du match lpc22xx-gpio with Driver lpc22xx-i2c
chow: inode=-1609189728
chow: net=-1609189392 i->i_head=-1609144760
chow: knode1=-1609189396
chow: knode=-1609189396
chow: n
chow:__driver_attach
chow: driver_probe_device
chow:platform: try du match lpc22xx-timer with Driver lpc22xx-i2c
chow: inode=-1609189396
chow: net=-1609189088 i->i_head=-1609144760
chow: knode1=-1609189092
chow: knode=-1609189092
chow: n
chow:__driver_attach
chow: inode=-1609189092
chow: net=-1609188672 i->i_head=-1609144760
chow: knode1=-1609188676
chow: knode=-1609188676
chow: n
chow:__driver_attach
chow: driver_probe_device
chow:platform: try du match nvram with Driver lpc22xx-i2c
chow: inode=-1609188676
chow: net=-1609188368 i->i_head=-1609144760
chow: knode1=-1609188372
chow: knode=-1609188372
chow: n
chow:__driver_attach
chow: driver_probe_device
chow:platform: try du match lpc22xx-i2c.0 with Driver lpc22xx-i2c
chow:platform: Matched Device lpc22xx-i2c.0 with Driver lpc22xx-i2c
chow: really_probe
lpc22xx_i2c_probe base=e005c000 irq=19
Division by zero in kernel.
Function entered at [<a0020500>] from [<a0020d3c>]
Function entered at [<a0020d24>] from [<a00cbaa8>]
Function entered at [<a011e0f4>] from [<a0018f5c>]
r5:a015bba4 r4:a030f800
Function entered at [<a0018e54>] from [<a0103908>]
r7:00000000 r6:a015bc2c r5:a015bba4 r4:a01676d4
Function entered at [<a01038e8>] from [<a010198c>]
Function entered at [<a0101800>] from [<a0101bec>]
Function entered at [<a0101afc>] from [<a0100ab4>]
r6:a01676d4 r5:a01b7ee8 r4:00000000
Function entered at [<a0100a4c>] from [<a0101c24>]
r8:a01b6000 r7:a01676dc r6:a01665b0 r5:00000000 r4:a01676d4
Function entered at [<a0101bf4>] from [<a01010a8>]
r4:a01676d4
Function entered at [<a0100f40>] from [<a0102094>]
Function entered at [<a0102038>] from [<a0103a1c>]
r4:00000000
Function entered at [<a01039b0>] from [<a0019018>]
Function entered at [<a0019004>] from [<a0008ba4>]
Function entered at [<a0008b00>] from [<a0031c9c>]
=== lpc22xx_pca_init
Chow: i2c probe
chow: inode=-1609188372
chow: net=-1609188036 i->i_head=-1609144760
chow: knode1=-1609188040
chow: knode=-1609188040
chow: n
chow:__driver_attach
chow: driver_probe_device
chow:platform: try du match lpc22xx-usb.0 with Driver lpc22xx-i2c
chow: inode=-1609188040
chow: net=-1609187704 i->i_head=-1609144760
chow: knode1=-1609187708
chow: knode=-1609187708
chow: n
chow:__driver_attach
chow: driver_probe_device
chow:platform: try du match lpc22xx-can.0 with Driver lpc22xx-i2c
chow: inode=-1609187708
chow: net=-1609187316 i->i_head=-1609144760
chow: knode1=-1609187320
chow: knode=-1609187320
chow: n
chow:__driver_attach
chow: driver_probe_device
chow:platform: try du match lpc2468-ea-flash with Driver lpc22xx-i2c
chow: inode=-1609187320
chow: net=-1608527788 i->i_head=-1609144760
chow: knode1=-1608527792
chow: knode=-1608527792
chow: n
chow:__driver_attach
chow: inode=-1608527792
chow: net=-1607466412 i->i_head=-1609144760
chow: knode1=-1607466416
chow: knode=-1607466416
chow: n
chow:__driver_attach
chow: inode=-1607466416
chow: net=-1609144760 i->i_head=-1609144760
chow: knode=0
chow:bus for dev :0
chow: 3
chow:error=0
Chow:rtc_class_open rtc0: rtc_class=1
drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
VFS: Mounted root (jffs2 filesystem).
init started: BusyBox v1.00 (2010.06.01-15:23+0000) multi-call binary
init started: BusyBox v1.00 (2010.06.01-15:23+0000) multi-call binary
Starting pid 18, console : '/etc/rc'
Welcome to
____ _ _
/ __| ||_|
_ _| | | | _ ____ _ _ _ _
| | | | | | || | _ \| | | |\ \/ /
| |_| | |__| || | | | | |_| |/ \
| ___\____|_||_|_| |_|\____|\_/\_/
| |
|_|
For further information check:
http://www.uclinux.org/
http://www.olimex.com/dev/
Starting pid 30, console : '/bin/sh'
BusyBox v1.00 (2010.06.01-16:26+0000) Built-in shell (msh)
Enter 'help' for a list of built-in commands.
#
作者: joey_chow 发布时间: 2010-07-24
回复 joey_chow
大概看了一下这个RTC驱动,,,它是I2C接口的。
你说的没有执行probe() ,可能是因为没有注册i2c adapter到内核....在注册adapter时就会注册一个device..
LZ可以看看i2c bus的匹配规则:
static struct bus_type i2c_bus_type = {
.name = "i2c",
.dev_attrs = i2c_dev_attrs,
.match = i2c_device_match,
.uevent = i2c_device_uevent,
.probe = i2c_device_probe,
.remove = i2c_device_remove,
.shutdown = i2c_device_shutdown,
.suspend = i2c_device_suspend,
.resume = i2c_device_resume,
};
跟踪一下上面红色的回调函数就可以清楚它的匹配规则了....
大概看了一下这个RTC驱动,,,它是I2C接口的。
你说的没有执行probe() ,可能是因为没有注册i2c adapter到内核....在注册adapter时就会注册一个device..
LZ可以看看i2c bus的匹配规则:
static struct bus_type i2c_bus_type = {
.name = "i2c",
.dev_attrs = i2c_dev_attrs,
.match = i2c_device_match,
.uevent = i2c_device_uevent,
.probe = i2c_device_probe,
.remove = i2c_device_remove,
.shutdown = i2c_device_shutdown,
.suspend = i2c_device_suspend,
.resume = i2c_device_resume,
};
跟踪一下上面红色的回调函数就可以清楚它的匹配规则了....
作者: wmmy2008 发布时间: 2010-07-24
这种驱动问题,LZ可以发到驱动版
作者: wmmy2008 发布时间: 2010-07-24
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28