Re: [PATCH V4 12/14] i3c: mipi-i3c-hci-pci: Propagate I3C wakeup requirements to PCI
Frank Li <[email protected]>
| Newsgroups | org.infradead.lists.linux-i3c,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pci,org.kernel.vger.linux-pm |
|---|---|
| Message-ID | <anTVr7sk3Cd4jJE5@lizhi-Precision-Tower-5810> |
On Thu, Aug 06, 2026 at 04:18:55PM +0300, Adrian Hunter wrote: > Keep the PCI wakeup state aligned with the wakeup requirements of the > devices served by the controller(s). > > The PCI function is the wakeup source for HCI instances exposed beneath > it. However, wakeup is only needed when at least one attached I3C device > is enabled as a wakeup source. > > During suspend, check whether any HCI instance has a wakeup-enabled I3C > device and enable wakeup for the PCI function only in that case. > Otherwise leave PCI wakeup disabled. > > Note, the suspend callback is used for both system and runtime suspend. > Although this change may update the PCI wakeup state during runtime > suspend, it does so only when the required wakeup state changes. > Moreover, PCI wakeup-capable devices already have PME wakeup armed for > runtime suspend, so changing the wakeup-enabled state does not affect > runtime PM wakeup behavior. > > Note also, since the PCI wakeup state is derived from the wakeup > configuration of the attached I3C devices, the PCI device power/wakeup > sysfs attribute no longer provides independent wakeup control. > > Signed-off-by: Adrian Hunter <[email protected]> Reviewed-by: Frank Li <[email protected]> > --- > > > Changes in V4: > > Updated for the rename of i3c_master_any_wakeup_enabled() to > i3c_master_has_wakeup_enabled_devs(). > > Changes in V2 and V3: > > None > > > .../master/mipi-i3c-hci/mipi-i3c-hci-pci.c | 23 +++++++++++++++++-- > 1 file changed, 21 insertions(+), 2 deletions(-) > > diff --git a/drivers/i3c/master/mipi-i3c-hci/mipi-i3c-hci-pci.c b/drivers/i3c/master/mipi-i3c-hci/mipi-i3c-hci-pci.c > index 5a9e2a43eff8..42c172e82622 100644 > --- a/drivers/i3c/master/mipi-i3c-hci/mipi-i3c-hci-pci.c > +++ b/drivers/i3c/master/mipi-i3c-hci/mipi-i3c-hci-pci.c > @@ -265,6 +265,8 @@ static bool mipi_i3c_hci_pci_is_operational(struct device *dev, bool update) > struct mipi_i3c_hci_pci_pm_data { > struct device *dev[INST_MAX]; > int dev_cnt; > + bool can_wakeup; > + bool may_wakeup; > }; > > static bool mipi_i3c_hci_pci_is_mfd(struct device *dev) > @@ -272,6 +274,13 @@ static bool mipi_i3c_hci_pci_is_mfd(struct device *dev) > return dev_is_platform(dev) && mfd_get_cell(to_platform_device(dev)); > } > > +static bool mipi_i3c_hci_pci_any_wakeup_enabled(struct device *dev) > +{ > + struct i3c_hci *hci = dev_get_drvdata(dev); > + > + return i3c_master_has_wakeup_enabled_devs(&hci->master); > +} > + > static int mipi_i3c_hci_pci_suspend_instance(struct device *dev, void *data) > { > struct mipi_i3c_hci_pci_pm_data *pm_data = data; > @@ -287,6 +296,9 @@ static int mipi_i3c_hci_pci_suspend_instance(struct device *dev, void *data) > > pm_data->dev[pm_data->dev_cnt++] = dev; > > + if (pm_data->can_wakeup && mipi_i3c_hci_pci_any_wakeup_enabled(dev)) > + pm_data->may_wakeup = true; > + > return 0; > } > > @@ -317,12 +329,19 @@ static int mipi_i3c_hci_pci_suspend(struct device *dev) > if (!hci->info->control_instance_pm) > return 0; > > + pm_data.can_wakeup = device_can_wakeup(dev); > + > ret = device_for_each_child_reverse(dev, &pm_data, mipi_i3c_hci_pci_suspend_instance); > - if (ret) > + if (ret) { > for (int i = 0; i < pm_data.dev_cnt; i++) > i3c_hci_rpm_resume(pm_data.dev[i]); > + return ret; > + } > > - return ret; > + if (device_may_wakeup(dev) != pm_data.may_wakeup) > + device_set_wakeup_enable(dev, pm_data.may_wakeup); > + > + return 0; > } > > static int mipi_i3c_hci_pci_resume(struct device *dev) > -- > 2.53.0 > -- linux-i3c mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-i3c