diff mbox series

lib: utils/reset: Add voltage level for gpio_reset

Message ID 20211024164642.810274-1-wxjstz@126.com
State Rejected
Headers show
Series lib: utils/reset: Add voltage level for gpio_reset | expand

Commit Message

Xiang W Oct. 24, 2021, 4:46 p.m. UTC
The reset voltage may be different under different platforms, so fdt
should describe the reset level.

Signed-off-by: Xiang W <wxjstz@126.com>
---
 lib/utils/reset/fdt_reset_gpio.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

Comments

Jessica Clarke Oct. 24, 2021, 4:53 p.m. UTC | #1
On 24 Oct 2021, at 17:46, Xiang W <wxjstz@126.com> wrote:
> 
> The reset voltage may be different under different platforms, so fdt
> should describe the reset level.
> 
> Signed-off-by: Xiang W <wxjstz@126.com>
> ---
> lib/utils/reset/fdt_reset_gpio.c | 13 ++++++++++---
> 1 file changed, 10 insertions(+), 3 deletions(-)
> 
> diff --git a/lib/utils/reset/fdt_reset_gpio.c b/lib/utils/reset/fdt_reset_gpio.c
> index 4da1450..b834522 100644
> --- a/lib/utils/reset/fdt_reset_gpio.c
> +++ b/lib/utils/reset/fdt_reset_gpio.c
> @@ -21,16 +21,19 @@
> 
> struct gpio_reset {
> 	struct gpio_pin pin;
> +	u32 active_level;
> 	u32 active_delay;
> 	u32 inactive_delay;
> };
> 
> static struct gpio_reset poweroff = {
> +	.active_level = 1,
> 	.active_delay = 100,
> 	.inactive_delay = 100
> };
> 
> static struct gpio_reset restart = {
> +	.active_level = 1,
> 	.active_delay = 100,
> 	.inactive_delay = 100
> };
> @@ -68,15 +71,15 @@ static void gpio_system_reset(u32 type, u32 reason)
> 
> 	if (reset) {
> 		/* drive it active, also inactive->active edge */
> -		gpio_direction_output(&reset->pin, 1);
> +		gpio_direction_output(&reset->pin, reset->active_level);
> 		sbi_timer_mdelay(reset->active_delay);
> 
> 		/* drive inactive, also active->inactive edge */
> -		gpio_set(&reset->pin, 0);
> +		gpio_set(&reset->pin, !reset->active_level);
> 		sbi_timer_mdelay(reset->inactive_delay);
> 
> 		/* drive it active, also inactive->active edge */
> -		gpio_set(&reset->pin, 1);
> +		gpio_set(&reset->pin, reset->active_level);
> 	}
> 	/* hang !!! */
> 	sbi_hart_hang();
> @@ -107,6 +110,10 @@ static int gpio_reset_init(void *fdt, int nodeoff,
> 			return rc;
> 	}
> 
> +	val = fdt_getprop(fdt, nodeoff, "active-level", &len);

This property is neither documented in the binding specification for
gpio-restart nor is it checked by Linux.

> +	if (len > 0)
> +		reset->active_level = !!fdt32_to_cpu(*val);
> +
> 	val = fdt_getprop(fdt, nodeoff, "active-delay-ms", &len);

In fact these are also wrong. The binding does not have a -ms suffix on
the (in)active-delay property names.

Jess
Xiang W Oct. 24, 2021, 5:10 p.m. UTC | #2
在 2021-10-24星期日的 17:53 +0100,Jessica Clarke写道:
> On 24 Oct 2021, at 17:46, Xiang W <wxjstz@126.com> wrote:
> > 
> > The reset voltage may be different under different platforms, so
> > fdt
> > should describe the reset level.
> > 
> > Signed-off-by: Xiang W <wxjstz@126.com>
> > ---
> > lib/utils/reset/fdt_reset_gpio.c | 13 ++++++++++---
> > 1 file changed, 10 insertions(+), 3 deletions(-)
> > 
> > diff --git a/lib/utils/reset/fdt_reset_gpio.c
> > b/lib/utils/reset/fdt_reset_gpio.c
> > index 4da1450..b834522 100644
> > --- a/lib/utils/reset/fdt_reset_gpio.c
> > +++ b/lib/utils/reset/fdt_reset_gpio.c
> > @@ -21,16 +21,19 @@
> > 
> > struct gpio_reset {
> >         struct gpio_pin pin;
> > +       u32 active_level;
> >         u32 active_delay;
> >         u32 inactive_delay;
> > };
> > 
> > static struct gpio_reset poweroff = {
> > +       .active_level = 1,
> >         .active_delay = 100,
> >         .inactive_delay = 100
> > };
> > 
> > static struct gpio_reset restart = {
> > +       .active_level = 1,
> >         .active_delay = 100,
> >         .inactive_delay = 100
> > };
> > @@ -68,15 +71,15 @@ static void gpio_system_reset(u32 type, u32
> > reason)
> > 
> >         if (reset) {
> >                 /* drive it active, also inactive->active edge */
> > -               gpio_direction_output(&reset->pin, 1);
> > +               gpio_direction_output(&reset->pin, reset-
> > >active_level);
> >                 sbi_timer_mdelay(reset->active_delay);
> > 
> >                 /* drive inactive, also active->inactive edge */
> > -               gpio_set(&reset->pin, 0);
> > +               gpio_set(&reset->pin, !reset->active_level);
> >                 sbi_timer_mdelay(reset->inactive_delay);
> > 
> >                 /* drive it active, also inactive->active edge */
> > -               gpio_set(&reset->pin, 1);
> > +               gpio_set(&reset->pin, reset->active_level);
> >         }
> >         /* hang !!! */
> >         sbi_hart_hang();
> > @@ -107,6 +110,10 @@ static int gpio_reset_init(void *fdt, int
> > nodeoff,
> >                         return rc;
> >         }
> > 
> > +       val = fdt_getprop(fdt, nodeoff, "active-level", &len);
> 
> This property is neither documented in the binding specification for
> gpio-restart nor is it checked by Linux.

This DT is only processed by opensbi, and linux should be reset through
the sbi interface, instead of controlling gpio to perform the reset by
itself.

Regards,
Xiang W

> 
> > +       if (len > 0)
> > +               reset->active_level = !!fdt32_to_cpu(*val);
> > +
> >         val = fdt_getprop(fdt, nodeoff, "active-delay-ms", &len);
> 
> In fact these are also wrong. The binding does not have a -ms suffix
> on
> the (in)active-delay property names.
> 
> Jess
Jessica Clarke Oct. 24, 2021, 5:26 p.m. UTC | #3
On 24 Oct 2021, at 18:10, Xiang W <wxjstz@126.com> wrote:
> 
> 在 2021-10-24星期日的 17:53 +0100,Jessica Clarke写道:
>> On 24 Oct 2021, at 17:46, Xiang W <wxjstz@126.com> wrote:
>>> 
>>> The reset voltage may be different under different platforms, so
>>> fdt
>>> should describe the reset level.
>>> 
>>> Signed-off-by: Xiang W <wxjstz@126.com>
>>> ---
>>> lib/utils/reset/fdt_reset_gpio.c | 13 ++++++++++---
>>> 1 file changed, 10 insertions(+), 3 deletions(-)
>>> 
>>> diff --git a/lib/utils/reset/fdt_reset_gpio.c
>>> b/lib/utils/reset/fdt_reset_gpio.c
>>> index 4da1450..b834522 100644
>>> --- a/lib/utils/reset/fdt_reset_gpio.c
>>> +++ b/lib/utils/reset/fdt_reset_gpio.c
>>> @@ -21,16 +21,19 @@
>>> 
>>> struct gpio_reset {
>>>         struct gpio_pin pin;
>>> +       u32 active_level;
>>>         u32 active_delay;
>>>         u32 inactive_delay;
>>> };
>>> 
>>> static struct gpio_reset poweroff = {
>>> +       .active_level = 1,
>>>         .active_delay = 100,
>>>         .inactive_delay = 100
>>> };
>>> 
>>> static struct gpio_reset restart = {
>>> +       .active_level = 1,
>>>         .active_delay = 100,
>>>         .inactive_delay = 100
>>> };
>>> @@ -68,15 +71,15 @@ static void gpio_system_reset(u32 type, u32
>>> reason)
>>> 
>>>         if (reset) {
>>>                 /* drive it active, also inactive->active edge */
>>> -               gpio_direction_output(&reset->pin, 1);
>>> +               gpio_direction_output(&reset->pin, reset-
>>>> active_level);
>>>                 sbi_timer_mdelay(reset->active_delay);
>>> 
>>>                 /* drive inactive, also active->inactive edge */
>>> -               gpio_set(&reset->pin, 0);
>>> +               gpio_set(&reset->pin, !reset->active_level);
>>>                 sbi_timer_mdelay(reset->inactive_delay);
>>> 
>>>                 /* drive it active, also inactive->active edge */
>>> -               gpio_set(&reset->pin, 1);
>>> +               gpio_set(&reset->pin, reset->active_level);
>>>         }
>>>         /* hang !!! */
>>>         sbi_hart_hang();
>>> @@ -107,6 +110,10 @@ static int gpio_reset_init(void *fdt, int
>>> nodeoff,
>>>                         return rc;
>>>         }
>>> 
>>> +       val = fdt_getprop(fdt, nodeoff, "active-level", &len);
>> 
>> This property is neither documented in the binding specification for
>> gpio-restart nor is it checked by Linux.
> 
> This DT is only processed by opensbi, and linux should be reset through
> the sbi interface, instead of controlling gpio to perform the reset by
> itself.

Well, there are several things going on:

1. In general, you can’t just make up properties in the global
   namespace, that’s how you end up with the kind of mess device trees
   have the reputation of having
2. Linux doesn’t need this property and supports far more hardware than
   OpenSBI does, so why does OpenSBI need knowledge of this property but
   Linux doesn’t on any platform for any architecture?
3. OpenSBI doesn’t provide the device tree, in general, pre-OpenSBI
   firmware does, be it U-Boot SPL or something else, and in general that
   device tree *will* make its way all the way to the OS. Linux might go and
   ignore that and use its own device tree because the whole situation is a
   mess, but that’s not the point, this can and will be exposed to OSes running
   on top.

Jess
Xiang W Oct. 24, 2021, 6:09 p.m. UTC | #4
在 2021-10-24星期日的 18:26 +0100,Jessica Clarke写道:
> > > 
> > > This property is neither documented in the binding specification
> > > for
> > > gpio-restart nor is it checked by Linux.
> > 
> > This DT is only processed by opensbi, and linux should be reset
> > through
> > the sbi interface, instead of controlling gpio to perform the reset
> > by
> > itself.
> 
> Well, there are several things going on:
> 
> 1. In general, you can’t just make up properties in the global
>    namespace, that’s how you end up with the kind of mess device
> trees
>    have the reputation of having
> 2. Linux doesn’t need this property and supports far more hardware
> than
>    OpenSBI does, so why does OpenSBI need knowledge of this property
> but
>    Linux doesn’t on any platform for any architecture?
> 3. OpenSBI doesn’t provide the device tree, in general, pre-OpenSBI
>    firmware does, be it U-Boot SPL or something else, and in general
> that
>    device tree *will* make its way all the way to the OS. Linux might
> go and
>    ignore that and use its own device tree because the whole
> situation is a
>    mess, but that’s not the point, this can and will be exposed to
> OSes running
>    on top.
> 
> Jess

These attributes are under the gpio-restart/gpio-poweroff node and are
not global attributes. If you need to rename, you can submit a new
patch. The rename is added to the current patch, and the commit cannot
be kept clean

Regards,
Xiang W
Samuel Holland Oct. 24, 2021, 6:42 p.m. UTC | #5
On 10/24/21 11:46 AM, Xiang W wrote:
> The reset voltage may be different under different platforms, so fdt
> should describe the reset level.

FDT already has a way to describe the reset level: the flags cell in
your GPIO specifier. The GPIO controller is responsible for inverting
the levels when GPIO_FLAG_ACTIVE_LOW is present. That way, the inversion
logic does not need to be duplicated in every GPIO consumer driver.

> Signed-off-by: Xiang W <wxjstz@126.com>
> ---
>  lib/utils/reset/fdt_reset_gpio.c | 13 ++++++++++---
>  1 file changed, 10 insertions(+), 3 deletions(-)
> 
> diff --git a/lib/utils/reset/fdt_reset_gpio.c b/lib/utils/reset/fdt_reset_gpio.c
> index 4da1450..b834522 100644
> --- a/lib/utils/reset/fdt_reset_gpio.c
> +++ b/lib/utils/reset/fdt_reset_gpio.c
> @@ -21,16 +21,19 @@
>  
>  struct gpio_reset {
>  	struct gpio_pin pin;
> +	u32 active_level;
>  	u32 active_delay;
>  	u32 inactive_delay;
>  };
>  
>  static struct gpio_reset poweroff = {
> +	.active_level = 1,
>  	.active_delay = 100,
>  	.inactive_delay = 100
>  };
>  
>  static struct gpio_reset restart = {
> +	.active_level = 1,
>  	.active_delay = 100,
>  	.inactive_delay = 100
>  };
> @@ -68,15 +71,15 @@ static void gpio_system_reset(u32 type, u32 reason)
>  
>  	if (reset) {
>  		/* drive it active, also inactive->active edge */
> -		gpio_direction_output(&reset->pin, 1);
> +		gpio_direction_output(&reset->pin, reset->active_level);

"1" as an argument to gpio_direction_output/gpio_set always means the
active level, which could be high or low, depending on if reset->pin has
the GPIO_FLAG_ACTIVE_LOW flag.

>  		sbi_timer_mdelay(reset->active_delay);
>  
>  		/* drive inactive, also active->inactive edge */
> -		gpio_set(&reset->pin, 0);
> +		gpio_set(&reset->pin, !reset->active_level);
>  		sbi_timer_mdelay(reset->inactive_delay);
>  
>  		/* drive it active, also inactive->active edge */
> -		gpio_set(&reset->pin, 1);
> +		gpio_set(&reset->pin, reset->active_level);
>  	}
>  	/* hang !!! */
>  	sbi_hart_hang();
> @@ -107,6 +110,10 @@ static int gpio_reset_init(void *fdt, int nodeoff,
>  			return rc;
>  	}
>  
> +	val = fdt_getprop(fdt, nodeoff, "active-level", &len);
> +	if (len > 0)
> +		reset->active_level = !!fdt32_to_cpu(*val);
> +

Like Jessica said, all device tree properties must be documented in the
binding for that device. And the bindings for the "gpio-poweroff" and
"gpio-restart" compatible strings live in the Linux kernel tree. So if
you want to add a new property, that binding must be updated first.

But here, no new property is needed, because there is already a way to
do what you want within the existing binding.

Regards,
Samuel

>  	val = fdt_getprop(fdt, nodeoff, "active-delay-ms", &len);
>  	if (len > 0)
>  		reset->active_delay = fdt32_to_cpu(*val);
>
Jessica Clarke Oct. 24, 2021, 6:42 p.m. UTC | #6
On 24 Oct 2021, at 19:09, Xiang W <wxjstz@126.com> wrote:
> 
> 在 2021-10-24星期日的 18:26 +0100,Jessica Clarke写道:
>>>> 
>>>> This property is neither documented in the binding specification
>>>> for
>>>> gpio-restart nor is it checked by Linux.
>>> 
>>> This DT is only processed by opensbi, and linux should be reset
>>> through
>>> the sbi interface, instead of controlling gpio to perform the reset
>>> by
>>> itself.
>> 
>> Well, there are several things going on:
>> 
>> 1. In general, you can’t just make up properties in the global
>>    namespace, that’s how you end up with the kind of mess device
>> trees
>>    have the reputation of having
>> 2. Linux doesn’t need this property and supports far more hardware
>> than
>>    OpenSBI does, so why does OpenSBI need knowledge of this property
>> but
>>    Linux doesn’t on any platform for any architecture?
>> 3. OpenSBI doesn’t provide the device tree, in general, pre-OpenSBI
>>    firmware does, be it U-Boot SPL or something else, and in general
>> that
>>    device tree *will* make its way all the way to the OS. Linux might
>> go and
>>    ignore that and use its own device tree because the whole
>> situation is a
>>    mess, but that’s not the point, this can and will be exposed to
>> OSes running
>>    on top.
>> 
>> Jess
> 
> These attributes are under the gpio-restart/gpio-poweroff node and are
> not global attributes.

By global I mean they do not have a vendor prefix. They occupy the
global namespace of gpio-restart/gpio-poweroff property names that is
reserved for standard properties. To quote the devicetree specification:

> Nonstandard property names should specify a unique string prefix, such
> as a stock ticker symbol, identifying the name of the company or
> organization that defined the property.

This is a nonstandard property, therefore this patch is in violation of
that.

> If you need to rename, you can submit a new
> patch. The rename is added to the current patch, and the commit cannot
> be kept clean

The onus is on the patch submitter to do the right thing, not the
reviewer to fix the submitter’s mistakes.

Jess
Xiang W Oct. 25, 2021, 1:50 a.m. UTC | #7
在 2021-10-24星期日的 13:42 -0500,Samuel Holland写道:
> On 10/24/21 11:46 AM, Xiang W wrote:
> > The reset voltage may be different under different platforms, so
> > fdt
> > should describe the reset level.
> 
> FDT already has a way to describe the reset level: the flags cell in
> your GPIO specifier. The GPIO controller is responsible for inverting
> the levels when GPIO_FLAG_ACTIVE_LOW is present. That way, the
> inversion
> logic does not need to be duplicated in every GPIO consumer driver.
Thanks, great hint!

Regards,
Xiang W
> 
> > Signed-off-by: Xiang W <wxjstz@126.com>
> > ---
> >  lib/utils/reset/fdt_reset_gpio.c | 13 ++++++++++---
> >  1 file changed, 10 insertions(+), 3 deletions(-)
> > 
> > diff --git a/lib/utils/reset/fdt_reset_gpio.c
> > b/lib/utils/reset/fdt_reset_gpio.c
> > index 4da1450..b834522 100644
> > --- a/lib/utils/reset/fdt_reset_gpio.c
> > +++ b/lib/utils/reset/fdt_reset_gpio.c
> > @@ -21,16 +21,19 @@
> >  
> >  struct gpio_reset {
> >         struct gpio_pin pin;
> > +       u32 active_level;
> >         u32 active_delay;
> >         u32 inactive_delay;
> >  };
> >  
> >  static struct gpio_reset poweroff = {
> > +       .active_level = 1,
> >         .active_delay = 100,
> >         .inactive_delay = 100
> >  };
> >  
> >  static struct gpio_reset restart = {
> > +       .active_level = 1,
> >         .active_delay = 100,
> >         .inactive_delay = 100
> >  };
> > @@ -68,15 +71,15 @@ static void gpio_system_reset(u32 type, u32
> > reason)
> >  
> >         if (reset) {
> >                 /* drive it active, also inactive->active edge */
> > -               gpio_direction_output(&reset->pin, 1);
> > +               gpio_direction_output(&reset->pin, reset-
> > >active_level);
> 
> "1" as an argument to gpio_direction_output/gpio_set always means the
> active level, which could be high or low, depending on if reset->pin
> has
> the GPIO_FLAG_ACTIVE_LOW flag.
> 
> >                 sbi_timer_mdelay(reset->active_delay);
> >  
> >                 /* drive inactive, also active->inactive edge */
> > -               gpio_set(&reset->pin, 0);
> > +               gpio_set(&reset->pin, !reset->active_level);
> >                 sbi_timer_mdelay(reset->inactive_delay);
> >  
> >                 /* drive it active, also inactive->active edge */
> > -               gpio_set(&reset->pin, 1);
> > +               gpio_set(&reset->pin, reset->active_level);
> >         }
> >         /* hang !!! */
> >         sbi_hart_hang();
> > @@ -107,6 +110,10 @@ static int gpio_reset_init(void *fdt, int
> > nodeoff,
> >                         return rc;
> >         }
> >  
> > +       val = fdt_getprop(fdt, nodeoff, "active-level", &len);
> > +       if (len > 0)
> > +               reset->active_level = !!fdt32_to_cpu(*val);
> > +
> 
> Like Jessica said, all device tree properties must be documented in
> the
> binding for that device. And the bindings for the "gpio-poweroff" and
> "gpio-restart" compatible strings live in the Linux kernel tree. So
> if
> you want to add a new property, that binding must be updated first.
> 
> But here, no new property is needed, because there is already a way
> to
> do what you want within the existing binding.
> 
> Regards,
> Samuel
> 
> >         val = fdt_getprop(fdt, nodeoff, "active-delay-ms", &len);
> >         if (len > 0)
> >                 reset->active_delay = fdt32_to_cpu(*val);
> >
Xiang W Oct. 25, 2021, 1:52 a.m. UTC | #8
在 2021-10-25星期一的 00:46 +0800,Xiang W写道:
> The reset voltage may be different under different platforms, so fdt
> should describe the reset level.
> 
> Signed-off-by: Xiang W <wxjstz@126.com>
> ---
>  lib/utils/reset/fdt_reset_gpio.c | 13 ++++++++++---
>  1 file changed, 10 insertions(+), 3 deletions(-)
> 
> diff --git a/lib/utils/reset/fdt_reset_gpio.c
> b/lib/utils/reset/fdt_reset_gpio.c
> index 4da1450..b834522 100644
> --- a/lib/utils/reset/fdt_reset_gpio.c
> +++ b/lib/utils/reset/fdt_reset_gpio.c
> @@ -21,16 +21,19 @@
>  
>  struct gpio_reset {
>         struct gpio_pin pin;
> +       u32 active_level;
>         u32 active_delay;
>         u32 inactive_delay;
>  };
>  
>  static struct gpio_reset poweroff = {
> +       .active_level = 1,
>         .active_delay = 100,
>         .inactive_delay = 100
>  };
>  
>  static struct gpio_reset restart = {
> +       .active_level = 1,
>         .active_delay = 100,
>         .inactive_delay = 100
>  };
> @@ -68,15 +71,15 @@ static void gpio_system_reset(u32 type, u32
> reason)
>  
>         if (reset) {
>                 /* drive it active, also inactive->active edge */
> -               gpio_direction_output(&reset->pin, 1);
> +               gpio_direction_output(&reset->pin, reset-
> >active_level);
>                 sbi_timer_mdelay(reset->active_delay);
>  
>                 /* drive inactive, also active->inactive edge */
> -               gpio_set(&reset->pin, 0);
> +               gpio_set(&reset->pin, !reset->active_level);
>                 sbi_timer_mdelay(reset->inactive_delay);
>  
>                 /* drive it active, also inactive->active edge */
> -               gpio_set(&reset->pin, 1);
> +               gpio_set(&reset->pin, reset->active_level);
>         }
>         /* hang !!! */
>         sbi_hart_hang();
> @@ -107,6 +110,10 @@ static int gpio_reset_init(void *fdt, int
> nodeoff,
>                         return rc;
>         }
>  
> +       val = fdt_getprop(fdt, nodeoff, "active-level", &len);
> +       if (len > 0)
> +               reset->active_level = !!fdt32_to_cpu(*val);
> +
>         val = fdt_getprop(fdt, nodeoff, "active-delay-ms", &len);
>         if (len > 0)
>                 reset->active_delay = fdt32_to_cpu(*val);

sorry!!!
revoke this patch.

Regards,
Xiang W
diff mbox series

Patch

diff --git a/lib/utils/reset/fdt_reset_gpio.c b/lib/utils/reset/fdt_reset_gpio.c
index 4da1450..b834522 100644
--- a/lib/utils/reset/fdt_reset_gpio.c
+++ b/lib/utils/reset/fdt_reset_gpio.c
@@ -21,16 +21,19 @@ 
 
 struct gpio_reset {
 	struct gpio_pin pin;
+	u32 active_level;
 	u32 active_delay;
 	u32 inactive_delay;
 };
 
 static struct gpio_reset poweroff = {
+	.active_level = 1,
 	.active_delay = 100,
 	.inactive_delay = 100
 };
 
 static struct gpio_reset restart = {
+	.active_level = 1,
 	.active_delay = 100,
 	.inactive_delay = 100
 };
@@ -68,15 +71,15 @@  static void gpio_system_reset(u32 type, u32 reason)
 
 	if (reset) {
 		/* drive it active, also inactive->active edge */
-		gpio_direction_output(&reset->pin, 1);
+		gpio_direction_output(&reset->pin, reset->active_level);
 		sbi_timer_mdelay(reset->active_delay);
 
 		/* drive inactive, also active->inactive edge */
-		gpio_set(&reset->pin, 0);
+		gpio_set(&reset->pin, !reset->active_level);
 		sbi_timer_mdelay(reset->inactive_delay);
 
 		/* drive it active, also inactive->active edge */
-		gpio_set(&reset->pin, 1);
+		gpio_set(&reset->pin, reset->active_level);
 	}
 	/* hang !!! */
 	sbi_hart_hang();
@@ -107,6 +110,10 @@  static int gpio_reset_init(void *fdt, int nodeoff,
 			return rc;
 	}
 
+	val = fdt_getprop(fdt, nodeoff, "active-level", &len);
+	if (len > 0)
+		reset->active_level = !!fdt32_to_cpu(*val);
+
 	val = fdt_getprop(fdt, nodeoff, "active-delay-ms", &len);
 	if (len > 0)
 		reset->active_delay = fdt32_to_cpu(*val);