On Fri, Jul 05, 2019 at 05:44:01PM +0300, Yehezkel Bernat wrote: > On Fri, Jul 5, 2019 at 12:58 PM Mika Westerberg > <mika.westerberg@xxxxxxxxxxxxxxx> wrote: > > > > +static void icm_icl_rtd3_veto(struct tb *tb, const struct icm_pkg_header *hdr) > > +{ > > + const struct icm_icl_event_rtd3_veto *pkg = > > + (const struct icm_icl_event_rtd3_veto *)hdr; > > + struct icm *icm = tb_priv(tb); > > + > > + tb_dbg(tb, "ICM rtd3 veto=0x%08x\n", pkg->veto_reason); > > + > > + if (pkg->veto_reason) { > > + if (!icm->veto) { > > + icm->veto = true; > > + /* Keep the domain powered while veto is in effect */ > > + pm_runtime_get(&tb->dev); > > + } > > + } else { > > + if (icm->veto) { > > + icm->veto = false; > > + /* Allow the domain suspend now */ > > + pm_runtime_mark_last_busy(&tb->dev); > > + pm_runtime_put_autosuspend(&tb->dev); > > Handling the removal of the veto is duplicated below. Worth introducing as a > helper function? > > > + } > > + } > > +} > > + > > ... > > > @@ -1853,6 +1943,18 @@ static void icm_complete(struct tb *tb) > > if (tb->nhi->going_away) > > return; > > > > + /* > > + * If RTD3 was vetoed before we entered system suspend allow it > > + * again now before driver ready is sent. Firmware sends a new RTD3 > > + * veto if it is still the case after we have sent it driver ready > > + * command. > > + */ > > + if (icm->veto) { > > + icm->veto = false; > > + pm_runtime_mark_last_busy(&tb->dev); > > + pm_runtime_put_autosuspend(&tb->dev); > > + } > > + > > Here is the duplication. Indeed, I'll put it to a helper function. > > +static int nhi_suspend_power_down(struct tb *tb) > > +{ > > + int ret; > > + > > + /* > > + * If there is no device connected we need to perform an additional > > + * handshake through LC mailbox and force power down before > > + * entering D3. > > + */ > > + ret = device_for_each_child(&tb->root_switch->dev, NULL, > > + nhi_device_connected); > > + if (!ret) { > > + lc_mailbox_cmd(tb->nhi, LC_PREPARE_FOR_RESET); > > + ret = lc_mailbox_cmd_complete(tb->nhi, > > + LC_MAILBOX_TIMEOUT); > > + if (ret) > > + return ret; > > + > > + return nhi_power_down(tb->nhi); > > Just to be sure: unforce power is done only if no device is connected? > My understanding of the comment above was that unforce power should be done > anyway (so it should be outside of this if block), and the difference between > the cases is only about the additional LC mailbox message. I guess I misread it. nhi_power_down() should be only called if no device was connected so it should be in correct place. I can try to clarify the comment a bit, though.