mirror of
https://github.com/sysprog21/lkmpg.git
synced 2025-02-21 18:28:04 +08:00
Allow GPIO example built with Linux v6.10+
Since the commit dbcedec ("gpiolib: legacy: Remove unused gpio_request_array() and gpio_free_array()"), these functions had no users in kernel and were subsequently removed to simplify the library. These functions have been removed from GPIO examples for Linux v6.10+ to ensure compatibility across all kernel versions. Testing detail: - Tested on Raspberry Pi 5B with Raspberry Pi OS (Debian 12, Linux version 6.12.1-v8-16k+) - Verified the GPIO examples compile and load successfully - Verified GPIO17 interrupt turns on the LED (GPIO4) - Verified GPIO18 interrupt turns off the LED (GPIO4) Close #285
This commit is contained in:
parent
0b455a21a7
commit
bde77a155e
@ -13,6 +13,11 @@
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 10, 0)
|
||||
#define NO_GPIO_REQUEST_ARRAY
|
||||
#endif
|
||||
|
||||
static int button_irqs[] = { -1, -1 };
|
||||
|
||||
@ -50,21 +55,41 @@ static int __init bottomhalf_init(void)
|
||||
|
||||
pr_info("%s\n", __func__);
|
||||
|
||||
/* register LED gpios */
|
||||
/* register LED gpios */
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
ret = gpio_request(leds[0].gpio, leds[0].label);
|
||||
#else
|
||||
ret = gpio_request_array(leds, ARRAY_SIZE(leds));
|
||||
#endif
|
||||
|
||||
if (ret) {
|
||||
pr_err("Unable to request GPIOs for LEDs: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* register BUTTON gpios */
|
||||
/* register BUTTON gpios */
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
ret = gpio_request(buttons[0].gpio, buttons[0].label);
|
||||
|
||||
if (ret) {
|
||||
pr_err("Unable to request GPIOs for BUTTONs: %d\n", ret);
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
ret = gpio_request(buttons[1].gpio, buttons[1].label);
|
||||
|
||||
if (ret) {
|
||||
pr_err("Unable to request GPIOs for BUTTONs: %d\n", ret);
|
||||
goto fail2;
|
||||
}
|
||||
#else
|
||||
ret = gpio_request_array(buttons, ARRAY_SIZE(buttons));
|
||||
|
||||
if (ret) {
|
||||
pr_err("Unable to request GPIOs for BUTTONs: %d\n", ret);
|
||||
goto fail1;
|
||||
}
|
||||
#endif
|
||||
|
||||
pr_info("Current button1 value: %d\n", gpio_get_value(buttons[0].gpio));
|
||||
|
||||
@ -72,7 +97,11 @@ static int __init bottomhalf_init(void)
|
||||
|
||||
if (ret < 0) {
|
||||
pr_err("Unable to request IRQ: %d\n", ret);
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
goto fail3;
|
||||
#else
|
||||
goto fail2;
|
||||
#endif
|
||||
}
|
||||
|
||||
button_irqs[0] = ret;
|
||||
@ -86,14 +115,22 @@ static int __init bottomhalf_init(void)
|
||||
|
||||
if (ret) {
|
||||
pr_err("Unable to request IRQ: %d\n", ret);
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
goto fail3;
|
||||
#else
|
||||
goto fail2;
|
||||
#endif
|
||||
}
|
||||
|
||||
ret = gpio_to_irq(buttons[1].gpio);
|
||||
|
||||
if (ret < 0) {
|
||||
pr_err("Unable to request IRQ: %d\n", ret);
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
goto fail3;
|
||||
#else
|
||||
goto fail2;
|
||||
#endif
|
||||
}
|
||||
|
||||
button_irqs[1] = ret;
|
||||
@ -107,12 +144,29 @@ static int __init bottomhalf_init(void)
|
||||
|
||||
if (ret) {
|
||||
pr_err("Unable to request IRQ: %d\n", ret);
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
goto fail4;
|
||||
#else
|
||||
goto fail3;
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
/* cleanup what has been setup so far */
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
fail4:
|
||||
free_irq(button_irqs[0], NULL);
|
||||
|
||||
fail3:
|
||||
gpio_free(buttons[1].gpio);
|
||||
|
||||
fail2:
|
||||
gpio_free(buttons[0].gpio);
|
||||
|
||||
fail1:
|
||||
gpio_free(leds[0].gpio);
|
||||
#else
|
||||
fail3:
|
||||
free_irq(button_irqs[0], NULL);
|
||||
|
||||
@ -121,27 +175,37 @@ fail2:
|
||||
|
||||
fail1:
|
||||
gpio_free_array(leds, ARRAY_SIZE(leds));
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit bottomhalf_exit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
pr_info("%s\n", __func__);
|
||||
|
||||
/* free irqs */
|
||||
free_irq(button_irqs[0], NULL);
|
||||
free_irq(button_irqs[1], NULL);
|
||||
|
||||
/* turn all LEDs off */
|
||||
/* turn all LEDs off */
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
gpio_set_value(leds[0].gpio, 0);
|
||||
#else
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(leds); i++)
|
||||
gpio_set_value(leds[i].gpio, 0);
|
||||
#endif
|
||||
|
||||
/* unregister */
|
||||
/* unregister */
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
gpio_free(leds[0].gpio);
|
||||
gpio_free(buttons[0].gpio);
|
||||
gpio_free(buttons[1].gpio);
|
||||
#else
|
||||
gpio_free_array(leds, ARRAY_SIZE(leds));
|
||||
gpio_free_array(buttons, ARRAY_SIZE(buttons));
|
||||
#endif
|
||||
}
|
||||
|
||||
module_init(bottomhalf_init);
|
||||
|
@ -14,6 +14,11 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 10, 0)
|
||||
#define NO_GPIO_REQUEST_ARRAY
|
||||
#endif
|
||||
|
||||
/* Macro DECLARE_TASKLET_OLD exists for compatibility.
|
||||
* See https://lwn.net/Articles/830964/
|
||||
@ -70,7 +75,11 @@ static int __init bottomhalf_init(void)
|
||||
pr_info("%s\n", __func__);
|
||||
|
||||
/* register LED gpios */
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
ret = gpio_request(leds[0].gpio, leds[0].label);
|
||||
#else
|
||||
ret = gpio_request_array(leds, ARRAY_SIZE(leds));
|
||||
#endif
|
||||
|
||||
if (ret) {
|
||||
pr_err("Unable to request GPIOs for LEDs: %d\n", ret);
|
||||
@ -78,12 +87,28 @@ static int __init bottomhalf_init(void)
|
||||
}
|
||||
|
||||
/* register BUTTON gpios */
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
ret = gpio_request(buttons[0].gpio, buttons[0].label);
|
||||
|
||||
if (ret) {
|
||||
pr_err("Unable to request GPIOs for BUTTONs: %d\n", ret);
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
ret = gpio_request(buttons[1].gpio, buttons[1].label);
|
||||
|
||||
if (ret) {
|
||||
pr_err("Unable to request GPIOs for BUTTONs: %d\n", ret);
|
||||
goto fail2;
|
||||
}
|
||||
#else
|
||||
ret = gpio_request_array(buttons, ARRAY_SIZE(buttons));
|
||||
|
||||
if (ret) {
|
||||
pr_err("Unable to request GPIOs for BUTTONs: %d\n", ret);
|
||||
goto fail1;
|
||||
}
|
||||
#endif
|
||||
|
||||
pr_info("Current button1 value: %d\n", gpio_get_value(buttons[0].gpio));
|
||||
|
||||
@ -91,7 +116,11 @@ static int __init bottomhalf_init(void)
|
||||
|
||||
if (ret < 0) {
|
||||
pr_err("Unable to request IRQ: %d\n", ret);
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
goto fail3;
|
||||
#else
|
||||
goto fail2;
|
||||
#endif
|
||||
}
|
||||
|
||||
button_irqs[0] = ret;
|
||||
@ -104,14 +133,22 @@ static int __init bottomhalf_init(void)
|
||||
|
||||
if (ret) {
|
||||
pr_err("Unable to request IRQ: %d\n", ret);
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
goto fail3;
|
||||
#else
|
||||
goto fail2;
|
||||
#endif
|
||||
}
|
||||
|
||||
ret = gpio_to_irq(buttons[1].gpio);
|
||||
|
||||
if (ret < 0) {
|
||||
pr_err("Unable to request IRQ: %d\n", ret);
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
goto fail3;
|
||||
#else
|
||||
goto fail2;
|
||||
#endif
|
||||
}
|
||||
|
||||
button_irqs[1] = ret;
|
||||
@ -124,12 +161,29 @@ static int __init bottomhalf_init(void)
|
||||
|
||||
if (ret) {
|
||||
pr_err("Unable to request IRQ: %d\n", ret);
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
goto fail4;
|
||||
#else
|
||||
goto fail3;
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
/* cleanup what has been setup so far */
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
fail4:
|
||||
free_irq(button_irqs[0], NULL);
|
||||
|
||||
fail3:
|
||||
gpio_free(buttons[1].gpio);
|
||||
|
||||
fail2:
|
||||
gpio_free(buttons[0].gpio);
|
||||
|
||||
fail1:
|
||||
gpio_free(leds[0].gpio);
|
||||
#else
|
||||
fail3:
|
||||
free_irq(button_irqs[0], NULL);
|
||||
|
||||
@ -138,14 +192,13 @@ fail2:
|
||||
|
||||
fail1:
|
||||
gpio_free_array(leds, ARRAY_SIZE(leds));
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit bottomhalf_exit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
pr_info("%s\n", __func__);
|
||||
|
||||
/* free irqs */
|
||||
@ -153,12 +206,23 @@ static void __exit bottomhalf_exit(void)
|
||||
free_irq(button_irqs[1], NULL);
|
||||
|
||||
/* turn all LEDs off */
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
gpio_set_value(leds[0].gpio, 0);
|
||||
#else
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(leds); i++)
|
||||
gpio_set_value(leds[i].gpio, 0);
|
||||
#endif
|
||||
|
||||
/* unregister */
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
gpio_free(leds[0].gpio);
|
||||
gpio_free(buttons[0].gpio);
|
||||
gpio_free(buttons[1].gpio);
|
||||
#else
|
||||
gpio_free_array(leds, ARRAY_SIZE(leds));
|
||||
gpio_free_array(buttons, ARRAY_SIZE(buttons));
|
||||
#endif
|
||||
}
|
||||
|
||||
module_init(bottomhalf_init);
|
||||
|
@ -13,6 +13,11 @@
|
||||
#include <linux/kernel.h> /* for ARRAY_SIZE() */
|
||||
#include <linux/module.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 10, 0)
|
||||
#define NO_GPIO_REQUEST_ARRAY
|
||||
#endif
|
||||
|
||||
static int button_irqs[] = { -1, -1 };
|
||||
|
||||
@ -47,7 +52,11 @@ static int __init intrpt_init(void)
|
||||
pr_info("%s\n", __func__);
|
||||
|
||||
/* register LED gpios */
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
ret = gpio_request(leds[0].gpio, leds[0].label);
|
||||
#else
|
||||
ret = gpio_request_array(leds, ARRAY_SIZE(leds));
|
||||
#endif
|
||||
|
||||
if (ret) {
|
||||
pr_err("Unable to request GPIOs for LEDs: %d\n", ret);
|
||||
@ -55,12 +64,28 @@ static int __init intrpt_init(void)
|
||||
}
|
||||
|
||||
/* register BUTTON gpios */
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
ret = gpio_request(buttons[0].gpio, buttons[0].label);
|
||||
|
||||
if (ret) {
|
||||
pr_err("Unable to request GPIOs for BUTTONs: %d\n", ret);
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
ret = gpio_request(buttons[1].gpio, buttons[1].label);
|
||||
|
||||
if (ret) {
|
||||
pr_err("Unable to request GPIOs for BUTTONs: %d\n", ret);
|
||||
goto fail2;
|
||||
}
|
||||
#else
|
||||
ret = gpio_request_array(buttons, ARRAY_SIZE(buttons));
|
||||
|
||||
if (ret) {
|
||||
pr_err("Unable to request GPIOs for BUTTONs: %d\n", ret);
|
||||
goto fail1;
|
||||
}
|
||||
#endif
|
||||
|
||||
pr_info("Current button1 value: %d\n", gpio_get_value(buttons[0].gpio));
|
||||
|
||||
@ -68,7 +93,11 @@ static int __init intrpt_init(void)
|
||||
|
||||
if (ret < 0) {
|
||||
pr_err("Unable to request IRQ: %d\n", ret);
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
goto fail3;
|
||||
#else
|
||||
goto fail2;
|
||||
#endif
|
||||
}
|
||||
|
||||
button_irqs[0] = ret;
|
||||
@ -81,14 +110,22 @@ static int __init intrpt_init(void)
|
||||
|
||||
if (ret) {
|
||||
pr_err("Unable to request IRQ: %d\n", ret);
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
goto fail3;
|
||||
#else
|
||||
goto fail2;
|
||||
#endif
|
||||
}
|
||||
|
||||
ret = gpio_to_irq(buttons[1].gpio);
|
||||
|
||||
if (ret < 0) {
|
||||
pr_err("Unable to request IRQ: %d\n", ret);
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
goto fail3;
|
||||
#else
|
||||
goto fail2;
|
||||
#endif
|
||||
}
|
||||
|
||||
button_irqs[1] = ret;
|
||||
@ -101,12 +138,29 @@ static int __init intrpt_init(void)
|
||||
|
||||
if (ret) {
|
||||
pr_err("Unable to request IRQ: %d\n", ret);
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
goto fail4;
|
||||
#else
|
||||
goto fail3;
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
/* cleanup what has been setup so far */
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
fail4:
|
||||
free_irq(button_irqs[0], NULL);
|
||||
|
||||
fail3:
|
||||
gpio_free(buttons[1].gpio);
|
||||
|
||||
fail2:
|
||||
gpio_free(buttons[0].gpio);
|
||||
|
||||
fail1:
|
||||
gpio_free(leds[0].gpio);
|
||||
#else
|
||||
fail3:
|
||||
free_irq(button_irqs[0], NULL);
|
||||
|
||||
@ -115,14 +169,13 @@ fail2:
|
||||
|
||||
fail1:
|
||||
gpio_free_array(leds, ARRAY_SIZE(leds));
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit intrpt_exit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
pr_info("%s\n", __func__);
|
||||
|
||||
/* free irqs */
|
||||
@ -130,12 +183,23 @@ static void __exit intrpt_exit(void)
|
||||
free_irq(button_irqs[1], NULL);
|
||||
|
||||
/* turn all LEDs off */
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
gpio_set_value(leds[0].gpio, 0);
|
||||
#else
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(leds); i++)
|
||||
gpio_set_value(leds[i].gpio, 0);
|
||||
#endif
|
||||
|
||||
/* unregister */
|
||||
#ifdef NO_GPIO_REQUEST_ARRAY
|
||||
gpio_free(leds[0].gpio);
|
||||
gpio_free(buttons[0].gpio);
|
||||
gpio_free(buttons[1].gpio);
|
||||
#else
|
||||
gpio_free_array(leds, ARRAY_SIZE(leds));
|
||||
gpio_free_array(buttons, ARRAY_SIZE(buttons));
|
||||
#endif
|
||||
}
|
||||
|
||||
module_init(intrpt_init);
|
||||
|
Loading…
x
Reference in New Issue
Block a user