203 lines
6.7 KiB
Diff
203 lines
6.7 KiB
Diff
From fc0e7f3b161868a6ab3e40938cb820ef23d223f6 Mon Sep 17 00:00:00 2001
|
|
From: Romuald JEANNE <romuald.jeanne@st.com>
|
|
Date: Tue, 17 Sep 2019 14:27:05 +0200
|
|
Subject: [PATCH 07/30] ARM stm32mp1 r2 GPIO
|
|
|
|
---
|
|
drivers/gpio/gpiolib-of.c | 5 +++++
|
|
drivers/gpio/gpiolib.c | 50 ++++++++++++++++++++++++++++-------------
|
|
drivers/gpio/gpiolib.h | 2 ++
|
|
include/dt-bindings/gpio/gpio.h | 6 +++++
|
|
include/linux/gpio/machine.h | 2 ++
|
|
include/linux/of_gpio.h | 2 ++
|
|
6 files changed, 51 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
|
|
index e0f149b..a8cba78 100644
|
|
--- a/drivers/gpio/gpiolib-of.c
|
|
+++ b/drivers/gpio/gpiolib-of.c
|
|
@@ -281,6 +281,11 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
|
|
if (of_flags & OF_GPIO_TRANSITORY)
|
|
*flags |= GPIO_TRANSITORY;
|
|
|
|
+ if (of_flags & OF_GPIO_PULL_UP)
|
|
+ *flags |= GPIO_PULL_UP;
|
|
+ if (of_flags & OF_GPIO_PULL_DOWN)
|
|
+ *flags |= GPIO_PULL_DOWN;
|
|
+
|
|
return desc;
|
|
}
|
|
|
|
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
|
|
index fd713326..af5d0e6 100644
|
|
--- a/drivers/gpio/gpiolib.c
|
|
+++ b/drivers/gpio/gpiolib.c
|
|
@@ -2519,6 +2519,14 @@ EXPORT_SYMBOL_GPL(gpiochip_free_own_desc);
|
|
* rely on gpio_request() having been called beforehand.
|
|
*/
|
|
|
|
+static int gpio_set_config(struct gpio_chip *gc, unsigned offset,
|
|
+ enum pin_config_param mode)
|
|
+{
|
|
+ unsigned long config = { PIN_CONF_PACKED(mode, 0) };
|
|
+
|
|
+ return gc->set_config ? gc->set_config(gc, offset, config) : -ENOTSUPP;
|
|
+}
|
|
+
|
|
/**
|
|
* gpiod_direction_input - set the GPIO direction to input
|
|
* @desc: GPIO to set to input
|
|
@@ -2547,20 +2555,19 @@ int gpiod_direction_input(struct gpio_desc *desc)
|
|
if (status == 0)
|
|
clear_bit(FLAG_IS_OUT, &desc->flags);
|
|
|
|
+ if (test_bit(FLAG_PULL_UP, &desc->flags))
|
|
+ gpio_set_config(chip, gpio_chip_hwgpio(desc),
|
|
+ PIN_CONFIG_BIAS_PULL_UP);
|
|
+ else if (test_bit(FLAG_PULL_DOWN, &desc->flags))
|
|
+ gpio_set_config(chip, gpio_chip_hwgpio(desc),
|
|
+ PIN_CONFIG_BIAS_PULL_DOWN);
|
|
+
|
|
trace_gpio_direction(desc_to_gpio(desc), 1, status);
|
|
|
|
return status;
|
|
}
|
|
EXPORT_SYMBOL_GPL(gpiod_direction_input);
|
|
|
|
-static int gpio_set_drive_single_ended(struct gpio_chip *gc, unsigned offset,
|
|
- enum pin_config_param mode)
|
|
-{
|
|
- unsigned long config = { PIN_CONF_PACKED(mode, 0) };
|
|
-
|
|
- return gc->set_config ? gc->set_config(gc, offset, config) : -ENOTSUPP;
|
|
-}
|
|
-
|
|
static int gpiod_direction_output_raw_commit(struct gpio_desc *desc, int value)
|
|
{
|
|
struct gpio_chip *gc = desc->gdev->chip;
|
|
@@ -2634,8 +2641,8 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
|
|
gc = desc->gdev->chip;
|
|
if (test_bit(FLAG_OPEN_DRAIN, &desc->flags)) {
|
|
/* First see if we can enable open drain in hardware */
|
|
- ret = gpio_set_drive_single_ended(gc, gpio_chip_hwgpio(desc),
|
|
- PIN_CONFIG_DRIVE_OPEN_DRAIN);
|
|
+ ret = gpio_set_config(gc, gpio_chip_hwgpio(desc),
|
|
+ PIN_CONFIG_DRIVE_OPEN_DRAIN);
|
|
if (!ret)
|
|
goto set_output_value;
|
|
/* Emulate open drain by not actively driving the line high */
|
|
@@ -2643,16 +2650,16 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
|
|
return gpiod_direction_input(desc);
|
|
}
|
|
else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) {
|
|
- ret = gpio_set_drive_single_ended(gc, gpio_chip_hwgpio(desc),
|
|
- PIN_CONFIG_DRIVE_OPEN_SOURCE);
|
|
+ ret = gpio_set_config(gc, gpio_chip_hwgpio(desc),
|
|
+ PIN_CONFIG_DRIVE_OPEN_SOURCE);
|
|
if (!ret)
|
|
goto set_output_value;
|
|
/* Emulate open source by not actively driving the line low */
|
|
if (!value)
|
|
return gpiod_direction_input(desc);
|
|
} else {
|
|
- gpio_set_drive_single_ended(gc, gpio_chip_hwgpio(desc),
|
|
- PIN_CONFIG_DRIVE_PUSH_PULL);
|
|
+ gpio_set_config(gc, gpio_chip_hwgpio(desc),
|
|
+ PIN_CONFIG_DRIVE_PUSH_PULL);
|
|
}
|
|
|
|
set_output_value:
|
|
@@ -2684,7 +2691,7 @@ int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce)
|
|
}
|
|
|
|
config = pinconf_to_config_packed(PIN_CONFIG_INPUT_DEBOUNCE, debounce);
|
|
- return chip->set_config(chip, gpio_chip_hwgpio(desc), config);
|
|
+ return gpio_set_config(chip, gpio_chip_hwgpio(desc), config);
|
|
}
|
|
EXPORT_SYMBOL_GPL(gpiod_set_debounce);
|
|
|
|
@@ -2721,7 +2728,7 @@ int gpiod_set_transitory(struct gpio_desc *desc, bool transitory)
|
|
packed = pinconf_to_config_packed(PIN_CONFIG_PERSIST_STATE,
|
|
!transitory);
|
|
gpio = gpio_chip_hwgpio(desc);
|
|
- rc = chip->set_config(chip, gpio, packed);
|
|
+ rc = gpio_set_config(chip, gpio, packed);
|
|
if (rc == -ENOTSUPP) {
|
|
dev_dbg(&desc->gdev->dev, "Persistence not supported for GPIO %d\n",
|
|
gpio);
|
|
@@ -3858,6 +3865,17 @@ int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
|
|
if (lflags & GPIO_OPEN_SOURCE)
|
|
set_bit(FLAG_OPEN_SOURCE, &desc->flags);
|
|
|
|
+ if ((lflags & GPIO_PULL_UP) && (lflags & GPIO_PULL_DOWN)) {
|
|
+ gpiod_err(desc,
|
|
+ "both pull-up and pull-down enabled, invalid configuration\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ if (lflags & GPIO_PULL_UP)
|
|
+ set_bit(FLAG_PULL_UP, &desc->flags);
|
|
+ else if (lflags & GPIO_PULL_DOWN)
|
|
+ set_bit(FLAG_PULL_DOWN, &desc->flags);
|
|
+
|
|
status = gpiod_set_transitory(desc, (lflags & GPIO_TRANSITORY));
|
|
if (status < 0)
|
|
return status;
|
|
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
|
|
index a7e49fef..34d2650 100644
|
|
--- a/drivers/gpio/gpiolib.h
|
|
+++ b/drivers/gpio/gpiolib.h
|
|
@@ -216,6 +216,8 @@ struct gpio_desc {
|
|
#define FLAG_USED_AS_IRQ 9 /* GPIO is connected to an IRQ */
|
|
#define FLAG_IS_HOGGED 11 /* GPIO is hogged */
|
|
#define FLAG_TRANSITORY 12 /* GPIO may lose value in sleep or reset */
|
|
+#define FLAG_PULL_UP 13 /* GPIO has pull up enabled */
|
|
+#define FLAG_PULL_DOWN 14 /* GPIO has pull down enabled */
|
|
|
|
/* Connection label */
|
|
const char *label;
|
|
diff --git a/include/dt-bindings/gpio/gpio.h b/include/dt-bindings/gpio/gpio.h
|
|
index 2cc10ae..c029467 100644
|
|
--- a/include/dt-bindings/gpio/gpio.h
|
|
+++ b/include/dt-bindings/gpio/gpio.h
|
|
@@ -33,4 +33,10 @@
|
|
#define GPIO_PERSISTENT 0
|
|
#define GPIO_TRANSITORY 8
|
|
|
|
+/* Bit 4 express pull up */
|
|
+#define GPIO_PULL_UP 16
|
|
+
|
|
+/* Bit 5 express pull down */
|
|
+#define GPIO_PULL_DOWN 32
|
|
+
|
|
#endif
|
|
diff --git a/include/linux/gpio/machine.h b/include/linux/gpio/machine.h
|
|
index daa44ea..69673be 100644
|
|
--- a/include/linux/gpio/machine.h
|
|
+++ b/include/linux/gpio/machine.h
|
|
@@ -12,6 +12,8 @@ enum gpio_lookup_flags {
|
|
GPIO_OPEN_SOURCE = (1 << 2),
|
|
GPIO_PERSISTENT = (0 << 3),
|
|
GPIO_TRANSITORY = (1 << 3),
|
|
+ GPIO_PULL_UP = (1 << 4),
|
|
+ GPIO_PULL_DOWN = (1 << 5),
|
|
};
|
|
|
|
/**
|
|
diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h
|
|
index 163b79e..f9737de 100644
|
|
--- a/include/linux/of_gpio.h
|
|
+++ b/include/linux/of_gpio.h
|
|
@@ -28,6 +28,8 @@ enum of_gpio_flags {
|
|
OF_GPIO_SINGLE_ENDED = 0x2,
|
|
OF_GPIO_OPEN_DRAIN = 0x4,
|
|
OF_GPIO_TRANSITORY = 0x8,
|
|
+ OF_GPIO_PULL_UP = 0x10,
|
|
+ OF_GPIO_PULL_DOWN = 0x20,
|
|
};
|
|
|
|
#ifdef CONFIG_OF_GPIO
|
|
--
|
|
2.7.4
|
|
|