- Fix a deadlock in the designware driver

- Fix the error path in i3c_master_add_i3c_dev_locked()
 -----BEGIN PGP SIGNATURE-----
 
 iQJKBAABCgA0FiEEKmCqpbOU668PNA69Ze02AX4ItwAFAlxUBSMWHGJicmV6aWxs
 b25Aa2VybmVsLm9yZwAKCRBl7TYBfgi3AEB+D/9fN3ErQqlgmRjZuVF0gqAWSekn
 Jnpz5fGpWVn/f9NAVRfZkk7czIJasvlE36pb4L/CeV9RI9Ad2YIljKjGJHduzlFC
 12pRuY65ilwW4wO2dYkaUZSCozhaJ9Jm+kwrm/YMZbs9anWBKFUgFXtX3E5iqeH7
 uVlS2toLhcWcqbQnO1QYIkScAnqrkyo74olbWo6PsxD1wCFL3DAXkxXbZRF2SHZm
 Icjp56QnLbot+5V5ING1azaXmi3k80hY4L/oaN08t1WFE4frSYOcLRgA8+kHAofb
 7wthK4JwyW8GUriIqLIfhk+migcjUyrFkPsLRLyGrx16DvF/tDnfbhU/JHfPr6dy
 8vTnglVunPAY3orZdMovZQhYzpm5vXgECF3aEExZe/KlJm+zccYirZngJLmAJL6z
 JQcBwvOdpnHa35Fyy+8ENJCGSgHbxaNJ9NjdD8rBmDrQijv5caPHgpfgt4+b+U6b
 Ndc5WKVqtia4x1A4HTEq3NWtkEkBTqsgaZcDC7ErvKh+8Uwelz4jpCT5E82WbyYK
 +LAHqNGxjMBFZnfQsJ+UHdYyoeafj5LgoJPilAEr/IwwAJqFNOUSLBizraQoKs6V
 Yz+1tndmGOP6vXa32Oykwf+mST0g6lpl05bLcmj0QE5uIic1062DEU8cCRUx8qZc
 zpTW3004/kEVv8NRqA==
 =cU2G
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Linus Torvalds 2019-02-01 10:17:51 -08:00
Родитель c228d294f2 f36c1f9a8d
Коммит 520fac05b6
2 изменённых файлов: 13 добавлений и 7 удалений

Просмотреть файл

@ -1828,7 +1828,7 @@ int i3c_master_add_i3c_dev_locked(struct i3c_master_controller *master,
ret = i3c_master_retrieve_dev_info(newdev);
if (ret)
goto err_free_dev;
goto err_detach_dev;
olddev = i3c_master_search_i3c_dev_duplicate(newdev);
if (olddev) {

Просмотреть файл

@ -419,12 +419,9 @@ static void dw_i3c_master_enqueue_xfer(struct dw_i3c_master *master,
spin_unlock_irqrestore(&master->xferqueue.lock, flags);
}
static void dw_i3c_master_dequeue_xfer(struct dw_i3c_master *master,
struct dw_i3c_xfer *xfer)
static void dw_i3c_master_dequeue_xfer_locked(struct dw_i3c_master *master,
struct dw_i3c_xfer *xfer)
{
unsigned long flags;
spin_lock_irqsave(&master->xferqueue.lock, flags);
if (master->xferqueue.cur == xfer) {
u32 status;
@ -439,6 +436,15 @@ static void dw_i3c_master_dequeue_xfer(struct dw_i3c_master *master,
} else {
list_del_init(&xfer->node);
}
}
static void dw_i3c_master_dequeue_xfer(struct dw_i3c_master *master,
struct dw_i3c_xfer *xfer)
{
unsigned long flags;
spin_lock_irqsave(&master->xferqueue.lock, flags);
dw_i3c_master_dequeue_xfer_locked(master, xfer);
spin_unlock_irqrestore(&master->xferqueue.lock, flags);
}
@ -494,7 +500,7 @@ static void dw_i3c_master_end_xfer_locked(struct dw_i3c_master *master, u32 isr)
complete(&xfer->comp);
if (ret < 0) {
dw_i3c_master_dequeue_xfer(master, xfer);
dw_i3c_master_dequeue_xfer_locked(master, xfer);
writel(readl(master->regs + DEVICE_CTRL) | DEV_CTRL_RESUME,
master->regs + DEVICE_CTRL);
}