diff options
Diffstat (limited to 'drivers/gpio/gpiolib.c')
| -rw-r--r-- | drivers/gpio/gpiolib.c | 12 | 
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 5050693dcc3..4b3f388bcc6 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)  static void *gpiolib_seq_start(struct seq_file *s, loff_t *pos)  { +	unsigned long flags;  	struct gpio_chip *chip = NULL;  	loff_t index = *pos; -	/* REVISIT this isn't locked against gpio_chip removal ... */ -  	s->private = ""; +	spin_lock_irqsave(&gpio_lock, flags);  	list_for_each_entry(chip, &gpio_chips, list) -		if (index-- == 0) +		if (index-- == 0) { +			spin_unlock_irqrestore(&gpio_lock, flags);  			return chip; +		} +	spin_unlock_irqrestore(&gpio_lock, flags);  	return NULL;  }  static void *gpiolib_seq_next(struct seq_file *s, void *v, loff_t *pos)  { +	unsigned long flags;  	struct gpio_chip *chip = v;  	void *ret = NULL; +	spin_lock_irqsave(&gpio_lock, flags);  	if (list_is_last(&chip->list, &gpio_chips))  		ret = NULL;  	else  		ret = list_entry(chip->list.next, struct gpio_chip, list); +	spin_unlock_irqrestore(&gpio_lock, flags);  	s->private = "\n";  	++*pos;  |