From: Andrew Jeffery <andrew@codeconstruct.com.au>
To: "Jamin Lin" <jamin_lin@aspeedtech.com>,
"Cédric Le Goater" <clg@kaod.org>,
"Peter Maydell" <peter.maydell@linaro.org>,
"Steven Lee" <steven_lee@aspeedtech.com>,
"Troy Lee" <leetroy@gmail.com>, "Joel Stanley" <joel@jms.id.au>,
"open list:ASPEED BMCs" <qemu-arm@nongnu.org>,
"open list:All patches CC here" <qemu-devel@nongnu.org>
Cc: troy_lee@aspeedtech.com, yunlin.tang@aspeedtech.com
Subject: Re: [PATCH v3 4/6] hw/gpio/aspeed: Fix clear incorrect interrupt status for GPIO index mode
Date: Fri, 27 Sep 2024 11:42:47 +0930 [thread overview]
Message-ID: <4ca92b4ccaa8d66db990dc51d4d50aa7e648ad5a.camel@codeconstruct.com.au> (raw)
In-Reply-To: <20240926074535.1286209-5-jamin_lin@aspeedtech.com>
On Thu, 2024-09-26 at 15:45 +0800, Jamin Lin wrote:
> The interrupt status field is W1C, where a set bit on read indicates an
> interrupt is pending. If the bit extracted from data is set it should
> clear the corresponding bit in group_value. However, if the extracted
> bit is clear then the value of the corresponding bit in group_value
> should be unchanged.
>
> SHARED_FIELD_EX32() extracts the interrupt status bit from the write
> (data). group_value is set to the set's interrupt status, which means
I think you should s/group_value/reg_value/ here as that's what's used
in the removed code below.
Though maybe Cédric can fix it up for you when he applies it if another
revision isn't otherwise necessary.
> that for any pin with an interrupt pending, the corresponding bit is
> set. The deposit32() call updates the bit at pin_idx in the group,
> using the value extracted from the write (data).
>
> The result is that if multiple interrupt status bits
> were pending and the write was acknowledging specific one bit,
> then the all interrupt status bits will be cleared.
> However, it is index mode and should only clear the corresponding bit.
>
> For example, say we have an interrupt pending for GPIOA0, where the
> following statements are true:
>
> set->int_status == 0b01
> s->pending == 1
>
> Before it is acknowledged, an interrupt becomes pending for GPIOA1:
>
> set->int_status == 0b11
> s->pending == 2
>
> A write is issued to acknowledge the interrupt for GPIOA0. This causes
> the following sequence:
>
> reg_value == 0b11
> pending == 2
> s->pending == 0
> set->int_status == 0b00
>
> It should only clear bit 0 in index mode and the correct result
> should be as following.
>
> set->int_status == 0b11
> s->pending == 2
>
> pending == 1
> s->pending == 1
> set->int_status == 0b10
>
Maybe this is a bit forward, but:
Suggested-by: Andrew Jeffery <andrew@codeconstruct.com.au>
Reviewed-by: Andrew Jeffery <andrew@codeconstruct.com.au>
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
> hw/gpio/aspeed_gpio.c | 27 +++++++++++++++++----------
> 1 file changed, 17 insertions(+), 10 deletions(-)
>
> diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
> index 8725606aec..16c18ea2f7 100644
> --- a/hw/gpio/aspeed_gpio.c
> +++ b/hw/gpio/aspeed_gpio.c
> @@ -641,7 +641,7 @@ static void aspeed_gpio_write_index_mode(void *opaque, hwaddr offset,
> uint32_t pin_idx = reg_idx_number % ASPEED_GPIOS_PER_SET;
> uint32_t group_idx = pin_idx / GPIOS_PER_GROUP;
> uint32_t reg_value = 0;
> - uint32_t cleared;
> + uint32_t pending = 0;
>
> set = &s->sets[set_idx];
> props = &agc->props[set_idx];
> @@ -703,16 +703,23 @@ static void aspeed_gpio_write_index_mode(void *opaque, hwaddr offset,
> FIELD_EX32(data, GPIO_INDEX_REG, INT_SENS_2));
> set->int_sens_2 = update_value_control_source(set, set->int_sens_2,
> reg_value);
> - /* set interrupt status */
> - reg_value = set->int_status;
> - reg_value = deposit32(reg_value, pin_idx, 1,
> - FIELD_EX32(data, GPIO_INDEX_REG, INT_STATUS));
> - cleared = ctpop32(reg_value & set->int_status);
> - if (s->pending && cleared) {
> - assert(s->pending >= cleared);
> - s->pending -= cleared;
> + /* interrupt status */
> + if (FIELD_EX32(data, GPIO_INDEX_REG, INT_STATUS)) {
> + /* pending is either 1 or 0 for a 1-bit field */
> + pending = extract32(set->int_status, pin_idx, 1);
> +
> + assert(s->pending >= pending);
> +
> + /* No change to s->pending if pending is 0 */
> + s->pending -= pending;
> +
> + /*
> + * The write acknowledged the interrupt regardless of whether it
> + * was pending or not. The post-condition is that it mustn't be
> + * pending. Unconditionally clear the status bit.
> + */
> + set->int_status = deposit32(set->int_status, pin_idx, 1, 0);
> }
> - set->int_status &= ~reg_value;
> break;
> case gpio_reg_idx_debounce:
> reg_value = set->debounce_1;
next prev parent reply other threads:[~2024-09-27 2:13 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-26 7:45 [PATCH v3 0/6] Support GPIO for AST2700 Jamin Lin via
2024-09-26 7:45 ` [PATCH v3 1/6] hw/gpio/aspeed: Fix coding style Jamin Lin via
2024-09-26 16:08 ` Cédric Le Goater
2024-09-26 7:45 ` [PATCH v3 2/6] hw/gpio/aspeed: Support to set the different memory size Jamin Lin via
2024-09-26 16:08 ` Cédric Le Goater
2024-09-26 7:45 ` [PATCH v3 3/6] hw/gpio/aspeed: Support different memory region ops Jamin Lin via
2024-09-26 16:08 ` Cédric Le Goater
2024-09-26 7:45 ` [PATCH v3 4/6] hw/gpio/aspeed: Fix clear incorrect interrupt status for GPIO index mode Jamin Lin via
2024-09-27 2:12 ` Andrew Jeffery [this message]
2024-09-27 2:15 ` Jamin Lin
2024-09-26 7:45 ` [PATCH v3 5/6] hw/gpio/aspeed: Add AST2700 support Jamin Lin via
2024-09-27 2:19 ` Andrew Jeffery
2024-09-27 3:19 ` Jamin Lin
2024-09-26 7:45 ` [PATCH v3 6/6] aspeed/soc: Support GPIO for AST2700 Jamin Lin via
2024-09-26 16:10 ` Cédric Le Goater
2024-09-27 2:17 ` Jamin Lin
2024-09-26 16:12 ` [PATCH v3 0/6] " Cédric Le Goater
2024-09-27 2:16 ` Jamin Lin
2024-09-27 6:16 ` Cédric Le Goater
2024-09-27 6:29 ` Jamin Lin
2024-09-27 12:09 ` Cédric Le Goater
2024-09-27 14:18 ` Konstantin Ryabitsev
2024-09-30 6:00 ` Jamin Lin via
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4ca92b4ccaa8d66db990dc51d4d50aa7e648ad5a.camel@codeconstruct.com.au \
--to=andrew@codeconstruct.com.au \
--cc=clg@kaod.org \
--cc=jamin_lin@aspeedtech.com \
--cc=joel@jms.id.au \
--cc=leetroy@gmail.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=steven_lee@aspeedtech.com \
--cc=troy_lee@aspeedtech.com \
--cc=yunlin.tang@aspeedtech.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).