aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpiolib.c
diff options
context:
space:
mode:
authorRojhalat Ibrahim <imr@rtschenk.de>2015-02-11 11:27:58 -0500
committerLinus Walleij <linus.walleij@linaro.org>2015-03-05 03:52:28 -0500
commit668585273246f67b0cdafa30dd2da2047a2e1290 (patch)
treec6e3186d6aab7d08e0f50b5030be4bef4a8b17df /drivers/gpio/gpiolib.c
parent7f2e553a7173b485db41a52060f91fb8e5ab1c69 (diff)
gpiolib: add gpiod_get_array and gpiod_put_array functions
Introduce new functions for conveniently obtaining and disposing of an entire array of GPIOs with one function call. ACPI parts tested by Mika Westerberg, DT parts tested by Rojhalat Ibrahim. Change log: v5: move the ACPI functions to gpiolib-acpi.c v4: - use shorter names for members of struct gpio_descs - rename lut_gpio_count to platform_gpio_count for clarity - add check for successful memory allocation - use ERR_CAST() v3: - rebase on current linux-gpio devel branch - fix ACPI GPIO counting - allow for zero-sized arrays - make the flags argument mandatory for the new functions - clarify documentation v2: change interface Suggested-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Rojhalat Ibrahim <imr@rtschenk.de> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com> Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com> Tested-by: Rojhalat Ibrahim <imr@rtschenk.de> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r--drivers/gpio/gpiolib.c145
1 files changed, 145 insertions, 0 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 2f8296c021e5..3d5b85a7dcdf 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1806,6 +1806,70 @@ static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id,
1806 return desc; 1806 return desc;
1807} 1807}
1808 1808
1809static int dt_gpio_count(struct device *dev, const char *con_id)
1810{
1811 int ret;
1812 char propname[32];
1813 unsigned int i;
1814
1815 for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) {
1816 if (con_id)
1817 snprintf(propname, sizeof(propname), "%s-%s",
1818 con_id, gpio_suffixes[i]);
1819 else
1820 snprintf(propname, sizeof(propname), "%s",
1821 gpio_suffixes[i]);
1822
1823 ret = of_gpio_named_count(dev->of_node, propname);
1824 if (ret >= 0)
1825 break;
1826 }
1827 return ret;
1828}
1829
1830static int platform_gpio_count(struct device *dev, const char *con_id)
1831{
1832 struct gpiod_lookup_table *table;
1833 struct gpiod_lookup *p;
1834 unsigned int count = 0;
1835
1836 table = gpiod_find_lookup_table(dev);
1837 if (!table)
1838 return -ENOENT;
1839
1840 for (p = &table->table[0]; p->chip_label; p++) {
1841 if ((con_id && p->con_id && !strcmp(con_id, p->con_id)) ||
1842 (!con_id && !p->con_id))
1843 count++;
1844 }
1845 if (!count)
1846 return -ENOENT;
1847
1848 return count;
1849}
1850
1851/**
1852 * gpiod_count - return the number of GPIOs associated with a device / function
1853 * or -ENOENT if no GPIO has been assigned to the requested function
1854 * @dev: GPIO consumer, can be NULL for system-global GPIOs
1855 * @con_id: function within the GPIO consumer
1856 */
1857int gpiod_count(struct device *dev, const char *con_id)
1858{
1859 int count = -ENOENT;
1860
1861 if (IS_ENABLED(CONFIG_OF) && dev && dev->of_node)
1862 count = dt_gpio_count(dev, con_id);
1863 else if (IS_ENABLED(CONFIG_ACPI) && dev && ACPI_HANDLE(dev))
1864 count = acpi_gpio_count(dev, con_id);
1865
1866 if (count < 0)
1867 count = platform_gpio_count(dev, con_id);
1868
1869 return count;
1870}
1871EXPORT_SYMBOL_GPL(gpiod_count);
1872
1809/** 1873/**
1810 * gpiod_get - obtain a GPIO for a given GPIO function 1874 * gpiod_get - obtain a GPIO for a given GPIO function
1811 * @dev: GPIO consumer, can be NULL for system-global GPIOs 1875 * @dev: GPIO consumer, can be NULL for system-global GPIOs
@@ -2090,6 +2154,72 @@ static void gpiochip_free_hogs(struct gpio_chip *chip)
2090} 2154}
2091 2155
2092/** 2156/**
2157 * gpiod_get_array - obtain multiple GPIOs from a multi-index GPIO function
2158 * @dev: GPIO consumer, can be NULL for system-global GPIOs
2159 * @con_id: function within the GPIO consumer
2160 * @flags: optional GPIO initialization flags
2161 *
2162 * This function acquires all the GPIOs defined under a given function.
2163 *
2164 * Return a struct gpio_descs containing an array of descriptors, -ENOENT if
2165 * no GPIO has been assigned to the requested function, or another IS_ERR()
2166 * code if an error occurred while trying to acquire the GPIOs.
2167 */
2168struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
2169 const char *con_id,
2170 enum gpiod_flags flags)
2171{
2172 struct gpio_desc *desc;
2173 struct gpio_descs *descs;
2174 int count;
2175
2176 count = gpiod_count(dev, con_id);
2177 if (count < 0)
2178 return ERR_PTR(count);
2179
2180 descs = kzalloc(sizeof(*descs) + sizeof(descs->desc[0]) * count,
2181 GFP_KERNEL);
2182 if (!descs)
2183 return ERR_PTR(-ENOMEM);
2184
2185 for (descs->ndescs = 0; descs->ndescs < count; ) {
2186 desc = gpiod_get_index(dev, con_id, descs->ndescs, flags);
2187 if (IS_ERR(desc)) {
2188 gpiod_put_array(descs);
2189 return ERR_CAST(desc);
2190 }
2191 descs->desc[descs->ndescs] = desc;
2192 descs->ndescs++;
2193 }
2194 return descs;
2195}
2196EXPORT_SYMBOL_GPL(gpiod_get_array);
2197
2198/**
2199 * gpiod_get_array_optional - obtain multiple GPIOs from a multi-index GPIO
2200 * function
2201 * @dev: GPIO consumer, can be NULL for system-global GPIOs
2202 * @con_id: function within the GPIO consumer
2203 * @flags: optional GPIO initialization flags
2204 *
2205 * This is equivalent to gpiod_get_array(), except that when no GPIO was
2206 * assigned to the requested function it will return NULL.
2207 */
2208struct gpio_descs *__must_check gpiod_get_array_optional(struct device *dev,
2209 const char *con_id,
2210 enum gpiod_flags flags)
2211{
2212 struct gpio_descs *descs;
2213
2214 descs = gpiod_get_array(dev, con_id, flags);
2215 if (IS_ERR(descs) && (PTR_ERR(descs) == -ENOENT))
2216 return NULL;
2217
2218 return descs;
2219}
2220EXPORT_SYMBOL_GPL(gpiod_get_array_optional);
2221
2222/**
2093 * gpiod_put - dispose of a GPIO descriptor 2223 * gpiod_put - dispose of a GPIO descriptor
2094 * @desc: GPIO descriptor to dispose of 2224 * @desc: GPIO descriptor to dispose of
2095 * 2225 *
@@ -2101,6 +2231,21 @@ void gpiod_put(struct gpio_desc *desc)
2101} 2231}
2102EXPORT_SYMBOL_GPL(gpiod_put); 2232EXPORT_SYMBOL_GPL(gpiod_put);
2103 2233
2234/**
2235 * gpiod_put_array - dispose of multiple GPIO descriptors
2236 * @descs: struct gpio_descs containing an array of descriptors
2237 */
2238void gpiod_put_array(struct gpio_descs *descs)
2239{
2240 unsigned int i;
2241
2242 for (i = 0; i < descs->ndescs; i++)
2243 gpiod_put(descs->desc[i]);
2244
2245 kfree(descs);
2246}
2247EXPORT_SYMBOL_GPL(gpiod_put_array);
2248
2104#ifdef CONFIG_DEBUG_FS 2249#ifdef CONFIG_DEBUG_FS
2105 2250
2106static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) 2251static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)