[RFC PATCH 4/4] lib: utils: add sifive reset device

Bin Meng bmeng.cn at gmail.com
Thu Jul 1 07:00:04 PDT 2021


On Thu, Jul 1, 2021 at 5:02 PM Green Wan <green.wan at sifive.com> wrote:
>
> Add sifive reset device based on DT binding as below.
>
>         gpio-poweroff {
>                 compatible = "gpio-poweroff";
>                 gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
>         };
>
> Signed-off-by: Green Wan <green.wan at sifive.com>
> ---
>  include/sbi_utils/sys/sifive_reset.h | 18 ++++++++
>  lib/utils/reset/fdt_reset.c          |  2 +
>  lib/utils/reset/fdt_reset_sifive.c   | 47 ++++++++++++++++++++
>  lib/utils/reset/objects.mk           |  1 +
>  lib/utils/sys/objects.mk             |  1 +
>  lib/utils/sys/sifive_reset.c         | 66 ++++++++++++++++++++++++++++
>  6 files changed, 135 insertions(+)
>  create mode 100644 include/sbi_utils/sys/sifive_reset.h
>  create mode 100644 lib/utils/reset/fdt_reset_sifive.c
>  create mode 100644 lib/utils/sys/sifive_reset.c
>
> diff --git a/include/sbi_utils/sys/sifive_reset.h b/include/sbi_utils/sys/sifive_reset.h
> new file mode 100644
> index 0000000..357fa8c
> --- /dev/null
> +++ b/include/sbi_utils/sys/sifive_reset.h
> @@ -0,0 +1,18 @@
> +/*
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * Copyright (c) 2021 SiFive
> + *
> + * Authors:
> + *   Green Wan <green.wan at sifive.com>
> + */
> +
> +#ifndef __SYS_SIFIVE_RESET_H__
> +#define __SYS_SIFIVE_RESET_H__
> +
> +#include <sbi/sbi_types.h>
> +#include <sbi_utils/fdt/fdt_helper.h>
> +
> +int sifive_reset_init_gpio(struct poweroff_gpio *ppwroff);
> +
> +#endif
> diff --git a/lib/utils/reset/fdt_reset.c b/lib/utils/reset/fdt_reset.c
> index 48a49fb..f3978b3 100644
> --- a/lib/utils/reset/fdt_reset.c
> +++ b/lib/utils/reset/fdt_reset.c
> @@ -13,11 +13,13 @@
>  #include <sbi_utils/reset/fdt_reset.h>
>
>  extern struct fdt_reset fdt_reset_sifive_test;
> +extern struct fdt_reset fdt_reset_sifive;
>  extern struct fdt_reset fdt_reset_htif;
>  extern struct fdt_reset fdt_reset_thead;
>
>  static struct fdt_reset *reset_drivers[] = {
>         &fdt_reset_sifive_test,
> +       &fdt_reset_sifive,
>         &fdt_reset_htif,
>         &fdt_reset_thead,
>  };
> diff --git a/lib/utils/reset/fdt_reset_sifive.c b/lib/utils/reset/fdt_reset_sifive.c
> new file mode 100644
> index 0000000..b5f3b1b
> --- /dev/null
> +++ b/lib/utils/reset/fdt_reset_sifive.c

I think this file should be renamed to fdt_reset_gpio, and used by any
platform that implements /gpio-poweroff or /gpio-restart.

> @@ -0,0 +1,47 @@
> +/*
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * Copyright (c) 2021 SiFive
> + *
> + * Authors:
> + *   Green Wan <green.wan at sifive.com>
> + */
> +
> +#include <sbi/sbi_console.h>
> +#include <sbi/sbi_platform.h>
> +#include <sbi/sbi_scratch.h>
> +#include <sbi_utils/fdt/fdt_helper.h>
> +#include <sbi_utils/gpio/fdt_gpio.h>
> +#include <sbi_utils/reset/fdt_reset.h>
> +#include <sbi_utils/sys/sifive_reset.h>
> +
> +static struct poweroff_gpio pwroff = {
> +       .act_delay = 100,
> +       .gpio = -1,
> +       .output_type = GPIO_ACTIVE_LOW,
> +};
> +
> +static int sifive_reset_init(void *fdt, int nodeoff,
> +                            const struct fdt_match *match)
> +{
> +       int rc;
> +
> +       rc = fdt_parse_gpio_pwroff(fdt, &pwroff, "/gpio-poweroff");
> +       if (rc) {
> +               sbi_printf("Warning: no gpio-poweroff definition in DT\n");
> +
> +               return rc;
> +       }
> +
> +       return sifive_reset_init_gpio(&pwroff);
> +}
> +
> +static const struct fdt_match sifive_reset_match[] = {
> +       { .compatible = "gpio-poweroff" },
> +       { },
> +};
> +
> +struct fdt_reset fdt_reset_sifive = {
> +       .match_table = sifive_reset_match,
> +       .init = sifive_reset_init,
> +};
> diff --git a/lib/utils/reset/objects.mk b/lib/utils/reset/objects.mk
> index bf005e8..1196e30 100644
> --- a/lib/utils/reset/objects.mk
> +++ b/lib/utils/reset/objects.mk
> @@ -10,5 +10,6 @@
>  libsbiutils-objs-y += reset/fdt_reset.o
>  libsbiutils-objs-y += reset/fdt_reset_htif.o
>  libsbiutils-objs-y += reset/fdt_reset_sifive_test.o
> +libsbiutils-objs-y += reset/fdt_reset_sifive.o
>  libsbiutils-objs-y += reset/fdt_reset_thead.o
>  libsbiutils-objs-y += reset/fdt_reset_thead_asm.o
> diff --git a/lib/utils/sys/objects.mk b/lib/utils/sys/objects.mk
> index 06be322..ad75f62 100644
> --- a/lib/utils/sys/objects.mk
> +++ b/lib/utils/sys/objects.mk
> @@ -9,3 +9,4 @@
>
>  libsbiutils-objs-y += sys/htif.o
>  libsbiutils-objs-y += sys/sifive_test.o
> +libsbiutils-objs-y += sys/sifive_reset.o
> diff --git a/lib/utils/sys/sifive_reset.c b/lib/utils/sys/sifive_reset.c
> new file mode 100644
> index 0000000..d086363
> --- /dev/null
> +++ b/lib/utils/sys/sifive_reset.c
> @@ -0,0 +1,66 @@
> +/*
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * Copyright (c) 2021 SiFive
> + *
> + * Authors:
> + *   Green Wan <green.wan at sifive.com>
> + */
> +
> +#include <sbi/riscv_io.h>
> +#include <sbi/sbi_console.h>
> +#include <sbi/sbi_ecall_interface.h>
> +#include <sbi/sbi_platform.h>
> +#include <sbi/sbi_system.h>
> +#include <sbi_utils/gpio/fdt_gpio.h>
> +#include <sbi_utils/sys/sifive_reset.h>
> +
> +static struct poweroff_gpio *ppwroff;
> +
> +static int sifive_system_reset_check(u32 type, u32 reason)
> +{
> +       switch (type) {
> +       case SBI_SRST_RESET_TYPE_SHUTDOWN:
> +       case SBI_SRST_RESET_TYPE_COLD_REBOOT:
> +       case SBI_SRST_RESET_TYPE_WARM_REBOOT:
> +               return 1;
> +       }
> +
> +       return 0;
> +}
> +
> +static void sifive_system_reset(u32 type, u32 reason)
> +{
> +       switch (type) {
> +       case SBI_SRST_RESET_TYPE_SHUTDOWN:
> +               if (!ppwroff || ppwroff->gpio < 0)
> +                       return;
> +
> +               if (ppwroff->output_type == GPIO_ACTIVE_LOW)
> +                       gpio_direction_output(ppwroff->gpio, 0);
> +               else
> +                       gpio_direction_output(ppwroff->gpio, 1);
> +
> +               /* if success, power is off now. */
> +               while (1)
> +                       wfi();
> +
> +               break;
> +       case SBI_SRST_RESET_TYPE_COLD_REBOOT:
> +       case SBI_SRST_RESET_TYPE_WARM_REBOOT:
> +               break;
> +       }
> +}
> +
> +static struct sbi_system_reset_device sifive_reset = {
> +       .name = "sifive_reset",
> +       .system_reset_check = sifive_system_reset_check,
> +       .system_reset = sifive_system_reset
> +};
> +
> +int sifive_reset_init_gpio(struct poweroff_gpio *gpio)
> +{
> +       ppwroff = gpio;
> +       sbi_system_reset_set_device(&sifive_reset);
> +       return 0;
> +}
> --

Regards,
Bin



More information about the opensbi mailing list