diff options
Diffstat (limited to 'drivers/gpio/gpiolib.c')
| -rw-r--r-- | drivers/gpio/gpiolib.c | 100 | 
1 files changed, 73 insertions, 27 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index de0213c9d11..5d6c71edc73 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1773,56 +1773,102 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)  	}  } -static int gpiolib_show(struct seq_file *s, void *unused) +static void *gpiolib_seq_start(struct seq_file *s, loff_t *pos)  { -	struct gpio_chip	*chip = NULL; -	unsigned		gpio; -	int			started = 0; +	struct gpio_chip *chip = NULL; +	unsigned int gpio; +	void *ret = NULL; +	loff_t index = 0;  	/* REVISIT this isn't locked against gpio_chip removal ... */  	for (gpio = 0; gpio_is_valid(gpio); gpio++) { -		struct device *dev; - -		if (chip == gpio_desc[gpio].chip) +		if (gpio_desc[gpio].chip == chip)  			continue; +  		chip = gpio_desc[gpio].chip;  		if (!chip)  			continue; -		seq_printf(s, "%sGPIOs %d-%d", -				started ? "\n" : "", -				chip->base, chip->base + chip->ngpio - 1); -		dev = chip->dev; -		if (dev) -			seq_printf(s, ", %s/%s", -				dev->bus ? dev->bus->name : "no-bus", -				dev_name(dev)); -		if (chip->label) -			seq_printf(s, ", %s", chip->label); -		if (chip->can_sleep) -			seq_printf(s, ", can sleep"); -		seq_printf(s, ":\n"); +		if (index++ >= *pos) { +			ret = chip; +			break; +		} +	} + +	s->private = ""; -		started = 1; -		if (chip->dbg_show) -			chip->dbg_show(s, chip); -		else -			gpiolib_dbg_show(s, chip); +	return ret; +} + +static void *gpiolib_seq_next(struct seq_file *s, void *v, loff_t *pos) +{ +	struct gpio_chip *chip = v; +	unsigned int gpio; +	void *ret = NULL; + +	/* skip GPIOs provided by the current chip */ +	for (gpio = chip->base + chip->ngpio; gpio_is_valid(gpio); gpio++) { +		chip = gpio_desc[gpio].chip; +		if (chip) { +			ret = chip; +			break; +		}  	} + +	s->private = "\n"; +	++*pos; + +	return ret; +} + +static void gpiolib_seq_stop(struct seq_file *s, void *v) +{ +} + +static int gpiolib_seq_show(struct seq_file *s, void *v) +{ +	struct gpio_chip *chip = v; +	struct device *dev; + +	seq_printf(s, "%sGPIOs %d-%d", (char *)s->private, +			chip->base, chip->base + chip->ngpio - 1); +	dev = chip->dev; +	if (dev) +		seq_printf(s, ", %s/%s", dev->bus ? dev->bus->name : "no-bus", +			dev_name(dev)); +	if (chip->label) +		seq_printf(s, ", %s", chip->label); +	if (chip->can_sleep) +		seq_printf(s, ", can sleep"); +	seq_printf(s, ":\n"); + +	if (chip->dbg_show) +		chip->dbg_show(s, chip); +	else +		gpiolib_dbg_show(s, chip); +  	return 0;  } +static const struct seq_operations gpiolib_seq_ops = { +	.start = gpiolib_seq_start, +	.next = gpiolib_seq_next, +	.stop = gpiolib_seq_stop, +	.show = gpiolib_seq_show, +}; +  static int gpiolib_open(struct inode *inode, struct file *file)  { -	return single_open(file, gpiolib_show, NULL); +	return seq_open(file, &gpiolib_seq_ops);  }  static const struct file_operations gpiolib_operations = { +	.owner		= THIS_MODULE,  	.open		= gpiolib_open,  	.read		= seq_read,  	.llseek		= seq_lseek, -	.release	= single_release, +	.release	= seq_release,  };  static int __init gpiolib_debugfs_init(void)  |