aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpiolib.c
diff options
context:
space:
mode:
authorThierry Reding <thierry.reding@avionic-design.de>2012-04-12 07:26:01 -0400
committerLinus Walleij <linus.walleij@linaro.org>2012-08-17 01:35:41 -0400
commitf9c4a31f61501d25f0a45faae6a5cd701ad5694a (patch)
treefc98b2e1357f7374a5384615f12fb2e9e7d25d37 /drivers/gpio/gpiolib.c
parentd9875690d9b89a866022ff49e3fcea892345ad92 (diff)
gpiolib: Use seq_file's iterator interface
When dumping a collection of items via seq_file, it is recommended to use the iterator interface. For the gpiolib debugfs interface this can be done to dump each GPIO chip in turn. Note that for gpiolib this is a little cumbersome because it does not provide a list of registered GPIO chips and the only way to iterate is over each GPIO individually. Once a chip is found, the number of GPIOs it provides can be skipped as a small optimization. This patch was requested by Arnd Bergmann here: http://article.gmane.org/gmane.linux.ports.tegra/3535 Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de> Cc: Linus Walleij <linus.walleij@stericsson.com> Cc: Grant Likely <grant.likely@secretlab.ca> Cc: linux-kernel@vger.kernel.org Reviewed-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r--drivers/gpio/gpiolib.c102
1 files changed, 74 insertions, 28 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index de0213c9d11c..5d6c71edc739 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)
1773 } 1773 }
1774} 1774}
1775 1775
1776static int gpiolib_show(struct seq_file *s, void *unused) 1776static void *gpiolib_seq_start(struct seq_file *s, loff_t *pos)
1777{ 1777{
1778 struct gpio_chip *chip = NULL; 1778 struct gpio_chip *chip = NULL;
1779 unsigned gpio; 1779 unsigned int gpio;
1780 int started = 0; 1780 void *ret = NULL;
1781 loff_t index = 0;
1781 1782
1782 /* REVISIT this isn't locked against gpio_chip removal ... */ 1783 /* REVISIT this isn't locked against gpio_chip removal ... */
1783 1784
1784 for (gpio = 0; gpio_is_valid(gpio); gpio++) { 1785 for (gpio = 0; gpio_is_valid(gpio); gpio++) {
1785 struct device *dev; 1786 if (gpio_desc[gpio].chip == chip)
1786
1787 if (chip == gpio_desc[gpio].chip)
1788 continue; 1787 continue;
1788
1789 chip = gpio_desc[gpio].chip; 1789 chip = gpio_desc[gpio].chip;
1790 if (!chip) 1790 if (!chip)
1791 continue; 1791 continue;
1792 1792
1793 seq_printf(s, "%sGPIOs %d-%d", 1793 if (index++ >= *pos) {
1794 started ? "\n" : "", 1794 ret = chip;
1795 chip->base, chip->base + chip->ngpio - 1); 1795 break;
1796 dev = chip->dev; 1796 }
1797 if (dev)
1798 seq_printf(s, ", %s/%s",
1799 dev->bus ? dev->bus->name : "no-bus",
1800 dev_name(dev));
1801 if (chip->label)
1802 seq_printf(s, ", %s", chip->label);
1803 if (chip->can_sleep)
1804 seq_printf(s, ", can sleep");
1805 seq_printf(s, ":\n");
1806
1807 started = 1;
1808 if (chip->dbg_show)
1809 chip->dbg_show(s, chip);
1810 else
1811 gpiolib_dbg_show(s, chip);
1812 } 1797 }
1798
1799 s->private = "";
1800
1801 return ret;
1802}
1803
1804static void *gpiolib_seq_next(struct seq_file *s, void *v, loff_t *pos)
1805{
1806 struct gpio_chip *chip = v;
1807 unsigned int gpio;
1808 void *ret = NULL;
1809
1810 /* skip GPIOs provided by the current chip */
1811 for (gpio = chip->base + chip->ngpio; gpio_is_valid(gpio); gpio++) {
1812 chip = gpio_desc[gpio].chip;
1813 if (chip) {
1814 ret = chip;
1815 break;
1816 }
1817 }
1818
1819 s->private = "\n";
1820 ++*pos;
1821
1822 return ret;
1823}
1824
1825static void gpiolib_seq_stop(struct seq_file *s, void *v)
1826{
1827}
1828
1829static int gpiolib_seq_show(struct seq_file *s, void *v)
1830{
1831 struct gpio_chip *chip = v;
1832 struct device *dev;
1833
1834 seq_printf(s, "%sGPIOs %d-%d", (char *)s->private,
1835 chip->base, chip->base + chip->ngpio - 1);
1836 dev = chip->dev;
1837 if (dev)
1838 seq_printf(s, ", %s/%s", dev->bus ? dev->bus->name : "no-bus",
1839 dev_name(dev));
1840 if (chip->label)
1841 seq_printf(s, ", %s", chip->label);
1842 if (chip->can_sleep)
1843 seq_printf(s, ", can sleep");
1844 seq_printf(s, ":\n");
1845
1846 if (chip->dbg_show)
1847 chip->dbg_show(s, chip);
1848 else
1849 gpiolib_dbg_show(s, chip);
1850
1813 return 0; 1851 return 0;
1814} 1852}
1815 1853
1854static const struct seq_operations gpiolib_seq_ops = {
1855 .start = gpiolib_seq_start,
1856 .next = gpiolib_seq_next,
1857 .stop = gpiolib_seq_stop,
1858 .show = gpiolib_seq_show,
1859};
1860
1816static int gpiolib_open(struct inode *inode, struct file *file) 1861static int gpiolib_open(struct inode *inode, struct file *file)
1817{ 1862{
1818 return single_open(file, gpiolib_show, NULL); 1863 return seq_open(file, &gpiolib_seq_ops);
1819} 1864}
1820 1865
1821static const struct file_operations gpiolib_operations = { 1866static const struct file_operations gpiolib_operations = {
1867 .owner = THIS_MODULE,
1822 .open = gpiolib_open, 1868 .open = gpiolib_open,
1823 .read = seq_read, 1869 .read = seq_read,
1824 .llseek = seq_lseek, 1870 .llseek = seq_lseek,
1825 .release = single_release, 1871 .release = seq_release,
1826}; 1872};
1827 1873
1828static int __init gpiolib_debugfs_init(void) 1874static int __init gpiolib_debugfs_init(void)