RE: RE: [PATCH] i3c: master: dw-i3c-master: fix OD timing for first broadcast

"Guntupalli, Manikanta" <[email protected]>
Newsgroups org.infradead.lists.linux-i3c
Message-ID <CY8PR12MB761142838F98DC828AF472248CF62@CY8PR12MB7611.namprd12.prod.outlook.com>
Public

Hi,

Adding the below contact:
+@Datta, Shubhrajyoti

Thanks,
Manikanta

> -----Original Message-----
> From: NG, TZE YEE <[email protected]>
> Sent: Wednesday, July 1, 2026 11:16 AM
> To: Guntupalli, Manikanta <[email protected]>
> Cc: [email protected]; [email protected]; Frank Li
> <[email protected]>
> Subject: Re: RE: [PATCH] i3c: master: dw-i3c-master: fix OD timing for first
> broadcast
>
> On 24/6/2026 2:44 pm, Guntupalli, Manikanta wrote:
> > Public
> >
> > Hi Tze Yee Ng,
> >
> > We will check this on our end and get back to you shortly with an update.
> >
> > Thanks,
> > Manikanta
> >
> >
>
> Hi Manikanta,
>
> Gentle follow-up on the AMD quirk question below. It has been about a week since
> your 24 June reply, and I have not seen an update yet.
>
> For AMDI0015 with AMD_I3C_OD_PP_TIMING, I still need your guidance on:
> - what OD timing ->set_speed(NORMAL) should restore,
> - how ->set_speed(SLOW) should be programmed, and
> - whether send_ccc_cmd() should keep forcing AMD_I3C_OD_TIMING before every
> CCC.
>
> Once I have your input, I can send an AMD-specific follow-up patch.
>
> Thanks,
> Tze Yee Ng
>
> >> -----Original Message-----
> >> From: NG, TZE YEE <[email protected]>
> >> Sent: Friday, June 19, 2026 1:49 PM
> >> To: Guntupalli, Manikanta <[email protected]>
> >> Cc: [email protected]; [email protected]; Frank Li
> >> <[email protected]>
> >> Subject: Re: [PATCH] i3c: master: dw-i3c-master: fix OD timing for
> >> first broadcast
> >>
> >> On 12/6/2026 3:58 pm, Ng, Tze Yee wrote:
> >>> On 12/6/2026 12:21 am, Frank Li wrote:
> >>>> [You don't often get email from [email protected]. Learn why
> >>>> this is important at https://aka.ms/LearnAboutSenderIdentification
> >>>> ]
> >>>>
> >>>> On Wed, Jun 10, 2026 at 08:36:55AM +0000, [email protected] wrote:
> >>>>> Thank you for your contribution! Sashiko AI review found 5
> >>>>> potential
> >>>>> issue(s) to consider:
> >>>>>
> >>>>> New issues:
> >>>>> - [High] The newly introduced `dw_i3c_master_set_speed()`
> >>>>> permanently overwrites hardware-specific AMD timings with generic timings.
> >>>>> - [High] The `od_hcnt` calculation for `I3C_OPEN_DRAIN_SLOW_SPEED`
> >>>>> violates the `tHIGH_INIT` minimum requirement.
> >>>>>
> >>>>> Pre-existing issues:
> >>>>> - [High] The IRQ handler accesses hardware registers without
> >>>>> Runtime PM protection.
> >>>>> - [High] Use-After-Free and invalid `queue_work()` due to improper
> >>>>> teardown ordering in `dw_i3c_common_remove()`.
> >>>>> - [High] `dw_i3c_master_set_dev_nack_retry` modifies hardware
> >>>>> registers without resuming the device via Runtime PM.
> >>>>> --
> >>>>>
> >>>>> commit bd5322e3d6d6cd3a6a8155f24cc89a12fe61be00
> >>>>> Author: Tze Yee Ng <[email protected]>
> >>>>>
> >>>>> i3c: master: dw-i3c-master: fix OD timing for first broadcast
> >>>>>
> >>>>> This commit implements the set_speed() callback to switch
> >>>>> open-drain timing for the first broadcast address to slow speed.
> >>>>> It aims to fix I2C devices with spike filters not being detected
> >>>>> on mixed buses by dynamically switching between slow and normal open
> drain speeds.
> >>>>>
> >>>>>> diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/
> >>>>>> master/dw-i3c-master.c index a7593d6efac5a..6cf7071d3d06b 100644
> >>>>>> --- a/drivers/i3c/master/dw-i3c-master.c
> >>>>>> +++ b/drivers/i3c/master/dw-i3c-master.c
> >>>>> [ ... ]
> >>>>>> @@ -1484,6 +1485,57 @@ static irqreturn_t
> >>>>>> dw_i3c_master_irq_handler(int irq, void *dev_id)
> >>>>>>       return IRQ_HANDLED;
> >>>>>>    }
> >>>>>
> >>>>> [Severity: High]
> >>>>> This is a pre-existing issue, but does the IRQ handler access
> >>>>> hardware registers without Runtime PM protection?
> >>>>>
> >>>>> The interrupt handler directly reads hardware registers before
> >>>>> checking the device's PM active state:
> >>>>>
> >>>>> drivers/i3c/master/dw-i3c-master.c:dw_i3c_master_irq_handler() {
> >>>>>       ...
> >>>>>       status = readl(master->regs + INTR_STATUS);
> >>>>>       ...
> >>>>> }
> >>>>>
> >>>>> Since the driver does not synchronize IRQs in its runtime_suspend
> >>>>> callback, if an interrupt arrives right as the device enters
> >>>>> runtime suspend (or if a spurious interrupt occurs), will this raw
> >>>>> register read access powered-down hardware and cause a synchronous
> >>>>> external abort?
> >>>>>
> >>>>>> +static int dw_i3c_master_set_speed(struct i3c_master_controller
> >>>>>> +*m,
> >>>>>> +                              enum i3c_open_drain_speed speed) {
> >>>>> [ ... ]
> >>>>>> +   switch (speed) {
> >>>>>> +   case I3C_OPEN_DRAIN_SLOW_SPEED:
> >>>>> [ ... ]
> >>>>>> +           core_period = DIV_ROUND_UP(1000000000, core_rate);
> >>>>>> +           lcnt =
> >>>>>> +SCL_I3C_TIMING_LCNT(master->i3c_od_timing_normal);
> >>>>>> +           od_hcnt = max_t(u8, SCL_I3C_TIMING_CNT_MIN,
> >>>>>> +
> >>>>>> +DIV_ROUND_UP(I3C_BUS_THIGH_INIT_OD_MIN_NS,
> >>>>>> +                                        core_period) - 1);
> >>>>>
> >>>>> [Severity: High]
> >>>>> Does this precision loss guarantee the resulting pulse is shorter
> >>>>> than the specification minimum for certain clock frequencies?
> >>>>>
> >>>>> If core_period is calculated by rounding up 1000000000 /
> >>>>> core_rate, using this overestimated integer in the division
> >>>>> DIV_ROUND_UP(I3C_BUS_THIGH_INIT_OD_MIN_NS, core_period) - 1
> >>>>> underestimates the necessary cycle count.
> >>>>>
> >>>>> For example, at a 133.3 MHz core rate, the exact period is 7.5 ns
> >>>>> but core_period evaluates to 8 ns. The calculated cycle count
> >>>>> evaluates to 25 cycles, which produces a 187.5 ns pulse.
> >>>>>
> >>>>> Does this violate the strict 200 ns minimum for tHIGH_INIT
> >>>>> required by the I3C specification?
> >>>>
> >>>> Is it true?
> >>>>
> >>>>>
> >>>>>> +           scl_timing = SCL_I3C_TIMING_HCNT(od_hcnt) |
> >>>>>> +                        SCL_I3C_TIMING_LCNT(lcnt);
> >>>>>> +           writel(scl_timing, master->regs + SCL_I3C_OD_TIMING);
> >>>>>> +           master->i3c_od_timing = scl_timing;
> >>>>>> +           break;
> >>>>>> +
> >>>>>> +   case I3C_OPEN_DRAIN_NORMAL_SPEED:
> >>>>>> +           writel(master->i3c_od_timing_normal,
> >>>>>> +                  master->regs + SCL_I3C_OD_TIMING);
> >>>>>
> >>>>> [Severity: High]
> >>>>> Does unconditionally restoring master->i3c_od_timing_normal here
> >>>>> permanently overwrite hardware-specific AMD timings with generic
> >>>>> timings?
> >>>>>
> >>>>> If amd_configure_od_pp_quirk() is not updated to modify
> >>>>> master->i3c_od_timing_normal, restoring it after a broadcast
> >>>>> master->destroys
> >>>>> the
> >>>>> required AMD-specific quirk timings.
> >>>>>
> >>>>> Additionally, does dw_i3c_master_send_ccc_cmd() unconditionally
> >>>>> overwrite the OD timing with AMD normal timing right before
> >>>>> sending a broadcast CCC, bypassing the
> I3C_OPEN_DRAIN_SLOW_SPEED
> >>>>> state expected by the I3C core?
> >>>>>
> >>>>>> +           master->i3c_od_timing = master->i3c_od_timing_normal;
> >>>>>> +           break;
> >>>>
> >>>> Please check this also?
> >>>>
> >>>> Frank
> >>>>
> >>>>> [ ... ]
> >>>>>> +static int dw_i3c_master_set_dev_nack_retry(struct
> >>>>>> i3c_master_controller *m,
> >>>>>> +                                       unsigned long
> >>>>>> dev_nack_retry_cnt)
> >>>>>> +{
> >>>>> [ ... ]
> >>>>>> +   for (i = 0; i < master->maxdevs; i++) {
> >>>>>> +           /* Skip free/empty slots */
> >>>>>> +           if (master->free_pos & BIT(i))
> >>>>>> +                   continue;
> >>>>>> +
> >>>>>> +           reg = readl(master->regs +
> >>>>>> +
> >>>>>> +DEV_ADDR_TABLE_LOC(master->datstartaddr,
> >>>>>> i));
> >>>>>
> >>>>> [Severity: High]
> >>>>> This is a pre-existing issue, but does this function modify
> >>>>> hardware registers without resuming the device via Runtime PM?
> >>>>>
> >>>>> The sysfs attribute dev_nack_retry_count directly invokes
> >>>>> master->ops->set_dev_nack_retry(). Since sysfs callbacks can be
> >>>>> triggered
> >>>>> from userspace at any time, executing this while the device is
> >>>>> runtime suspended will access powered-down hardware.
> >>>>>
> >>>>> On ARM SoCs, can this trigger a kernel panic (external abort) and
> >>>>> allow userspace to trivially crash the system?
> >>>>>
> >>>>> [ ... ]
> >>>>>
> >>>>> [Severity: High]
> >>>>> This is a pre-existing issue, but is there a use-after-free or
> >>>>> invalid
> >>>>> queue_work() due to improper teardown ordering in
> >>>>> dw_i3c_common_remove()?
> >>>>>
> >>>>> dw_i3c_common_remove() calls cancel_work_sync(&master->hj_work)
> >>>>> before the
> >>>>> hardware interrupt is disabled and freed by devres:
> >>>>>
> >>>>> drivers/i3c/master/dw-i3c-master.c:dw_i3c_common_remove() {
> >>>>>       ...
> >>>>>       cancel_work_sync(&master->hj_work);
> >>>>>       i3c_master_unregister(&master->base);
> >>>>>       ...
> >>>>> }
> >>>>>
> >>>>> Because the IRQ remains active throughout the function and during
> >>>>> early devres teardown, can an incoming Hot Join interrupt trigger
> >>>>> the IRQ handler, which will call queue_work() to re-queue hj_work?
> >>>>>
> >>>>> Does this either cause queue_work() to execute on a destroyed
> >>>>> workqueue or result in a use-after-free when the workqueue
> >>>>> subsequently processes the work using the master object that has
> >>>>> already been freed by devres?
> >>>>>
> >>>>> --
> >>>>> Sashiko AI review · https://nam10.safelinks.protection.outlook.com/?
> >>>>>
> >>
> url=https%3A%2F%2Fsashiko.dev%2F%23%2Fpatchset%2Febddb8b62eae92de0a
> >> 7
> >>>>> eeda93cb18213c677ae96.1781077653.git.tze.yee.ng%40altera.com%3Fpar
> >>>>> t%
> >>>>>
> >>
> 3D1&data=05%7C02%7Ctze.yee.ng%40altera.com%7C8e2758995cb645fd357608
> >> d
> >>>>>
> >>
> ec7d58fc1%7Cfbd72e03d4a54110adce614d51f2077a%7C0%7C0%7C6391679172
> >> 502
> >>>>>
> >>
> 16401%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLj
> >> AuMD
> >>>>>
> >>
> AwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%
> >> 7C&
> >>>>>
> >>
> sdata=by5%2FiOLcg8kdN%2FkGUwg3B988Zkk3%2FjQJA%2FOqMllYOY0%3D&r
> >> eserve
> >>>>> d=0
> >>>>>
> >>>>> --
> >>>>> linux-i3c mailing list
> >>>>> [email protected]
> >>>>> https://nam10.safelinks.protection.outlook.com/?
> >>>>> url=http%3A%2F%2Flists.infradead.org%2Fmailman%2Flistinfo%2Flinux-
> >>>>>
> >>
> i3c&data=05%7C02%7Ctze.yee.ng%40altera.com%7C8e2758995cb645fd357608d
> >>>>>
> >>
> ec7d58fc1%7Cfbd72e03d4a54110adce614d51f2077a%7C0%7C0%7C6391679172
> >> 502
> >>>>>
> >>
> 61515%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLj
> >> AuMD
> >>>>>
> >>
> AwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%
> >> 7C&
> >>>>>
> sdata=yRfffqH10vlfqPSccrkt3XJkPqEDr7Ecoe08uXGamcQ%3D&reserved=0
> >>>
> >>> Hi Frank,
> >>>
> >>> Sashiko is correct that the initial core_period-based calculation
> >>> could undershoot the 200 ns tHIGH_INIT minimum at some core clock
> >>> rates. I checked the Zephyr DesignWare I3C driver, which uses a
> >>> core_rate-based calculation aligned with the DWC timing model. v2
> >>> will adopt the same
> >>> approach:
> >>>
> >>> od_hcnt = DIV_ROUND_UP((u64)I3C_BUS_THIGH_INIT_OD_MIN_NS *
> >> core_rate,
> >>>                          1000000000ULL) - 1;
> >>>
> >>> still using the existing - 1 and SCL_I3C_TIMING_CNT_MIN convention
> >>> from dw_i3c_clk_cfg().
> >>>
> >>> Reference: https://github.com/zephyrproject-rtos/zephyr/
> >>> commit/4d6673bc693920bdacf96d7cd3cfeb71d421e0ae
> >>> (drivers/i3c/i3c_dw.c,
> >>> dw_i3c_init_scl_timing())
> >>>
> >>> For AMD specific timings,  I left existing AMD behavior unchanged in v1.
> >>> @Manikanta Guntupalli, for AMDI0015, should ->set_speed() use
> >>> AMD_I3C_OD_TIMING or generic timing as the normal OD baseline at
> >>> slow/ normal speed? I can add AMD-specific handling in v2 once that is
> clarified.
> >>>
> >>> Thanks,
> >>> Tze Yee
> >>
> >> Hi Manikanta,
> >>
> >> Just checking whether you had a chance to look at the AMD
> >> dw-i3c-master question below.
> >>
> >> For AMDI0015, I need to know whether ->set_speed() should use
> >> AMD_I3C_OD_TIMING or generic OD timing as the normal baseline, and
> >> whether
> >> send_ccc_cmd() should stop overwriting OD timing before RSTDAA.
> >>
> >> Once I have your guidance, I can send an AMD-specific follow-up patch.
> >>
> >> Thanks,
> >> Tze Yee Ng
> >

-- 
linux-i3c mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-i3c
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.