Skip to content

Commit

Permalink
Fix GPIO example to run on Kernel 6.10+
Browse files Browse the repository at this point in the history
gpio_request_array() and gpio_free_array() were removed in
Kernel v6.10-rc1. Use gpio_request() and gpio_free() instead
to make the example run successfully on v6.10+.
  • Loading branch information
jeremy90307 committed Dec 4, 2024
1 parent c1228db commit f341e72
Show file tree
Hide file tree
Showing 3 changed files with 184 additions and 76 deletions.
89 changes: 63 additions & 26 deletions examples/bh_threaded.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 GPIO_NO_REQUEST_ARRAY
#endif

static int button_irqs[] = { -1, -1 };

Expand Down Expand Up @@ -50,36 +55,49 @@ static int __init bottomhalf_init(void)

pr_info("%s\n", __func__);

/* register LED gpios */
/* register LED gpios */
#ifdef GPIO_NO_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 GPIO_NO_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;
goto Button0Error;
}

ret = gpio_request(buttons[1].gpio, buttons[1].label);

if (ret) {
pr_err("Unable to request GPIOs for BUTTONs: %d\n", ret);
goto fail2;
}
ret = gpio_request(buttons[1].gpio, buttons[1].label);

if (ret) {
pr_err("Unable to request GPIOs for BUTTONs: %d\n", ret);
goto Botton1Error;
}
#else
ret = gpio_request_array(buttons, ARRAY_SIZE(buttons));

if (ret) {
pr_err("Unable to request GPIOs for BUTTONs: %d\n", ret);
goto BottonError;
}
#endif

pr_info("Current button1 value: %d\n", gpio_get_value(buttons[0].gpio));

ret = gpio_to_irq(buttons[0].gpio);

if (ret < 0) {
pr_err("Unable to request IRQ: %d\n", ret);
goto fail3;
goto IRQ0Error;
}

button_irqs[0] = ret;
Expand All @@ -93,14 +111,14 @@ static int __init bottomhalf_init(void)

if (ret) {
pr_err("Unable to request IRQ: %d\n", ret);
goto fail3;
goto IRQ0Error;
}

ret = gpio_to_irq(buttons[1].gpio);

if (ret < 0) {
pr_err("Unable to request IRQ: %d\n", ret);
goto fail3;
goto IRQ0Error;
}

button_irqs[1] = ret;
Expand All @@ -114,23 +132,31 @@ static int __init bottomhalf_init(void)

if (ret) {
pr_err("Unable to request IRQ: %d\n", ret);
goto fail4;
goto IRQ1Error;
}

return 0;

/* cleanup what has been setup so far */
fail4:
IRQ1Error:
free_irq(button_irqs[0], NULL);

fail3:
gpio_free(buttons[1].gpio);
#ifdef GPIO_NO_REQUEST_ARRAY
IRQ0Error:
gpio_free(buttons[1].gpio);

fail2:
gpio_free(buttons[0].gpio);

fail1:
gpio_free(leds[0].gpio);
Botton1Error:
gpio_free(buttons[0].gpio);

Button0Error:
gpio_free(leds[0].gpio);
#else
IRQ0Error:
gpio_free_array(buttons, ARRAY_SIZE(leds));

BottonError:
gpio_free_array(leds, ARRAY_SIZE(leds));
#endif

return ret;
}
Expand All @@ -143,13 +169,24 @@ static void __exit bottomhalf_exit(void)
free_irq(button_irqs[0], NULL);
free_irq(button_irqs[1], NULL);

/* turn all LEDs off */
gpio_set_value(leds[0].gpio, 0);

/* unregister */
gpio_free(leds[0].gpio);
/* turn all LEDs off */
#ifdef GPIO_NO_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 GPIO_NO_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);
Expand Down
76 changes: 55 additions & 21 deletions examples/bottomhalf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 GPIO_NO_REQUEST_ARRAY
#endif

/* Macro DECLARE_TASKLET_OLD exists for compatibility.
* See https://lwn.net/Articles/830964/
Expand Down Expand Up @@ -69,36 +74,49 @@ static int __init bottomhalf_init(void)

pr_info("%s\n", __func__);

/* register LED gpios */
/* register LED gpios */
#ifdef GPIO_NO_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 GPIO_NO_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;
goto Button0Error;
}

ret = gpio_request(buttons[1].gpio, buttons[1].label);

if (ret) {
pr_err("Unable to request GPIOs for BUTTONs: %d\n", ret);
goto fail2;
goto Botton1Error;
}
#else
ret = gpio_request_array(buttons, ARRAY_SIZE(buttons));

if (ret) {
pr_err("Unable to request GPIOs for BUTTONs: %d\n", ret);
goto BottonError;
}
#endif

pr_info("Current button1 value: %d\n", gpio_get_value(buttons[0].gpio));

ret = gpio_to_irq(buttons[0].gpio);

if (ret < 0) {
pr_err("Unable to request IRQ: %d\n", ret);
goto fail3;
goto IRQ0Error;
}

button_irqs[0] = ret;
Expand All @@ -111,14 +129,14 @@ static int __init bottomhalf_init(void)

if (ret) {
pr_err("Unable to request IRQ: %d\n", ret);
goto fail3;
goto IRQ0Error;
}

ret = gpio_to_irq(buttons[1].gpio);

if (ret < 0) {
pr_err("Unable to request IRQ: %d\n", ret);
goto fail3;
goto IRQ0Error;
}

button_irqs[1] = ret;
Expand All @@ -131,42 +149,58 @@ static int __init bottomhalf_init(void)

if (ret) {
pr_err("Unable to request IRQ: %d\n", ret);
goto fail4;
goto IRQ1Error;
}

return 0;

/* cleanup what has been setup so far */
fail4:
IRQ1Error:
free_irq(button_irqs[0], NULL);

fail3:
gpio_free(buttons[0].gpio);
#ifdef GPIO_NO_REQUEST_ARRAY
IRQ0Error:
gpio_free(buttons[1].gpio);

fail2:
Botton1Error:
gpio_free(buttons[0].gpio);

fail1:
Button0Error:
gpio_free(leds[0].gpio);

#else
IRQ0Error:
gpio_free_array(buttons, ARRAY_SIZE(leds));

BottonError:
gpio_free_array(leds, ARRAY_SIZE(leds));
#endif

return ret;
}

static void __exit bottomhalf_exit(void)
{
pr_info("%s\n", __func__);

/* free irqs */
free_irq(button_irqs[0], NULL);
free_irq(button_irqs[1], NULL);

/* turn all LEDs off */
/* free irqs */
#ifdef GPIO_NO_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 */
gpio_free(leds[0].gpio);
gpio_free(buttons[1].gpio);
/* unregister */
#ifdef GPIO_NO_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);
Expand Down
Loading

0 comments on commit f341e72

Please sign in to comment.