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:
Jeremy90307 2024-12-06 12:06:46 +08:00
parent 0b455a21a7
commit bde77a155e
3 changed files with 202 additions and 10 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);