diff options
Diffstat (limited to 'drivers/i3c/master.c')
-rw-r--r-- | drivers/i3c/master.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c index e66a1f84cefb..0cdc94e4cb77 100644 --- a/drivers/i3c/master.c +++ b/drivers/i3c/master.c @@ -2374,7 +2374,7 @@ static void i3c_master_unregister_i3c_devs(struct i3c_master_controller *master) void i3c_master_queue_ibi(struct i3c_dev_desc *dev, struct i3c_ibi_slot *slot) { atomic_inc(&dev->ibi->pending_ibis); - queue_work(dev->common.master->wq, &slot->work); + queue_work(dev->ibi->wq, &slot->work); } EXPORT_SYMBOL_GPL(i3c_master_queue_ibi); @@ -2819,6 +2819,12 @@ int i3c_dev_request_ibi_locked(struct i3c_dev_desc *dev, if (!ibi) return -ENOMEM; + ibi->wq = alloc_ordered_workqueue(dev_name(i3cdev_to_dev(dev->dev)), WQ_MEM_RECLAIM); + if (!ibi->wq) { + kfree(ibi); + return -ENOMEM; + } + atomic_set(&ibi->pending_ibis, 0); init_completion(&ibi->all_ibis_handled); ibi->handler = req->handler; @@ -2846,6 +2852,12 @@ void i3c_dev_free_ibi_locked(struct i3c_dev_desc *dev) WARN_ON(i3c_dev_disable_ibi_locked(dev)); master->ops->free_ibi(dev); + + if (dev->ibi->wq) { + destroy_workqueue(dev->ibi->wq); + dev->ibi->wq = NULL; + } + kfree(dev->ibi); dev->ibi = NULL; } |