Skip to content

Commit a770d94

Browse files
rjarzmiklinusw
authored andcommitted
gpio: pxa: add pin control gpio direction and request
If a pin control driver is available, use it to change the gpio direction. If not fallback to directly manipulating the gpio direction register. The reason to use the pin control driver first is that pin control in pxa2xx architecture implies changing the gpio direction, even for non gpio functions. In order to do it atomically, only one driver should control the gpio direction, and if a pin controller is available, it has to be him. There is a small catch : if CONFIG_PINCTRL is selected, then a pinctrl driver has to be probed. If not, gpio_request() will return -EPROBE_DEFER as pinctrl_request_gpio() returns it in that case. Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
1 parent 2f46205 commit a770d94

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

drivers/gpio/gpio-pxa.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <linux/io.h>
2525
#include <linux/of.h>
2626
#include <linux/of_device.h>
27+
#include <linux/pinctrl/consumer.h>
2728
#include <linux/platform_device.h>
2829
#include <linux/syscore_ops.h>
2930
#include <linux/slab.h>
@@ -251,6 +252,11 @@ static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
251252
void __iomem *base = gpio_bank_base(chip, offset);
252253
uint32_t value, mask = GPIO_bit(offset);
253254
unsigned long flags;
255+
int ret;
256+
257+
ret = pinctrl_gpio_direction_input(chip->base + offset);
258+
if (!ret)
259+
return 0;
254260

255261
spin_lock_irqsave(&gpio_lock, flags);
256262

@@ -271,9 +277,14 @@ static int pxa_gpio_direction_output(struct gpio_chip *chip,
271277
void __iomem *base = gpio_bank_base(chip, offset);
272278
uint32_t tmp, mask = GPIO_bit(offset);
273279
unsigned long flags;
280+
int ret;
274281

275282
writel_relaxed(mask, base + (value ? GPSR_OFFSET : GPCR_OFFSET));
276283

284+
ret = pinctrl_gpio_direction_output(chip->base + offset);
285+
if (!ret)
286+
return 0;
287+
277288
spin_lock_irqsave(&gpio_lock, flags);
278289

279290
tmp = readl_relaxed(base + GPDR_OFFSET);
@@ -318,6 +329,16 @@ static int pxa_gpio_of_xlate(struct gpio_chip *gc,
318329
}
319330
#endif
320331

332+
static int pxa_gpio_request(struct gpio_chip *chip, unsigned int offset)
333+
{
334+
return pinctrl_request_gpio(chip->base + offset);
335+
}
336+
337+
static void pxa_gpio_free(struct gpio_chip *chip, unsigned int offset)
338+
{
339+
pinctrl_free_gpio(chip->base + offset);
340+
}
341+
321342
static int pxa_init_gpio_chip(struct pxa_gpio_chip *pchip, int ngpio,
322343
struct device_node *np, void __iomem *regbase)
323344
{
@@ -336,6 +357,8 @@ static int pxa_init_gpio_chip(struct pxa_gpio_chip *pchip, int ngpio,
336357
pchip->chip.set = pxa_gpio_set;
337358
pchip->chip.to_irq = pxa_gpio_to_irq;
338359
pchip->chip.ngpio = ngpio;
360+
pchip->chip.request = pxa_gpio_request;
361+
pchip->chip.free = pxa_gpio_free;
339362
#ifdef CONFIG_OF_GPIO
340363
pchip->chip.of_node = np;
341364
pchip->chip.of_xlate = pxa_gpio_of_xlate;

0 commit comments

Comments
 (0)