rk提供的rfkill-bt.c驱动访问外扩GPIO输出如下警告:
[ 4.694993] ------------[ cut here ]------------
[ 4.694994] WARNING: CPU: 7 PID: 582 at drivers/gpio/gpiolib.c:2805 gpiod_get_raw_value+0x58/0xd4
[ 4.695003] Modules linked in:
[ 4.695006] CPU: 7 PID: 582 Comm: systemd-rfkill Not tainted 6.1.75 #41
[ 4.695008] Hardware name: Rockchip RK3588 Board (DT)
[ 4.695010] pstate: 80400009 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ 4.695012] pc : gpiod_get_raw_value+0x58/0xd4
[ 4.695015] lr : rfkill_rk_set_power+0xb0/0x394
[ 4.695018] sp : ffffffc00d673c30
[ 4.695020] x29: ffffffc00d673c30 x28: ffffff8109c77000 x27: 0000000000000000
[ 4.695023] x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000000
[ 4.695026] x23: 0000000060001000 x22: ffffff8103039080 x21: ffffffc0096c3418
[ 4.695029] x20: ffffff8102e2be80 x19: ffffff8102e97118 x18: 0000000000001000
[ 4.695032] x17: 0000000000000000 x16: 0000000000000400 x15: 0000000000000000
[ 4.695035] x14: 0000000000000400 x13: 3131313131313131 x12: 31313120203a7265
[ 4.695038] x11: fffffffffffcf480 x10: ffffffc00a3036b8 x9 : ffffffc009344310
[ 4.695041] x8 : ffffffc00a2536b8 x7 : ffffffc00a3036b8 x6 : 0000000000000000
[ 4.695043] x5 : ffffff82f6de7ae0 x4 : ffffffc00a3e50b8 x3 : 0000000000000010
[ 4.695046] x2 : 0000000000000028 x1 : ffffff8102e964c0 x0 : 0000000000000001
[ 4.695049] Call trace:
[ 4.695051] gpiod_get_raw_value+0x58/0xd4
[ 4.695053] rfkill_rk_set_power+0xb0/0x394
[ 4.695054] rfkill_set_block+0xbc/0x234
[ 4.695058] rfkill_fop_write+0x1fc/0x234
[ 4.695062] vfs_write+0xc4/0x374
[ 4.695066] ksys_write+0xdc/0xf4
[ 4.695069] __arm64_sys_write+0x20/0x2c
[ 4.695072] invoke_syscall+0x4c/0x110
[ 4.695075] el0_svc_common.constprop.0+0x54/0x180
[ 4.695078] do_el0_svc+0x20/0x30
[ 4.695080] el0_svc+0x24/0xa4
[ 4.695084] el0t_64_sync_handler+0xb0/0xb4
[ 4.695087] el0t_64_sync+0x174/0x178
原因是驱动中采用gpio_get_value获取GPIO引脚状态时会调用到gpiod_get_raw_value。从代码中可以看到当GPIO的can_sleep是true是就会有警告,但是这个警告不会影响到系统运行。
int gpiod_get_raw_value(const struct gpio_desc *desc)
{VALIDATE_DESC(desc);/* Should be using gpiod_get_raw_value_cansleep() */WARN_ON(desc->gdev->can_sleep);return gpiod_get_raw_value_commit(desc);
}
修改这个错误,简单粗暴的方式就是注释掉WARN_ON(desc->gdev->can_sleep)
,但不推荐,另一个方式就是将rfkill-bt.c中的gpio_get_value该成gpio_get_value_cansleep。
两个函数的差异: