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: master: Add i3c_master_do_daa_ext() for post-hibernation address recovery

After system hibernation, I3C Dynamic Addresses may be reassigned at boot
and no longer match the values recorded before suspend. Introduce
i3c_master_do_daa_ext() to handle this situation.

The restore procedure is straightforward: issue a Reset Dynamic Address
Assignment (RSTDAA), then run the standard DAA sequence. The existing DAA
logic already supports detecting and updating devices whose dynamic
addresses differ from previously known values.

Refactor the DAA path by introducing a shared helper used by both the
normal i3c_master_do_daa() path and the new extended restore function,
and correct the kernel-doc in the process.

Export i3c_master_do_daa_ext() so that master drivers can invoke it from
their PM restore callbacks.

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

authored by

Adrian Hunter and committed by
Alexandre Belloni
c481ef12 b58eaa47

+39 -11
+38 -11
drivers/i3c/master.c
··· 1768 1768 } 1769 1769 1770 1770 /** 1771 - * i3c_master_do_daa() - do a DAA (Dynamic Address Assignment) 1772 - * @master: master doing the DAA 1771 + * i3c_master_do_daa_ext() - Dynamic Address Assignment (extended version) 1772 + * @master: controller 1773 + * @rstdaa: whether to first perform Reset of Dynamic Addresses (RSTDAA) 1773 1774 * 1774 - * This function is instantiating an I3C device object and adding it to the 1775 - * I3C device list. All device information are automatically retrieved using 1776 - * standard CCC commands. 1775 + * Perform Dynamic Address Assignment with optional support for System 1776 + * Hibernation (@rstdaa is true). 1777 1777 * 1778 - * The I3C device object is returned in case the master wants to attach 1779 - * private data to it using i3c_dev_set_master_data(). 1780 - * 1781 - * This function must be called with the bus lock held in write mode. 1778 + * After System Hibernation, Dynamic Addresses can have been reassigned at boot 1779 + * time to different values. A simple strategy is followed to handle that. 1780 + * Perform a Reset of Dynamic Addresses (RSTDAA) followed by the normal DAA 1781 + * procedure which has provision for reassigning addresses that differ from the 1782 + * previously recorded addresses. 1782 1783 * 1783 1784 * Return: a 0 in case of success, an negative error code otherwise. 1784 1785 */ 1785 - int i3c_master_do_daa(struct i3c_master_controller *master) 1786 + int i3c_master_do_daa_ext(struct i3c_master_controller *master, bool rstdaa) 1786 1787 { 1788 + int rstret = 0; 1787 1789 int ret; 1788 1790 1789 1791 ret = i3c_master_rpm_get(master); ··· 1793 1791 return ret; 1794 1792 1795 1793 i3c_bus_maintenance_lock(&master->bus); 1794 + 1795 + if (rstdaa) { 1796 + rstret = i3c_master_rstdaa_locked(master, I3C_BROADCAST_ADDR); 1797 + if (rstret == I3C_ERROR_M2) 1798 + rstret = 0; 1799 + } 1800 + 1796 1801 ret = master->ops->do_daa(master); 1802 + 1797 1803 i3c_bus_maintenance_unlock(&master->bus); 1798 1804 1799 1805 if (ret) ··· 1812 1802 i3c_bus_normaluse_unlock(&master->bus); 1813 1803 out: 1814 1804 i3c_master_rpm_put(master); 1815 - return ret; 1805 + 1806 + return rstret ?: ret; 1807 + } 1808 + EXPORT_SYMBOL_GPL(i3c_master_do_daa_ext); 1809 + 1810 + /** 1811 + * i3c_master_do_daa() - do a DAA (Dynamic Address Assignment) 1812 + * @master: master doing the DAA 1813 + * 1814 + * This function instantiates I3C device objects and adds them to the 1815 + * I3C device list. All device information is automatically retrieved using 1816 + * standard CCC commands. 1817 + * 1818 + * Return: a 0 in case of success, an negative error code otherwise. 1819 + */ 1820 + int i3c_master_do_daa(struct i3c_master_controller *master) 1821 + { 1822 + return i3c_master_do_daa_ext(master, false); 1816 1823 } 1817 1824 EXPORT_SYMBOL_GPL(i3c_master_do_daa); 1818 1825
+1
include/linux/i3c/master.h
··· 605 605 int i3c_master_add_i3c_dev_locked(struct i3c_master_controller *master, 606 606 u8 addr); 607 607 int i3c_master_do_daa(struct i3c_master_controller *master); 608 + int i3c_master_do_daa_ext(struct i3c_master_controller *master, bool rstdaa); 608 609 struct i3c_dma *i3c_master_dma_map_single(struct device *dev, void *ptr, 609 610 size_t len, bool force_bounce, 610 611 enum dma_data_direction dir);