Skip to content

Commit 520fac0

Browse files
committed
Merge tag 'i3c/fixes-for-5.0-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux
Pull i3c fixes from Boris Brezillon: - Fix a deadlock in the designware driver - Fix the error path in i3c_master_add_i3c_dev_locked() * tag 'i3c/fixes-for-5.0-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux: i3c: master: dw: fix deadlock i3c: fix missing detach if failed to retrieve i3c dev
2 parents c228d29 + f36c1f9 commit 520fac0

File tree

2 files changed

+13
-7
lines changed

2 files changed

+13
-7
lines changed

drivers/i3c/master.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1828,7 +1828,7 @@ int i3c_master_add_i3c_dev_locked(struct i3c_master_controller *master,
18281828

18291829
ret = i3c_master_retrieve_dev_info(newdev);
18301830
if (ret)
1831-
goto err_free_dev;
1831+
goto err_detach_dev;
18321832

18331833
olddev = i3c_master_search_i3c_dev_duplicate(newdev);
18341834
if (olddev) {

drivers/i3c/master/dw-i3c-master.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -419,12 +419,9 @@ static void dw_i3c_master_enqueue_xfer(struct dw_i3c_master *master,
419419
spin_unlock_irqrestore(&master->xferqueue.lock, flags);
420420
}
421421

422-
static void dw_i3c_master_dequeue_xfer(struct dw_i3c_master *master,
423-
struct dw_i3c_xfer *xfer)
422+
static void dw_i3c_master_dequeue_xfer_locked(struct dw_i3c_master *master,
423+
struct dw_i3c_xfer *xfer)
424424
{
425-
unsigned long flags;
426-
427-
spin_lock_irqsave(&master->xferqueue.lock, flags);
428425
if (master->xferqueue.cur == xfer) {
429426
u32 status;
430427

@@ -439,6 +436,15 @@ static void dw_i3c_master_dequeue_xfer(struct dw_i3c_master *master,
439436
} else {
440437
list_del_init(&xfer->node);
441438
}
439+
}
440+
441+
static void dw_i3c_master_dequeue_xfer(struct dw_i3c_master *master,
442+
struct dw_i3c_xfer *xfer)
443+
{
444+
unsigned long flags;
445+
446+
spin_lock_irqsave(&master->xferqueue.lock, flags);
447+
dw_i3c_master_dequeue_xfer_locked(master, xfer);
442448
spin_unlock_irqrestore(&master->xferqueue.lock, flags);
443449
}
444450

@@ -494,7 +500,7 @@ static void dw_i3c_master_end_xfer_locked(struct dw_i3c_master *master, u32 isr)
494500
complete(&xfer->comp);
495501

496502
if (ret < 0) {
497-
dw_i3c_master_dequeue_xfer(master, xfer);
503+
dw_i3c_master_dequeue_xfer_locked(master, xfer);
498504
writel(readl(master->regs + DEVICE_CTRL) | DEV_CTRL_RESUME,
499505
master->regs + DEVICE_CTRL);
500506
}

0 commit comments

Comments
 (0)