@@ -175,6 +175,7 @@ struct svc_i3c_regs_save {
175
175
* @ibi.slots: Available IBI slots
176
176
* @ibi.tbq_slot: To be queued IBI slot
177
177
* @ibi.lock: IBI lock
178
+ * @lock: Transfer lock, protect between IBI work thread and callbacks from master
178
179
*/
179
180
struct svc_i3c_master {
180
181
struct i3c_master_controller base ;
@@ -203,6 +204,7 @@ struct svc_i3c_master {
203
204
/* Prevent races within IBI handlers */
204
205
spinlock_t lock ;
205
206
} ibi ;
207
+ struct mutex lock ;
206
208
};
207
209
208
210
/**
@@ -384,6 +386,7 @@ static void svc_i3c_master_ibi_work(struct work_struct *work)
384
386
u32 status , val ;
385
387
int ret ;
386
388
389
+ mutex_lock (& master -> lock );
387
390
/* Acknowledge the incoming interrupt with the AUTOIBI mechanism */
388
391
writel (SVC_I3C_MCTRL_REQUEST_AUTO_IBI |
389
392
SVC_I3C_MCTRL_IBIRESP_AUTO ,
@@ -460,6 +463,7 @@ static void svc_i3c_master_ibi_work(struct work_struct *work)
460
463
461
464
reenable_ibis :
462
465
svc_i3c_master_enable_interrupts (master , SVC_I3C_MINT_SLVSTART );
466
+ mutex_unlock (& master -> lock );
463
467
}
464
468
465
469
static irqreturn_t svc_i3c_master_irq_handler (int irq , void * dev_id )
@@ -1204,9 +1208,11 @@ static int svc_i3c_master_send_bdcast_ccc_cmd(struct svc_i3c_master *master,
1204
1208
cmd -> read_len = 0 ;
1205
1209
cmd -> continued = false;
1206
1210
1211
+ mutex_lock (& master -> lock );
1207
1212
svc_i3c_master_enqueue_xfer (master , xfer );
1208
1213
if (!wait_for_completion_timeout (& xfer -> comp , msecs_to_jiffies (1000 )))
1209
1214
svc_i3c_master_dequeue_xfer (master , xfer );
1215
+ mutex_unlock (& master -> lock );
1210
1216
1211
1217
ret = xfer -> ret ;
1212
1218
kfree (buf );
@@ -1250,9 +1256,11 @@ static int svc_i3c_master_send_direct_ccc_cmd(struct svc_i3c_master *master,
1250
1256
cmd -> read_len = read_len ;
1251
1257
cmd -> continued = false;
1252
1258
1259
+ mutex_lock (& master -> lock );
1253
1260
svc_i3c_master_enqueue_xfer (master , xfer );
1254
1261
if (!wait_for_completion_timeout (& xfer -> comp , msecs_to_jiffies (1000 )))
1255
1262
svc_i3c_master_dequeue_xfer (master , xfer );
1263
+ mutex_unlock (& master -> lock );
1256
1264
1257
1265
if (cmd -> read_len != xfer_len )
1258
1266
ccc -> dests [0 ].payload .len = cmd -> read_len ;
@@ -1309,9 +1317,11 @@ static int svc_i3c_master_priv_xfers(struct i3c_dev_desc *dev,
1309
1317
cmd -> continued = (i + 1 ) < nxfers ;
1310
1318
}
1311
1319
1320
+ mutex_lock (& master -> lock );
1312
1321
svc_i3c_master_enqueue_xfer (master , xfer );
1313
1322
if (!wait_for_completion_timeout (& xfer -> comp , msecs_to_jiffies (1000 )))
1314
1323
svc_i3c_master_dequeue_xfer (master , xfer );
1324
+ mutex_unlock (& master -> lock );
1315
1325
1316
1326
ret = xfer -> ret ;
1317
1327
svc_i3c_master_free_xfer (xfer );
@@ -1347,9 +1357,11 @@ static int svc_i3c_master_i2c_xfers(struct i2c_dev_desc *dev,
1347
1357
cmd -> continued = (i + 1 < nxfers );
1348
1358
}
1349
1359
1360
+ mutex_lock (& master -> lock );
1350
1361
svc_i3c_master_enqueue_xfer (master , xfer );
1351
1362
if (!wait_for_completion_timeout (& xfer -> comp , msecs_to_jiffies (1000 )))
1352
1363
svc_i3c_master_dequeue_xfer (master , xfer );
1364
+ mutex_unlock (& master -> lock );
1353
1365
1354
1366
ret = xfer -> ret ;
1355
1367
svc_i3c_master_free_xfer (xfer );
@@ -1540,6 +1552,8 @@ static int svc_i3c_master_probe(struct platform_device *pdev)
1540
1552
1541
1553
INIT_WORK (& master -> hj_work , svc_i3c_master_hj_work );
1542
1554
INIT_WORK (& master -> ibi_work , svc_i3c_master_ibi_work );
1555
+ mutex_init (& master -> lock );
1556
+
1543
1557
ret = devm_request_irq (dev , master -> irq , svc_i3c_master_irq_handler ,
1544
1558
IRQF_NO_SUSPEND , "svc-i3c-irq" , master );
1545
1559
if (ret )
0 commit comments