diff options
author | Bartosz Golaszewski <bgolaszewski@baylibre.com> | 2018-10-31 16:55:47 +0300 |
---|---|---|
committer | Bartosz Golaszewski <bgolaszewski@baylibre.com> | 2019-02-19 19:42:28 +0300 |
commit | 9212492f6eeaf944ee0966a85054a59314bb1c39 (patch) | |
tree | 1a5e6c7a405e7efe20acc6db899c28acfadc8b8d /drivers/gpio | |
parent | 8d91ecc84d1b177d9bcce6ce8e82c64347ceac9d (diff) | |
download | linux-9212492f6eeaf944ee0966a85054a59314bb1c39.tar.xz |
gpio: mockup: add locking
While no user reported any race condition problems with gpio-mockup,
let's be on the safe side and use a mutex when performing any changes
on the dummy chip structures.
Suggested-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpio-mockup.c | 50 |
1 files changed, 43 insertions, 7 deletions
diff --git a/drivers/gpio/gpio-mockup.c b/drivers/gpio/gpio-mockup.c index 6a50f9f59c90..b4c1de6acf74 100644 --- a/drivers/gpio/gpio-mockup.c +++ b/drivers/gpio/gpio-mockup.c @@ -54,6 +54,7 @@ struct gpio_mockup_chip { struct gpio_mockup_line_status *lines; struct irq_sim irqsim; struct dentry *dbg_dir; + struct mutex lock; }; struct gpio_mockup_dbgfs_private { @@ -82,29 +83,53 @@ static int gpio_mockup_range_ngpio(unsigned int index) return gpio_mockup_ranges[index * 2 + 1]; } -static int gpio_mockup_get(struct gpio_chip *gc, unsigned int offset) +static int __gpio_mockup_get(struct gpio_chip *gc, unsigned int offset) { struct gpio_mockup_chip *chip = gpiochip_get_data(gc); return chip->lines[offset].value; } -static void gpio_mockup_set(struct gpio_chip *gc, - unsigned int offset, int value) +static int gpio_mockup_get(struct gpio_chip *gc, unsigned int offset) +{ + struct gpio_mockup_chip *chip = gpiochip_get_data(gc); + int val; + + mutex_lock(&chip->lock); + val = __gpio_mockup_get(gc, offset); + mutex_unlock(&chip->lock); + + return val; +} + +static void __gpio_mockup_set(struct gpio_chip *gc, + unsigned int offset, int value) { struct gpio_mockup_chip *chip = gpiochip_get_data(gc); chip->lines[offset].value = !!value; } +static void gpio_mockup_set(struct gpio_chip *gc, + unsigned int offset, int value) +{ + struct gpio_mockup_chip *chip = gpiochip_get_data(gc); + + mutex_lock(&chip->lock); + __gpio_mockup_set(gc, offset, value); + mutex_unlock(&chip->lock); +} + static void gpio_mockup_set_multiple(struct gpio_chip *gc, unsigned long *mask, unsigned long *bits) { + struct gpio_mockup_chip *chip = gpiochip_get_data(gc); unsigned int bit; + mutex_lock(&chip->lock); for_each_set_bit(bit, mask, gc->ngpio) - gpio_mockup_set(gc, bit, test_bit(bit, bits)); - + __gpio_mockup_set(gc, bit, test_bit(bit, bits)); + mutex_unlock(&chip->lock); } static int gpio_mockup_dirout(struct gpio_chip *gc, @@ -112,8 +137,10 @@ static int gpio_mockup_dirout(struct gpio_chip *gc, { struct gpio_mockup_chip *chip = gpiochip_get_data(gc); - gpio_mockup_set(gc, offset, value); + mutex_lock(&chip->lock); chip->lines[offset].dir = GPIO_MOCKUP_DIR_OUT; + __gpio_mockup_set(gc, offset, value); + mutex_unlock(&chip->lock); return 0; } @@ -122,7 +149,9 @@ static int gpio_mockup_dirin(struct gpio_chip *gc, unsigned int offset) { struct gpio_mockup_chip *chip = gpiochip_get_data(gc); + mutex_lock(&chip->lock); chip->lines[offset].dir = GPIO_MOCKUP_DIR_IN; + mutex_unlock(&chip->lock); return 0; } @@ -130,8 +159,13 @@ static int gpio_mockup_dirin(struct gpio_chip *gc, unsigned int offset) static int gpio_mockup_get_direction(struct gpio_chip *gc, unsigned int offset) { struct gpio_mockup_chip *chip = gpiochip_get_data(gc); + int direction; - return !chip->lines[offset].dir; + mutex_lock(&chip->lock); + direction = !chip->lines[offset].dir; + mutex_unlock(&chip->lock); + + return direction; } static int gpio_mockup_to_irq(struct gpio_chip *gc, unsigned int offset) @@ -283,6 +317,8 @@ static int gpio_mockup_probe(struct platform_device *pdev) return -ENOMEM; } + mutex_init(&chip->lock); + gc = &chip->gc; gc->base = base; gc->ngpio = ngpio; |