在开发板Exynos4412上用4个led:LED2~5来模拟4bit数实验:
seg_led_drv.c
问题:
在卸载模块时,虽然没有崩溃,但是内核打印如下警告:
[ 3494.595000] WARNING: CPU: 2 PID: 1277 at drivers/gpio/gpiolib.c:1556 gpiod_free+0xc0/0xe8() //问题出现在内核文件gpiolib.c下gpiod_free+0xc0(第1556行)
[ 3494.595000] Modules linked in: seg_led_drv(O-) [last unloaded: seg_led_drv]
[ 3494.595000] CPU: 2 PID: 1277 Comm: rmmod Tainted: G W O 3.14.0 #8
[ 3494.595000] [] (unwind_backtrace) from [] (show_stack+0x10/0x14)
[ 3494.595000] [] (show_stack) from [] (dump_stack+0x64/0xb4)
[ 3494.595000] [] (dump_stack) from [] (warn_slowpath_common+0x68/0x88)
[ 3494.595000] [] (warn_slowpath_common) from [] (warn_slowpath_null+0x1c/0x24)
[ 3494.595000] [] (warn_slowpath_null) from [] (gpiod_free+0xc0/0xe8)
[ 3494.595000] [] (gpiod_free) from [] (free_gpio+0xf4/0x14c [seg_led_drv]) //驱动程序中seg_remove()下的free_gpio()函数调用了内核中的gpiod_free()函数
[ 3494.595000] [] (free_gpio [seg_led_drv]) from [] (seg_remove+0x2c/0x68 [seg_led_drv])
[ 3494.595000] [] (seg_remove [seg_led_drv]) from [] (platform_drv_remove+0x14/0x18)
[ 3494.685000] [] (platform_drv_remove) from [] (__device_release_driver+0x58/0xb4)
[ 3494.685000] [] (__device_release_driver) from [] (driver_detach+0xac/0xb0)
[ 3494.685000] [] (driver_detach) from [] (bus_remove_driver+0x4c/0x90)
[ 3494.685000] [] (bus_remove_driver) from [] (SyS_delete_module+0x124/0x180)
[ 3494.685000] [] (SyS_delete_module) from [] (ret_fast_syscall+0x0/0x30)
[ 3494.685000] ---[ end trace d371ea0a334f660f ]---
分析过程:
从打印信息可以看出:
1、当卸载驱动模块时,seg_remove中的释放gpio的操作(free_gpio ())出现了问题
2、问题根源在内核文件gpiolib.c的第1556行,查看该文件下包含1556行的函数,
1525 static void gpiod_free(struct gpio_desc *desc)
1526 {
1527 unsigned long flags;
1528 struct gpio_chip *chip;
1529
1530 might_sleep();
1531
1532 if (!desc) {
1533 WARN_ON(extra_checks);
1534 return;
1535 }
1536
1537 gpiod_unexport(desc);
1538
1539 spin_lock_irqsave(&gpio_lock, flags);
1540
1541 chip = desc->chip;
1542 if (chip && tes