@@ -175,6 +175,7 @@ struct svc_i3c_regs_save {
175175 * @ibi.slots: Available IBI slots
176176 * @ibi.tbq_slot: To be queued IBI slot
177177 * @ibi.lock: IBI lock
178+ * @lock: Transfer lock, protect between IBI work thread and callbacks from master
178179 */
179180struct svc_i3c_master {
180181 struct i3c_master_controller base ;
@@ -203,6 +204,7 @@ struct svc_i3c_master {
203204 /* Prevent races within IBI handlers */
204205 spinlock_t lock ;
205206 } ibi ;
207+ struct mutex lock ;
206208};
207209
208210/**
@@ -384,6 +386,7 @@ static void svc_i3c_master_ibi_work(struct work_struct *work)
384386 u32 status , val ;
385387 int ret ;
386388
389+ mutex_lock (& master -> lock );
387390 /* Acknowledge the incoming interrupt with the AUTOIBI mechanism */
388391 writel (SVC_I3C_MCTRL_REQUEST_AUTO_IBI |
389392 SVC_I3C_MCTRL_IBIRESP_AUTO ,
@@ -460,6 +463,7 @@ static void svc_i3c_master_ibi_work(struct work_struct *work)
460463
461464reenable_ibis :
462465 svc_i3c_master_enable_interrupts (master , SVC_I3C_MINT_SLVSTART );
466+ mutex_unlock (& master -> lock );
463467}
464468
465469static 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,
12041208 cmd -> read_len = 0 ;
12051209 cmd -> continued = false;
12061210
1211+ mutex_lock (& master -> lock );
12071212 svc_i3c_master_enqueue_xfer (master , xfer );
12081213 if (!wait_for_completion_timeout (& xfer -> comp , msecs_to_jiffies (1000 )))
12091214 svc_i3c_master_dequeue_xfer (master , xfer );
1215+ mutex_unlock (& master -> lock );
12101216
12111217 ret = xfer -> ret ;
12121218 kfree (buf );
@@ -1250,9 +1256,11 @@ static int svc_i3c_master_send_direct_ccc_cmd(struct svc_i3c_master *master,
12501256 cmd -> read_len = read_len ;
12511257 cmd -> continued = false;
12521258
1259+ mutex_lock (& master -> lock );
12531260 svc_i3c_master_enqueue_xfer (master , xfer );
12541261 if (!wait_for_completion_timeout (& xfer -> comp , msecs_to_jiffies (1000 )))
12551262 svc_i3c_master_dequeue_xfer (master , xfer );
1263+ mutex_unlock (& master -> lock );
12561264
12571265 if (cmd -> read_len != xfer_len )
12581266 ccc -> dests [0 ].payload .len = cmd -> read_len ;
@@ -1309,9 +1317,11 @@ static int svc_i3c_master_priv_xfers(struct i3c_dev_desc *dev,
13091317 cmd -> continued = (i + 1 ) < nxfers ;
13101318 }
13111319
1320+ mutex_lock (& master -> lock );
13121321 svc_i3c_master_enqueue_xfer (master , xfer );
13131322 if (!wait_for_completion_timeout (& xfer -> comp , msecs_to_jiffies (1000 )))
13141323 svc_i3c_master_dequeue_xfer (master , xfer );
1324+ mutex_unlock (& master -> lock );
13151325
13161326 ret = xfer -> ret ;
13171327 svc_i3c_master_free_xfer (xfer );
@@ -1347,9 +1357,11 @@ static int svc_i3c_master_i2c_xfers(struct i2c_dev_desc *dev,
13471357 cmd -> continued = (i + 1 < nxfers );
13481358 }
13491359
1360+ mutex_lock (& master -> lock );
13501361 svc_i3c_master_enqueue_xfer (master , xfer );
13511362 if (!wait_for_completion_timeout (& xfer -> comp , msecs_to_jiffies (1000 )))
13521363 svc_i3c_master_dequeue_xfer (master , xfer );
1364+ mutex_unlock (& master -> lock );
13531365
13541366 ret = xfer -> ret ;
13551367 svc_i3c_master_free_xfer (xfer );
@@ -1540,6 +1552,8 @@ static int svc_i3c_master_probe(struct platform_device *pdev)
15401552
15411553 INIT_WORK (& master -> hj_work , svc_i3c_master_hj_work );
15421554 INIT_WORK (& master -> ibi_work , svc_i3c_master_ibi_work );
1555+ mutex_init (& master -> lock );
1556+
15431557 ret = devm_request_irq (dev , master -> irq , svc_i3c_master_irq_handler ,
15441558 IRQF_NO_SUSPEND , "svc-i3c-irq" , master );
15451559 if (ret )
0 commit comments