[U-Boot] [PATCH v4 3/8] sandbox: gpio: Add basic driver for simulating GPIOs
Simon Glass
sjg at chromium.org
Tue Feb 21 07:27:31 CET 2012
Hi Mike,
On Mon, Feb 20, 2012 at 10:11 PM, Mike Frysinger <vapier at gentoo.org> wrote:
> here's the incremental/full diff against your v4 showing the direction i think
> things should end up at ... incremental inline below while full is attached.
> -mike
Hmmm I'm fine with the get_gpio_flags() rename, printf() changes, but
please see below.
>
> diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
> index 17e601d..aa2aa4c 100644
> --- a/drivers/gpio/sandbox.c
> +++ b/drivers/gpio/sandbox.c
> @@ -20,9 +20,6 @@
> */
>
> #include <common.h>
> -#include <asm/io.h>
> -#include <asm/bitops.h>
> -#include <asm-generic/gpio.h>
> #include <asm/gpio.h>
>
> /* Flags for each GPIO */
> @@ -42,38 +39,59 @@ struct gpio_state {
> static struct gpio_state state[CONFIG_SANDBOX_GPIO_COUNT];
>
> /* Access routines for GPIO state */
> -static u8 *get_gpio(unsigned gp)
> +static u8 *get_gpio_flags(unsigned gp)
> {
> - assert(gp < CONFIG_SANDBOX_GPIO_COUNT);
> + if (gp >= ARRAY_SIZE(state)) {
> + static u8 invalid_flags;
> + printf("sandbox_gpio: error: invalid gpio %u\n", gp);
> + return &invalid_flags;
> + }
> +
I think we want to die / fail the test here, but since we don't have
any tests I suppose this is ok for now. I like assert() because it
halts.
> return &state[gp].flags;
> }
>
> static int get_gpio_flag(unsigned gp, int flag)
> {
> - return (*get_gpio(gp) & flag) != 0;
> + return (*get_gpio_flags(gp) & flag) != 0;
> }
>
> -static void set_gpio_flag(unsigned gp, int flag, int value)
> +static int set_gpio_flag(unsigned gp, int flag, int value)
> {
> - u8 *gpio = get_gpio(gp);
> + u8 *gpio = get_gpio_flags(gp);
>
> if (value)
> *gpio |= flag;
> else
> *gpio &= ~flag;
> +
> + return 0;
> }
>
> +static int check_reserved(unsigned gpio, const char *func)
> +{
> + if (!get_gpio_flag(gpio, GPIOF_RESERVED)) {
> + printf("sandbox_gpio: %s: error: gpio %u not reserved\n",
> + func, gpio);
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +/*
> + * Back-channel sandbox-internal-only access to GPIO state
> + */
> +
> int sandbox_gpio_get_value(unsigned gp)
> {
> if (get_gpio_flag(gp, GPIOF_OUTPUT))
> - printf("sandbox_gpio: get_value on output GPIO %d\n", gp);
> - return *get_gpio(gp) & GPIOF_HIGH;
> + debug("sandbox_gpio: get_value on output gpio %u\n", gp);
> + return get_gpio_flag(gp, GPIOF_HIGH);
> }
>
> int sandbox_gpio_set_value(unsigned gp, int value)
> {
> - set_gpio_flag(gp, GPIOF_HIGH, value);
> - return 0;
> + return set_gpio_flag(gp, GPIOF_HIGH, value);
> }
>
> int sandbox_gpio_get_direction(unsigned gp)
> @@ -83,95 +101,90 @@ int sandbox_gpio_get_direction(unsigned gp)
>
> int sandbox_gpio_set_direction(unsigned gp, int output)
> {
> - set_gpio_flag(gp, GPIOF_OUTPUT, output);
> - return 0;
> + return set_gpio_flag(gp, GPIOF_OUTPUT, output);
> }
>
> -static int check_reserved(unsigned gpio, const char *op_name)
> -{
> - if (!get_gpio_flag(gpio, GPIOF_RESERVED)) {
> - printf("sandbox_gpio: '%s' on unreserved GPIO\n", op_name);
> - return -1;
> - }
> -
> - return 0;
> -}
> -
> -/* These functions implement the public interface within U-Boot */
> +/*
> + * These functions implement the public interface within U-Boot
> + */
>
> /* set GPIO port 'gp' as an input */
> int gpio_direction_input(unsigned gp)
> {
> - debug("%s: gp = %d\n", __func__, gp);
> + debug("%s: gp:%u\n", __func__, gp);
> +
> if (check_reserved(gp, __func__))
> return -1;
> - set_gpio_flag(gp, GPIOF_OUTPUT, 0);
>
> - return 0;
> + return sandbox_gpio_set_direction(gp, 0);
Ick, we shouldn't call that function here - it is in the test code. Same below.
The idea is that this state has two completely separate sides to it -
by calling the 'test' functions from the 'U-Boot' functions I think
you are going to confuse people a lot.
> }
>
> /* set GPIO port 'gp' as an output, with polarity 'value' */
> int gpio_direction_output(unsigned gp, int value)
> {
> - debug("%s: gp = %d, value = %d\n", __func__, gp, value);
> + debug("%s: gp:%u, value = %d\n", __func__, gp, value);
> +
> if (check_reserved(gp, __func__))
> return -1;
> - set_gpio_flag(gp, GPIOF_OUTPUT, 1);
> - set_gpio_flag(gp, GPIOF_HIGH, value);
>
> - return 0;
> + return sandbox_gpio_set_direction(gp, 1) |
> + sandbox_gpio_set_value(gp, value);
> }
>
> /* read GPIO IN value of port 'gp' */
> int gpio_get_value(unsigned gp)
> {
> - debug("%s: gp = %d\n", __func__, gp);
> + debug("%s: gp:%u\n", __func__, gp);
> +
> if (check_reserved(gp, __func__))
> return -1;
> - if (get_gpio_flag(gp, GPIOF_OUTPUT))
> - printf("sandbox_gpio: get_value on output GPIO %d\n", gp);
>
> - return get_gpio_flag(gp, GPIOF_HIGH);
> + return sandbox_gpio_get_value(gp);
> }
>
> /* write GPIO OUT value to port 'gp' */
> int gpio_set_value(unsigned gp, int value)
> {
> - debug("%s: gp = %d, value = %d\n", __func__, gp, value);
> + debug("%s: gp:%u, value = %d\n", __func__, gp, value);
> +
> if (check_reserved(gp, __func__))
> return -1;
> - if (get_gpio_flag(gp, GPIOF_OUTPUT)) {
> - set_gpio_flag(gp, GPIOF_HIGH, value);
> - } else {
> - printf("sandbox_gpio: set_value on input GPIO %d\n", gp);
> +
> + if (!sandbox_gpio_get_direction(gp)) {
> + printf("sandbox_gpio: error: set_value on input gpio %u\n", gp);
> return -1;
> }
>
> - return 0;
> + return sandbox_gpio_set_value(gp, value);
> }
>
> int gpio_request(unsigned gp, const char *label)
> {
> - debug("%s: gp = %d, label= %s\n", __func__, gp, label);
> + debug("%s: gp:%u, label:%s\n", __func__, gp, label);
> +
> + if (gp >= ARRAY_SIZE(state)) {
> + printf("sandbox_gpio: error: invalid gpio %u\n", gp);
> + return -1;
> + }
> +
> if (get_gpio_flag(gp, GPIOF_RESERVED)) {
> - printf("sandbox_gpio: request on reserved GPIO\n");
> + printf("sandbox_gpio: error: gpio %u already reserved\n", gp);
> return -1;
> }
> - set_gpio_flag(gp, GPIOF_RESERVED, 1);
> - state[gp].label = label;
>
> - return 0;
> + state[gp].label = label;
> + return set_gpio_flag(gp, GPIOF_RESERVED, 1);
> }
>
> int gpio_free(unsigned gp)
> {
> - debug("%s: gp = %d\n", __func__, gp);
> + debug("%s: gp:%u\n", __func__, gp);
> +
> if (check_reserved(gp, __func__))
> return -1;
> - set_gpio_flag(gp, GPIOF_RESERVED, 0);
> - state[gp].label = NULL;
>
> - return 0;
> + state[gp].label = NULL;
> + return set_gpio_flag(gp, GPIOF_RESERVED, 0);
> }
>
> /* Display GPIO information */
> @@ -179,15 +192,15 @@ void gpio_info(void)
> {
> unsigned gpio;
>
> - printf("Sandbox GPIOs\n");
> + puts("Sandbox GPIOs\n");
>
> - for (gpio = 0; gpio < CONFIG_SANDBOX_GPIO_COUNT; ++gpio) {
> + for (gpio = 0; gpio < ARRAY_SIZE(state); ++gpio) {
> const char *label = state[gpio].label;
>
> printf("%4d: %s: %d [%c] %s\n",
> gpio,
> - get_gpio_flag(gpio, GPIOF_OUTPUT) ? "out" : " in",
> - get_gpio_flag(gpio, GPIOF_HIGH),
> + sandbox_gpio_get_direction(gpio) ? "out" : " in",
> + sandbox_gpio_get_value(gpio),
> get_gpio_flag(gpio, GPIOF_RESERVED) ? 'x' : ' ',
> label ? label : "");
> }
Regards,
Simon
More information about the U-Boot
mailing list