aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorBenoit Parrot <bparrot@ti.com>2015-02-02 12:44:44 -0500
committerLinus Walleij <linus.walleij@linaro.org>2015-03-04 05:09:00 -0500
commitf625d4601759f1cf1fd3ae58abeb0e203b8993b1 (patch)
tree8ca2d7871ec2b0d800ecd9a1e8e582c859deaf31 /drivers/gpio
parent984f66432e357701194abc7f753dcad89a1f9de3 (diff)
gpio: add GPIO hogging mechanism
Based on Boris Brezillion's work this is a reworked patch of his initial GPIO hogging mechanism. This patch provides a way to initially configure specific GPIO when the GPIO controller is probed. The actual DT scanning to collect the GPIO specific data is performed as part of gpiochip_add(). The purpose of this is to allow specific GPIOs to be configured without any driver specific code. This is particularly useful because board design are getting increasingly complex and given SoC pins can now have more than 10 mux values, a lot of connections are now dependent on external IO muxes to switch various modes. Specific drivers should not necessarily need to be aware of what accounts to a specific board implementation. This board level "description" should be best kept as part of the dts file. Signed-off-by: Benoit Parrot <bparrot@ti.com> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpiolib-of.c111
-rw-r--r--drivers/gpio/gpiolib.c124
-rw-r--r--drivers/gpio/gpiolib.h3
3 files changed, 219 insertions, 19 deletions
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index 8cad8e400b44..468d76ac1e84 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -22,6 +22,7 @@
22#include <linux/of_gpio.h> 22#include <linux/of_gpio.h>
23#include <linux/pinctrl/pinctrl.h> 23#include <linux/pinctrl/pinctrl.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/gpio/machine.h>
25 26
26#include "gpiolib.h" 27#include "gpiolib.h"
27 28
@@ -117,6 +118,114 @@ int of_get_named_gpio_flags(struct device_node *np, const char *list_name,
117EXPORT_SYMBOL(of_get_named_gpio_flags); 118EXPORT_SYMBOL(of_get_named_gpio_flags);
118 119
119/** 120/**
121 * of_get_gpio_hog() - Get a GPIO hog descriptor, names and flags for GPIO API
122 * @np: device node to get GPIO from
123 * @name: GPIO line name
124 * @lflags: gpio_lookup_flags - returned from of_find_gpio() or
125 * of_get_gpio_hog()
126 * @dflags: gpiod_flags - optional GPIO initialization flags
127 *
128 * Returns GPIO descriptor to use with Linux GPIO API, or one of the errno
129 * value on the error condition.
130 */
131static struct gpio_desc *of_get_gpio_hog(struct device_node *np,
132 const char **name,
133 enum gpio_lookup_flags *lflags,
134 enum gpiod_flags *dflags)
135{
136 struct device_node *chip_np;
137 enum of_gpio_flags xlate_flags;
138 struct gpio_desc *desc;
139 struct gg_data gg_data = {
140 .flags = &xlate_flags,
141 };
142 u32 tmp;
143 int i, ret;
144
145 chip_np = np->parent;
146 if (!chip_np)
147 return ERR_PTR(-EINVAL);
148
149 xlate_flags = 0;
150 *lflags = 0;
151 *dflags = 0;
152
153 ret = of_property_read_u32(chip_np, "#gpio-cells", &tmp);
154 if (ret)
155 return ERR_PTR(ret);
156
157 if (tmp > MAX_PHANDLE_ARGS)
158 return ERR_PTR(-EINVAL);
159
160 gg_data.gpiospec.args_count = tmp;
161 gg_data.gpiospec.np = chip_np;
162 for (i = 0; i < tmp; i++) {
163 ret = of_property_read_u32_index(np, "gpios", i,
164 &gg_data.gpiospec.args[i]);
165 if (ret)
166 return ERR_PTR(ret);
167 }
168
169 gpiochip_find(&gg_data, of_gpiochip_find_and_xlate);
170 if (!gg_data.out_gpio) {
171 if (np->parent == np)
172 return ERR_PTR(-ENXIO);
173 else
174 return ERR_PTR(-EINVAL);
175 }
176
177 if (xlate_flags & OF_GPIO_ACTIVE_LOW)
178 *lflags |= GPIO_ACTIVE_LOW;
179
180 if (of_property_read_bool(np, "input"))
181 *dflags |= GPIOD_IN;
182 else if (of_property_read_bool(np, "output-low"))
183 *dflags |= GPIOD_OUT_LOW;
184 else if (of_property_read_bool(np, "output-high"))
185 *dflags |= GPIOD_OUT_HIGH;
186 else {
187 pr_warn("GPIO line %d (%s): no hogging state specified, bailing out\n",
188 desc_to_gpio(gg_data.out_gpio), np->name);
189 return ERR_PTR(-EINVAL);
190 }
191
192 if (name && of_property_read_string(np, "line-name", name))
193 *name = np->name;
194
195 desc = gg_data.out_gpio;
196
197 return desc;
198}
199
200/**
201 * of_gpiochip_scan_hogs - Scan gpio-controller and apply GPIO hog as requested
202 * @chip: gpio chip to act on
203 *
204 * This is only used by of_gpiochip_add to request/set GPIO initial
205 * configuration.
206 */
207static void of_gpiochip_scan_hogs(struct gpio_chip *chip)
208{
209 struct gpio_desc *desc = NULL;
210 struct device_node *np;
211 const char *name;
212 enum gpio_lookup_flags lflags;
213 enum gpiod_flags dflags;
214
215 for_each_child_of_node(chip->of_node, np) {
216 if (!of_property_read_bool(np, "gpio-hog"))
217 continue;
218
219 desc = of_get_gpio_hog(np, &name, &lflags, &dflags);
220 if (IS_ERR(desc))
221 continue;
222
223 if (gpiod_hog(desc, name, lflags, dflags))
224 continue;
225 }
226}
227
228/**
120 * of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags 229 * of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags
121 * @gc: pointer to the gpio_chip structure 230 * @gc: pointer to the gpio_chip structure
122 * @np: device node of the GPIO chip 231 * @np: device node of the GPIO chip
@@ -325,6 +434,8 @@ void of_gpiochip_add(struct gpio_chip *chip)
325 434
326 of_gpiochip_add_pin_range(chip); 435 of_gpiochip_add_pin_range(chip);
327 of_node_get(chip->of_node); 436 of_node_get(chip->of_node);
437
438 of_gpiochip_scan_hogs(chip);
328} 439}
329 440
330void of_gpiochip_remove(struct gpio_chip *chip) 441void of_gpiochip_remove(struct gpio_chip *chip)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 1ca9295b2c10..15837263dbb3 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -315,6 +315,7 @@ EXPORT_SYMBOL_GPL(gpiochip_add);
315 315
316/* Forward-declaration */ 316/* Forward-declaration */
317static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip); 317static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip);
318static void gpiochip_free_hogs(struct gpio_chip *chip);
318 319
319/** 320/**
320 * gpiochip_remove() - unregister a gpio_chip 321 * gpiochip_remove() - unregister a gpio_chip
@@ -333,6 +334,7 @@ void gpiochip_remove(struct gpio_chip *chip)
333 334
334 acpi_gpiochip_remove(chip); 335 acpi_gpiochip_remove(chip);
335 gpiochip_remove_pin_ranges(chip); 336 gpiochip_remove_pin_ranges(chip);
337 gpiochip_free_hogs(chip);
336 of_gpiochip_remove(chip); 338 of_gpiochip_remove(chip);
337 339
338 spin_lock_irqsave(&gpio_lock, flags); 340 spin_lock_irqsave(&gpio_lock, flags);
@@ -866,6 +868,7 @@ static bool __gpiod_free(struct gpio_desc *desc)
866 clear_bit(FLAG_REQUESTED, &desc->flags); 868 clear_bit(FLAG_REQUESTED, &desc->flags);
867 clear_bit(FLAG_OPEN_DRAIN, &desc->flags); 869 clear_bit(FLAG_OPEN_DRAIN, &desc->flags);
868 clear_bit(FLAG_OPEN_SOURCE, &desc->flags); 870 clear_bit(FLAG_OPEN_SOURCE, &desc->flags);
871 clear_bit(FLAG_IS_HOGGED, &desc->flags);
869 ret = true; 872 ret = true;
870 } 873 }
871 874
@@ -1840,6 +1843,47 @@ struct gpio_desc *__must_check __gpiod_get_optional(struct device *dev,
1840} 1843}
1841EXPORT_SYMBOL_GPL(__gpiod_get_optional); 1844EXPORT_SYMBOL_GPL(__gpiod_get_optional);
1842 1845
1846
1847/**
1848 * gpiod_configure_flags - helper function to configure a given GPIO
1849 * @desc: gpio whose value will be assigned
1850 * @con_id: function within the GPIO consumer
1851 * @lflags: gpio_lookup_flags - returned from of_find_gpio() or
1852 * of_get_gpio_hog()
1853 * @dflags: gpiod_flags - optional GPIO initialization flags
1854 *
1855 * Return 0 on success, -ENOENT if no GPIO has been assigned to the
1856 * requested function and/or index, or another IS_ERR() code if an error
1857 * occurred while trying to acquire the GPIO.
1858 */
1859static int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
1860 unsigned long lflags, enum gpiod_flags dflags)
1861{
1862 int status;
1863
1864 if (lflags & GPIO_ACTIVE_LOW)
1865 set_bit(FLAG_ACTIVE_LOW, &desc->flags);
1866 if (lflags & GPIO_OPEN_DRAIN)
1867 set_bit(FLAG_OPEN_DRAIN, &desc->flags);
1868 if (lflags & GPIO_OPEN_SOURCE)
1869 set_bit(FLAG_OPEN_SOURCE, &desc->flags);
1870
1871 /* No particular flag request, return here... */
1872 if (!(dflags & GPIOD_FLAGS_BIT_DIR_SET)) {
1873 pr_debug("no flags found for %s\n", con_id);
1874 return 0;
1875 }
1876
1877 /* Process flags */
1878 if (dflags & GPIOD_FLAGS_BIT_DIR_OUT)
1879 status = gpiod_direction_output(desc,
1880 dflags & GPIOD_FLAGS_BIT_DIR_VAL);
1881 else
1882 status = gpiod_direction_input(desc);
1883
1884 return status;
1885}
1886
1843/** 1887/**
1844 * gpiod_get_index - obtain a GPIO from a multi-index GPIO function 1888 * gpiod_get_index - obtain a GPIO from a multi-index GPIO function
1845 * @dev: GPIO consumer, can be NULL for system-global GPIOs 1889 * @dev: GPIO consumer, can be NULL for system-global GPIOs
@@ -1889,28 +1933,10 @@ struct gpio_desc *__must_check __gpiod_get_index(struct device *dev,
1889 } 1933 }
1890 1934
1891 status = gpiod_request(desc, con_id); 1935 status = gpiod_request(desc, con_id);
1892
1893 if (status < 0) 1936 if (status < 0)
1894 return ERR_PTR(status); 1937 return ERR_PTR(status);
1895 1938
1896 if (lookupflags & GPIO_ACTIVE_LOW) 1939 status = gpiod_configure_flags(desc, con_id, lookupflags, flags);
1897 set_bit(FLAG_ACTIVE_LOW, &desc->flags);
1898 if (lookupflags & GPIO_OPEN_DRAIN)
1899 set_bit(FLAG_OPEN_DRAIN, &desc->flags);
1900 if (lookupflags & GPIO_OPEN_SOURCE)
1901 set_bit(FLAG_OPEN_SOURCE, &desc->flags);
1902
1903 /* No particular flag request, return here... */
1904 if (!(flags & GPIOD_FLAGS_BIT_DIR_SET))
1905 return desc;
1906
1907 /* Process flags */
1908 if (flags & GPIOD_FLAGS_BIT_DIR_OUT)
1909 status = gpiod_direction_output(desc,
1910 flags & GPIOD_FLAGS_BIT_DIR_VAL);
1911 else
1912 status = gpiod_direction_input(desc);
1913
1914 if (status < 0) { 1940 if (status < 0) {
1915 dev_dbg(dev, "setup of GPIO %s failed\n", con_id); 1941 dev_dbg(dev, "setup of GPIO %s failed\n", con_id);
1916 gpiod_put(desc); 1942 gpiod_put(desc);
@@ -2006,6 +2032,66 @@ struct gpio_desc *__must_check __gpiod_get_index_optional(struct device *dev,
2006EXPORT_SYMBOL_GPL(__gpiod_get_index_optional); 2032EXPORT_SYMBOL_GPL(__gpiod_get_index_optional);
2007 2033
2008/** 2034/**
2035 * gpiod_hog - Hog the specified GPIO desc given the provided flags
2036 * @desc: gpio whose value will be assigned
2037 * @name: gpio line name
2038 * @lflags: gpio_lookup_flags - returned from of_find_gpio() or
2039 * of_get_gpio_hog()
2040 * @dflags: gpiod_flags - optional GPIO initialization flags
2041 */
2042int gpiod_hog(struct gpio_desc *desc, const char *name,
2043 unsigned long lflags, enum gpiod_flags dflags)
2044{
2045 struct gpio_chip *chip;
2046 struct gpio_desc *local_desc;
2047 int hwnum;
2048 int status;
2049
2050 chip = gpiod_to_chip(desc);
2051 hwnum = gpio_chip_hwgpio(desc);
2052
2053 local_desc = gpiochip_request_own_desc(chip, hwnum, name);
2054 if (IS_ERR(local_desc)) {
2055 pr_debug("requesting own GPIO %s failed\n", name);
2056 return PTR_ERR(local_desc);
2057 }
2058
2059 status = gpiod_configure_flags(desc, name, lflags, dflags);
2060 if (status < 0) {
2061 pr_debug("setup of GPIO %s failed\n", name);
2062 gpiochip_free_own_desc(desc);
2063 return status;
2064 }
2065
2066 /* Mark GPIO as hogged so it can be identified and removed later */
2067 set_bit(FLAG_IS_HOGGED, &desc->flags);
2068
2069 pr_info("GPIO line %d (%s) hogged as %s%s\n",
2070 desc_to_gpio(desc), name,
2071 (dflags&GPIOD_FLAGS_BIT_DIR_OUT) ? "output" : "input",
2072 (dflags&GPIOD_FLAGS_BIT_DIR_OUT) ?
2073 (dflags&GPIOD_FLAGS_BIT_DIR_VAL) ? "/high" : "/low":"");
2074
2075 return 0;
2076}
2077
2078/**
2079 * gpiochip_free_hogs - Scan gpio-controller chip and release GPIO hog
2080 * @chip: gpio chip to act on
2081 *
2082 * This is only used by of_gpiochip_remove to free hogged gpios
2083 */
2084static void gpiochip_free_hogs(struct gpio_chip *chip)
2085{
2086 int id;
2087
2088 for (id = 0; id < chip->ngpio; id++) {
2089 if (test_bit(FLAG_IS_HOGGED, &chip->desc[id].flags))
2090 gpiochip_free_own_desc(&chip->desc[id]);
2091 }
2092}
2093
2094/**
2009 * gpiod_put - dispose of a GPIO descriptor 2095 * gpiod_put - dispose of a GPIO descriptor
2010 * @desc: GPIO descriptor to dispose of 2096 * @desc: GPIO descriptor to dispose of
2011 * 2097 *
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index 550a5eafbd38..cadba26c45a6 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -78,6 +78,7 @@ struct gpio_desc {
78#define FLAG_OPEN_SOURCE 8 /* Gpio is open source type */ 78#define FLAG_OPEN_SOURCE 8 /* Gpio is open source type */
79#define FLAG_USED_AS_IRQ 9 /* GPIO is connected to an IRQ */ 79#define FLAG_USED_AS_IRQ 9 /* GPIO is connected to an IRQ */
80#define FLAG_SYSFS_DIR 10 /* show sysfs direction attribute */ 80#define FLAG_SYSFS_DIR 10 /* show sysfs direction attribute */
81#define FLAG_IS_HOGGED 11 /* GPIO is hogged */
81 82
82#define ID_SHIFT 16 /* add new flags before this one */ 83#define ID_SHIFT 16 /* add new flags before this one */
83 84
@@ -89,6 +90,8 @@ struct gpio_desc {
89 90
90int gpiod_request(struct gpio_desc *desc, const char *label); 91int gpiod_request(struct gpio_desc *desc, const char *label);
91void gpiod_free(struct gpio_desc *desc); 92void gpiod_free(struct gpio_desc *desc);
93int gpiod_hog(struct gpio_desc *desc, const char *name,
94 unsigned long lflags, enum gpiod_flags dflags);
92 95
93/* 96/*
94 * Return the GPIO number of the passed descriptor relative to its chip 97 * Return the GPIO number of the passed descriptor relative to its chip