1313#include <zephyr/sys/byteorder.h>
1414#include <zephyr/sys/sys_io.h>
1515#include <zephyr/sys/util.h>
16+ #include <zephyr/pm/device.h>
1617
1718#include <stdlib.h>
1819
@@ -1254,33 +1255,47 @@ static int cdns_i3c_target_ibi_raise(const struct device *dev, struct i3c_ibi *r
12541255{
12551256 const struct cdns_i3c_config * config = dev -> config ;
12561257 struct cdns_i3c_data * data = dev -> data ;
1258+ int ret ;
12571259
12581260 __ASSERT_NO_MSG (request != NULL );
12591261
1262+ k_mutex_lock (& data -> bus_lock , K_FOREVER );
1263+ pm_device_busy_set (dev );
1264+
12601265 /* make sure we are not currently the active controller */
12611266 if (sys_read32 (config -> base + MST_STATUS0 ) & MST_STATUS0_MASTER_MODE ) {
1262- return - EACCES ;
1267+ ret = - EACCES ;
1268+ goto error ;
12631269 }
12641270
12651271 switch (request -> ibi_type ) {
12661272 case I3C_IBI_TARGET_INTR :
12671273 /* Check IP Revision since older versions of CDNS IP do not support IBI interrupt*/
12681274 if (REV_ID_REV (data -> hw_cfg .rev_id ) >= REV_ID_VERSION (1 , 7 )) {
1269- return cdns_i3c_target_ibi_raise_intr (dev , request );
1275+ ret = cdns_i3c_target_ibi_raise_intr (dev , request );
12701276 } else {
1271- return - ENOTSUP ;
1277+ ret = - ENOTSUP ;
12721278 }
1279+ break ;
12731280 case I3C_IBI_CONTROLLER_ROLE_REQUEST :
12741281#ifdef CONFIG_I3C_CONTROLLER
1275- return cdns_i3c_target_ibi_raise_cr (dev );
1282+ ret = cdns_i3c_target_ibi_raise_cr (dev );
12761283#else
1277- return - ENOTSUP ;
1284+ ret = - ENOTSUP ;
12781285#endif
1286+ break ;
12791287 case I3C_IBI_HOTJOIN :
1280- return cdns_i3c_target_ibi_raise_hj (dev );
1288+ ret = cdns_i3c_target_ibi_raise_hj (dev );
1289+ break ;
12811290 default :
1282- return - EINVAL ;
1291+ ret = - EINVAL ;
1292+ break ;
12831293 }
1294+ error :
1295+ pm_device_busy_clear (dev );
1296+ k_mutex_unlock (& data -> bus_lock );
1297+
1298+ return ret ;
12841299}
12851300#endif /* CONFIG_I3C_TARGET */
12861301#endif /* CONFIG_I3C_USE_IBI */
@@ -1439,14 +1454,7 @@ static int cdns_i3c_do_ccc(const struct device *dev, struct i3c_ccc_payload *pay
14391454 int ret = 0 ;
14401455 uint8_t num_cmds = 0 ;
14411456
1442- /* make sure we are currently the active controller */
1443- if (!(sys_read32 (config -> base + MST_STATUS0 ) & MST_STATUS0_MASTER_MODE )) {
1444- return - EACCES ;
1445- }
1446-
1447- if (payload == NULL ) {
1448- return - EINVAL ;
1449- }
1457+ __ASSERT_NO_MSG (payload != NULL );
14501458
14511459 /*
14521460 * Ensure data will fit within FIFOs.
@@ -1480,9 +1488,16 @@ static int cdns_i3c_do_ccc(const struct device *dev, struct i3c_ccc_payload *pay
14801488 return - ENOMEM ;
14811489 }
14821490
1483- LOG_DBG ("%s: CCC[0x%02x]" , dev -> name , payload -> ccc .id );
1484-
14851491 k_mutex_lock (& data -> bus_lock , K_FOREVER );
1492+ pm_device_busy_set (dev );
1493+
1494+ /* make sure we are currently the active controller */
1495+ if (!(sys_read32 (config -> base + MST_STATUS0 ) & MST_STATUS0_MASTER_MODE )) {
1496+ ret = - EACCES ;
1497+ goto error ;
1498+ }
1499+
1500+ LOG_DBG ("%s: CCC[0x%02x]" , dev -> name , payload -> ccc .id );
14861501
14871502 /* wait for idle */
14881503 ret = cdns_i3c_wait_for_idle (dev );
@@ -1589,6 +1604,7 @@ static int cdns_i3c_do_ccc(const struct device *dev, struct i3c_ccc_payload *pay
15891604 }
15901605#endif /* CONFIG_I3C_CONTROLLER && CONFIG_I3C_TARGET */
15911606error :
1607+ pm_device_busy_clear (dev );
15921608 k_mutex_unlock (& data -> bus_lock );
15931609
15941610 return ret ;
@@ -1765,7 +1781,11 @@ static int cdns_i3c_i2c_api_configure(const struct device *dev, uint32_t config)
17651781 }
17661782
17671783 k_mutex_lock (& data -> bus_lock , K_FOREVER );
1784+ pm_device_busy_set (dev );
1785+
17681786 cdns_i3c_set_prescalers (dev );
1787+
1788+ pm_device_busy_clear (dev );
17691789 k_mutex_unlock (& data -> bus_lock );
17701790
17711791 return 0 ;
@@ -1800,7 +1820,11 @@ static int cdns_i3c_configure(const struct device *dev, enum i3c_config_type typ
18001820 data -> common .ctrl_config .scl .i2c = ctrl_cfg -> scl .i2c ;
18011821
18021822 k_mutex_lock (& data -> bus_lock , K_FOREVER );
1823+ pm_device_busy_set (dev );
1824+
18031825 cdns_i3c_set_prescalers (dev );
1826+
1827+ pm_device_busy_clear (dev );
18041828 k_mutex_unlock (& data -> bus_lock );
18051829#else
18061830 return - ENOTSUP ;
@@ -2023,14 +2047,7 @@ static int cdns_i3c_i2c_transfer(const struct device *dev, struct i3c_i2c_device
20232047 uint32_t rxsize = 0 ;
20242048 int ret ;
20252049
2026- /* make sure we are currently the active controller */
2027- if (!(sys_read32 (config -> base + MST_STATUS0 ) & MST_STATUS0_MASTER_MODE )) {
2028- return - EACCES ;
2029- }
2030-
2031- if (num_msgs == 0 ) {
2032- return 0 ;
2033- }
2050+ __ASSERT_NO_MSG (num_msgs > 0 );
20342051
20352052 if (num_msgs > data -> hw_cfg .cmd_mem_depth || num_msgs > data -> hw_cfg .cmdr_mem_depth ) {
20362053 LOG_ERR ("%s: Too many messages" , dev -> name );
@@ -2053,6 +2070,13 @@ static int cdns_i3c_i2c_transfer(const struct device *dev, struct i3c_i2c_device
20532070 }
20542071
20552072 k_mutex_lock (& data -> bus_lock , K_FOREVER );
2073+ pm_device_busy_set (dev );
2074+
2075+ /* make sure we are currently the active controller */
2076+ if (!(sys_read32 (config -> base + MST_STATUS0 ) & MST_STATUS0_MASTER_MODE )) {
2077+ ret = - EACCES ;
2078+ goto error ;
2079+ }
20562080
20572081 /* wait for idle */
20582082 ret = cdns_i3c_wait_for_idle (dev );
@@ -2100,6 +2124,7 @@ static int cdns_i3c_i2c_transfer(const struct device *dev, struct i3c_i2c_device
21002124
21012125 ret = data -> xfer .ret ;
21022126error :
2127+ pm_device_busy_clear (dev );
21032128 k_mutex_unlock (& data -> bus_lock );
21042129
21052130 return ret ;
@@ -2154,16 +2179,20 @@ static int cdns_i3c_attach_device(const struct device *dev, struct i3c_device_de
21542179 if ((desc -> static_addr != 0 ) || (desc -> dynamic_addr != 0 )) {
21552180 const struct cdns_i3c_config * config = dev -> config ;
21562181 struct cdns_i3c_data * data = dev -> data ;
2182+ int slot ;
2183+
2184+ k_mutex_lock (& data -> bus_lock , K_FOREVER );
2185+ pm_device_busy_set (dev );
21572186
2158- int slot = cdns_i3c_master_get_rr_slot (dev , desc -> dynamic_addr );
2187+ slot = cdns_i3c_master_get_rr_slot (dev , desc -> dynamic_addr );
21592188
21602189 if (slot < 0 ) {
21612190 LOG_ERR ("%s: no space for i3c device: %s" , dev -> name , desc -> dev -> name );
2191+ pm_device_busy_clear (dev );
2192+ k_mutex_unlock (& data -> bus_lock );
21622193 return slot ;
21632194 }
21642195
2165- k_mutex_lock (& data -> bus_lock , K_FOREVER );
2166-
21672196 sys_write32 (sys_read32 (config -> base + DEVS_CTRL ) | DEVS_CTRL_DEV_ACTIVE (slot ),
21682197 config -> base + DEVS_CTRL );
21692198
@@ -2182,6 +2211,7 @@ static int cdns_i3c_attach_device(const struct device *dev, struct i3c_device_de
21822211 sys_write32 (dev_id_rr1 , config -> base + DEV_ID_RR1 (slot ));
21832212 sys_write32 (dev_id_rr2 , config -> base + DEV_ID_RR2 (slot ));
21842213
2214+ pm_device_busy_clear (dev );
21852215 k_mutex_unlock (& data -> bus_lock );
21862216 }
21872217
@@ -2201,6 +2231,7 @@ static int cdns_i3c_reattach_device(const struct device *dev, struct i3c_device_
22012231 }
22022232
22032233 k_mutex_lock (& data -> bus_lock , K_FOREVER );
2234+ pm_device_busy_set (dev );
22042235
22052236 uint32_t dev_id_rr0 = DEV_ID_RR0_IS_I3C | prepare_rr0_dev_address (desc -> dynamic_addr );
22062237 uint32_t dev_id_rr1 = DEV_ID_RR1_PID_MSB ((desc -> pid & 0xFFFFFFFF0000 ) >> 16 );
@@ -2211,6 +2242,7 @@ static int cdns_i3c_reattach_device(const struct device *dev, struct i3c_device_
22112242 sys_write32 (dev_id_rr1 , config -> base + DEV_ID_RR1 (cdns_i3c_device_data -> id ));
22122243 sys_write32 (dev_id_rr2 , config -> base + DEV_ID_RR2 (cdns_i3c_device_data -> id ));
22132244
2245+ pm_device_busy_clear (dev );
22142246 k_mutex_unlock (& data -> bus_lock );
22152247
22162248 return 0 ;
@@ -2228,13 +2260,15 @@ static int cdns_i3c_detach_device(const struct device *dev, struct i3c_device_de
22282260 }
22292261
22302262 k_mutex_lock (& data -> bus_lock , K_FOREVER );
2263+ pm_device_busy_set (dev );
22312264
22322265 sys_write32 (sys_read32 (config -> base + DEVS_CTRL ) |
22332266 DEVS_CTRL_DEV_CLR (cdns_i3c_device_data -> id ),
22342267 config -> base + DEVS_CTRL );
22352268 data -> free_rr_slots |= BIT (cdns_i3c_device_data -> id );
22362269 desc -> controller_priv = NULL ;
22372270
2271+ pm_device_busy_clear (dev );
22382272 k_mutex_unlock (& data -> bus_lock );
22392273
22402274 return 0 ;
@@ -2253,6 +2287,7 @@ static int cdns_i3c_i2c_attach_device(const struct device *dev, struct i3c_i2c_d
22532287 }
22542288
22552289 k_mutex_lock (& data -> bus_lock , K_FOREVER );
2290+ pm_device_busy_set (dev );
22562291
22572292 uint32_t dev_id_rr0 = prepare_rr0_dev_address (desc -> addr );
22582293 uint32_t dev_id_rr2 = DEV_ID_RR2_LVR (desc -> lvr );
@@ -2268,6 +2303,7 @@ static int cdns_i3c_i2c_attach_device(const struct device *dev, struct i3c_i2c_d
22682303 sys_write32 (sys_read32 (config -> base + DEVS_CTRL ) | DEVS_CTRL_DEV_ACTIVE (slot ),
22692304 config -> base + DEVS_CTRL );
22702305
2306+ pm_device_busy_clear (dev );
22712307 k_mutex_unlock (& data -> bus_lock );
22722308
22732309 return 0 ;
@@ -2285,13 +2321,15 @@ static int cdns_i3c_i2c_detach_device(const struct device *dev, struct i3c_i2c_d
22852321 }
22862322
22872323 k_mutex_lock (& data -> bus_lock , K_FOREVER );
2324+ pm_device_busy_set (dev );
22882325
22892326 sys_write32 (sys_read32 (config -> base + DEVS_CTRL ) |
22902327 DEVS_CTRL_DEV_CLR (cdns_i2c_device_data -> id ),
22912328 config -> base + DEVS_CTRL );
22922329 data -> free_rr_slots |= BIT (cdns_i2c_device_data -> id );
22932330 desc -> controller_priv = NULL ;
22942331
2332+ pm_device_busy_clear (dev );
22952333 k_mutex_unlock (& data -> bus_lock );
22962334
22972335 return 0 ;
@@ -2318,14 +2356,7 @@ static int cdns_i3c_transfer(const struct device *dev, struct i3c_device_desc *t
23182356 int rxsize = 0 ;
23192357 int ret ;
23202358
2321- /* make sure we are currently the active controller */
2322- if (!(sys_read32 (config -> base + MST_STATUS0 ) & MST_STATUS0_MASTER_MODE )) {
2323- return - EACCES ;
2324- }
2325-
2326- if (num_msgs == 0 ) {
2327- return 0 ;
2328- }
2359+ __ASSERT_NO_MSG (num_msgs > 0 );
23292360
23302361 if (num_msgs > data -> hw_cfg .cmd_mem_depth || num_msgs > data -> hw_cfg .cmdr_mem_depth ) {
23312362 LOG_ERR ("%s: Too many messages" , dev -> name );
@@ -2352,6 +2383,13 @@ static int cdns_i3c_transfer(const struct device *dev, struct i3c_device_desc *t
23522383 }
23532384
23542385 k_mutex_lock (& data -> bus_lock , K_FOREVER );
2386+ pm_device_busy_set (dev );
2387+
2388+ /* make sure we are currently the active controller */
2389+ if (!(sys_read32 (config -> base + MST_STATUS0 ) & MST_STATUS0_MASTER_MODE )) {
2390+ ret = - EACCES ;
2391+ goto error ;
2392+ }
23552393
23562394 /* wait for idle */
23572395 ret = cdns_i3c_wait_for_idle (dev );
@@ -2484,6 +2522,7 @@ static int cdns_i3c_transfer(const struct device *dev, struct i3c_device_desc *t
24842522
24852523 ret = data -> xfer .ret ;
24862524error :
2525+ pm_device_busy_clear (dev );
24872526 k_mutex_unlock (& data -> bus_lock );
24882527
24892528 return ret ;
@@ -3171,18 +3210,21 @@ static int cdns_i3c_target_tx_write(const struct device *dev, uint8_t *buf, uint
31713210 uint32_t val = 0 ;
31723211 uint16_t remain = len ;
31733212
3213+ k_mutex_lock (& data -> bus_lock , K_FOREVER );
3214+ pm_device_busy_set (dev );
3215+
31743216 /* check if we are currently a target */
31753217 if (sys_read32 (config -> base + MST_STATUS0 ) & MST_STATUS0_MASTER_MODE ) {
3176- return - EACCES ;
3218+ i = - EACCES ;
3219+ goto error ;
31773220 }
31783221
31793222 /* check if there is space available in the tx fifo */
31803223 if (sys_read32 (config -> base + SLV_STATUS1 ) & SLV_STATUS1_SDR_TX_FULL ) {
3181- return - ENOSPC ;
3224+ i = - ENOSPC ;
3225+ goto error ;
31823226 }
31833227
3184- k_mutex_lock (& data -> bus_lock , K_FOREVER );
3185-
31863228 /* rev 1p7 requires the length be written to the SLV_CTRL reg */
31873229 if (REV_ID_REV (data -> hw_cfg .rev_id ) >= REV_ID_VERSION (1 , 7 )) {
31883230 sys_write32 (len , config -> base + SLV_CTRL );
@@ -3233,7 +3275,8 @@ static int cdns_i3c_target_tx_write(const struct device *dev, uint8_t *buf, uint
32333275 LOG_ERR ("%s: Unsupported HDR Mode %d" , dev -> name , hdr_mode );
32343276 i = - ENOTSUP ;
32353277 }
3236-
3278+ error :
3279+ pm_device_busy_clear (dev );
32373280 k_mutex_unlock (& data -> bus_lock );
32383281
32393282 /* return total bytes written */
0 commit comments