Reviewed-by: Glenn Miles <[email protected]>

Thanks,

Glenn

On Fri, 2026-11-06 at 12:04 +0100, Markus Armbruster wrote:
> Pass the index via object_class_property_add() parameter @opaque
> instead extracting it from the property name.
> 
> Signed-off-by: Markus Armbruster <[email protected]>
> ---
>  hw/gpio/pca9552.c | 60 ++++++++++++++---------------------------------
>  hw/gpio/pca9554.c | 30 +++++++-----------------
>  2 files changed, 25 insertions(+), 65 deletions(-)
> 
> diff --git a/hw/gpio/pca9552.c b/hw/gpio/pca9552.c
> index f97ad6d083..c8d0e9a16d 100644
> --- a/hw/gpio/pca9552.c
> +++ b/hw/gpio/pca9552.c
> @@ -360,18 +360,12 @@ static void pca955x_get_led(Object *obj, Visitor *v, 
> const char *name,
>  {
>      PCA955xClass *k = PCA955X_GET_CLASS(obj);
>      PCA955xState *s = PCA955X(obj);
> -    int led, rc, reg;
> +    uintptr_t led = (uintptr_t)opaque;
> +    int reg;
>      Pca9552LedState state;
>  
> -    rc = sscanf(name, "led%2d", &led);
> -    if (rc != 1) {
> -        error_setg(errp, "%s: error reading %s", __func__, name);
> -        return;
> -    }
> -    if (led < 0 || led >= k->pin_count) {
> -        error_setg(errp, "%s: invalid led %s", __func__, name);
> -        return;
> -    }
> +    assert(led < k->pin_count);
> +
>      /*
>       * Get the LSx register as the qom interface should expose the device
>       * state, not the modeled 'input line' behaviour which would come from
> @@ -397,21 +391,15 @@ static void pca955x_set_led(Object *obj, Visitor *v, 
> const char *name,
>  {
>      PCA955xClass *k = PCA955X_GET_CLASS(obj);
>      PCA955xState *s = PCA955X(obj);
> -    int led, rc, reg, val;
> +    uintptr_t led = (uintptr_t)opaque;
> +    int reg, val;
>      Pca9552LedState state;
>  
> +    assert(led < k->pin_count);
> +
>      if (!visit_type_Pca9552LedState(v, name, &state, errp)) {
>          return;
>      }
> -    rc = sscanf(name, "led%2d", &led);
> -    if (rc != 1) {
> -        error_setg(errp, "%s: error reading %s", __func__, name);
> -        return;
> -    }
> -    if (led < 0 || led >= k->pin_count) {
> -        error_setg(errp, "%s: invalid led %s", __func__, name);
> -        return;
> -    }
>  
>      reg = PCA9552_LS0 + led / 4;
>      val = pca955x_read(s, reg);
> @@ -426,19 +414,11 @@ static void pca955x_get_pin(Object *obj, Visitor *v, 
> const char *name,
>  {
>      PCA955xClass *k = PCA955X_GET_CLASS(obj);
>      PCA955xState *s = PCA955X(obj);
> -    int pin, rc;
> +    uintptr_t pin = (uintptr_t)opaque;
>      uint8_t input_reg;
>      GpioPinState state;
>  
> -    rc = sscanf(name, "pin%2d", &pin);
> -    if (rc != 1) {
> -        error_setg(errp, "%s: error reading %s", __func__, name);
> -        return;
> -    }
> -    if (pin < 0 || pin >= k->pin_count) {
> -        error_setg(errp, "%s invalid pin %s", __func__, name);
> -        return;
> -    }
> +    assert(pin < k->pin_count);
>  
>      /*
>       * Report the raw pin logic level; polarity inversion is a read-time
> @@ -454,28 +434,22 @@ static void pca955x_set_pin(Object *obj, Visitor *v, 
> const char *name,
>  {
>      PCA955xClass *k = PCA955X_GET_CLASS(obj);
>      PCA955xState *s = PCA955X(obj);
> -    int pin, rc;
> +    uintptr_t pin = (uintptr_t)opaque;
>      GpioPinState state;
>      uint8_t config_reg;
>  
> +    assert(pin < k->pin_count);
> +
>      if (!visit_type_GpioPinState(v, name, &state, errp)) {
>          return;
>      }
> -    rc = sscanf(name, "pin%2d", &pin);
> -    if (rc != 1) {
> -        error_setg(errp, "%s: error reading %s", __func__, name);
> -        return;
> -    }
> -    if (pin < 0 || pin >= k->pin_count) {
> -        error_setg(errp, "%s invalid pin %s", __func__, name);
> -        return;
> -    }
>  
>      /* Only input-configured pins can be driven by an external device. */
>      config_reg = PCA9535_CONFIG0 + (pin / 8);
>      if (!((s->regs[config_reg] >> (pin % 8)) & 0x1)) {
>          qemu_log_mask(LOG_UNIMP,
> -                      "%s: pin %d is configured as output, ignoring set\n",
> +                      "%s: pin %" PRIdPTR " is configured as output, "
> +                      "ignoring set\n",
>                        s->description, pin);
>          return;
>      }
> @@ -549,14 +523,14 @@ static void pca955x_pin_init(PCA955xClass *k)
>              object_class_property_add(OBJECT_CLASS(k), name,
>                                        "str", &Pca9552LedState_type_info,
>                                        pca955x_get_led, pca955x_set_led,
> -                                      NULL, NULL);
> +                                      NULL, (void *)(uintptr_t)ix);
>          } else {
>              /* GPIO variant: expose the pin logic level as pin%d. */
>              name = g_strdup_printf("pin%d", ix);
>              object_class_property_add(OBJECT_CLASS(k), name,
>                                        "str", &GpioPinState_type_info,
>                                        pca955x_get_pin, pca955x_set_pin,
> -                                      NULL, NULL);
> +                                      NULL, (void *)(uintptr_t)ix);
>          }
>          g_free(name);
>      }
> diff --git a/hw/gpio/pca9554.c b/hw/gpio/pca9554.c
> index e2d481866f..d987b16cd0 100644
> --- a/hw/gpio/pca9554.c
> +++ b/hw/gpio/pca9554.c
> @@ -173,18 +173,10 @@ static void pca9554_get_pin(Object *obj, Visitor *v, 
> const char *name,
>                              void *opaque, Error **errp)
>  {
>      PCA9554State *s = PCA9554_BASE(obj);
> -    int pin, rc;
> +    uintptr_t pin = (uintptr_t)opaque;
>      GpioPinState state;
>  
> -    rc = sscanf(name, "pin%2d", &pin);
> -    if (rc != 1) {
> -        error_setg(errp, "%s: error reading %s", __func__, name);
> -        return;
> -    }
> -    if (pin < 0 || pin >= PCA9554_BASE_GET_CLASS(s)->pin_count) {
> -        error_setg(errp, "%s invalid pin %s", __func__, name);
> -        return;
> -    }
> +    assert(pin < PCA9554_BASE_GET_CLASS(s)->pin_count);
>  
>      /*
>       * Report the physical pin level. The input register is kept in sync by
> @@ -200,28 +192,22 @@ static void pca9554_set_pin(Object *obj, Visitor *v, 
> const char *name,
>                              void *opaque, Error **errp)
>  {
>      PCA9554State *s = PCA9554_BASE(obj);
> -    int pin, rc, val;
> +    uintptr_t pin = (uintptr_t)opaque;
> +    int val;
>      uint8_t mask;
>      GpioPinState state;
>  
> +    assert(pin < PCA9554_BASE_GET_CLASS(s)->pin_count);
> +
>      if (!visit_type_GpioPinState(v, name, &state, errp)) {
>          return;
>      }
> -    rc = sscanf(name, "pin%2d", &pin);
> -    if (rc != 1) {
> -        error_setg(errp, "%s: error reading %s", __func__, name);
> -        return;
> -    }
> -    if (pin < 0 || pin >= PCA9554_BASE_GET_CLASS(s)->pin_count) {
> -        error_setg(errp, "%s invalid pin %s", __func__, name);
> -        return;
> -    }
>  
>      if (s->hw_dir) {
>          /* Warn and ignore if the guest has configured this pin as output */
>          if (!((s->regs[PCA9554_CONFIG] >> pin) & 0x1)) {
>              qemu_log_mask(LOG_UNIMP,
> -                          "%s: pin %d is configured as output, "
> +                          "%s: pin %" PRIdPTR " is configured as output, "
>                            "ignoring external set\n",
>                            s->description, pin);
>              return;
> @@ -290,7 +276,7 @@ static void pca9554_pin_init(PCA9554Class *pc)
>          object_class_property_add(OBJECT_CLASS(pc), name,
>                                    "str", &GpioPinState_type_info,
>                                    pca9554_get_pin, pca9554_set_pin,
> -                                  NULL, NULL);
> +                                  NULL, (void *)(uintptr_t)pin);
>          g_free(name);
>      }
>  }


Reply via email to