* [RFC] gpiolib: import gpio_request_array() from linux 3.7 @ 2013-02-03 19:16 Antony Pavlov 2013-02-03 21:13 ` Jean-Christophe PLAGNIOL-VILLARD 0 siblings, 1 reply; 10+ messages in thread From: Antony Pavlov @ 2013-02-03 19:16 UTC (permalink / raw) To: barebox Also import related functions gpio_request_one() and gpio_free_array(). Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> --- drivers/gpio/gpio.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/gpio.h | 43 +++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) diff --git a/drivers/gpio/gpio.c b/drivers/gpio/gpio.c index d37f5a0..631168d 100644 --- a/drivers/gpio/gpio.c +++ b/drivers/gpio/gpio.c @@ -65,6 +65,72 @@ void gpio_free(unsigned gpio) free(gi->label); } +/** + * gpio_request_one - request a single GPIO with initial configuration + * @gpio: the GPIO number + * @flags: GPIO configuration as specified by GPIOF_* + * @label: a literal description string of this GPIO + */ +int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) +{ + int err; + + err = gpio_request(gpio, label); + if (err) + return err; + + if (flags & GPIOF_DIR_IN) + err = gpio_direction_input(gpio); + else + err = gpio_direction_output(gpio, + (flags & GPIOF_INIT_HIGH) ? 1 : 0); + + if (err) + goto free_gpio; + + return 0; + +free_gpio: + gpio_free(gpio); + return err; +} +EXPORT_SYMBOL(gpio_request_one); + +/** + * gpio_request_array - request multiple GPIOs in a single call + * @array: array of the 'struct gpio' + * @num: how many GPIOs in the array + */ +int gpio_request_array(const struct gpio *array, size_t num) +{ + int i, err; + + for (i = 0; i < num; i++, array++) { + err = gpio_request_one(array->gpio, array->flags, array->label); + if (err) + goto err_free; + } + return 0; + +err_free: + while (i--) + gpio_free((--array)->gpio); + return err; +} +EXPORT_SYMBOL(gpio_request_array); + +/** + * gpio_free_array - release multiple GPIOs in a single call + * @array: array of the 'struct gpio' + * @num: how many GPIOs in the array + */ +void gpio_free_array(const struct gpio *array, size_t num) +{ + while (num--) + gpio_free((array++)->gpio); +} +EXPORT_SYMBOL(gpio_free_array); + void gpio_set_value(unsigned gpio, int value) { struct gpio_info *gi = &gpio_desc[gpio]; diff --git a/include/gpio.h b/include/gpio.h index eedb980..37c151d 100644 --- a/include/gpio.h +++ b/include/gpio.h @@ -3,6 +3,29 @@ #include <asm/gpio.h> +/* make these flag values available regardless of GPIO kconfig options */ +#define GPIOF_DIR_OUT (0 << 0) +#define GPIOF_DIR_IN (1 << 0) + +#define GPIOF_INIT_LOW (0 << 1) +#define GPIOF_INIT_HIGH (1 << 1) + +#define GPIOF_IN (GPIOF_DIR_IN) +#define GPIOF_OUT_INIT_LOW (GPIOF_DIR_OUT | GPIOF_INIT_LOW) +#define GPIOF_OUT_INIT_HIGH (GPIOF_DIR_OUT | GPIOF_INIT_HIGH) + +/** + * struct gpio - a structure describing a GPIO with configuration + * @gpio: the GPIO number + * @flags: GPIO configuration as specified by GPIOF_* + * @label: a literal description string of this GPIO + */ +struct gpio { + unsigned gpio; + unsigned long flags; + const char *label; +}; + #ifndef CONFIG_GPIOLIB static inline int gpio_request(unsigned gpio, const char *label) { @@ -12,9 +35,29 @@ static inline int gpio_request(unsigned gpio, const char *label) static inline void gpio_free(unsigned gpio) { } + +static inline int gpio_request_one(unsigned gpio, + unsigned long flags, const char *label) +{ + return 0; +} + +static inline int gpio_request_array(const struct gpio *array, size_t num) +{ + return 0; +} + +static inline void gpio_free_array(const struct gpio *array, size_t num) +{ + /* GPIO can never have been requested */ + WARN_ON(1); +} #else int gpio_request(unsigned gpio, const char *label); void gpio_free(unsigned gpio); +int gpio_request_one(unsigned gpio, unsigned long flags, const char *label); +int gpio_request_array(const struct gpio *array, size_t num); +void gpio_free_array(const struct gpio *array, size_t num); #endif struct gpio_chip; -- 1.7.10.4 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC] gpiolib: import gpio_request_array() from linux 3.7 2013-02-03 19:16 [RFC] gpiolib: import gpio_request_array() from linux 3.7 Antony Pavlov @ 2013-02-03 21:13 ` Jean-Christophe PLAGNIOL-VILLARD 2013-02-03 21:22 ` Antony Pavlov 0 siblings, 1 reply; 10+ messages in thread From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-02-03 21:13 UTC (permalink / raw) To: Antony Pavlov; +Cc: barebox On 23:16 Sun 03 Feb , Antony Pavlov wrote: > Also import related functions gpio_request_one() and > gpio_free_array(). > > Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> > --- > drivers/gpio/gpio.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ > include/gpio.h | 43 +++++++++++++++++++++++++++++++++ > 2 files changed, 109 insertions(+) > > diff --git a/drivers/gpio/gpio.c b/drivers/gpio/gpio.c > index d37f5a0..631168d 100644 > --- a/drivers/gpio/gpio.c > +++ b/drivers/gpio/gpio.c > @@ -65,6 +65,72 @@ void gpio_free(unsigned gpio) > free(gi->label); > } > > +/** > + * gpio_request_one - request a single GPIO with initial configuration > + * @gpio: the GPIO number > + * @flags: GPIO configuration as specified by GPIOF_* > + * @label: a literal description string of this GPIO > + */ > +int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) > +{ > + int err; > + > + err = gpio_request(gpio, label); > + if (err) > + return err; > + > + if (flags & GPIOF_DIR_IN) > + err = gpio_direction_input(gpio); > + else > + err = gpio_direction_output(gpio, > + (flags & GPIOF_INIT_HIGH) ? 1 : 0); > + > + if (err) > + goto free_gpio; > + > + return 0; > + > +free_gpio: > + gpio_free(gpio); > + return err; > +} > +EXPORT_SYMBOL(gpio_request_one); > + > +/** > + * gpio_request_array - request multiple GPIOs in a single call > + * @array: array of the 'struct gpio' > + * @num: how many GPIOs in the array > + */ > +int gpio_request_array(const struct gpio *array, size_t num) > +{ > + int i, err; > + > + for (i = 0; i < num; i++, array++) { > + err = gpio_request_one(array->gpio, array->flags, array->label); > + if (err) > + goto err_free; > + } > + return 0; > + > +err_free: > + while (i--) > + gpio_free((--array)->gpio); > + return err; > +} > +EXPORT_SYMBOL(gpio_request_array); > + > +/** > + * gpio_free_array - release multiple GPIOs in a single call > + * @array: array of the 'struct gpio' > + * @num: how many GPIOs in the array > + */ > +void gpio_free_array(const struct gpio *array, size_t num) > +{ > + while (num--) > + gpio_free((array++)->gpio); > +} > +EXPORT_SYMBOL(gpio_free_array); > + > void gpio_set_value(unsigned gpio, int value) > { > struct gpio_info *gi = &gpio_desc[gpio]; > diff --git a/include/gpio.h b/include/gpio.h > index eedb980..37c151d 100644 > --- a/include/gpio.h > +++ b/include/gpio.h > @@ -3,6 +3,29 @@ > > #include <asm/gpio.h> > > +/* make these flag values available regardless of GPIO kconfig options */ > +#define GPIOF_DIR_OUT (0 << 0) > +#define GPIOF_DIR_IN (1 << 0) > + > +#define GPIOF_INIT_LOW (0 << 1) > +#define GPIOF_INIT_HIGH (1 << 1) > + > +#define GPIOF_IN (GPIOF_DIR_IN) > +#define GPIOF_OUT_INIT_LOW (GPIOF_DIR_OUT | GPIOF_INIT_LOW) > +#define GPIOF_OUT_INIT_HIGH (GPIOF_DIR_OUT | GPIOF_INIT_HIGH) > + > +/** > + * struct gpio - a structure describing a GPIO with configuration > + * @gpio: the GPIO number > + * @flags: GPIO configuration as specified by GPIOF_* > + * @label: a literal description string of this GPIO > + */ > +struct gpio { > + unsigned gpio; > + unsigned long flags; > + const char *label; > +}; > + > #ifndef CONFIG_GPIOLIB > static inline int gpio_request(unsigned gpio, const char *label) > { > @@ -12,9 +35,29 @@ static inline int gpio_request(unsigned gpio, const char *label) > static inline void gpio_free(unsigned gpio) > { > } > + > +static inline int gpio_request_one(unsigned gpio, > + unsigned long flags, const char *label) > +{ > + return 0; > +} > + > +static inline int gpio_request_array(const struct gpio *array, size_t num) > +{ > + return 0; > +} you can not do this as if we start to use this in generic driver where gpio_direction_input/output work we will endup with no configuration so you need to provide working inline instead > + > +static inline void gpio_free_array(const struct gpio *array, size_t num) > +{ > + /* GPIO can never have been requested */ > + WARN_ON(1); > +} > #else > int gpio_request(unsigned gpio, const char *label); > void gpio_free(unsigned gpio); > +int gpio_request_one(unsigned gpio, unsigned long flags, const char *label); > +int gpio_request_array(const struct gpio *array, size_t num); > +void gpio_free_array(const struct gpio *array, size_t num); > #endif > > struct gpio_chip; > -- > 1.7.10.4 > > > _______________________________________________ > barebox mailing list > barebox@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/barebox _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC] gpiolib: import gpio_request_array() from linux 3.7 2013-02-03 21:13 ` Jean-Christophe PLAGNIOL-VILLARD @ 2013-02-03 21:22 ` Antony Pavlov 2013-02-04 8:37 ` Sascha Hauer 0 siblings, 1 reply; 10+ messages in thread From: Antony Pavlov @ 2013-02-03 21:22 UTC (permalink / raw) To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox On 4 February 2013 01:13, Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> wrote: > On 23:16 Sun 03 Feb , Antony Pavlov wrote: >> Also import related functions gpio_request_one() and >> gpio_free_array(). >> >> Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> >> --- >> drivers/gpio/gpio.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ >> include/gpio.h | 43 +++++++++++++++++++++++++++++++++ >> 2 files changed, 109 insertions(+) >> >> diff --git a/drivers/gpio/gpio.c b/drivers/gpio/gpio.c >> index d37f5a0..631168d 100644 >> --- a/drivers/gpio/gpio.c >> +++ b/drivers/gpio/gpio.c >> @@ -65,6 +65,72 @@ void gpio_free(unsigned gpio) >> free(gi->label); >> } >> >> +/** >> + * gpio_request_one - request a single GPIO with initial configuration >> + * @gpio: the GPIO number >> + * @flags: GPIO configuration as specified by GPIOF_* >> + * @label: a literal description string of this GPIO >> + */ >> +int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) >> +{ >> + int err; >> + >> + err = gpio_request(gpio, label); >> + if (err) >> + return err; >> + >> + if (flags & GPIOF_DIR_IN) >> + err = gpio_direction_input(gpio); >> + else >> + err = gpio_direction_output(gpio, >> + (flags & GPIOF_INIT_HIGH) ? 1 : 0); >> + >> + if (err) >> + goto free_gpio; >> + >> + return 0; >> + >> +free_gpio: >> + gpio_free(gpio); >> + return err; >> +} >> +EXPORT_SYMBOL(gpio_request_one); >> + >> +/** >> + * gpio_request_array - request multiple GPIOs in a single call >> + * @array: array of the 'struct gpio' >> + * @num: how many GPIOs in the array >> + */ >> +int gpio_request_array(const struct gpio *array, size_t num) >> +{ >> + int i, err; >> + >> + for (i = 0; i < num; i++, array++) { >> + err = gpio_request_one(array->gpio, array->flags, array->label); >> + if (err) >> + goto err_free; >> + } >> + return 0; >> + >> +err_free: >> + while (i--) >> + gpio_free((--array)->gpio); >> + return err; >> +} >> +EXPORT_SYMBOL(gpio_request_array); >> + >> +/** >> + * gpio_free_array - release multiple GPIOs in a single call >> + * @array: array of the 'struct gpio' >> + * @num: how many GPIOs in the array >> + */ >> +void gpio_free_array(const struct gpio *array, size_t num) >> +{ >> + while (num--) >> + gpio_free((array++)->gpio); >> +} >> +EXPORT_SYMBOL(gpio_free_array); >> + >> void gpio_set_value(unsigned gpio, int value) >> { >> struct gpio_info *gi = &gpio_desc[gpio]; >> diff --git a/include/gpio.h b/include/gpio.h >> index eedb980..37c151d 100644 >> --- a/include/gpio.h >> +++ b/include/gpio.h >> @@ -3,6 +3,29 @@ >> >> #include <asm/gpio.h> >> >> +/* make these flag values available regardless of GPIO kconfig options */ >> +#define GPIOF_DIR_OUT (0 << 0) >> +#define GPIOF_DIR_IN (1 << 0) >> + >> +#define GPIOF_INIT_LOW (0 << 1) >> +#define GPIOF_INIT_HIGH (1 << 1) >> + >> +#define GPIOF_IN (GPIOF_DIR_IN) >> +#define GPIOF_OUT_INIT_LOW (GPIOF_DIR_OUT | GPIOF_INIT_LOW) >> +#define GPIOF_OUT_INIT_HIGH (GPIOF_DIR_OUT | GPIOF_INIT_HIGH) >> + >> +/** >> + * struct gpio - a structure describing a GPIO with configuration >> + * @gpio: the GPIO number >> + * @flags: GPIO configuration as specified by GPIOF_* >> + * @label: a literal description string of this GPIO >> + */ >> +struct gpio { >> + unsigned gpio; >> + unsigned long flags; >> + const char *label; >> +}; >> + >> #ifndef CONFIG_GPIOLIB >> static inline int gpio_request(unsigned gpio, const char *label) >> { >> @@ -12,9 +35,29 @@ static inline int gpio_request(unsigned gpio, const char *label) >> static inline void gpio_free(unsigned gpio) >> { >> } >> + >> +static inline int gpio_request_one(unsigned gpio, >> + unsigned long flags, const char *label) >> +{ >> + return 0; >> +} >> + >> +static inline int gpio_request_array(const struct gpio *array, size_t num) >> +{ >> + return 0; >> +} > you can not do this > > as if we start to use this in generic driver where gpio_direction_input/output > work > > we will endup with no configuration But now in include/gpio.h we have this: static inline int gpio_request(unsigned gpio, const char *label) { return 0; } Can you explain the difference? > so you need to provide working inline instead >> + >> +static inline void gpio_free_array(const struct gpio *array, size_t num) >> +{ >> + /* GPIO can never have been requested */ >> + WARN_ON(1); >> +} >> #else >> int gpio_request(unsigned gpio, const char *label); >> void gpio_free(unsigned gpio); >> +int gpio_request_one(unsigned gpio, unsigned long flags, const char *label); >> +int gpio_request_array(const struct gpio *array, size_t num); >> +void gpio_free_array(const struct gpio *array, size_t num); >> #endif >> >> struct gpio_chip; >> -- >> 1.7.10.4 >> >> >> _______________________________________________ >> barebox mailing list >> barebox@lists.infradead.org >> http://lists.infradead.org/mailman/listinfo/barebox -- Best regards, Antony Pavlov _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC] gpiolib: import gpio_request_array() from linux 3.7 2013-02-03 21:22 ` Antony Pavlov @ 2013-02-04 8:37 ` Sascha Hauer 2013-02-05 6:10 ` Antony Pavlov 0 siblings, 1 reply; 10+ messages in thread From: Sascha Hauer @ 2013-02-04 8:37 UTC (permalink / raw) To: Antony Pavlov; +Cc: barebox On Mon, Feb 04, 2013 at 01:22:39AM +0400, Antony Pavlov wrote: > On 4 February 2013 01:13, Jean-Christophe PLAGNIOL-VILLARD > <plagnioj@jcrosoft.com> wrote: > > On 23:16 Sun 03 Feb , Antony Pavlov wrote: > >> Also import related functions gpio_request_one() and > >> gpio_free_array(). > >> > >> Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> > >> --- > >> drivers/gpio/gpio.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ > >> include/gpio.h | 43 +++++++++++++++++++++++++++++++++ > >> 2 files changed, 109 insertions(+) > >> > >> diff --git a/drivers/gpio/gpio.c b/drivers/gpio/gpio.c > >> index d37f5a0..631168d 100644 > >> --- a/drivers/gpio/gpio.c > >> +++ b/drivers/gpio/gpio.c > >> @@ -65,6 +65,72 @@ void gpio_free(unsigned gpio) > >> free(gi->label); > >> } > >> > >> +/** > >> + * gpio_request_one - request a single GPIO with initial configuration > >> + * @gpio: the GPIO number > >> + * @flags: GPIO configuration as specified by GPIOF_* > >> + * @label: a literal description string of this GPIO > >> + */ > >> +int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) > >> +{ > >> + int err; > >> + > >> + err = gpio_request(gpio, label); > >> + if (err) > >> + return err; > >> + > >> + if (flags & GPIOF_DIR_IN) > >> + err = gpio_direction_input(gpio); > >> + else > >> + err = gpio_direction_output(gpio, > >> + (flags & GPIOF_INIT_HIGH) ? 1 : 0); > >> + > >> + if (err) > >> + goto free_gpio; > >> + > >> + return 0; > >> + > >> +free_gpio: > >> + gpio_free(gpio); > >> + return err; > >> +} > >> +EXPORT_SYMBOL(gpio_request_one); > >> + > >> +/** > >> + * gpio_request_array - request multiple GPIOs in a single call > >> + * @array: array of the 'struct gpio' > >> + * @num: how many GPIOs in the array > >> + */ > >> +int gpio_request_array(const struct gpio *array, size_t num) > >> +{ > >> + int i, err; > >> + > >> + for (i = 0; i < num; i++, array++) { > >> + err = gpio_request_one(array->gpio, array->flags, array->label); > >> + if (err) > >> + goto err_free; > >> + } > >> + return 0; > >> + > >> +err_free: > >> + while (i--) > >> + gpio_free((--array)->gpio); > >> + return err; > >> +} > >> +EXPORT_SYMBOL(gpio_request_array); > >> + > >> +/** > >> + * gpio_free_array - release multiple GPIOs in a single call > >> + * @array: array of the 'struct gpio' > >> + * @num: how many GPIOs in the array > >> + */ > >> +void gpio_free_array(const struct gpio *array, size_t num) > >> +{ > >> + while (num--) > >> + gpio_free((array++)->gpio); > >> +} > >> +EXPORT_SYMBOL(gpio_free_array); > >> + > >> void gpio_set_value(unsigned gpio, int value) > >> { > >> struct gpio_info *gi = &gpio_desc[gpio]; > >> diff --git a/include/gpio.h b/include/gpio.h > >> index eedb980..37c151d 100644 > >> --- a/include/gpio.h > >> +++ b/include/gpio.h > >> @@ -3,6 +3,29 @@ > >> > >> #include <asm/gpio.h> > >> > >> +/* make these flag values available regardless of GPIO kconfig options */ > >> +#define GPIOF_DIR_OUT (0 << 0) > >> +#define GPIOF_DIR_IN (1 << 0) > >> + > >> +#define GPIOF_INIT_LOW (0 << 1) > >> +#define GPIOF_INIT_HIGH (1 << 1) > >> + > >> +#define GPIOF_IN (GPIOF_DIR_IN) > >> +#define GPIOF_OUT_INIT_LOW (GPIOF_DIR_OUT | GPIOF_INIT_LOW) > >> +#define GPIOF_OUT_INIT_HIGH (GPIOF_DIR_OUT | GPIOF_INIT_HIGH) > >> + > >> +/** > >> + * struct gpio - a structure describing a GPIO with configuration > >> + * @gpio: the GPIO number > >> + * @flags: GPIO configuration as specified by GPIOF_* > >> + * @label: a literal description string of this GPIO > >> + */ > >> +struct gpio { > >> + unsigned gpio; > >> + unsigned long flags; > >> + const char *label; > >> +}; > >> + > >> #ifndef CONFIG_GPIOLIB > >> static inline int gpio_request(unsigned gpio, const char *label) > >> { > >> @@ -12,9 +35,29 @@ static inline int gpio_request(unsigned gpio, const char *label) > >> static inline void gpio_free(unsigned gpio) > >> { > >> } > >> + > >> +static inline int gpio_request_one(unsigned gpio, > >> + unsigned long flags, const char *label) > >> +{ > >> + return 0; > >> +} > >> + > >> +static inline int gpio_request_array(const struct gpio *array, size_t num) > >> +{ > >> + return 0; > >> +} > > you can not do this > > > > as if we start to use this in generic driver where gpio_direction_input/output > > work > > > > we will endup with no configuration > > But now in include/gpio.h we have this: > > static inline int gpio_request(unsigned gpio, const char *label) > { > return 0; > } > > Can you explain the difference? gpio_request is not implemented without gpiolib, still you have to configure the direction and value. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC] gpiolib: import gpio_request_array() from linux 3.7 2013-02-04 8:37 ` Sascha Hauer @ 2013-02-05 6:10 ` Antony Pavlov 2013-02-05 9:29 ` Sascha Hauer 0 siblings, 1 reply; 10+ messages in thread From: Antony Pavlov @ 2013-02-05 6:10 UTC (permalink / raw) To: Sascha Hauer; +Cc: barebox On 4 February 2013 12:37, Sascha Hauer <s.hauer@pengutronix.de> wrote: > On Mon, Feb 04, 2013 at 01:22:39AM +0400, Antony Pavlov wrote: >> On 4 February 2013 01:13, Jean-Christophe PLAGNIOL-VILLARD >> <plagnioj@jcrosoft.com> wrote: >> > On 23:16 Sun 03 Feb , Antony Pavlov wrote: >> >> Also import related functions gpio_request_one() and >> >> gpio_free_array(). >> >> >> >> Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> >> >> --- >> >> drivers/gpio/gpio.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ >> >> include/gpio.h | 43 +++++++++++++++++++++++++++++++++ >> >> 2 files changed, 109 insertions(+) >> >> >> >> diff --git a/drivers/gpio/gpio.c b/drivers/gpio/gpio.c >> >> index d37f5a0..631168d 100644 >> >> --- a/drivers/gpio/gpio.c >> >> +++ b/drivers/gpio/gpio.c >> >> @@ -65,6 +65,72 @@ void gpio_free(unsigned gpio) >> >> free(gi->label); >> >> } >> >> >> >> +/** >> >> + * gpio_request_one - request a single GPIO with initial configuration >> >> + * @gpio: the GPIO number >> >> + * @flags: GPIO configuration as specified by GPIOF_* >> >> + * @label: a literal description string of this GPIO >> >> + */ >> >> +int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) >> >> +{ >> >> + int err; >> >> + >> >> + err = gpio_request(gpio, label); >> >> + if (err) >> >> + return err; >> >> + >> >> + if (flags & GPIOF_DIR_IN) >> >> + err = gpio_direction_input(gpio); >> >> + else >> >> + err = gpio_direction_output(gpio, >> >> + (flags & GPIOF_INIT_HIGH) ? 1 : 0); >> >> + >> >> + if (err) >> >> + goto free_gpio; >> >> + >> >> + return 0; >> >> + >> >> +free_gpio: >> >> + gpio_free(gpio); >> >> + return err; >> >> +} >> >> +EXPORT_SYMBOL(gpio_request_one); >> >> + >> >> +/** >> >> + * gpio_request_array - request multiple GPIOs in a single call >> >> + * @array: array of the 'struct gpio' >> >> + * @num: how many GPIOs in the array >> >> + */ >> >> +int gpio_request_array(const struct gpio *array, size_t num) >> >> +{ >> >> + int i, err; >> >> + >> >> + for (i = 0; i < num; i++, array++) { >> >> + err = gpio_request_one(array->gpio, array->flags, array->label); >> >> + if (err) >> >> + goto err_free; >> >> + } >> >> + return 0; >> >> + >> >> +err_free: >> >> + while (i--) >> >> + gpio_free((--array)->gpio); >> >> + return err; >> >> +} >> >> +EXPORT_SYMBOL(gpio_request_array); >> >> + >> >> +/** >> >> + * gpio_free_array - release multiple GPIOs in a single call >> >> + * @array: array of the 'struct gpio' >> >> + * @num: how many GPIOs in the array >> >> + */ >> >> +void gpio_free_array(const struct gpio *array, size_t num) >> >> +{ >> >> + while (num--) >> >> + gpio_free((array++)->gpio); >> >> +} >> >> +EXPORT_SYMBOL(gpio_free_array); >> >> + >> >> void gpio_set_value(unsigned gpio, int value) >> >> { >> >> struct gpio_info *gi = &gpio_desc[gpio]; >> >> diff --git a/include/gpio.h b/include/gpio.h >> >> index eedb980..37c151d 100644 >> >> --- a/include/gpio.h >> >> +++ b/include/gpio.h >> >> @@ -3,6 +3,29 @@ >> >> >> >> #include <asm/gpio.h> >> >> >> >> +/* make these flag values available regardless of GPIO kconfig options */ >> >> +#define GPIOF_DIR_OUT (0 << 0) >> >> +#define GPIOF_DIR_IN (1 << 0) >> >> + >> >> +#define GPIOF_INIT_LOW (0 << 1) >> >> +#define GPIOF_INIT_HIGH (1 << 1) >> >> + >> >> +#define GPIOF_IN (GPIOF_DIR_IN) >> >> +#define GPIOF_OUT_INIT_LOW (GPIOF_DIR_OUT | GPIOF_INIT_LOW) >> >> +#define GPIOF_OUT_INIT_HIGH (GPIOF_DIR_OUT | GPIOF_INIT_HIGH) >> >> + >> >> +/** >> >> + * struct gpio - a structure describing a GPIO with configuration >> >> + * @gpio: the GPIO number >> >> + * @flags: GPIO configuration as specified by GPIOF_* >> >> + * @label: a literal description string of this GPIO >> >> + */ >> >> +struct gpio { >> >> + unsigned gpio; >> >> + unsigned long flags; >> >> + const char *label; >> >> +}; >> >> + >> >> #ifndef CONFIG_GPIOLIB >> >> static inline int gpio_request(unsigned gpio, const char *label) >> >> { >> >> @@ -12,9 +35,29 @@ static inline int gpio_request(unsigned gpio, const char *label) >> >> static inline void gpio_free(unsigned gpio) >> >> { >> >> } >> >> + >> >> +static inline int gpio_request_one(unsigned gpio, >> >> + unsigned long flags, const char *label) >> >> +{ >> >> + return 0; >> >> +} >> >> + >> >> +static inline int gpio_request_array(const struct gpio *array, size_t num) >> >> +{ >> >> + return 0; >> >> +} >> > you can not do this >> > >> > as if we start to use this in generic driver where gpio_direction_input/output >> > work >> > >> > we will endup with no configuration >> >> But now in include/gpio.h we have this: >> >> static inline int gpio_request(unsigned gpio, const char *label) >> { >> return 0; >> } >> >> Can you explain the difference? > > gpio_request is not implemented without gpiolib, still you have to > configure the direction and value. Can we use this functions only if gpiolib is enabled? Can we skip the function's definiton in the non-gpio situation? -- Best regards, Antony Pavlov _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC] gpiolib: import gpio_request_array() from linux 3.7 2013-02-05 6:10 ` Antony Pavlov @ 2013-02-05 9:29 ` Sascha Hauer 2013-02-05 10:19 ` Jean-Christophe PLAGNIOL-VILLARD 0 siblings, 1 reply; 10+ messages in thread From: Sascha Hauer @ 2013-02-05 9:29 UTC (permalink / raw) To: Antony Pavlov; +Cc: barebox On Tue, Feb 05, 2013 at 10:10:18AM +0400, Antony Pavlov wrote: > On 4 February 2013 12:37, Sascha Hauer <s.hauer@pengutronix.de> wrote: > > On Mon, Feb 04, 2013 at 01:22:39AM +0400, Antony Pavlov wrote: > >> On 4 February 2013 01:13, Jean-Christophe PLAGNIOL-VILLARD > >> <plagnioj@jcrosoft.com> wrote: > >> > On 23:16 Sun 03 Feb , Antony Pavlov wrote: > >> >> Also import related functions gpio_request_one() and > >> >> gpio_free_array(). > >> >> > >> >> Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> > >> >> --- > >> >> drivers/gpio/gpio.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ > >> >> include/gpio.h | 43 +++++++++++++++++++++++++++++++++ > >> >> 2 files changed, 109 insertions(+) > >> >> > >> >> diff --git a/drivers/gpio/gpio.c b/drivers/gpio/gpio.c > >> >> index d37f5a0..631168d 100644 > >> >> --- a/drivers/gpio/gpio.c > >> >> +++ b/drivers/gpio/gpio.c > >> >> @@ -65,6 +65,72 @@ void gpio_free(unsigned gpio) > >> >> free(gi->label); > >> >> } > >> >> > >> >> +/** > >> >> + * gpio_request_one - request a single GPIO with initial configuration > >> >> + * @gpio: the GPIO number > >> >> + * @flags: GPIO configuration as specified by GPIOF_* > >> >> + * @label: a literal description string of this GPIO > >> >> + */ > >> >> +int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) > >> >> +{ > >> >> + int err; > >> >> + > >> >> + err = gpio_request(gpio, label); > >> >> + if (err) > >> >> + return err; > >> >> + > >> >> + if (flags & GPIOF_DIR_IN) > >> >> + err = gpio_direction_input(gpio); > >> >> + else > >> >> + err = gpio_direction_output(gpio, > >> >> + (flags & GPIOF_INIT_HIGH) ? 1 : 0); > >> >> + > >> >> + if (err) > >> >> + goto free_gpio; > >> >> + > >> >> + return 0; > >> >> + > >> >> +free_gpio: > >> >> + gpio_free(gpio); > >> >> + return err; > >> >> +} > >> >> +EXPORT_SYMBOL(gpio_request_one); > >> >> + > >> >> +/** > >> >> + * gpio_request_array - request multiple GPIOs in a single call > >> >> + * @array: array of the 'struct gpio' > >> >> + * @num: how many GPIOs in the array > >> >> + */ > >> >> +int gpio_request_array(const struct gpio *array, size_t num) > >> >> +{ > >> >> + int i, err; > >> >> + > >> >> + for (i = 0; i < num; i++, array++) { > >> >> + err = gpio_request_one(array->gpio, array->flags, array->label); > >> >> + if (err) > >> >> + goto err_free; > >> >> + } > >> >> + return 0; > >> >> + > >> >> +err_free: > >> >> + while (i--) > >> >> + gpio_free((--array)->gpio); > >> >> + return err; > >> >> +} > >> >> +EXPORT_SYMBOL(gpio_request_array); > >> >> + > >> >> +/** > >> >> + * gpio_free_array - release multiple GPIOs in a single call > >> >> + * @array: array of the 'struct gpio' > >> >> + * @num: how many GPIOs in the array > >> >> + */ > >> >> +void gpio_free_array(const struct gpio *array, size_t num) > >> >> +{ > >> >> + while (num--) > >> >> + gpio_free((array++)->gpio); > >> >> +} > >> >> +EXPORT_SYMBOL(gpio_free_array); > >> >> + > >> >> void gpio_set_value(unsigned gpio, int value) > >> >> { > >> >> struct gpio_info *gi = &gpio_desc[gpio]; > >> >> diff --git a/include/gpio.h b/include/gpio.h > >> >> index eedb980..37c151d 100644 > >> >> --- a/include/gpio.h > >> >> +++ b/include/gpio.h > >> >> @@ -3,6 +3,29 @@ > >> >> > >> >> #include <asm/gpio.h> > >> >> > >> >> +/* make these flag values available regardless of GPIO kconfig options */ > >> >> +#define GPIOF_DIR_OUT (0 << 0) > >> >> +#define GPIOF_DIR_IN (1 << 0) > >> >> + > >> >> +#define GPIOF_INIT_LOW (0 << 1) > >> >> +#define GPIOF_INIT_HIGH (1 << 1) > >> >> + > >> >> +#define GPIOF_IN (GPIOF_DIR_IN) > >> >> +#define GPIOF_OUT_INIT_LOW (GPIOF_DIR_OUT | GPIOF_INIT_LOW) > >> >> +#define GPIOF_OUT_INIT_HIGH (GPIOF_DIR_OUT | GPIOF_INIT_HIGH) > >> >> + > >> >> +/** > >> >> + * struct gpio - a structure describing a GPIO with configuration > >> >> + * @gpio: the GPIO number > >> >> + * @flags: GPIO configuration as specified by GPIOF_* > >> >> + * @label: a literal description string of this GPIO > >> >> + */ > >> >> +struct gpio { > >> >> + unsigned gpio; > >> >> + unsigned long flags; > >> >> + const char *label; > >> >> +}; > >> >> + > >> >> #ifndef CONFIG_GPIOLIB > >> >> static inline int gpio_request(unsigned gpio, const char *label) > >> >> { > >> >> @@ -12,9 +35,29 @@ static inline int gpio_request(unsigned gpio, const char *label) > >> >> static inline void gpio_free(unsigned gpio) > >> >> { > >> >> } > >> >> + > >> >> +static inline int gpio_request_one(unsigned gpio, > >> >> + unsigned long flags, const char *label) > >> >> +{ > >> >> + return 0; > >> >> +} > >> >> + > >> >> +static inline int gpio_request_array(const struct gpio *array, size_t num) > >> >> +{ > >> >> + return 0; > >> >> +} > >> > you can not do this > >> > > >> > as if we start to use this in generic driver where gpio_direction_input/output > >> > work > >> > > >> > we will endup with no configuration > >> > >> But now in include/gpio.h we have this: > >> > >> static inline int gpio_request(unsigned gpio, const char *label) > >> { > >> return 0; > >> } > >> > >> Can you explain the difference? > > > > gpio_request is not implemented without gpiolib, still you have to > > configure the direction and value. > > Can we use this functions only if gpiolib is enabled? > Can we skip the function's definiton in the non-gpio situation? Sounds fine. We should get rid of the !gpiolib drivers anyway, maybe this adds some motivation. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC] gpiolib: import gpio_request_array() from linux 3.7 2013-02-05 9:29 ` Sascha Hauer @ 2013-02-05 10:19 ` Jean-Christophe PLAGNIOL-VILLARD 2013-02-05 11:02 ` Antony Pavlov 0 siblings, 1 reply; 10+ messages in thread From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-02-05 10:19 UTC (permalink / raw) To: Sascha Hauer; +Cc: barebox On 10:29 Tue 05 Feb , Sascha Hauer wrote: > On Tue, Feb 05, 2013 at 10:10:18AM +0400, Antony Pavlov wrote: > > On 4 February 2013 12:37, Sascha Hauer <s.hauer@pengutronix.de> wrote: > > > On Mon, Feb 04, 2013 at 01:22:39AM +0400, Antony Pavlov wrote: > > >> On 4 February 2013 01:13, Jean-Christophe PLAGNIOL-VILLARD > > >> <plagnioj@jcrosoft.com> wrote: > > >> > On 23:16 Sun 03 Feb , Antony Pavlov wrote: > > >> >> Also import related functions gpio_request_one() and > > >> >> gpio_free_array(). > > >> >> > > >> >> Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> > > >> >> --- > > >> >> drivers/gpio/gpio.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ > > >> >> include/gpio.h | 43 +++++++++++++++++++++++++++++++++ > > >> >> 2 files changed, 109 insertions(+) > > >> >> > > >> >> diff --git a/drivers/gpio/gpio.c b/drivers/gpio/gpio.c > > >> >> index d37f5a0..631168d 100644 > > >> >> --- a/drivers/gpio/gpio.c > > >> >> +++ b/drivers/gpio/gpio.c > > >> >> @@ -65,6 +65,72 @@ void gpio_free(unsigned gpio) > > >> >> free(gi->label); > > >> >> } > > >> >> > > >> >> +/** > > >> >> + * gpio_request_one - request a single GPIO with initial configuration > > >> >> + * @gpio: the GPIO number > > >> >> + * @flags: GPIO configuration as specified by GPIOF_* > > >> >> + * @label: a literal description string of this GPIO > > >> >> + */ > > >> >> +int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) > > >> >> +{ > > >> >> + int err; > > >> >> + > > >> >> + err = gpio_request(gpio, label); > > >> >> + if (err) > > >> >> + return err; > > >> >> + > > >> >> + if (flags & GPIOF_DIR_IN) > > >> >> + err = gpio_direction_input(gpio); > > >> >> + else > > >> >> + err = gpio_direction_output(gpio, > > >> >> + (flags & GPIOF_INIT_HIGH) ? 1 : 0); > > >> >> + > > >> >> + if (err) > > >> >> + goto free_gpio; > > >> >> + > > >> >> + return 0; > > >> >> + > > >> >> +free_gpio: > > >> >> + gpio_free(gpio); > > >> >> + return err; > > >> >> +} > > >> >> +EXPORT_SYMBOL(gpio_request_one); > > >> >> + > > >> >> +/** > > >> >> + * gpio_request_array - request multiple GPIOs in a single call > > >> >> + * @array: array of the 'struct gpio' > > >> >> + * @num: how many GPIOs in the array > > >> >> + */ > > >> >> +int gpio_request_array(const struct gpio *array, size_t num) > > >> >> +{ > > >> >> + int i, err; > > >> >> + > > >> >> + for (i = 0; i < num; i++, array++) { > > >> >> + err = gpio_request_one(array->gpio, array->flags, array->label); > > >> >> + if (err) > > >> >> + goto err_free; > > >> >> + } > > >> >> + return 0; > > >> >> + > > >> >> +err_free: > > >> >> + while (i--) > > >> >> + gpio_free((--array)->gpio); > > >> >> + return err; > > >> >> +} > > >> >> +EXPORT_SYMBOL(gpio_request_array); > > >> >> + > > >> >> +/** > > >> >> + * gpio_free_array - release multiple GPIOs in a single call > > >> >> + * @array: array of the 'struct gpio' > > >> >> + * @num: how many GPIOs in the array > > >> >> + */ > > >> >> +void gpio_free_array(const struct gpio *array, size_t num) > > >> >> +{ > > >> >> + while (num--) > > >> >> + gpio_free((array++)->gpio); > > >> >> +} > > >> >> +EXPORT_SYMBOL(gpio_free_array); > > >> >> + > > >> >> void gpio_set_value(unsigned gpio, int value) > > >> >> { > > >> >> struct gpio_info *gi = &gpio_desc[gpio]; > > >> >> diff --git a/include/gpio.h b/include/gpio.h > > >> >> index eedb980..37c151d 100644 > > >> >> --- a/include/gpio.h > > >> >> +++ b/include/gpio.h > > >> >> @@ -3,6 +3,29 @@ > > >> >> > > >> >> #include <asm/gpio.h> > > >> >> > > >> >> +/* make these flag values available regardless of GPIO kconfig options */ > > >> >> +#define GPIOF_DIR_OUT (0 << 0) > > >> >> +#define GPIOF_DIR_IN (1 << 0) > > >> >> + > > >> >> +#define GPIOF_INIT_LOW (0 << 1) > > >> >> +#define GPIOF_INIT_HIGH (1 << 1) > > >> >> + > > >> >> +#define GPIOF_IN (GPIOF_DIR_IN) > > >> >> +#define GPIOF_OUT_INIT_LOW (GPIOF_DIR_OUT | GPIOF_INIT_LOW) > > >> >> +#define GPIOF_OUT_INIT_HIGH (GPIOF_DIR_OUT | GPIOF_INIT_HIGH) > > >> >> + > > >> >> +/** > > >> >> + * struct gpio - a structure describing a GPIO with configuration > > >> >> + * @gpio: the GPIO number > > >> >> + * @flags: GPIO configuration as specified by GPIOF_* > > >> >> + * @label: a literal description string of this GPIO > > >> >> + */ > > >> >> +struct gpio { > > >> >> + unsigned gpio; > > >> >> + unsigned long flags; > > >> >> + const char *label; > > >> >> +}; > > >> >> + > > >> >> #ifndef CONFIG_GPIOLIB > > >> >> static inline int gpio_request(unsigned gpio, const char *label) > > >> >> { > > >> >> @@ -12,9 +35,29 @@ static inline int gpio_request(unsigned gpio, const char *label) > > >> >> static inline void gpio_free(unsigned gpio) > > >> >> { > > >> >> } > > >> >> + > > >> >> +static inline int gpio_request_one(unsigned gpio, > > >> >> + unsigned long flags, const char *label) > > >> >> +{ > > >> >> + return 0; > > >> >> +} > > >> >> + > > >> >> +static inline int gpio_request_array(const struct gpio *array, size_t num) > > >> >> +{ > > >> >> + return 0; > > >> >> +} > > >> > you can not do this > > >> > > > >> > as if we start to use this in generic driver where gpio_direction_input/output > > >> > work > > >> > > > >> > we will endup with no configuration > > >> > > >> But now in include/gpio.h we have this: > > >> > > >> static inline int gpio_request(unsigned gpio, const char *label) > > >> { > > >> return 0; > > >> } > > >> > > >> Can you explain the difference? > > > > > > gpio_request is not implemented without gpiolib, still you have to > > > configure the direction and value. > > > > Can we use this functions only if gpiolib is enabled? > > Can we skip the function's definiton in the non-gpio situation? > > Sounds fine. We should get rid of the !gpiolib drivers anyway, maybe > this adds some motivation. until every driver are swith to gpiolib NACK as if we switch any generic driver to this as leds, gpio-keys, i2c-gpio etc... we break board support siliently Best Regards, J. > > Sascha > > -- > Pengutronix e.K. | | > Industrial Linux Solutions | http://www.pengutronix.de/ | > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | > Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC] gpiolib: import gpio_request_array() from linux 3.7 2013-02-05 10:19 ` Jean-Christophe PLAGNIOL-VILLARD @ 2013-02-05 11:02 ` Antony Pavlov 2013-02-06 18:02 ` Antony Pavlov 2013-02-06 19:31 ` Sascha Hauer 0 siblings, 2 replies; 10+ messages in thread From: Antony Pavlov @ 2013-02-05 11:02 UTC (permalink / raw) To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox On 5 February 2013 14:19, Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> wrote: > On 10:29 Tue 05 Feb , Sascha Hauer wrote: >> On Tue, Feb 05, 2013 at 10:10:18AM +0400, Antony Pavlov wrote: >> > On 4 February 2013 12:37, Sascha Hauer <s.hauer@pengutronix.de> wrote: >> > > On Mon, Feb 04, 2013 at 01:22:39AM +0400, Antony Pavlov wrote: >> > >> On 4 February 2013 01:13, Jean-Christophe PLAGNIOL-VILLARD >> > >> <plagnioj@jcrosoft.com> wrote: >> > >> > On 23:16 Sun 03 Feb , Antony Pavlov wrote: >> > >> >> Also import related functions gpio_request_one() and >> > >> >> gpio_free_array(). >> > >> >> >> > >> >> Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> >> > >> >> --- >> > >> >> drivers/gpio/gpio.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ >> > >> >> include/gpio.h | 43 +++++++++++++++++++++++++++++++++ >> > >> >> 2 files changed, 109 insertions(+) >> > >> >> >> > >> >> diff --git a/drivers/gpio/gpio.c b/drivers/gpio/gpio.c >> > >> >> index d37f5a0..631168d 100644 >> > >> >> --- a/drivers/gpio/gpio.c >> > >> >> +++ b/drivers/gpio/gpio.c >> > >> >> @@ -65,6 +65,72 @@ void gpio_free(unsigned gpio) >> > >> >> free(gi->label); >> > >> >> } >> > >> >> >> > >> >> +/** >> > >> >> + * gpio_request_one - request a single GPIO with initial configuration >> > >> >> + * @gpio: the GPIO number >> > >> >> + * @flags: GPIO configuration as specified by GPIOF_* >> > >> >> + * @label: a literal description string of this GPIO >> > >> >> + */ >> > >> >> +int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) >> > >> >> +{ >> > >> >> + int err; >> > >> >> + >> > >> >> + err = gpio_request(gpio, label); >> > >> >> + if (err) >> > >> >> + return err; >> > >> >> + >> > >> >> + if (flags & GPIOF_DIR_IN) >> > >> >> + err = gpio_direction_input(gpio); >> > >> >> + else >> > >> >> + err = gpio_direction_output(gpio, >> > >> >> + (flags & GPIOF_INIT_HIGH) ? 1 : 0); >> > >> >> + >> > >> >> + if (err) >> > >> >> + goto free_gpio; >> > >> >> + >> > >> >> + return 0; >> > >> >> + >> > >> >> +free_gpio: >> > >> >> + gpio_free(gpio); >> > >> >> + return err; >> > >> >> +} >> > >> >> +EXPORT_SYMBOL(gpio_request_one); >> > >> >> + >> > >> >> +/** >> > >> >> + * gpio_request_array - request multiple GPIOs in a single call >> > >> >> + * @array: array of the 'struct gpio' >> > >> >> + * @num: how many GPIOs in the array >> > >> >> + */ >> > >> >> +int gpio_request_array(const struct gpio *array, size_t num) >> > >> >> +{ >> > >> >> + int i, err; >> > >> >> + >> > >> >> + for (i = 0; i < num; i++, array++) { >> > >> >> + err = gpio_request_one(array->gpio, array->flags, array->label); >> > >> >> + if (err) >> > >> >> + goto err_free; >> > >> >> + } >> > >> >> + return 0; >> > >> >> + >> > >> >> +err_free: >> > >> >> + while (i--) >> > >> >> + gpio_free((--array)->gpio); >> > >> >> + return err; >> > >> >> +} >> > >> >> +EXPORT_SYMBOL(gpio_request_array); >> > >> >> + >> > >> >> +/** >> > >> >> + * gpio_free_array - release multiple GPIOs in a single call >> > >> >> + * @array: array of the 'struct gpio' >> > >> >> + * @num: how many GPIOs in the array >> > >> >> + */ >> > >> >> +void gpio_free_array(const struct gpio *array, size_t num) >> > >> >> +{ >> > >> >> + while (num--) >> > >> >> + gpio_free((array++)->gpio); >> > >> >> +} >> > >> >> +EXPORT_SYMBOL(gpio_free_array); >> > >> >> + >> > >> >> void gpio_set_value(unsigned gpio, int value) >> > >> >> { >> > >> >> struct gpio_info *gi = &gpio_desc[gpio]; >> > >> >> diff --git a/include/gpio.h b/include/gpio.h >> > >> >> index eedb980..37c151d 100644 >> > >> >> --- a/include/gpio.h >> > >> >> +++ b/include/gpio.h >> > >> >> @@ -3,6 +3,29 @@ >> > >> >> >> > >> >> #include <asm/gpio.h> >> > >> >> >> > >> >> +/* make these flag values available regardless of GPIO kconfig options */ >> > >> >> +#define GPIOF_DIR_OUT (0 << 0) >> > >> >> +#define GPIOF_DIR_IN (1 << 0) >> > >> >> + >> > >> >> +#define GPIOF_INIT_LOW (0 << 1) >> > >> >> +#define GPIOF_INIT_HIGH (1 << 1) >> > >> >> + >> > >> >> +#define GPIOF_IN (GPIOF_DIR_IN) >> > >> >> +#define GPIOF_OUT_INIT_LOW (GPIOF_DIR_OUT | GPIOF_INIT_LOW) >> > >> >> +#define GPIOF_OUT_INIT_HIGH (GPIOF_DIR_OUT | GPIOF_INIT_HIGH) >> > >> >> + >> > >> >> +/** >> > >> >> + * struct gpio - a structure describing a GPIO with configuration >> > >> >> + * @gpio: the GPIO number >> > >> >> + * @flags: GPIO configuration as specified by GPIOF_* >> > >> >> + * @label: a literal description string of this GPIO >> > >> >> + */ >> > >> >> +struct gpio { >> > >> >> + unsigned gpio; >> > >> >> + unsigned long flags; >> > >> >> + const char *label; >> > >> >> +}; >> > >> >> + >> > >> >> #ifndef CONFIG_GPIOLIB >> > >> >> static inline int gpio_request(unsigned gpio, const char *label) >> > >> >> { >> > >> >> @@ -12,9 +35,29 @@ static inline int gpio_request(unsigned gpio, const char *label) >> > >> >> static inline void gpio_free(unsigned gpio) >> > >> >> { >> > >> >> } >> > >> >> + >> > >> >> +static inline int gpio_request_one(unsigned gpio, >> > >> >> + unsigned long flags, const char *label) >> > >> >> +{ >> > >> >> + return 0; >> > >> >> +} >> > >> >> + >> > >> >> +static inline int gpio_request_array(const struct gpio *array, size_t num) >> > >> >> +{ >> > >> >> + return 0; >> > >> >> +} >> > >> > you can not do this >> > >> > >> > >> > as if we start to use this in generic driver where gpio_direction_input/output >> > >> > work >> > >> > >> > >> > we will endup with no configuration >> > >> >> > >> But now in include/gpio.h we have this: >> > >> >> > >> static inline int gpio_request(unsigned gpio, const char *label) >> > >> { >> > >> return 0; >> > >> } >> > >> >> > >> Can you explain the difference? >> > > >> > > gpio_request is not implemented without gpiolib, still you have to >> > > configure the direction and value. >> > >> > Can we use this functions only if gpiolib is enabled? >> > Can we skip the function's definiton in the non-gpio situation? >> >> Sounds fine. We should get rid of the !gpiolib drivers anyway, maybe >> this adds some motivation. > > until every driver are swith to gpiolib NACK as if we switch any generic > driver to this as leds, gpio-keys, i2c-gpio etc... we break board support > siliently but leds, gpio-keys, i2c-gpio etc don't use gpio_request_one()-related functions. If we ristrict the usage of gpio_request_one()-related functions (use it only in board code for gpiolib-enabled machines) we can avoid mentioned problems. -- Best regards, Antony Pavlov _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC] gpiolib: import gpio_request_array() from linux 3.7 2013-02-05 11:02 ` Antony Pavlov @ 2013-02-06 18:02 ` Antony Pavlov 2013-02-06 19:31 ` Sascha Hauer 1 sibling, 0 replies; 10+ messages in thread From: Antony Pavlov @ 2013-02-06 18:02 UTC (permalink / raw) To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox ping On 5 February 2013 15:02, Antony Pavlov <antonynpavlov@gmail.com> wrote: > On 5 February 2013 14:19, Jean-Christophe PLAGNIOL-VILLARD > <plagnioj@jcrosoft.com> wrote: >> On 10:29 Tue 05 Feb , Sascha Hauer wrote: >>> On Tue, Feb 05, 2013 at 10:10:18AM +0400, Antony Pavlov wrote: >>> > On 4 February 2013 12:37, Sascha Hauer <s.hauer@pengutronix.de> wrote: >>> > > On Mon, Feb 04, 2013 at 01:22:39AM +0400, Antony Pavlov wrote: >>> > >> On 4 February 2013 01:13, Jean-Christophe PLAGNIOL-VILLARD >>> > >> <plagnioj@jcrosoft.com> wrote: >>> > >> > On 23:16 Sun 03 Feb , Antony Pavlov wrote: >>> > >> >> Also import related functions gpio_request_one() and >>> > >> >> gpio_free_array(). >>> > >> >> >>> > >> >> Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> >>> > >> >> --- >>> > >> >> drivers/gpio/gpio.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ >>> > >> >> include/gpio.h | 43 +++++++++++++++++++++++++++++++++ >>> > >> >> 2 files changed, 109 insertions(+) >>> > >> >> >>> > >> >> diff --git a/drivers/gpio/gpio.c b/drivers/gpio/gpio.c >>> > >> >> index d37f5a0..631168d 100644 >>> > >> >> --- a/drivers/gpio/gpio.c >>> > >> >> +++ b/drivers/gpio/gpio.c >>> > >> >> @@ -65,6 +65,72 @@ void gpio_free(unsigned gpio) >>> > >> >> free(gi->label); >>> > >> >> } >>> > >> >> >>> > >> >> +/** >>> > >> >> + * gpio_request_one - request a single GPIO with initial configuration >>> > >> >> + * @gpio: the GPIO number >>> > >> >> + * @flags: GPIO configuration as specified by GPIOF_* >>> > >> >> + * @label: a literal description string of this GPIO >>> > >> >> + */ >>> > >> >> +int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) >>> > >> >> +{ >>> > >> >> + int err; >>> > >> >> + >>> > >> >> + err = gpio_request(gpio, label); >>> > >> >> + if (err) >>> > >> >> + return err; >>> > >> >> + >>> > >> >> + if (flags & GPIOF_DIR_IN) >>> > >> >> + err = gpio_direction_input(gpio); >>> > >> >> + else >>> > >> >> + err = gpio_direction_output(gpio, >>> > >> >> + (flags & GPIOF_INIT_HIGH) ? 1 : 0); >>> > >> >> + >>> > >> >> + if (err) >>> > >> >> + goto free_gpio; >>> > >> >> + >>> > >> >> + return 0; >>> > >> >> + >>> > >> >> +free_gpio: >>> > >> >> + gpio_free(gpio); >>> > >> >> + return err; >>> > >> >> +} >>> > >> >> +EXPORT_SYMBOL(gpio_request_one); >>> > >> >> + >>> > >> >> +/** >>> > >> >> + * gpio_request_array - request multiple GPIOs in a single call >>> > >> >> + * @array: array of the 'struct gpio' >>> > >> >> + * @num: how many GPIOs in the array >>> > >> >> + */ >>> > >> >> +int gpio_request_array(const struct gpio *array, size_t num) >>> > >> >> +{ >>> > >> >> + int i, err; >>> > >> >> + >>> > >> >> + for (i = 0; i < num; i++, array++) { >>> > >> >> + err = gpio_request_one(array->gpio, array->flags, array->label); >>> > >> >> + if (err) >>> > >> >> + goto err_free; >>> > >> >> + } >>> > >> >> + return 0; >>> > >> >> + >>> > >> >> +err_free: >>> > >> >> + while (i--) >>> > >> >> + gpio_free((--array)->gpio); >>> > >> >> + return err; >>> > >> >> +} >>> > >> >> +EXPORT_SYMBOL(gpio_request_array); >>> > >> >> + >>> > >> >> +/** >>> > >> >> + * gpio_free_array - release multiple GPIOs in a single call >>> > >> >> + * @array: array of the 'struct gpio' >>> > >> >> + * @num: how many GPIOs in the array >>> > >> >> + */ >>> > >> >> +void gpio_free_array(const struct gpio *array, size_t num) >>> > >> >> +{ >>> > >> >> + while (num--) >>> > >> >> + gpio_free((array++)->gpio); >>> > >> >> +} >>> > >> >> +EXPORT_SYMBOL(gpio_free_array); >>> > >> >> + >>> > >> >> void gpio_set_value(unsigned gpio, int value) >>> > >> >> { >>> > >> >> struct gpio_info *gi = &gpio_desc[gpio]; >>> > >> >> diff --git a/include/gpio.h b/include/gpio.h >>> > >> >> index eedb980..37c151d 100644 >>> > >> >> --- a/include/gpio.h >>> > >> >> +++ b/include/gpio.h >>> > >> >> @@ -3,6 +3,29 @@ >>> > >> >> >>> > >> >> #include <asm/gpio.h> >>> > >> >> >>> > >> >> +/* make these flag values available regardless of GPIO kconfig options */ >>> > >> >> +#define GPIOF_DIR_OUT (0 << 0) >>> > >> >> +#define GPIOF_DIR_IN (1 << 0) >>> > >> >> + >>> > >> >> +#define GPIOF_INIT_LOW (0 << 1) >>> > >> >> +#define GPIOF_INIT_HIGH (1 << 1) >>> > >> >> + >>> > >> >> +#define GPIOF_IN (GPIOF_DIR_IN) >>> > >> >> +#define GPIOF_OUT_INIT_LOW (GPIOF_DIR_OUT | GPIOF_INIT_LOW) >>> > >> >> +#define GPIOF_OUT_INIT_HIGH (GPIOF_DIR_OUT | GPIOF_INIT_HIGH) >>> > >> >> + >>> > >> >> +/** >>> > >> >> + * struct gpio - a structure describing a GPIO with configuration >>> > >> >> + * @gpio: the GPIO number >>> > >> >> + * @flags: GPIO configuration as specified by GPIOF_* >>> > >> >> + * @label: a literal description string of this GPIO >>> > >> >> + */ >>> > >> >> +struct gpio { >>> > >> >> + unsigned gpio; >>> > >> >> + unsigned long flags; >>> > >> >> + const char *label; >>> > >> >> +}; >>> > >> >> + >>> > >> >> #ifndef CONFIG_GPIOLIB >>> > >> >> static inline int gpio_request(unsigned gpio, const char *label) >>> > >> >> { >>> > >> >> @@ -12,9 +35,29 @@ static inline int gpio_request(unsigned gpio, const char *label) >>> > >> >> static inline void gpio_free(unsigned gpio) >>> > >> >> { >>> > >> >> } >>> > >> >> + >>> > >> >> +static inline int gpio_request_one(unsigned gpio, >>> > >> >> + unsigned long flags, const char *label) >>> > >> >> +{ >>> > >> >> + return 0; >>> > >> >> +} >>> > >> >> + >>> > >> >> +static inline int gpio_request_array(const struct gpio *array, size_t num) >>> > >> >> +{ >>> > >> >> + return 0; >>> > >> >> +} >>> > >> > you can not do this >>> > >> > >>> > >> > as if we start to use this in generic driver where gpio_direction_input/output >>> > >> > work >>> > >> > >>> > >> > we will endup with no configuration >>> > >> >>> > >> But now in include/gpio.h we have this: >>> > >> >>> > >> static inline int gpio_request(unsigned gpio, const char *label) >>> > >> { >>> > >> return 0; >>> > >> } >>> > >> >>> > >> Can you explain the difference? >>> > > >>> > > gpio_request is not implemented without gpiolib, still you have to >>> > > configure the direction and value. >>> > >>> > Can we use this functions only if gpiolib is enabled? >>> > Can we skip the function's definiton in the non-gpio situation? >>> >>> Sounds fine. We should get rid of the !gpiolib drivers anyway, maybe >>> this adds some motivation. >> >> until every driver are swith to gpiolib NACK as if we switch any generic >> driver to this as leds, gpio-keys, i2c-gpio etc... we break board support >> siliently > > but leds, gpio-keys, i2c-gpio etc don't use > gpio_request_one()-related functions. > If we ristrict the usage of gpio_request_one()-related functions (use > it only in board code for gpiolib-enabled machines) > we can avoid mentioned problems. > > -- > Best regards, > Antony Pavlov -- Best regards, Antony Pavlov _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC] gpiolib: import gpio_request_array() from linux 3.7 2013-02-05 11:02 ` Antony Pavlov 2013-02-06 18:02 ` Antony Pavlov @ 2013-02-06 19:31 ` Sascha Hauer 1 sibling, 0 replies; 10+ messages in thread From: Sascha Hauer @ 2013-02-06 19:31 UTC (permalink / raw) To: Antony Pavlov; +Cc: barebox On Tue, Feb 05, 2013 at 03:02:54PM +0400, Antony Pavlov wrote: > On 5 February 2013 14:19, Jean-Christophe PLAGNIOL-VILLARD > <plagnioj@jcrosoft.com> wrote: > > On 10:29 Tue 05 Feb , Sascha Hauer wrote: > >> On Tue, Feb 05, 2013 at 10:10:18AM +0400, Antony Pavlov wrote: > >> > On 4 February 2013 12:37, Sascha Hauer <s.hauer@pengutronix.de> wrote: > >> > > On Mon, Feb 04, 2013 at 01:22:39AM +0400, Antony Pavlov wrote: > >> > >> On 4 February 2013 01:13, Jean-Christophe PLAGNIOL-VILLARD > >> > >> <plagnioj@jcrosoft.com> wrote: > >> > >> > On 23:16 Sun 03 Feb , Antony Pavlov wrote: > >> > >> >> Also import related functions gpio_request_one() and > >> > >> >> gpio_free_array(). > >> > >> >> > >> > >> >> Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> > >> > >> >> --- > >> > >> >> drivers/gpio/gpio.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ > >> > >> >> include/gpio.h | 43 +++++++++++++++++++++++++++++++++ > >> > >> >> 2 files changed, 109 insertions(+) > >> > >> >> > >> > >> >> diff --git a/drivers/gpio/gpio.c b/drivers/gpio/gpio.c > >> > >> >> index d37f5a0..631168d 100644 > >> > >> >> --- a/drivers/gpio/gpio.c > >> > >> >> +++ b/drivers/gpio/gpio.c > >> > >> >> @@ -65,6 +65,72 @@ void gpio_free(unsigned gpio) > >> > >> >> free(gi->label); > >> > >> >> } > >> > >> >> > >> > >> >> +/** > >> > >> >> + * gpio_request_one - request a single GPIO with initial configuration > >> > >> >> + * @gpio: the GPIO number > >> > >> >> + * @flags: GPIO configuration as specified by GPIOF_* > >> > >> >> + * @label: a literal description string of this GPIO > >> > >> >> + */ > >> > >> >> +int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) > >> > >> >> +{ > >> > >> >> + int err; > >> > >> >> + > >> > >> >> + err = gpio_request(gpio, label); > >> > >> >> + if (err) > >> > >> >> + return err; > >> > >> >> + > >> > >> >> + if (flags & GPIOF_DIR_IN) > >> > >> >> + err = gpio_direction_input(gpio); > >> > >> >> + else > >> > >> >> + err = gpio_direction_output(gpio, > >> > >> >> + (flags & GPIOF_INIT_HIGH) ? 1 : 0); > >> > >> >> + > >> > >> >> + if (err) > >> > >> >> + goto free_gpio; > >> > >> >> + > >> > >> >> + return 0; > >> > >> >> + > >> > >> >> +free_gpio: > >> > >> >> + gpio_free(gpio); > >> > >> >> + return err; > >> > >> >> +} > >> > >> >> +EXPORT_SYMBOL(gpio_request_one); > >> > >> >> + > >> > >> >> +/** > >> > >> >> + * gpio_request_array - request multiple GPIOs in a single call > >> > >> >> + * @array: array of the 'struct gpio' > >> > >> >> + * @num: how many GPIOs in the array > >> > >> >> + */ > >> > >> >> +int gpio_request_array(const struct gpio *array, size_t num) > >> > >> >> +{ > >> > >> >> + int i, err; > >> > >> >> + > >> > >> >> + for (i = 0; i < num; i++, array++) { > >> > >> >> + err = gpio_request_one(array->gpio, array->flags, array->label); > >> > >> >> + if (err) > >> > >> >> + goto err_free; > >> > >> >> + } > >> > >> >> + return 0; > >> > >> >> + > >> > >> >> +err_free: > >> > >> >> + while (i--) > >> > >> >> + gpio_free((--array)->gpio); > >> > >> >> + return err; > >> > >> >> +} > >> > >> >> +EXPORT_SYMBOL(gpio_request_array); > >> > >> >> + > >> > >> >> +/** > >> > >> >> + * gpio_free_array - release multiple GPIOs in a single call > >> > >> >> + * @array: array of the 'struct gpio' > >> > >> >> + * @num: how many GPIOs in the array > >> > >> >> + */ > >> > >> >> +void gpio_free_array(const struct gpio *array, size_t num) > >> > >> >> +{ > >> > >> >> + while (num--) > >> > >> >> + gpio_free((array++)->gpio); > >> > >> >> +} > >> > >> >> +EXPORT_SYMBOL(gpio_free_array); > >> > >> >> + > >> > >> >> void gpio_set_value(unsigned gpio, int value) > >> > >> >> { > >> > >> >> struct gpio_info *gi = &gpio_desc[gpio]; > >> > >> >> diff --git a/include/gpio.h b/include/gpio.h > >> > >> >> index eedb980..37c151d 100644 > >> > >> >> --- a/include/gpio.h > >> > >> >> +++ b/include/gpio.h > >> > >> >> @@ -3,6 +3,29 @@ > >> > >> >> > >> > >> >> #include <asm/gpio.h> > >> > >> >> > >> > >> >> +/* make these flag values available regardless of GPIO kconfig options */ > >> > >> >> +#define GPIOF_DIR_OUT (0 << 0) > >> > >> >> +#define GPIOF_DIR_IN (1 << 0) > >> > >> >> + > >> > >> >> +#define GPIOF_INIT_LOW (0 << 1) > >> > >> >> +#define GPIOF_INIT_HIGH (1 << 1) > >> > >> >> + > >> > >> >> +#define GPIOF_IN (GPIOF_DIR_IN) > >> > >> >> +#define GPIOF_OUT_INIT_LOW (GPIOF_DIR_OUT | GPIOF_INIT_LOW) > >> > >> >> +#define GPIOF_OUT_INIT_HIGH (GPIOF_DIR_OUT | GPIOF_INIT_HIGH) > >> > >> >> + > >> > >> >> +/** > >> > >> >> + * struct gpio - a structure describing a GPIO with configuration > >> > >> >> + * @gpio: the GPIO number > >> > >> >> + * @flags: GPIO configuration as specified by GPIOF_* > >> > >> >> + * @label: a literal description string of this GPIO > >> > >> >> + */ > >> > >> >> +struct gpio { > >> > >> >> + unsigned gpio; > >> > >> >> + unsigned long flags; > >> > >> >> + const char *label; > >> > >> >> +}; > >> > >> >> + > >> > >> >> #ifndef CONFIG_GPIOLIB > >> > >> >> static inline int gpio_request(unsigned gpio, const char *label) > >> > >> >> { > >> > >> >> @@ -12,9 +35,29 @@ static inline int gpio_request(unsigned gpio, const char *label) > >> > >> >> static inline void gpio_free(unsigned gpio) > >> > >> >> { > >> > >> >> } > >> > >> >> + > >> > >> >> +static inline int gpio_request_one(unsigned gpio, > >> > >> >> + unsigned long flags, const char *label) > >> > >> >> +{ > >> > >> >> + return 0; > >> > >> >> +} > >> > >> >> + > >> > >> >> +static inline int gpio_request_array(const struct gpio *array, size_t num) > >> > >> >> +{ > >> > >> >> + return 0; > >> > >> >> +} > >> > >> > you can not do this > >> > >> > > >> > >> > as if we start to use this in generic driver where gpio_direction_input/output > >> > >> > work > >> > >> > > >> > >> > we will endup with no configuration > >> > >> > >> > >> But now in include/gpio.h we have this: > >> > >> > >> > >> static inline int gpio_request(unsigned gpio, const char *label) > >> > >> { > >> > >> return 0; > >> > >> } > >> > >> > >> > >> Can you explain the difference? > >> > > > >> > > gpio_request is not implemented without gpiolib, still you have to > >> > > configure the direction and value. > >> > > >> > Can we use this functions only if gpiolib is enabled? > >> > Can we skip the function's definiton in the non-gpio situation? > >> > >> Sounds fine. We should get rid of the !gpiolib drivers anyway, maybe > >> this adds some motivation. > > > > until every driver are swith to gpiolib NACK as if we switch any generic > > driver to this as leds, gpio-keys, i2c-gpio etc... we break board support > > siliently > > but leds, gpio-keys, i2c-gpio etc don't use > gpio_request_one()-related functions. > If we ristrict the usage of gpio_request_one()-related functions (use > it only in board code for gpiolib-enabled machines) > we can avoid mentioned problems. You should probably just provide a static inline wrapper for the !gpiolib case. It's sufficiently easy to do and avoids that someone who wants to use the functions in a driver has to fixup all other gpio drivers first. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2013-02-06 19:31 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2013-02-03 19:16 [RFC] gpiolib: import gpio_request_array() from linux 3.7 Antony Pavlov 2013-02-03 21:13 ` Jean-Christophe PLAGNIOL-VILLARD 2013-02-03 21:22 ` Antony Pavlov 2013-02-04 8:37 ` Sascha Hauer 2013-02-05 6:10 ` Antony Pavlov 2013-02-05 9:29 ` Sascha Hauer 2013-02-05 10:19 ` Jean-Christophe PLAGNIOL-VILLARD 2013-02-05 11:02 ` Antony Pavlov 2013-02-06 18:02 ` Antony Pavlov 2013-02-06 19:31 ` Sascha Hauer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox