2024-01-19 05:47:12

by Dylan Hung

[permalink] [raw]
Subject: [PATCH] i3c: dw: Disable IBI IRQ depends on hot-join and SIR enabling

Disable IBI IRQ signal and status only when hot-join and SIR enabling of
all target devices attached to the bus are disabled.

Fixes: e389b1d72a62 ("i3c: dw: Add support for in-band interrupts")

Signed-off-by: Dylan Hung <[email protected]>
---
drivers/i3c/master/dw-i3c-master.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
index ef5751e91cc9..276153e10f5a 100644
--- a/drivers/i3c/master/dw-i3c-master.c
+++ b/drivers/i3c/master/dw-i3c-master.c
@@ -1163,8 +1163,10 @@ static void dw_i3c_master_set_sir_enabled(struct dw_i3c_master *master,
global = reg == 0xffffffff;
reg &= ~BIT(idx);
} else {
- global = reg == 0;
+ bool hj_rejected = !!(readl(master->regs + DEVICE_CTRL) & DEV_CTRL_HOT_JOIN_NACK);
+
reg |= BIT(idx);
+ global = (reg == 0xffffffff) && hj_rejected;
}
writel(reg, master->regs + IBI_SIR_REQ_REJECT);

--
2.25.1



2024-02-18 23:33:22

by Alexandre Belloni

[permalink] [raw]
Subject: Re: [PATCH] i3c: dw: Disable IBI IRQ depends on hot-join and SIR enabling

On Fri, 19 Jan 2024 13:45:47 +0800, Dylan Hung wrote:
> Disable IBI IRQ signal and status only when hot-join and SIR enabling of
> all target devices attached to the bus are disabled.
>
> Fixes: e389b1d72a62 ("i3c: dw: Add support for in-band interrupts")
>
>

Applied, thanks!

[1/1] i3c: dw: Disable IBI IRQ depends on hot-join and SIR enabling
https://git.kernel.org/abelloni/c/10201396ef64

Best regards,

--
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

2024-02-19 20:39:00

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH] i3c: dw: Disable IBI IRQ depends on hot-join and SIR enabling

Fri, Jan 19, 2024 at 01:45:47PM +0800, Dylan Hung kirjoitti:
> Disable IBI IRQ signal and status only when hot-join and SIR enabling of
> all target devices attached to the bus are disabled.

> Fixes: e389b1d72a62 ("i3c: dw: Add support for in-band interrupts")
>
> Signed-off-by: Dylan Hung <[email protected]>

Tag block is not supposed to have blank lines.

..

> @@ -1163,8 +1163,10 @@ static void dw_i3c_master_set_sir_enabled(struct dw_i3c_master *master,
> global = reg == 0xffffffff;
> reg &= ~BIT(idx);
> } else {
> - global = reg == 0;
> + bool hj_rejected = !!(readl(master->regs + DEVICE_CTRL) & DEV_CTRL_HOT_JOIN_NACK);

'!!()' is redundant.

> +
> reg |= BIT(idx);
> + global = (reg == 0xffffffff) && hj_rejected;
> }

Moreover, you can refactor a bit both branches, like

bool hj_rejected = true;
...
if (...) {
...
} else {
hj_rejected = readl(master->regs + DEVICE_CTRL) & DEV_CTRL_HOT_JOIN_NACK;
...
}
global = (reg == 0xffffffff) && hj_rejected;


--
With Best Regards,
Andy Shevchenko



2024-05-01 06:22:22

by Jeremy Kerr

[permalink] [raw]
Subject: Re: [PATCH] i3c: dw: Disable IBI IRQ depends on hot-join and SIR enabling

Hi Dylan,

Just a question on a prior patch you sent:

> Disable IBI IRQ signal and status only when hot-join and SIR enabling
> of all target devices attached to the bus are disabled.
>
> Fixes: e389b1d72a62 ("i3c: dw: Add support for in-band interrupts")

[...]

> --- a/drivers/i3c/master/dw-i3c-master.c
> +++ b/drivers/i3c/master/dw-i3c-master.c
> @@ -1163,8 +1163,10 @@ static void dw_i3c_master_set_sir_enabled(struct dw_i3c_master *master,
>                 global = reg == 0xffffffff;
>                 reg &= ~BIT(idx);
>         } else {
> -               global = reg == 0;
> +               bool hj_rejected = !!(readl(master->regs + DEVICE_CTRL) & DEV_CTRL_HOT_JOIN_NACK);
> +
>                 reg |= BIT(idx);
> +               global = (reg == 0xffffffff) && hj_rejected;
>         }
>         writel(reg, master->regs + IBI_SIR_REQ_REJECT);
>  

My interpretation of this change is that we keep the "global" IBI irq
enabled if hot-join-nack is set (ie, always, because we don't support
hot join, and configure the hardware to nack all hot join requests).

However, we never enable the hot-join NACK interrupt - IBI_QUEUE_CTRL
bit 0 is never set. So I can't see how we would ever get an interrupt
for the hot join NACK case anyway. Because of that, this patch is just
keeping the IBI threshold interrupt always enabled for no reason.

Or is something else happening here? Is there another cause for the IBI
threshold IRQs?

Cheers,


Jeremy

2024-05-02 05:24:53

by Dylan Hung

[permalink] [raw]
Subject: RE: [PATCH] i3c: dw: Disable IBI IRQ depends on hot-join and SIR enabling

Hi Jeremy,

> -----Original Message-----
> From: Jeremy Kerr <[email protected]>
> Sent: Wednesday, May 1, 2024 2:22 PM
> To: Dylan Hung <[email protected]>;
> [email protected]; [email protected]; u.kleine-
> [email protected]; [email protected];
> [email protected]; [email protected];
> [email protected]; [email protected]; linux-
> [email protected]
> Cc: BMC-SW <[email protected]>
> Subject: Re: [PATCH] i3c: dw: Disable IBI IRQ depends on hot-join and SIR
> enabling
>
> Hi Dylan,
>
> Just a question on a prior patch you sent:
>
> > Disable IBI IRQ signal and status only when hot-join and SIR enabling
> > of all target devices attached to the bus are disabled.
> >
> > Fixes: e389b1d72a62 ("i3c: dw: Add support for in-band interrupts")
>
> [...]
>
> > --- a/drivers/i3c/master/dw-i3c-master.c
> > +++ b/drivers/i3c/master/dw-i3c-master.c
> > @@ -1163,8 +1163,10 @@ static void
> > dw_i3c_master_set_sir_enabled(struct dw_i3c_master *master,
> >                 global = reg == 0xffffffff;
> >                 reg &= ~BIT(idx);
> >         } else {
> > -               global = reg == 0;
> > +               bool hj_rejected = !!(readl(master->regs +
> > +DEVICE_CTRL) & DEV_CTRL_HOT_JOIN_NACK);
> > +
> >                 reg |= BIT(idx);
> > +               global = (reg == 0xffffffff) && hj_rejected;
> >         }
> >         writel(reg, master->regs + IBI_SIR_REQ_REJECT);
> >
>

```
if (global)
dw_i3c_master_enable_sir_signal(master, enable);
```

> My interpretation of this change is that we keep the "global" IBI irq enabled if
> hot-join-nack is set (ie, always, because we don't support hot join, and
> configure the hardware to nack all hot join requests).
>
I would like to clarify the control logic, incorporating the principle of disabling the SIR interrupt signal:

Case 1:
When `DEV_CTRL_HOT_JOIN_NACK` is set, indicating `hj_rejected` is true, it signifies the controller's non-receptiveness to the hot-join event. Consequently, we can safely disable the SIR interrupt signal if none of the target devices request SIR (reg == 0xffffffff).

Case 2:
When `DEV_CTRL_HOT_JOIN_NACK` is unset, indicating `hj_rejected` is false, this indicates the controller's readiness to engage with the hot-join event. Therefore, it's imperative to keep the SIR interrupt signal enabled, even if not all target devices request SIR. In this case, `global` is false and `enable` is false.

Here's a summary table to illustrate the logic:

| enable | reg==0xffffffff? | hj_rejected? | global | result |
|--- |--- |--- |--- |--- |
| false | true | true | true | disable SIR interrupt |
| false | false | true | false | keep SIR interrupt |
| false | true | false | false | keep SIR interrupt |
| false | false | false | false | keep SIR interrupt |

> However, we never enable the hot-join NACK interrupt - IBI_QUEUE_CTRL bit
> 0 is never set. So I can't see how we would ever get an interrupt for the hot
> join NACK case anyway. Because of that, this patch is just keeping the IBI
> threshold interrupt always enabled for no reason.
>

Billy recently submitted a change to implement the hot-join enabling/disabling. Therefore, it is timely to consider the hot-join functionality.
https://patchwork.kernel.org/project/linux-i3c/patch/[email protected]/

> Or is something else happening here? Is there another cause for the IBI
> threshold IRQs?
>
> Cheers,
>
>
> Jeremy

2024-05-06 05:10:02

by Jeremy Kerr

[permalink] [raw]
Subject: Re: [PATCH] i3c: dw: Disable IBI IRQ depends on hot-join and SIR enabling

Hi Dylan,

Thanks for the response! I have a couple of follow-up things though:

> > My interpretation of this change is that we keep the "global" IBI irq enabled if
> > hot-join-nack is set (ie, always, because we don't support hot join, and
> > configure the hardware to nack all hot join requests).
> >
> I would like to clarify the control logic, incorporating the principle
> of disabling the SIR interrupt signal:
>
> Case 1:
> When `DEV_CTRL_HOT_JOIN_NACK` is set, indicating `hj_rejected` is
> true, it signifies the controller's non-receptiveness to the hot-join
> event. Consequently, we can safely disable the SIR interrupt signal if
> none of the target devices request SIR (reg == 0xffffffff).
>
> Case 2:
> When `DEV_CTRL_HOT_JOIN_NACK` is unset, indicating `hj_rejected` is
> false, this indicates the controller's readiness to engage with the
> hot-join event. Therefore, it's imperative to keep the SIR interrupt
> signal enabled, even if not all target devices request SIR. In this
> case, `global` is false and `enable` is false.

Yep, I see what you're doing there, but it looks like the correct state
would never be set if we're not enabling/disabling the IBIs separately;
with this code, we would only ever enable the SIR for the HJ if we
*also* happen to enable IBIs.

The initial state would be to have all SIRs masked.

> Billy recently submitted a change to implement the hot-join enabling/disabling. Therefore, it is timely to consider the hot-join functionality.
> https://patchwork.kernel.org/project/linux-i3c/patch/[email protected]/

Yep, I saw that, excellent! It's next on my list to take a look at.

It's just a little unusual that we're enabling the HJ interrupt before
actually having the HJ support though.

Cheers,


Jeremy

2024-05-06 05:58:08

by Dylan Hung

[permalink] [raw]
Subject: RE: [PATCH] i3c: dw: Disable IBI IRQ depends on hot-join and SIR enabling

Hi Jeremy,

> -----Original Message-----
> From: Jeremy Kerr <[email protected]>
> Sent: Monday, May 6, 2024 1:10 PM
> To: Dylan Hung <[email protected]>;
> [email protected]; [email protected]; u.kleine-
> [email protected]; [email protected];
> [email protected]; [email protected];
> [email protected]; [email protected]; linux-
> [email protected]
> Cc: BMC-SW <[email protected]>
> Subject: Re: [PATCH] i3c: dw: Disable IBI IRQ depends on hot-join and SIR
> enabling
>
> Hi Dylan,
>
> Thanks for the response! I have a couple of follow-up things though:
>
> > > My interpretation of this change is that we keep the "global" IBI
> > > irq enabled if hot-join-nack is set (ie, always, because we don't
> > > support hot join, and configure the hardware to nack all hot join
> requests).
> > >
> > I would like to clarify the control logic, incorporating the principle
> > of disabling the SIR interrupt signal:
> >
> > Case 1:
> > When `DEV_CTRL_HOT_JOIN_NACK` is set, indicating `hj_rejected` is
> > true, it signifies the controller's non-receptiveness to the hot-join
> > event. Consequently, we can safely disable the SIR interrupt signal if
> > none of the target devices request SIR (reg == 0xffffffff).
> >
> > Case 2:
> > When `DEV_CTRL_HOT_JOIN_NACK` is unset, indicating `hj_rejected` is
> > false, this indicates the controller's readiness to engage with the
> > hot-join event. Therefore, it's imperative to keep the SIR interrupt
> > signal enabled, even if not all target devices request SIR. In this
> > case, `global` is false and `enable` is false.
>
> Yep, I see what you're doing there, but it looks like the correct state would
> never be set if we're not enabling/disabling the IBIs separately; with this code,
> we would only ever enable the SIR for the HJ if we
> *also* happen to enable IBIs.

When we want to enable the SIR, the current code doesn't check whether the
hot-join is enable or not. The modification I made pertains to disabling the SIR interrupt.
It doesn't alter the logic for enabling the SIR.

```
reg = readl(master->regs + IBI_SIR_REQ_REJECT);
if (enable) {
global = reg == 0xffffffff;
reg &= ~BIT(idx);
}
```

>
> The initial state would be to have all SIRs masked.
>

Yes, indeed. The "global" variable is also true because "reg == 0xffffffff" is true.
Therefore, the INTR_IBI_THLD_STAT bit will be set in the following code.

> > Billy recently submitted a change to implement the hot-join
> enabling/disabling. Therefore, it is timely to consider the hot-join
> functionality.
> > https://patchwork.kernel.org/project/linux-i3c/patch/20240429073624.25
> > [email protected]/
>
> Yep, I saw that, excellent! It's next on my list to take a look at.
>
> It's just a little unusual that we're enabling the HJ interrupt before actually
> having the HJ support though.
>
> Cheers,
>
>
> Jeremy

2024-05-06 06:58:19

by Jeremy Kerr

[permalink] [raw]
Subject: Re: [PATCH] i3c: dw: Disable IBI IRQ depends on hot-join and SIR enabling

Hi Dylan,

> > The initial state would be to have all SIRs masked.
> >
>
> Yes, indeed. The "global" variable is also true because "reg ==
> 0xffffffff" is true.
> Therefore, the INTR_IBI_THLD_STAT bit will be set in the following
> code.

That's mainly my point - none of this code is ever run unless the
->enable_ibi or ->disable_ibi controller callback is invoked.

So we'll end up with the HJ interrupt only being enabled if some i3c
device driver enables IBIs, which is a bit of a weird side-effect.

It probably makes more sense when the rest of the HJ code is added, but
not so much as a standalone patch.

Cheers,


Jeremy