[PATCH 1/5] hw/gpio: Add property for ASPEED GPIO in 32 bits basis

Coco Li posted 5 patches 5 months, 1 week ago
Maintainers: Tyrone Ting <kfting@nuvoton.com>, Hao Wu <wuhaotsh@google.com>, Peter Maydell <peter.maydell@linaro.org>, "Cédric Le Goater" <clg@kaod.org>, Steven Lee <steven_lee@aspeedtech.com>, Troy Lee <leetroy@gmail.com>, Jamin Lin <jamin_lin@aspeedtech.com>, Andrew Jeffery <andrew@codeconstruct.com.au>, Joel Stanley <joel@jms.id.au>, Markus Armbruster <armbru@redhat.com>, Fabiano Rosas <farosas@suse.de>, Laurent Vivier <lvivier@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>
There is a newer version of this series
[PATCH 1/5] hw/gpio: Add property for ASPEED GPIO in 32 bits basis
Posted by Coco Li 5 months, 1 week ago
From: Felix Wu <flwu@google.com>

Added 32 bits property for ASPEED GPIO. Previously it can only be access in bitwise manner.

This change gives ASPEED similar behavior as Nuvoton.

Signed-off-by: Felix Wu <flwu@google.com>
---
 hw/gpio/aspeed_gpio.c | 57 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
index 609a556908..2d78bf9515 100644
--- a/hw/gpio/aspeed_gpio.c
+++ b/hw/gpio/aspeed_gpio.c
@@ -1308,6 +1308,57 @@ static void aspeed_gpio_2700_write(void *opaque, hwaddr offset,
 }
 
 /* Setup functions */
+static void aspeed_gpio_set_set(Object *obj, Visitor *v,
+                                        const char *name, void *opaque,
+                                        Error **errp)
+{
+    uint32_t set_val = 0;
+    AspeedGPIOState *s = ASPEED_GPIO(obj);
+    AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
+    int set_idx = 0;
+
+    if (!visit_type_uint32(v, name, &set_val, errp)) {
+        return;
+    }
+
+    if (sscanf(name, "gpio-set[%d]", &set_idx) != 1) {
+        error_setg(errp, "%s: error reading %s", __func__, name);
+        return;
+    }
+
+    if (set_idx >= agc->nr_gpio_sets || set_idx < 0) {
+        error_setg(errp, "%s: invalid set_idx %s", __func__, name);
+        return;
+    }
+
+    aspeed_gpio_update(s, &s->sets[set_idx], set_val,
+                       ~s->sets[set_idx].direction);
+}
+
+static void aspeed_gpio_get_set(Object *obj, Visitor *v,
+                                        const char *name, void *opaque,
+                                        Error **errp)
+{
+    uint32_t set_val = 0;
+    AspeedGPIOState *s = ASPEED_GPIO(obj);
+    AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
+    int set_idx = 0;
+
+    if (sscanf(name, "gpio-set[%d]", &set_idx) != 1) {
+        error_setg(errp, "%s: error reading %s", __func__, name);
+        return;
+    }
+
+    if (set_idx >= agc->nr_gpio_sets || set_idx < 0) {
+        error_setg(errp, "%s: invalid set_idx %s", __func__, name);
+        return;
+    }
+
+    set_val = s->sets[set_idx].data_value;
+    visit_type_uint32(v, name, &set_val, errp);
+}
+
+/****************** Setup functions ******************/
 static const GPIOSetProperties ast2400_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
     [0] = {0xffffffff,  0xffffffff,  {"A", "B", "C", "D"} },
     [1] = {0xffffffff,  0xffffffff,  {"E", "F", "G", "H"} },
@@ -1435,6 +1486,12 @@ static void aspeed_gpio_init(Object *obj)
             g_free(name);
         }
     }
+
+    for (int i = 0; i < agc->nr_gpio_sets; i++) {
+        char *name = g_strdup_printf("gpio-set[%d]", i);
+        object_property_add(obj, name, "uint32", aspeed_gpio_get_set,
+        aspeed_gpio_set_set, NULL, NULL);
+    }
 }
 
 static const VMStateDescription vmstate_gpio_regs = {
-- 
2.51.0.338.gd7d06c2dae-goog
Re: [PATCH 1/5] hw/gpio: Add property for ASPEED GPIO in 32 bits basis
Posted by Andrew Jeffery 5 months ago
On Wed, 2025-09-03 at 21:38 +0000, Coco Li wrote:
> From: Felix Wu <flwu@google.com>
> 
> Added 32 bits property for ASPEED GPIO. Previously it can only be access in bitwise manner.
> 
> This change gives ASPEED similar behavior as Nuvoton.

Can you point me to the Nuvoton functionality? I had a quick look and
couldn't immediately see an equivalent implementation.

Regardless, I'd like to see more motivation in the commit message than
"make it behave like Nuvoton". Can you provide a concrete use-case as
an example?

Andrew
Re: [PATCH 1/5] hw/gpio: Add property for ASPEED GPIO in 32 bits basis
Posted by Coco Li 5 months ago
Hello Andrew,

I discussed with the original author of the patch and the Nuvoton
functionality mentioned above has not been upstreamed since then,
unfortunately.
Aside from the comment above, we believe this patch series allows gpios to
be accessed more dynamically/flexibly in complicated simulation, and also
helps with accessing advanced gpio features, see the sgpio implementation
later in this patch series.

Best,
Coco

On Tue, Sep 9, 2025 at 8:52 PM Andrew Jeffery <andrew@codeconstruct.com.au>
wrote:

> On Wed, 2025-09-03 at 21:38 +0000, Coco Li wrote:
> > From: Felix Wu <flwu@google.com>
> >
> > Added 32 bits property for ASPEED GPIO. Previously it can only be access
> in bitwise manner.
> >
> > This change gives ASPEED similar behavior as Nuvoton.
>
> Can you point me to the Nuvoton functionality? I had a quick look and
> couldn't immediately see an equivalent implementation.
>
> Regardless, I'd like to see more motivation in the commit message than
> "make it behave like Nuvoton". Can you provide a concrete use-case as
> an example?
>
> Andrew
>
Re: [PATCH 1/5] hw/gpio: Add property for ASPEED GPIO in 32 bits basis
Posted by Andrew Jeffery 4 months, 3 weeks ago
Hi Coco,

On Fri, 2025-09-12 at 10:43 -0700, Coco Li wrote:
> Hello Andrew,
> 
> I discussed with the original author of the patch and the Nuvoton
> functionality mentioned above has not been upstreamed since then,
> unfortunately.

Okay, so can you please update the commit message to reflect this?

> Aside from the comment above, we believe this patch series allows gpios to
> be accessed more dynamically/flexibly in complicated simulation, and also
> helps with accessing advanced gpio features, see the sgpio implementation
> later in this patch series.

Can you please add a discussion of these complex simulations to the
commit message? I'd like a description of what you're doing where the
current pin-specific interface is insufficient. Motivations help a lot
with the patch review.

Thanks,

Andrew
Re: [PATCH 1/5] hw/gpio: Add property for ASPEED GPIO in 32 bits basis
Posted by Cédric Le Goater 5 months ago
+Andrew for awareness

On 9/3/25 23:38, Coco Li wrote:
> From: Felix Wu <flwu@google.com>
> 
> Added 32 bits property for ASPEED GPIO. Previously it can only be access in bitwise manner.
> 
> This change gives ASPEED similar behavior as Nuvoton.
> 
> Signed-off-by: Felix Wu <flwu@google.com>
> ---
>   hw/gpio/aspeed_gpio.c | 57 +++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 57 insertions(+)
> 
> diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
> index 609a556908..2d78bf9515 100644
> --- a/hw/gpio/aspeed_gpio.c
> +++ b/hw/gpio/aspeed_gpio.c
> @@ -1308,6 +1308,57 @@ static void aspeed_gpio_2700_write(void *opaque, hwaddr offset,
>   }
>   
>   /* Setup functions */
> +static void aspeed_gpio_set_set(Object *obj, Visitor *v,
> +                                        const char *name, void *opaque,
> +                                        Error **errp)
> +{
> +    uint32_t set_val = 0;
> +    AspeedGPIOState *s = ASPEED_GPIO(obj);
> +    AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
> +    int set_idx = 0;
> +
> +    if (!visit_type_uint32(v, name, &set_val, errp)) {
> +        return;
> +    }
> +
> +    if (sscanf(name, "gpio-set[%d]", &set_idx) != 1) {
> +        error_setg(errp, "%s: error reading %s", __func__, name);
> +        return;
> +    }
> +
> +    if (set_idx >= agc->nr_gpio_sets || set_idx < 0) {
> +        error_setg(errp, "%s: invalid set_idx %s", __func__, name);
> +        return;
> +    }
> +
> +    aspeed_gpio_update(s, &s->sets[set_idx], set_val,
> +                       ~s->sets[set_idx].direction);
> +}
> +
> +static void aspeed_gpio_get_set(Object *obj, Visitor *v,
> +                                        const char *name, void *opaque,
> +                                        Error **errp)
> +{
> +    uint32_t set_val = 0;
> +    AspeedGPIOState *s = ASPEED_GPIO(obj);
> +    AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
> +    int set_idx = 0;
> +
> +    if (sscanf(name, "gpio-set[%d]", &set_idx) != 1) {
> +        error_setg(errp, "%s: error reading %s", __func__, name);
> +        return;
> +    }
> +
> +    if (set_idx >= agc->nr_gpio_sets || set_idx < 0) {
> +        error_setg(errp, "%s: invalid set_idx %s", __func__, name);
> +        return;
> +    }
> +
> +    set_val = s->sets[set_idx].data_value;
> +    visit_type_uint32(v, name, &set_val, errp);
> +}
> +
> +/****************** Setup functions ******************/
>   static const GPIOSetProperties ast2400_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
>       [0] = {0xffffffff,  0xffffffff,  {"A", "B", "C", "D"} },
>       [1] = {0xffffffff,  0xffffffff,  {"E", "F", "G", "H"} },
> @@ -1435,6 +1486,12 @@ static void aspeed_gpio_init(Object *obj)
>               g_free(name);
>           }
>       }
> +
> +    for (int i = 0; i < agc->nr_gpio_sets; i++) {
> +        char *name = g_strdup_printf("gpio-set[%d]", i);
> +        object_property_add(obj, name, "uint32", aspeed_gpio_get_set,
> +        aspeed_gpio_set_set, NULL, NULL);
> +    }
>   }
>   
>   static const VMStateDescription vmstate_gpio_regs = {