Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

i3c: mipi-i3c-hci: Allow parent to manage runtime PM

Some platforms implement the MIPI I3C HCI Multi-Bus Instance capability,
where a single parent device hosts multiple I3C controller instances. In
such designs, the parent - not the individual child instances - may need to
coordinate runtime PM so that all controllers runtime PM callbacks are
invoked in a controlled and synchronized manner.

For example, if the parent enables IBI-wakeup when transitioning into a
low-power state, every bus instance must remain able to receive IBIs up
until that point. This requires deferring the individual controllers'
runtime suspend callbacks (which disable bus activity) until the parent
decides it is safe for all instances to suspend together.

To support this usage model:

* Export the low-level runtime PM suspend and resume helpers so that
the parent can explicitly invoke them.

* Add a new quirk, HCI_QUIRK_RPM_PARENT_MANAGED, allowing platforms to
bypass per-instance runtime PM callbacks and delegate control to the
parent device.

* Move DEFAULT_AUTOSUSPEND_DELAY_MS into the header so it can be shared
by parent-managed PM implementations.

The new quirk allows platforms with multi-bus parent-managed PM
infrastructure to correctly coordinate runtime PM across all I3C HCI
instances.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260306085338.62955-4-adrian.hunter@intel.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>

authored by

Adrian Hunter and committed by
Alexandre Belloni
82851828 5fe77a6d

+30 -4
+24 -4
drivers/i3c/master/mipi-i3c-hci/core.c
··· 759 759 return 0; 760 760 } 761 761 762 - static int i3c_hci_runtime_suspend(struct device *dev) 762 + int i3c_hci_rpm_suspend(struct device *dev) 763 763 { 764 764 struct i3c_hci *hci = dev_get_drvdata(dev); 765 765 int ret; ··· 776 776 777 777 return 0; 778 778 } 779 + EXPORT_SYMBOL_GPL(i3c_hci_rpm_suspend); 779 780 780 - static int i3c_hci_runtime_resume(struct device *dev) 781 + int i3c_hci_rpm_resume(struct device *dev) 781 782 { 782 783 struct i3c_hci *hci = dev_get_drvdata(dev); 783 784 int ret; ··· 800 799 reg_set(HC_CONTROL, HC_CONTROL_BUS_ENABLE | HC_CONTROL_HOT_JOIN_CTRL); 801 800 802 801 return 0; 802 + } 803 + EXPORT_SYMBOL_GPL(i3c_hci_rpm_resume); 804 + 805 + static int i3c_hci_runtime_suspend(struct device *dev) 806 + { 807 + struct i3c_hci *hci = dev_get_drvdata(dev); 808 + 809 + if (hci->quirks & HCI_QUIRK_RPM_PARENT_MANAGED) 810 + return 0; 811 + 812 + return i3c_hci_rpm_suspend(dev); 813 + } 814 + 815 + static int i3c_hci_runtime_resume(struct device *dev) 816 + { 817 + struct i3c_hci *hci = dev_get_drvdata(dev); 818 + 819 + if (hci->quirks & HCI_QUIRK_RPM_PARENT_MANAGED) 820 + return 0; 821 + 822 + return i3c_hci_rpm_resume(dev); 803 823 } 804 824 805 825 static int i3c_hci_suspend(struct device *dev) ··· 865 843 { 866 844 return i3c_hci_resume_common(dev, true); 867 845 } 868 - 869 - #define DEFAULT_AUTOSUSPEND_DELAY_MS 1000 870 846 871 847 static void i3c_hci_rpm_enable(struct device *dev) 872 848 {
+6
drivers/i3c/master/mipi-i3c-hci/hci.h
··· 151 151 #define HCI_QUIRK_RESP_BUF_THLD BIT(4) /* Set resp buf thld to 0 for AMD platforms */ 152 152 #define HCI_QUIRK_RPM_ALLOWED BIT(5) /* Runtime PM allowed */ 153 153 #define HCI_QUIRK_RPM_IBI_ALLOWED BIT(6) /* IBI and Hot-Join allowed while runtime suspended */ 154 + #define HCI_QUIRK_RPM_PARENT_MANAGED BIT(7) /* Runtime PM managed by parent device */ 154 155 155 156 /* global functions */ 156 157 void mipi_i3c_hci_resume(struct i3c_hci *hci); ··· 161 160 void amd_set_resp_buf_thld(struct i3c_hci *hci); 162 161 void i3c_hci_sync_irq_inactive(struct i3c_hci *hci); 163 162 int i3c_hci_process_xfer(struct i3c_hci *hci, struct hci_xfer *xfer, int n); 163 + 164 + #define DEFAULT_AUTOSUSPEND_DELAY_MS 1000 165 + 166 + int i3c_hci_rpm_suspend(struct device *dev); 167 + int i3c_hci_rpm_resume(struct device *dev); 164 168 165 169 #endif