diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index b13b7c7c335f415b6d952fb084250f5c18bfa5e0..e2abf0eabaf880b634b4d5bdfb5c27a9a0be0656 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -153,6 +153,9 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, *flags |= GPIO_OPEN_SOURCE; } + if (of_flags & OF_GPIO_SLEEP_MAY_LOOSE_VALUE) + *flags |= GPIO_SLEEP_MAY_LOOSE_VALUE; + return desc; } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 995ca9cf7dbf8bcbba297d7497c1dd3fcefa2286..c81c42093ff63d32c9d95d6cd39aefb60f45bd49 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -2869,6 +2869,16 @@ bool gpiochip_line_is_open_source(struct gpio_chip *chip, unsigned int offset) } EXPORT_SYMBOL_GPL(gpiochip_line_is_open_source); +bool gpiochip_line_is_persistent(struct gpio_chip *chip, unsigned int offset) +{ + if (offset >= chip->ngpio) + return false; + + return !test_bit(FLAG_SLEEP_MAY_LOOSE_VALUE, + &chip->gpiodev->descs[offset].flags); +} +EXPORT_SYMBOL_GPL(gpiochip_line_is_persistent); + /** * gpiod_get_raw_value_cansleep() - return a gpio's raw value * @desc: gpio whose value will be returned @@ -3225,6 +3235,8 @@ static int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id, set_bit(FLAG_OPEN_DRAIN, &desc->flags); if (lflags & GPIO_OPEN_SOURCE) set_bit(FLAG_OPEN_SOURCE, &desc->flags); + if (lflags & GPIO_SLEEP_MAY_LOOSE_VALUE) + set_bit(FLAG_SLEEP_MAY_LOOSE_VALUE, &desc->flags); /* No particular flag request, return here... */ if (!(dflags & GPIOD_FLAGS_BIT_DIR_SET)) { diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index 2495b7ee1b426969406b60fbb52b8a9fecae6917..f74b8a7632424fb92f81e0106fc3ed1caf2e9c7c 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -190,6 +190,7 @@ struct gpio_desc { #define FLAG_OPEN_SOURCE 8 /* Gpio is open source type */ #define FLAG_USED_AS_IRQ 9 /* GPIO is connected to an IRQ */ #define FLAG_IS_HOGGED 11 /* GPIO is hogged */ +#define FLAG_SLEEP_MAY_LOOSE_VALUE 12 /* GPIO may loose value in sleep */ /* Connection label */ const char *label; diff --git a/include/dt-bindings/gpio/gpio.h b/include/dt-bindings/gpio/gpio.h index b4f54da694eb4a65ecff5a6a34c3ed2db1c088db..c5074584561d9459db81230a9d7081b30189cac8 100644 --- a/include/dt-bindings/gpio/gpio.h +++ b/include/dt-bindings/gpio/gpio.h @@ -28,4 +28,8 @@ #define GPIO_OPEN_DRAIN (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN) #define GPIO_OPEN_SOURCE (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_SOURCE) +/* Bit 3 express GPIO suspend/resume persistence */ +#define GPIO_SLEEP_MAINTAIN_VALUE 0 +#define GPIO_SLEEP_MAY_LOOSE_VALUE 8 + #endif diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 393582867afddb17e2969a659bedcb975f710208..af20369ec8e7b573dec63dcf77346ddd75e4e332 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -213,6 +213,9 @@ bool gpiochip_line_is_irq(struct gpio_chip *chip, unsigned int offset); bool gpiochip_line_is_open_drain(struct gpio_chip *chip, unsigned int offset); bool gpiochip_line_is_open_source(struct gpio_chip *chip, unsigned int offset); +/* Sleep persistence inquiry for drivers */ +bool gpiochip_line_is_persistent(struct gpio_chip *chip, unsigned int offset); + /* get driver data */ void *gpiochip_get_data(struct gpio_chip *chip); diff --git a/include/linux/gpio/machine.h b/include/linux/gpio/machine.h index c0d712d22b079ebc16129ef2618f41762276cf5e..13adadf53c09f3c33da076de181f61e0f16baaa6 100644 --- a/include/linux/gpio/machine.h +++ b/include/linux/gpio/machine.h @@ -9,6 +9,8 @@ enum gpio_lookup_flags { GPIO_ACTIVE_LOW = (1 << 0), GPIO_OPEN_DRAIN = (1 << 1), GPIO_OPEN_SOURCE = (1 << 2), + GPIO_SLEEP_MAINTAIN_VALUE = (0 << 3), + GPIO_SLEEP_MAY_LOOSE_VALUE = (1 << 3), }; /** diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h index 1e089d5a182beb076d9021e41ab9672820dcfb82..ca10f43564deec18de2f03f225b2e479902976f1 100644 --- a/include/linux/of_gpio.h +++ b/include/linux/of_gpio.h @@ -31,6 +31,7 @@ enum of_gpio_flags { OF_GPIO_ACTIVE_LOW = 0x1, OF_GPIO_SINGLE_ENDED = 0x2, OF_GPIO_OPEN_DRAIN = 0x4, + OF_GPIO_SLEEP_MAY_LOOSE_VALUE = 0x8, }; #ifdef CONFIG_OF_GPIO