aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2013-02-09 04:41:49 -0500
committerGrant Likely <grant.likely@secretlab.ca>2013-02-11 17:21:28 -0500
commit362432aed5e5b497a8cf7b20c268ba71df93c045 (patch)
tree4a87f9533b3310c0bbd2a87477bf52bb0286cf41
parent6c0b4e6c85d085bd92966bc2b8da73e2d7f35929 (diff)
gpiolib: Fix locking on gpio debugfs files
The debugfs files really need to hold the gpiolib spinlock before accessing the list. Otherwise chip addition/removal will cause an oops. Cc: Alexandre Courbot <acourbot@nvidia.com> Cc: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
-rw-r--r--drivers/gpio/gpiolib.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 5050693dcc35..4b3f388bcc6d 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2053,29 +2053,35 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
2053 2053
2054static void *gpiolib_seq_start(struct seq_file *s, loff_t *pos) 2054static void *gpiolib_seq_start(struct seq_file *s, loff_t *pos)
2055{ 2055{
2056 unsigned long flags;
2056 struct gpio_chip *chip = NULL; 2057 struct gpio_chip *chip = NULL;
2057 loff_t index = *pos; 2058 loff_t index = *pos;
2058 2059
2059 /* REVISIT this isn't locked against gpio_chip removal ... */
2060
2061 s->private = ""; 2060 s->private = "";
2062 2061
2062 spin_lock_irqsave(&gpio_lock, flags);
2063 list_for_each_entry(chip, &gpio_chips, list) 2063 list_for_each_entry(chip, &gpio_chips, list)
2064 if (index-- == 0) 2064 if (index-- == 0) {
2065 spin_unlock_irqrestore(&gpio_lock, flags);
2065 return chip; 2066 return chip;
2067 }
2068 spin_unlock_irqrestore(&gpio_lock, flags);
2066 2069
2067 return NULL; 2070 return NULL;
2068} 2071}
2069 2072
2070static void *gpiolib_seq_next(struct seq_file *s, void *v, loff_t *pos) 2073static void *gpiolib_seq_next(struct seq_file *s, void *v, loff_t *pos)
2071{ 2074{
2075 unsigned long flags;
2072 struct gpio_chip *chip = v; 2076 struct gpio_chip *chip = v;
2073 void *ret = NULL; 2077 void *ret = NULL;
2074 2078
2079 spin_lock_irqsave(&gpio_lock, flags);
2075 if (list_is_last(&chip->list, &gpio_chips)) 2080 if (list_is_last(&chip->list, &gpio_chips))
2076 ret = NULL; 2081 ret = NULL;
2077 else 2082 else
2078 ret = list_entry(chip->list.next, struct gpio_chip, list); 2083 ret = list_entry(chip->list.next, struct gpio_chip, list);
2084 spin_unlock_irqrestore(&gpio_lock, flags);
2079 2085
2080 s->private = "\n"; 2086 s->private = "\n";
2081 ++*pos; 2087 ++*pos;