13
13
#include <zephyr/sys/byteorder.h>
14
14
#include <zephyr/sys/sys_io.h>
15
15
#include <zephyr/sys/util.h>
16
+ #include <zephyr/pm/device.h>
16
17
17
18
#include <stdlib.h>
18
19
@@ -1254,33 +1255,47 @@ static int cdns_i3c_target_ibi_raise(const struct device *dev, struct i3c_ibi *r
1254
1255
{
1255
1256
const struct cdns_i3c_config * config = dev -> config ;
1256
1257
struct cdns_i3c_data * data = dev -> data ;
1258
+ int ret ;
1257
1259
1258
1260
__ASSERT_NO_MSG (request != NULL );
1259
1261
1262
+ k_mutex_lock (& data -> bus_lock , K_FOREVER );
1263
+ pm_device_busy_set (dev );
1264
+
1260
1265
/* make sure we are not currently the active controller */
1261
1266
if (sys_read32 (config -> base + MST_STATUS0 ) & MST_STATUS0_MASTER_MODE ) {
1262
- return - EACCES ;
1267
+ ret = - EACCES ;
1268
+ goto error ;
1263
1269
}
1264
1270
1265
1271
switch (request -> ibi_type ) {
1266
1272
case I3C_IBI_TARGET_INTR :
1267
1273
/* Check IP Revision since older versions of CDNS IP do not support IBI interrupt*/
1268
1274
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 );
1270
1276
} else {
1271
- return - ENOTSUP ;
1277
+ ret = - ENOTSUP ;
1272
1278
}
1279
+ break ;
1273
1280
case I3C_IBI_CONTROLLER_ROLE_REQUEST :
1274
1281
#ifdef CONFIG_I3C_CONTROLLER
1275
- return cdns_i3c_target_ibi_raise_cr (dev );
1282
+ ret = cdns_i3c_target_ibi_raise_cr (dev );
1276
1283
#else
1277
- return - ENOTSUP ;
1284
+ ret = - ENOTSUP ;
1278
1285
#endif
1286
+ break ;
1279
1287
case I3C_IBI_HOTJOIN :
1280
- return cdns_i3c_target_ibi_raise_hj (dev );
1288
+ ret = cdns_i3c_target_ibi_raise_hj (dev );
1289
+ break ;
1281
1290
default :
1282
- return - EINVAL ;
1291
+ ret = - EINVAL ;
1292
+ break ;
1283
1293
}
1294
+ error :
1295
+ pm_device_busy_clear (dev );
1296
+ k_mutex_unlock (& data -> bus_lock );
1297
+
1298
+ return ret ;
1284
1299
}
1285
1300
#endif /* CONFIG_I3C_TARGET */
1286
1301
#endif /* CONFIG_I3C_USE_IBI */
@@ -1439,14 +1454,7 @@ static int cdns_i3c_do_ccc(const struct device *dev, struct i3c_ccc_payload *pay
1439
1454
int ret = 0 ;
1440
1455
uint8_t num_cmds = 0 ;
1441
1456
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 );
1450
1458
1451
1459
/*
1452
1460
* 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
1480
1488
return - ENOMEM ;
1481
1489
}
1482
1490
1483
- LOG_DBG ("%s: CCC[0x%02x]" , dev -> name , payload -> ccc .id );
1484
-
1485
1491
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 );
1486
1501
1487
1502
/* wait for idle */
1488
1503
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
1589
1604
}
1590
1605
#endif /* CONFIG_I3C_CONTROLLER && CONFIG_I3C_TARGET */
1591
1606
error :
1607
+ pm_device_busy_clear (dev );
1592
1608
k_mutex_unlock (& data -> bus_lock );
1593
1609
1594
1610
return ret ;
@@ -1765,7 +1781,11 @@ static int cdns_i3c_i2c_api_configure(const struct device *dev, uint32_t config)
1765
1781
}
1766
1782
1767
1783
k_mutex_lock (& data -> bus_lock , K_FOREVER );
1784
+ pm_device_busy_set (dev );
1785
+
1768
1786
cdns_i3c_set_prescalers (dev );
1787
+
1788
+ pm_device_busy_clear (dev );
1769
1789
k_mutex_unlock (& data -> bus_lock );
1770
1790
1771
1791
return 0 ;
@@ -1800,7 +1820,11 @@ static int cdns_i3c_configure(const struct device *dev, enum i3c_config_type typ
1800
1820
data -> common .ctrl_config .scl .i2c = ctrl_cfg -> scl .i2c ;
1801
1821
1802
1822
k_mutex_lock (& data -> bus_lock , K_FOREVER );
1823
+ pm_device_busy_set (dev );
1824
+
1803
1825
cdns_i3c_set_prescalers (dev );
1826
+
1827
+ pm_device_busy_clear (dev );
1804
1828
k_mutex_unlock (& data -> bus_lock );
1805
1829
#else
1806
1830
return - ENOTSUP ;
@@ -2023,14 +2047,7 @@ static int cdns_i3c_i2c_transfer(const struct device *dev, struct i3c_i2c_device
2023
2047
uint32_t rxsize = 0 ;
2024
2048
int ret ;
2025
2049
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 );
2034
2051
2035
2052
if (num_msgs > data -> hw_cfg .cmd_mem_depth || num_msgs > data -> hw_cfg .cmdr_mem_depth ) {
2036
2053
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
2053
2070
}
2054
2071
2055
2072
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
+ }
2056
2080
2057
2081
/* wait for idle */
2058
2082
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
2100
2124
2101
2125
ret = data -> xfer .ret ;
2102
2126
error :
2127
+ pm_device_busy_clear (dev );
2103
2128
k_mutex_unlock (& data -> bus_lock );
2104
2129
2105
2130
return ret ;
@@ -2154,16 +2179,20 @@ static int cdns_i3c_attach_device(const struct device *dev, struct i3c_device_de
2154
2179
if ((desc -> static_addr != 0 ) || (desc -> dynamic_addr != 0 )) {
2155
2180
const struct cdns_i3c_config * config = dev -> config ;
2156
2181
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 );
2157
2186
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 );
2159
2188
2160
2189
if (slot < 0 ) {
2161
2190
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 );
2162
2193
return slot ;
2163
2194
}
2164
2195
2165
- k_mutex_lock (& data -> bus_lock , K_FOREVER );
2166
-
2167
2196
sys_write32 (sys_read32 (config -> base + DEVS_CTRL ) | DEVS_CTRL_DEV_ACTIVE (slot ),
2168
2197
config -> base + DEVS_CTRL );
2169
2198
@@ -2182,6 +2211,7 @@ static int cdns_i3c_attach_device(const struct device *dev, struct i3c_device_de
2182
2211
sys_write32 (dev_id_rr1 , config -> base + DEV_ID_RR1 (slot ));
2183
2212
sys_write32 (dev_id_rr2 , config -> base + DEV_ID_RR2 (slot ));
2184
2213
2214
+ pm_device_busy_clear (dev );
2185
2215
k_mutex_unlock (& data -> bus_lock );
2186
2216
}
2187
2217
@@ -2201,6 +2231,7 @@ static int cdns_i3c_reattach_device(const struct device *dev, struct i3c_device_
2201
2231
}
2202
2232
2203
2233
k_mutex_lock (& data -> bus_lock , K_FOREVER );
2234
+ pm_device_busy_set (dev );
2204
2235
2205
2236
uint32_t dev_id_rr0 = DEV_ID_RR0_IS_I3C | prepare_rr0_dev_address (desc -> dynamic_addr );
2206
2237
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_
2211
2242
sys_write32 (dev_id_rr1 , config -> base + DEV_ID_RR1 (cdns_i3c_device_data -> id ));
2212
2243
sys_write32 (dev_id_rr2 , config -> base + DEV_ID_RR2 (cdns_i3c_device_data -> id ));
2213
2244
2245
+ pm_device_busy_clear (dev );
2214
2246
k_mutex_unlock (& data -> bus_lock );
2215
2247
2216
2248
return 0 ;
@@ -2228,13 +2260,15 @@ static int cdns_i3c_detach_device(const struct device *dev, struct i3c_device_de
2228
2260
}
2229
2261
2230
2262
k_mutex_lock (& data -> bus_lock , K_FOREVER );
2263
+ pm_device_busy_set (dev );
2231
2264
2232
2265
sys_write32 (sys_read32 (config -> base + DEVS_CTRL ) |
2233
2266
DEVS_CTRL_DEV_CLR (cdns_i3c_device_data -> id ),
2234
2267
config -> base + DEVS_CTRL );
2235
2268
data -> free_rr_slots |= BIT (cdns_i3c_device_data -> id );
2236
2269
desc -> controller_priv = NULL ;
2237
2270
2271
+ pm_device_busy_clear (dev );
2238
2272
k_mutex_unlock (& data -> bus_lock );
2239
2273
2240
2274
return 0 ;
@@ -2253,6 +2287,7 @@ static int cdns_i3c_i2c_attach_device(const struct device *dev, struct i3c_i2c_d
2253
2287
}
2254
2288
2255
2289
k_mutex_lock (& data -> bus_lock , K_FOREVER );
2290
+ pm_device_busy_set (dev );
2256
2291
2257
2292
uint32_t dev_id_rr0 = prepare_rr0_dev_address (desc -> addr );
2258
2293
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
2268
2303
sys_write32 (sys_read32 (config -> base + DEVS_CTRL ) | DEVS_CTRL_DEV_ACTIVE (slot ),
2269
2304
config -> base + DEVS_CTRL );
2270
2305
2306
+ pm_device_busy_clear (dev );
2271
2307
k_mutex_unlock (& data -> bus_lock );
2272
2308
2273
2309
return 0 ;
@@ -2285,13 +2321,15 @@ static int cdns_i3c_i2c_detach_device(const struct device *dev, struct i3c_i2c_d
2285
2321
}
2286
2322
2287
2323
k_mutex_lock (& data -> bus_lock , K_FOREVER );
2324
+ pm_device_busy_set (dev );
2288
2325
2289
2326
sys_write32 (sys_read32 (config -> base + DEVS_CTRL ) |
2290
2327
DEVS_CTRL_DEV_CLR (cdns_i2c_device_data -> id ),
2291
2328
config -> base + DEVS_CTRL );
2292
2329
data -> free_rr_slots |= BIT (cdns_i2c_device_data -> id );
2293
2330
desc -> controller_priv = NULL ;
2294
2331
2332
+ pm_device_busy_clear (dev );
2295
2333
k_mutex_unlock (& data -> bus_lock );
2296
2334
2297
2335
return 0 ;
@@ -2318,14 +2356,7 @@ static int cdns_i3c_transfer(const struct device *dev, struct i3c_device_desc *t
2318
2356
int rxsize = 0 ;
2319
2357
int ret ;
2320
2358
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 );
2329
2360
2330
2361
if (num_msgs > data -> hw_cfg .cmd_mem_depth || num_msgs > data -> hw_cfg .cmdr_mem_depth ) {
2331
2362
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
2352
2383
}
2353
2384
2354
2385
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
+ }
2355
2393
2356
2394
/* wait for idle */
2357
2395
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
2484
2522
2485
2523
ret = data -> xfer .ret ;
2486
2524
error :
2525
+ pm_device_busy_clear (dev );
2487
2526
k_mutex_unlock (& data -> bus_lock );
2488
2527
2489
2528
return ret ;
@@ -3171,18 +3210,21 @@ static int cdns_i3c_target_tx_write(const struct device *dev, uint8_t *buf, uint
3171
3210
uint32_t val = 0 ;
3172
3211
uint16_t remain = len ;
3173
3212
3213
+ k_mutex_lock (& data -> bus_lock , K_FOREVER );
3214
+ pm_device_busy_set (dev );
3215
+
3174
3216
/* check if we are currently a target */
3175
3217
if (sys_read32 (config -> base + MST_STATUS0 ) & MST_STATUS0_MASTER_MODE ) {
3176
- return - EACCES ;
3218
+ i = - EACCES ;
3219
+ goto error ;
3177
3220
}
3178
3221
3179
3222
/* check if there is space available in the tx fifo */
3180
3223
if (sys_read32 (config -> base + SLV_STATUS1 ) & SLV_STATUS1_SDR_TX_FULL ) {
3181
- return - ENOSPC ;
3224
+ i = - ENOSPC ;
3225
+ goto error ;
3182
3226
}
3183
3227
3184
- k_mutex_lock (& data -> bus_lock , K_FOREVER );
3185
-
3186
3228
/* rev 1p7 requires the length be written to the SLV_CTRL reg */
3187
3229
if (REV_ID_REV (data -> hw_cfg .rev_id ) >= REV_ID_VERSION (1 , 7 )) {
3188
3230
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
3233
3275
LOG_ERR ("%s: Unsupported HDR Mode %d" , dev -> name , hdr_mode );
3234
3276
i = - ENOTSUP ;
3235
3277
}
3236
-
3278
+ error :
3279
+ pm_device_busy_clear (dev );
3237
3280
k_mutex_unlock (& data -> bus_lock );
3238
3281
3239
3282
/* return total bytes written */
0 commit comments