aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartosz Golaszewski <bartosz.golaszewski@linaro.org>2023-08-21 17:09:04 +0200
committerBartosz Golaszewski <bartosz.golaszewski@linaro.org>2023-08-24 10:12:41 +0200
commit12bd0088e0f4fcba00259e3991eeb7c83d1e7823 (patch)
treeebce86d7b537288090b479f656693459f9e9ddb1
parentf6444fb306d6dcb797c693d7fdd9ff9a81e6dc1a (diff)
downloadlibgpiod-v1.6.x.tar.gz
tests: mockup: unbind mockup devices before unloading the modulev1.6.x
gpio-mockup relies on the GPIO devices being registered in module's __init function and them being unregistered in __exit. This works with the GPIO subsystem as it only takes a reference to the underlying owner module when a GPIO descriptor is requested and not when the GPIO device is instantiated. This behavior may change in the future in the kernel so make the behavior of libgpiomockup more correct and have it unbind all mockup devices over sysfs before unloading the module. Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
-rw-r--r--tests/mockup/gpio-mockup.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/tests/mockup/gpio-mockup.c b/tests/mockup/gpio-mockup.c
index fa27bd74..387e4498 100644
--- a/tests/mockup/gpio-mockup.c
+++ b/tests/mockup/gpio-mockup.c
@@ -5,6 +5,7 @@
* Copyright (C) 2019 Bartosz Golaszewski <bgolaszewski@baylibre.com>
*/
+#include <dirent.h>
#include <errno.h>
#include <libkmod.h>
#include <libudev.h>
@@ -357,6 +358,51 @@ err_out:
return -1;
}
+static int dir_filter(const struct dirent *entry)
+{
+ return !strncmp(entry->d_name, "gpio-mockup.", 12);
+}
+
+static void free_dirs(struct dirent **entries, size_t count)
+{
+ size_t i;
+
+ for (i = 0; i < count; i++)
+ free(entries[i]);
+ free(entries);
+}
+
+static int unbind_devices(void)
+{
+ struct dirent **entries;
+ int i, count, fd;
+ ssize_t ret;
+
+ count = scandir("/sys/bus/platform/drivers/gpio-mockup", &entries,
+ dir_filter, alphasort);
+ if (count < 0)
+ return -1;
+
+ fd = open("/sys/bus/platform/drivers/gpio-mockup/unbind", O_WRONLY);
+ if (fd < 0) {
+ free_dirs(entries, count);
+ return -1;
+ }
+
+ for (i = 0; i < count; i++) {
+ ret = write(fd, entries[i]->d_name, strlen(entries[i]->d_name));
+ if (ret < 0) {
+ close(fd);
+ free_dirs(entries, count);
+ return -1;
+ }
+ }
+
+ close(fd);
+ free_dirs(entries, count);
+ return 0;
+}
+
EXPORT int gpio_mockup_remove(struct gpio_mockup *ctx)
{
unsigned int i;
@@ -367,6 +413,10 @@ EXPORT int gpio_mockup_remove(struct gpio_mockup *ctx)
return -1;
}
+ rv = unbind_devices();
+ if (rv)
+ return -1;
+
rv = kmod_module_remove_module(ctx->module, 0);
if (rv)
return -1;