[PATCH V4 12/14] i3c: mipi-i3c-hci-pci: Propagate I3C wakeup requirements to PCI

Frank Li Frank.li at oss.nxp.com
Thu Aug 6 11:42:55 PDT 2026


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 <adrian.hunter at intel.com>

Reviewed-by: Frank Li <Frank.Li at nxp.com>

> ---
>
>
> 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
>



More information about the linux-i3c mailing list