diff mbox

[2/2] gpiolib: Add and use OF_GPIO_SINGLE_ENDED flag

Message ID 1444684821-17389-3-git-send-email-laurent.pinchart@ideasonboard.com
State New
Headers show

Commit Message

Laurent Pinchart Oct. 12, 2015, 9:20 p.m. UTC
The flag matches the DT GPIO_SINGLE_ENDED flag and allows drivers to
parse and use the DT flag to handle single-ended (open-drain or
open-source) GPIOs.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpio/gpiolib.c  | 20 ++++++++++++++++++--
 include/linux/of_gpio.h |  1 +
 2 files changed, 19 insertions(+), 2 deletions(-)

Comments

Linus Walleij Oct. 16, 2015, 8:52 p.m. UTC | #1
On Mon, Oct 12, 2015 at 11:20 PM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:

> The flag matches the DT GPIO_SINGLE_ENDED flag and allows drivers to
> parse and use the DT flag to handle single-ended (open-drain or
> open-source) GPIOs.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Patch applied!

I feel a bit guilty for fixing the OF docs (with help from Nikolaus Schaller)
and then just leaving it open as an exercise for someone else to implement
it in gpiolib ... hats of for immediately grasping this and implementing it
exactly as it should be!

All of a sudden I now have an influx of GPIO drivers supporting open drain.
I wonder why it happens right now, probably sun spot activity.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index de93fc0a380f..53aa9c80604d 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1709,6 +1709,13 @@  static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
 	if (of_flags & OF_GPIO_ACTIVE_LOW)
 		*flags |= GPIO_ACTIVE_LOW;
 
+	if (of_flags & OF_GPIO_SINGLE_ENDED) {
+		if (of_flags & OF_GPIO_ACTIVE_LOW)
+			*flags |= GPIO_OPEN_DRAIN;
+		else
+			*flags |= GPIO_OPEN_SOURCE;
+	}
+
 	return desc;
 }
 
@@ -2062,6 +2069,7 @@  struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
 {
 	struct gpio_desc *desc = ERR_PTR(-ENODEV);
 	bool active_low = false;
+	bool single_ended = false;
 	int ret;
 
 	if (!fwnode)
@@ -2072,8 +2080,10 @@  struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
 
 		desc = of_get_named_gpiod_flags(to_of_node(fwnode), propname, 0,
 						&flags);
-		if (!IS_ERR(desc))
+		if (!IS_ERR(desc)) {
 			active_low = flags & OF_GPIO_ACTIVE_LOW;
+			single_ended = flags & OF_GPIO_SINGLE_ENDED;
+		}
 	} else if (is_acpi_node(fwnode)) {
 		struct acpi_gpio_info info;
 
@@ -2086,10 +2096,16 @@  struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
 	if (IS_ERR(desc))
 		return desc;
 
-	/* Only value flag can be set from both DT and ACPI is active_low */
 	if (active_low)
 		set_bit(FLAG_ACTIVE_LOW, &desc->flags);
 
+	if (single_ended) {
+		if (active_low)
+			set_bit(FLAG_OPEN_DRAIN, &desc->flags);
+		else
+			set_bit(FLAG_OPEN_SOURCE, &desc->flags);
+	}
+
 	ret = gpiod_request(desc, NULL);
 	if (ret)
 		return ERR_PTR(ret);
diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h
index 69dbe312b11b..e8d662a1b6d1 100644
--- a/include/linux/of_gpio.h
+++ b/include/linux/of_gpio.h
@@ -29,6 +29,7 @@  struct device_node;
  */
 enum of_gpio_flags {
 	OF_GPIO_ACTIVE_LOW = 0x1,
+	OF_GPIO_SINGLE_ENDED = 0x2,
 };
 
 #ifdef CONFIG_OF_GPIO