aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorBartosz Golaszewski <bartosz.golaszewski@linaro.org>2024-01-05 13:12:45 +0100
committerBartosz Golaszewski <bartosz.golaszewski@linaro.org>2024-02-12 10:50:24 +0100
commit8ce6fd81a452d554889874e50cd34e92cf4547d6 (patch)
treed9c67f4a4f4f6471450bc7777cb26ad722926547 /drivers/gpio
parente348544f7994d252427ed3ae637c7081cbb90f66 (diff)
downloadlinux-8ce6fd81a452d554889874e50cd34e92cf4547d6.tar.gz
gpio: of: assign and read the hog pointer atomically
The device nodes representing GPIO hogs cannot be deleted without unregistering the GPIO chip so there's no need to serialize their access. However we must ensure that users can get the right address so write and read it atomically. Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpiolib-of.c4
-rw-r--r--drivers/gpio/gpiolib.c2
2 files changed, 3 insertions, 3 deletions
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index 35d717fd393f2..523b047a28035 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -801,7 +801,7 @@ static int of_gpiochip_add_hog(struct gpio_chip *chip, struct device_node *hog)
return ret;
#ifdef CONFIG_OF_DYNAMIC
- desc->hog = hog;
+ WRITE_ONCE(desc->hog, hog);
#endif
}
@@ -849,7 +849,7 @@ static void of_gpiochip_remove_hog(struct gpio_chip *chip,
struct gpio_desc *desc;
for_each_gpio_desc_with_flag(chip, desc, FLAG_IS_HOGGED)
- if (desc->hog == hog)
+ if (READ_ONCE(desc->hog) == hog)
gpiochip_free_own_desc(desc);
}
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index a5598c3299ffe..03d7c3f92f5e3 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2330,7 +2330,7 @@ static bool gpiod_free_commit(struct gpio_desc *desc)
clear_bit(FLAG_EDGE_FALLING, &desc->flags);
clear_bit(FLAG_IS_HOGGED, &desc->flags);
#ifdef CONFIG_OF_DYNAMIC
- desc->hog = NULL;
+ WRITE_ONCE(desc->hog, NULL);
#endif
ret = true;
}