diff options
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/Kconfig | 8 | ||||
-rw-r--r-- | drivers/gpio/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpio/gpio-74x164.c | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-mcp23s08.c | 6 | ||||
-rw-r--r-- | drivers/gpio/gpio-mvebu.c | 30 | ||||
-rw-r--r-- | drivers/gpio/gpio-omap.c | 35 | ||||
-rw-r--r-- | drivers/gpio/gpio-timberdale.c | 4 | ||||
-rw-r--r-- | drivers/gpio/gpiolib-acpi.c | 54 | ||||
-rw-r--r-- | drivers/gpio/gpiolib-of.c | 52 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.c | 86 |
10 files changed, 266 insertions, 12 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 39d9323abbda..14a6c2913e49 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -47,7 +47,11 @@ if GPIOLIB | |||
47 | 47 | ||
48 | config OF_GPIO | 48 | config OF_GPIO |
49 | def_bool y | 49 | def_bool y |
50 | depends on OF && !SPARC | 50 | depends on OF |
51 | |||
52 | config GPIO_ACPI | ||
53 | def_bool y | ||
54 | depends on ACPI | ||
51 | 55 | ||
52 | config DEBUG_GPIO | 56 | config DEBUG_GPIO |
53 | bool "Debug GPIO calls" | 57 | bool "Debug GPIO calls" |
@@ -496,7 +500,7 @@ config GPIO_ADP5588_IRQ | |||
496 | 500 | ||
497 | config GPIO_ADNP | 501 | config GPIO_ADNP |
498 | tristate "Avionic Design N-bit GPIO expander" | 502 | tristate "Avionic Design N-bit GPIO expander" |
499 | depends on I2C && OF | 503 | depends on I2C && OF_GPIO |
500 | help | 504 | help |
501 | This option enables support for N GPIOs found on Avionic Design | 505 | This option enables support for N GPIOs found on Avionic Design |
502 | I2C GPIO expanders. The register space will be extended by powers | 506 | I2C GPIO expanders. The register space will be extended by powers |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index a41c2503bd40..76b344683251 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -4,6 +4,7 @@ ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG | |||
4 | 4 | ||
5 | obj-$(CONFIG_GPIOLIB) += gpiolib.o devres.o | 5 | obj-$(CONFIG_GPIOLIB) += gpiolib.o devres.o |
6 | obj-$(CONFIG_OF_GPIO) += gpiolib-of.o | 6 | obj-$(CONFIG_OF_GPIO) += gpiolib-of.o |
7 | obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o | ||
7 | 8 | ||
8 | # Device drivers. Generally keep list sorted alphabetically | 9 | # Device drivers. Generally keep list sorted alphabetically |
9 | obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o | 10 | obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o |
diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/gpio-74x164.c index ed3e55161bdc..f05e54258ffb 100644 --- a/drivers/gpio/gpio-74x164.c +++ b/drivers/gpio/gpio-74x164.c | |||
@@ -153,7 +153,7 @@ static int __devinit gen_74x164_probe(struct spi_device *spi) | |||
153 | } | 153 | } |
154 | 154 | ||
155 | chip->gpio_chip.ngpio = GEN_74X164_NUMBER_GPIOS * chip->registers; | 155 | chip->gpio_chip.ngpio = GEN_74X164_NUMBER_GPIOS * chip->registers; |
156 | chip->buffer = devm_kzalloc(&spi->dev, chip->gpio_chip.ngpio, GFP_KERNEL); | 156 | chip->buffer = devm_kzalloc(&spi->dev, chip->registers, GFP_KERNEL); |
157 | if (!chip->buffer) { | 157 | if (!chip->buffer) { |
158 | ret = -ENOMEM; | 158 | ret = -ENOMEM; |
159 | goto exit_destroy; | 159 | goto exit_destroy; |
diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index 0f425189de11..ce1c84760076 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c | |||
@@ -77,7 +77,7 @@ struct mcp23s08_driver_data { | |||
77 | 77 | ||
78 | /*----------------------------------------------------------------------*/ | 78 | /*----------------------------------------------------------------------*/ |
79 | 79 | ||
80 | #ifdef CONFIG_I2C | 80 | #if IS_ENABLED(CONFIG_I2C) |
81 | 81 | ||
82 | static int mcp23008_read(struct mcp23s08 *mcp, unsigned reg) | 82 | static int mcp23008_read(struct mcp23s08 *mcp, unsigned reg) |
83 | { | 83 | { |
@@ -399,7 +399,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, | |||
399 | break; | 399 | break; |
400 | #endif /* CONFIG_SPI_MASTER */ | 400 | #endif /* CONFIG_SPI_MASTER */ |
401 | 401 | ||
402 | #ifdef CONFIG_I2C | 402 | #if IS_ENABLED(CONFIG_I2C) |
403 | case MCP_TYPE_008: | 403 | case MCP_TYPE_008: |
404 | mcp->ops = &mcp23008_ops; | 404 | mcp->ops = &mcp23008_ops; |
405 | mcp->chip.ngpio = 8; | 405 | mcp->chip.ngpio = 8; |
@@ -473,7 +473,7 @@ fail: | |||
473 | 473 | ||
474 | /*----------------------------------------------------------------------*/ | 474 | /*----------------------------------------------------------------------*/ |
475 | 475 | ||
476 | #ifdef CONFIG_I2C | 476 | #if IS_ENABLED(CONFIG_I2C) |
477 | 477 | ||
478 | static int __devinit mcp230xx_probe(struct i2c_client *client, | 478 | static int __devinit mcp230xx_probe(struct i2c_client *client, |
479 | const struct i2c_device_id *id) | 479 | const struct i2c_device_id *id) |
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index 8b3065703566..a515b9294e92 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c | |||
@@ -92,6 +92,11 @@ static inline void __iomem *mvebu_gpioreg_out(struct mvebu_gpio_chip *mvchip) | |||
92 | return mvchip->membase + GPIO_OUT_OFF; | 92 | return mvchip->membase + GPIO_OUT_OFF; |
93 | } | 93 | } |
94 | 94 | ||
95 | static inline void __iomem *mvebu_gpioreg_blink(struct mvebu_gpio_chip *mvchip) | ||
96 | { | ||
97 | return mvchip->membase + GPIO_BLINK_EN_OFF; | ||
98 | } | ||
99 | |||
95 | static inline void __iomem *mvebu_gpioreg_io_conf(struct mvebu_gpio_chip *mvchip) | 100 | static inline void __iomem *mvebu_gpioreg_io_conf(struct mvebu_gpio_chip *mvchip) |
96 | { | 101 | { |
97 | return mvchip->membase + GPIO_IO_CONF_OFF; | 102 | return mvchip->membase + GPIO_IO_CONF_OFF; |
@@ -206,6 +211,23 @@ static int mvebu_gpio_get(struct gpio_chip *chip, unsigned pin) | |||
206 | return (u >> pin) & 1; | 211 | return (u >> pin) & 1; |
207 | } | 212 | } |
208 | 213 | ||
214 | static void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value) | ||
215 | { | ||
216 | struct mvebu_gpio_chip *mvchip = | ||
217 | container_of(chip, struct mvebu_gpio_chip, chip); | ||
218 | unsigned long flags; | ||
219 | u32 u; | ||
220 | |||
221 | spin_lock_irqsave(&mvchip->lock, flags); | ||
222 | u = readl_relaxed(mvebu_gpioreg_blink(mvchip)); | ||
223 | if (value) | ||
224 | u |= 1 << pin; | ||
225 | else | ||
226 | u &= ~(1 << pin); | ||
227 | writel_relaxed(u, mvebu_gpioreg_blink(mvchip)); | ||
228 | spin_unlock_irqrestore(&mvchip->lock, flags); | ||
229 | } | ||
230 | |||
209 | static int mvebu_gpio_direction_input(struct gpio_chip *chip, unsigned pin) | 231 | static int mvebu_gpio_direction_input(struct gpio_chip *chip, unsigned pin) |
210 | { | 232 | { |
211 | struct mvebu_gpio_chip *mvchip = | 233 | struct mvebu_gpio_chip *mvchip = |
@@ -244,6 +266,9 @@ static int mvebu_gpio_direction_output(struct gpio_chip *chip, unsigned pin, | |||
244 | if (ret) | 266 | if (ret) |
245 | return ret; | 267 | return ret; |
246 | 268 | ||
269 | mvebu_gpio_blink(chip, pin, 0); | ||
270 | mvebu_gpio_set(chip, pin, value); | ||
271 | |||
247 | spin_lock_irqsave(&mvchip->lock, flags); | 272 | spin_lock_irqsave(&mvchip->lock, flags); |
248 | u = readl_relaxed(mvebu_gpioreg_io_conf(mvchip)); | 273 | u = readl_relaxed(mvebu_gpioreg_io_conf(mvchip)); |
249 | u &= ~(1 << pin); | 274 | u &= ~(1 << pin); |
@@ -381,11 +406,13 @@ static int mvebu_gpio_irq_set_type(struct irq_data *d, unsigned int type) | |||
381 | u = readl_relaxed(mvebu_gpioreg_in_pol(mvchip)); | 406 | u = readl_relaxed(mvebu_gpioreg_in_pol(mvchip)); |
382 | u &= ~(1 << pin); | 407 | u &= ~(1 << pin); |
383 | writel_relaxed(u, mvebu_gpioreg_in_pol(mvchip)); | 408 | writel_relaxed(u, mvebu_gpioreg_in_pol(mvchip)); |
409 | break; | ||
384 | case IRQ_TYPE_EDGE_FALLING: | 410 | case IRQ_TYPE_EDGE_FALLING: |
385 | case IRQ_TYPE_LEVEL_LOW: | 411 | case IRQ_TYPE_LEVEL_LOW: |
386 | u = readl_relaxed(mvebu_gpioreg_in_pol(mvchip)); | 412 | u = readl_relaxed(mvebu_gpioreg_in_pol(mvchip)); |
387 | u |= 1 << pin; | 413 | u |= 1 << pin; |
388 | writel_relaxed(u, mvebu_gpioreg_in_pol(mvchip)); | 414 | writel_relaxed(u, mvebu_gpioreg_in_pol(mvchip)); |
415 | break; | ||
389 | case IRQ_TYPE_EDGE_BOTH: { | 416 | case IRQ_TYPE_EDGE_BOTH: { |
390 | u32 v; | 417 | u32 v; |
391 | 418 | ||
@@ -401,6 +428,7 @@ static int mvebu_gpio_irq_set_type(struct irq_data *d, unsigned int type) | |||
401 | else | 428 | else |
402 | u &= ~(1 << pin); /* rising */ | 429 | u &= ~(1 << pin); /* rising */ |
403 | writel_relaxed(u, mvebu_gpioreg_in_pol(mvchip)); | 430 | writel_relaxed(u, mvebu_gpioreg_in_pol(mvchip)); |
431 | break; | ||
404 | } | 432 | } |
405 | } | 433 | } |
406 | return 0; | 434 | return 0; |
@@ -642,7 +670,7 @@ static int __devinit mvebu_gpio_probe(struct platform_device *pdev) | |||
642 | ct->handler = handle_edge_irq; | 670 | ct->handler = handle_edge_irq; |
643 | ct->chip.name = mvchip->chip.label; | 671 | ct->chip.name = mvchip->chip.label; |
644 | 672 | ||
645 | irq_setup_generic_chip(gc, IRQ_MSK(ngpios), IRQ_GC_INIT_MASK_CACHE, | 673 | irq_setup_generic_chip(gc, IRQ_MSK(ngpios), 0, |
646 | IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); | 674 | IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); |
647 | 675 | ||
648 | /* Setup irq domain on top of the generic chip. */ | 676 | /* Setup irq domain on top of the generic chip. */ |
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index eb73dee0ab33..d71e5bdf7b97 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
@@ -251,6 +251,40 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio, | |||
251 | } | 251 | } |
252 | } | 252 | } |
253 | 253 | ||
254 | /** | ||
255 | * _clear_gpio_debounce - clear debounce settings for a gpio | ||
256 | * @bank: the gpio bank we're acting upon | ||
257 | * @gpio: the gpio number on this @gpio | ||
258 | * | ||
259 | * If a gpio is using debounce, then clear the debounce enable bit and if | ||
260 | * this is the only gpio in this bank using debounce, then clear the debounce | ||
261 | * time too. The debounce clock will also be disabled when calling this function | ||
262 | * if this is the only gpio in the bank using debounce. | ||
263 | */ | ||
264 | static void _clear_gpio_debounce(struct gpio_bank *bank, unsigned gpio) | ||
265 | { | ||
266 | u32 gpio_bit = GPIO_BIT(bank, gpio); | ||
267 | |||
268 | if (!bank->dbck_flag) | ||
269 | return; | ||
270 | |||
271 | if (!(bank->dbck_enable_mask & gpio_bit)) | ||
272 | return; | ||
273 | |||
274 | bank->dbck_enable_mask &= ~gpio_bit; | ||
275 | bank->context.debounce_en &= ~gpio_bit; | ||
276 | __raw_writel(bank->context.debounce_en, | ||
277 | bank->base + bank->regs->debounce_en); | ||
278 | |||
279 | if (!bank->dbck_enable_mask) { | ||
280 | bank->context.debounce = 0; | ||
281 | __raw_writel(bank->context.debounce, bank->base + | ||
282 | bank->regs->debounce); | ||
283 | clk_disable(bank->dbck); | ||
284 | bank->dbck_enabled = false; | ||
285 | } | ||
286 | } | ||
287 | |||
254 | static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio, | 288 | static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio, |
255 | unsigned trigger) | 289 | unsigned trigger) |
256 | { | 290 | { |
@@ -539,6 +573,7 @@ static void _reset_gpio(struct gpio_bank *bank, int gpio) | |||
539 | _set_gpio_irqenable(bank, gpio, 0); | 573 | _set_gpio_irqenable(bank, gpio, 0); |
540 | _clear_gpio_irqstatus(bank, gpio); | 574 | _clear_gpio_irqstatus(bank, gpio); |
541 | _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE); | 575 | _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE); |
576 | _clear_gpio_debounce(bank, gpio); | ||
542 | } | 577 | } |
543 | 578 | ||
544 | /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ | 579 | /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ |
diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/gpio-timberdale.c index 031c6adf5b65..1a3e2b9b4772 100644 --- a/drivers/gpio/gpio-timberdale.c +++ b/drivers/gpio/gpio-timberdale.c | |||
@@ -116,7 +116,7 @@ static void timbgpio_irq_disable(struct irq_data *d) | |||
116 | unsigned long flags; | 116 | unsigned long flags; |
117 | 117 | ||
118 | spin_lock_irqsave(&tgpio->lock, flags); | 118 | spin_lock_irqsave(&tgpio->lock, flags); |
119 | tgpio->last_ier &= ~(1 << offset); | 119 | tgpio->last_ier &= ~(1UL << offset); |
120 | iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); | 120 | iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); |
121 | spin_unlock_irqrestore(&tgpio->lock, flags); | 121 | spin_unlock_irqrestore(&tgpio->lock, flags); |
122 | } | 122 | } |
@@ -128,7 +128,7 @@ static void timbgpio_irq_enable(struct irq_data *d) | |||
128 | unsigned long flags; | 128 | unsigned long flags; |
129 | 129 | ||
130 | spin_lock_irqsave(&tgpio->lock, flags); | 130 | spin_lock_irqsave(&tgpio->lock, flags); |
131 | tgpio->last_ier |= 1 << offset; | 131 | tgpio->last_ier |= 1UL << offset; |
132 | iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); | 132 | iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); |
133 | spin_unlock_irqrestore(&tgpio->lock, flags); | 133 | spin_unlock_irqrestore(&tgpio->lock, flags); |
134 | } | 134 | } |
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c new file mode 100644 index 000000000000..cbad6e908d30 --- /dev/null +++ b/drivers/gpio/gpiolib-acpi.c | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * ACPI helpers for GPIO API | ||
3 | * | ||
4 | * Copyright (C) 2012, Intel Corporation | ||
5 | * Authors: Mathias Nyman <mathias.nyman@linux.intel.com> | ||
6 | * Mika Westerberg <mika.westerberg@linux.intel.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/errno.h> | ||
14 | #include <linux/gpio.h> | ||
15 | #include <linux/export.h> | ||
16 | #include <linux/acpi_gpio.h> | ||
17 | #include <linux/acpi.h> | ||
18 | |||
19 | static int acpi_gpiochip_find(struct gpio_chip *gc, void *data) | ||
20 | { | ||
21 | if (!gc->dev) | ||
22 | return false; | ||
23 | |||
24 | return ACPI_HANDLE(gc->dev) == data; | ||
25 | } | ||
26 | |||
27 | /** | ||
28 | * acpi_get_gpio() - Translate ACPI GPIO pin to GPIO number usable with GPIO API | ||
29 | * @path: ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1") | ||
30 | * @pin: ACPI GPIO pin number (0-based, controller-relative) | ||
31 | * | ||
32 | * Returns GPIO number to use with Linux generic GPIO API, or errno error value | ||
33 | */ | ||
34 | |||
35 | int acpi_get_gpio(char *path, int pin) | ||
36 | { | ||
37 | struct gpio_chip *chip; | ||
38 | acpi_handle handle; | ||
39 | acpi_status status; | ||
40 | |||
41 | status = acpi_get_handle(NULL, path, &handle); | ||
42 | if (ACPI_FAILURE(status)) | ||
43 | return -ENODEV; | ||
44 | |||
45 | chip = gpiochip_find(handle, acpi_gpiochip_find); | ||
46 | if (!chip) | ||
47 | return -ENODEV; | ||
48 | |||
49 | if (!gpio_is_valid(chip->base + pin)) | ||
50 | return -EINVAL; | ||
51 | |||
52 | return chip->base + pin; | ||
53 | } | ||
54 | EXPORT_SYMBOL_GPL(acpi_get_gpio); | ||
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index f1a45997aea8..d542a141811a 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/of.h> | 19 | #include <linux/of.h> |
20 | #include <linux/of_address.h> | 20 | #include <linux/of_address.h> |
21 | #include <linux/of_gpio.h> | 21 | #include <linux/of_gpio.h> |
22 | #include <linux/pinctrl/pinctrl.h> | ||
22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
23 | 24 | ||
24 | /* Private data structure for of_gpiochip_find_and_xlate */ | 25 | /* Private data structure for of_gpiochip_find_and_xlate */ |
@@ -216,6 +217,54 @@ err0: | |||
216 | } | 217 | } |
217 | EXPORT_SYMBOL(of_mm_gpiochip_add); | 218 | EXPORT_SYMBOL(of_mm_gpiochip_add); |
218 | 219 | ||
220 | #ifdef CONFIG_PINCTRL | ||
221 | static void of_gpiochip_add_pin_range(struct gpio_chip *chip) | ||
222 | { | ||
223 | struct device_node *np = chip->of_node; | ||
224 | struct of_phandle_args pinspec; | ||
225 | struct pinctrl_dev *pctldev; | ||
226 | int index = 0, ret; | ||
227 | |||
228 | if (!np) | ||
229 | return; | ||
230 | |||
231 | do { | ||
232 | ret = of_parse_phandle_with_args(np, "gpio-ranges", | ||
233 | "#gpio-range-cells", index, &pinspec); | ||
234 | if (ret) | ||
235 | break; | ||
236 | |||
237 | pctldev = of_pinctrl_get(pinspec.np); | ||
238 | if (!pctldev) | ||
239 | break; | ||
240 | |||
241 | /* | ||
242 | * This assumes that the n GPIO pins are consecutive in the | ||
243 | * GPIO number space, and that the pins are also consecutive | ||
244 | * in their local number space. Currently it is not possible | ||
245 | * to add different ranges for one and the same GPIO chip, | ||
246 | * as the code assumes that we have one consecutive range | ||
247 | * on both, mapping 1-to-1. | ||
248 | * | ||
249 | * TODO: make the OF bindings handle multiple sparse ranges | ||
250 | * on the same GPIO chip. | ||
251 | */ | ||
252 | ret = gpiochip_add_pin_range(chip, | ||
253 | pinctrl_dev_get_name(pctldev), | ||
254 | 0, /* offset in gpiochip */ | ||
255 | pinspec.args[0], | ||
256 | pinspec.args[1]); | ||
257 | |||
258 | if (ret) | ||
259 | break; | ||
260 | |||
261 | } while (index++); | ||
262 | } | ||
263 | |||
264 | #else | ||
265 | static void of_gpiochip_add_pin_range(struct gpio_chip *chip) {} | ||
266 | #endif | ||
267 | |||
219 | void of_gpiochip_add(struct gpio_chip *chip) | 268 | void of_gpiochip_add(struct gpio_chip *chip) |
220 | { | 269 | { |
221 | if ((!chip->of_node) && (chip->dev)) | 270 | if ((!chip->of_node) && (chip->dev)) |
@@ -229,11 +278,14 @@ void of_gpiochip_add(struct gpio_chip *chip) | |||
229 | chip->of_xlate = of_gpio_simple_xlate; | 278 | chip->of_xlate = of_gpio_simple_xlate; |
230 | } | 279 | } |
231 | 280 | ||
281 | of_gpiochip_add_pin_range(chip); | ||
232 | of_node_get(chip->of_node); | 282 | of_node_get(chip->of_node); |
233 | } | 283 | } |
234 | 284 | ||
235 | void of_gpiochip_remove(struct gpio_chip *chip) | 285 | void of_gpiochip_remove(struct gpio_chip *chip) |
236 | { | 286 | { |
287 | gpiochip_remove_pin_ranges(chip); | ||
288 | |||
237 | if (chip->of_node) | 289 | if (chip->of_node) |
238 | of_node_put(chip->of_node); | 290 | of_node_put(chip->of_node); |
239 | } | 291 | } |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index fd2b71c70997..199fca15f270 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -651,9 +651,11 @@ static ssize_t export_store(struct class *class, | |||
651 | */ | 651 | */ |
652 | 652 | ||
653 | status = gpio_request(gpio, "sysfs"); | 653 | status = gpio_request(gpio, "sysfs"); |
654 | if (status < 0) | 654 | if (status < 0) { |
655 | if (status == -EPROBE_DEFER) | ||
656 | status = -ENODEV; | ||
655 | goto done; | 657 | goto done; |
656 | 658 | } | |
657 | status = gpio_export(gpio, true); | 659 | status = gpio_export(gpio, true); |
658 | if (status < 0) | 660 | if (status < 0) |
659 | gpio_free(gpio); | 661 | gpio_free(gpio); |
@@ -1118,6 +1120,10 @@ int gpiochip_add(struct gpio_chip *chip) | |||
1118 | } | 1120 | } |
1119 | } | 1121 | } |
1120 | 1122 | ||
1123 | #ifdef CONFIG_PINCTRL | ||
1124 | INIT_LIST_HEAD(&chip->pin_ranges); | ||
1125 | #endif | ||
1126 | |||
1121 | of_gpiochip_add(chip); | 1127 | of_gpiochip_add(chip); |
1122 | 1128 | ||
1123 | unlock: | 1129 | unlock: |
@@ -1158,6 +1164,7 @@ int gpiochip_remove(struct gpio_chip *chip) | |||
1158 | 1164 | ||
1159 | spin_lock_irqsave(&gpio_lock, flags); | 1165 | spin_lock_irqsave(&gpio_lock, flags); |
1160 | 1166 | ||
1167 | gpiochip_remove_pin_ranges(chip); | ||
1161 | of_gpiochip_remove(chip); | 1168 | of_gpiochip_remove(chip); |
1162 | 1169 | ||
1163 | for (id = chip->base; id < chip->base + chip->ngpio; id++) { | 1170 | for (id = chip->base; id < chip->base + chip->ngpio; id++) { |
@@ -1215,6 +1222,77 @@ struct gpio_chip *gpiochip_find(void *data, | |||
1215 | } | 1222 | } |
1216 | EXPORT_SYMBOL_GPL(gpiochip_find); | 1223 | EXPORT_SYMBOL_GPL(gpiochip_find); |
1217 | 1224 | ||
1225 | #ifdef CONFIG_PINCTRL | ||
1226 | |||
1227 | /** | ||
1228 | * gpiochip_add_pin_range() - add a range for GPIO <-> pin mapping | ||
1229 | * @chip: the gpiochip to add the range for | ||
1230 | * @pinctrl_name: the dev_name() of the pin controller to map to | ||
1231 | * @gpio_offset: the start offset in the current gpio_chip number space | ||
1232 | * @pin_offset: the start offset in the pin controller number space | ||
1233 | * @npins: the number of pins from the offset of each pin space (GPIO and | ||
1234 | * pin controller) to accumulate in this range | ||
1235 | */ | ||
1236 | int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, | ||
1237 | unsigned int gpio_offset, unsigned int pin_offset, | ||
1238 | unsigned int npins) | ||
1239 | { | ||
1240 | struct gpio_pin_range *pin_range; | ||
1241 | int ret; | ||
1242 | |||
1243 | pin_range = kzalloc(sizeof(*pin_range), GFP_KERNEL); | ||
1244 | if (!pin_range) { | ||
1245 | pr_err("%s: GPIO chip: failed to allocate pin ranges\n", | ||
1246 | chip->label); | ||
1247 | return -ENOMEM; | ||
1248 | } | ||
1249 | |||
1250 | /* Use local offset as range ID */ | ||
1251 | pin_range->range.id = gpio_offset; | ||
1252 | pin_range->range.gc = chip; | ||
1253 | pin_range->range.name = chip->label; | ||
1254 | pin_range->range.base = chip->base + gpio_offset; | ||
1255 | pin_range->range.pin_base = pin_offset; | ||
1256 | pin_range->range.npins = npins; | ||
1257 | pin_range->pctldev = pinctrl_find_and_add_gpio_range(pinctl_name, | ||
1258 | &pin_range->range); | ||
1259 | if (IS_ERR(pin_range->pctldev)) { | ||
1260 | ret = PTR_ERR(pin_range->pctldev); | ||
1261 | pr_err("%s: GPIO chip: could not create pin range\n", | ||
1262 | chip->label); | ||
1263 | kfree(pin_range); | ||
1264 | return ret; | ||
1265 | } | ||
1266 | pr_debug("GPIO chip %s: created GPIO range %d->%d ==> %s PIN %d->%d\n", | ||
1267 | chip->label, gpio_offset, gpio_offset + npins - 1, | ||
1268 | pinctl_name, | ||
1269 | pin_offset, pin_offset + npins - 1); | ||
1270 | |||
1271 | list_add_tail(&pin_range->node, &chip->pin_ranges); | ||
1272 | |||
1273 | return 0; | ||
1274 | } | ||
1275 | EXPORT_SYMBOL_GPL(gpiochip_add_pin_range); | ||
1276 | |||
1277 | /** | ||
1278 | * gpiochip_remove_pin_ranges() - remove all the GPIO <-> pin mappings | ||
1279 | * @chip: the chip to remove all the mappings for | ||
1280 | */ | ||
1281 | void gpiochip_remove_pin_ranges(struct gpio_chip *chip) | ||
1282 | { | ||
1283 | struct gpio_pin_range *pin_range, *tmp; | ||
1284 | |||
1285 | list_for_each_entry_safe(pin_range, tmp, &chip->pin_ranges, node) { | ||
1286 | list_del(&pin_range->node); | ||
1287 | pinctrl_remove_gpio_range(pin_range->pctldev, | ||
1288 | &pin_range->range); | ||
1289 | kfree(pin_range); | ||
1290 | } | ||
1291 | } | ||
1292 | EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges); | ||
1293 | |||
1294 | #endif /* CONFIG_PINCTRL */ | ||
1295 | |||
1218 | /* These "optional" allocation calls help prevent drivers from stomping | 1296 | /* These "optional" allocation calls help prevent drivers from stomping |
1219 | * on each other, and help provide better diagnostics in debugfs. | 1297 | * on each other, and help provide better diagnostics in debugfs. |
1220 | * They're called even less than the "set direction" calls. | 1298 | * They're called even less than the "set direction" calls. |
@@ -1228,8 +1306,10 @@ int gpio_request(unsigned gpio, const char *label) | |||
1228 | 1306 | ||
1229 | spin_lock_irqsave(&gpio_lock, flags); | 1307 | spin_lock_irqsave(&gpio_lock, flags); |
1230 | 1308 | ||
1231 | if (!gpio_is_valid(gpio)) | 1309 | if (!gpio_is_valid(gpio)) { |
1310 | status = -EINVAL; | ||
1232 | goto done; | 1311 | goto done; |
1312 | } | ||
1233 | desc = &gpio_desc[gpio]; | 1313 | desc = &gpio_desc[gpio]; |
1234 | chip = desc->chip; | 1314 | chip = desc->chip; |
1235 | if (chip == NULL) | 1315 | if (chip == NULL) |