Reputation: 137
I have working with GPIOs in my kernel module, while I set or reset GPIOS from an IOCTL I got the following warning in my "dmesg" Log.
[11115.549204] WARNING: CPU: 1 PID: 5199 at drivers/gpio/gpiolib.c:2415 gpiod_get_raw_value+0x7c/0xb8
[11115.558267] Modules linked in: ariodrv(O) [last unloaded: ariodrv]
[11115.564570] CPU: 1 PID: 5199 Comm: ARIO_RMG Tainted: G W O 4.9.166.RMG.-00002-gcbd9807b6c03-dirty #13
[11115.574776] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
[11115.581320] Backtrace:
[11115.583816] [<8010b150>] (dump_backtrace) from [<8010b3fc>] (show_stack+0x18/0x1c)
[11115.591426] r7:00000009 r6:600b0013 r5:80c1ae70 r4:00000000
[11115.597119] [<8010b3e4>] (show_stack) from [<803f51d4>] (dump_stack+0x9c/0xb0)
[11115.604380] [<803f5138>] (dump_stack) from [<80124878>] (__warn+0xec/0x104)
[11115.611367] r7:00000009 r6:80a39e28 r5:00000000 r4:00000000
[11115.617050] [<8012478c>] (__warn) from [<80124948>] (warn_slowpath_null+0x28/0x30)
[11115.624653] r9:8d696000 r8:7ea8cfa0 r7:0000000e r6:8d26e600 r5:8c1f9c54 r4:8c207f10
[11115.632434] [<80124920>] (warn_slowpath_null) from [<8042fbb8>] (gpiod_get_raw_value+0x7c/0xb8)
[11115.641177] [<8042fb3c>] (gpiod_get_raw_value) from [<7f00cd78>] (device_ioctl+0x334/0x9f8 [ariodrv])
[11115.650428] r5:8004d282 r4:7ea8cfa0
[11115.654034] [<7f00ca44>] (device_ioctl [ariodrv]) from [<80219c58>] (do_vfs_ioctl+0xa8/0x914)
[11115.662595] r7:0000000e r6:8d26e600 r5:8ccc5bc0 r4:7ea8cfa0
[11115.668278] [<80219bb0>] (do_vfs_ioctl) from [<8021a500>] (SyS_ioctl+0x3c/0x64)
[11115.675618] r10:00000036 r9:8d696000 r8:7ea8cfa0 r7:8004d282 r6:8d26e600 r5:0000000e
[11115.683477] r4:8d26e601
[11115.686035] [<8021a4c4>] (SyS_ioctl) from [<80107960>] (ret_fast_syscall+0x0/0x48)
[11115.693645] r9:8d696000 r8:80107b44 r7:00000036 r6:00000000 r5:768c611c r4:7ea8cf98
[11115.701504] ---[ end trace 7be84f1e05fd36af ]---
But if I set or get a value to a GPIO pin in another function, like init function of my module I don't get these warnings...
So the question is how exactly I should work with a GPIO pin in an IOCTL call?
This is part of my GPIO set IOCTL code:
IOCTL_FUNC(...) {
....
case IOCTL_RMG_GPIO_SET:
{
....
//I have initialized the GPIO pin as output before, and assume my gpio pin number is 4.
//int gpioNumber = 4;
//int value = 1;
gpio_set_value(gpioNumber, value);
break;
}
....
}
It doesn't matter either I get or set a value. If I use those GPIOs in an IOCTL call I got warning. But in other internal functions like init_module()
or module_release()
functions I can set and get these values without warning.
EDIT 1:
The problem I have is on GPIOs which are on my IOexpander (MCP23xxx series), This IOexpander works on i2c bus. I don't have problem or any warning while using the GPIOs which are on my processor (iMX6DL).
EDIT 2:
@Tsyvarev and @0andriy Thank you guys, From this link I figured out gpiod_get_raw_value_cansleep()
function is not what I need, Cause this function needs a GPIO descriptor to work and my kernel error was for that. But the functions gpio_get_value_cansleep()
and gpio_set_value_cansleep()
functions are the functions are suited for i2c IO expander.
So thank you for helping me, The working code is now:
IOCTL_FUNC(...) {
....
case IOCTL_RMG_GPIO_SET:
{
....
//I have initialized the GPIO pin as output before, and assume my gpio pin number is 4.
//int gpioNumber = 4;
//int value = 1;
gpio_set_value_cansleep(gpioNumber, value);
break;
}
case IOCTL_RMG_GPIO_GET:
{
....
//I have initialized the GPIO pin as output before, and assume my gpio pin number is 4.
//int gpioNumber = 4;
value = gpio_get_value_cansleep(gpioNumber);
break;
}
....
}
Upvotes: 1
Views: 1328
Reputation: 13189
If you read the linux source at the warning, it tells you:
* This function should be called from contexts where we cannot sleep, and will
* complain if the GPIO chip functions potentially sleep.
WARN_ON(desc->gdev->chip->can_sleep);
You should be calling gpio_get_value_cansleep
Upvotes: 2