From 57ec42b9a1b7e4db4a1c2aa4fcc4eefe6d31bcb8 Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Tue, 3 Oct 2023 15:53:39 +0800 Subject: i3c: Fix typo "Provisional ID" to "Provisioned ID" The MIPI I3C spec refers to a Provisioned ID, since it is (sometimes) provisioned at device manufacturing. Signed-off-by: Matt Johnston Acked-by: Rob Herring Reviewed-by: Miquel Raynal Link: https://lore.kernel.org/r/20231003075339.197099-1-matt@codeconstruct.com.au Signed-off-by: Alexandre Belloni --- include/linux/i3c/device.h | 2 +- include/linux/i3c/master.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/i3c/device.h b/include/linux/i3c/device.h index 90fa83464f00..84ed77c04940 100644 --- a/include/linux/i3c/device.h +++ b/include/linux/i3c/device.h @@ -96,7 +96,7 @@ enum i3c_dcr { /** * struct i3c_device_info - I3C device information - * @pid: Provisional ID + * @pid: Provisioned ID * @bcr: Bus Characteristic Register * @dcr: Device Characteristic Register * @static_addr: static/I2C address diff --git a/include/linux/i3c/master.h b/include/linux/i3c/master.h index 0b52da4f2346..4fd6a777150f 100644 --- a/include/linux/i3c/master.h +++ b/include/linux/i3c/master.h @@ -166,7 +166,7 @@ struct i3c_device_ibi_info { * assigned a dynamic address by the master. Will be used during * bus initialization to assign it a specific dynamic address * before starting DAA (Dynamic Address Assignment) - * @pid: I3C Provisional ID exposed by the device. This is a unique identifier + * @pid: I3C Provisioned ID exposed by the device. This is a unique identifier * that may be used to attach boardinfo to i3c_dev_desc when the device * does not have a static address * @of_node: optional DT node in case the device has been described in the DT -- cgit v1.2.3 From 9fd00df05e81a2e1080ce6e9abc35533dca99d74 Mon Sep 17 00:00:00 2001 From: Zbigniew Lukwinski Date: Mon, 16 Oct 2023 00:23:34 +0200 Subject: i3c: master: handle IBIs in order they came IBI shall be handled in order they appear on the bus. Otherwise could hit case when order of handling them in device driver will be different. It may lead to invalid assembling fragmented packets or events order broken. Added separate workqueue with option WQ_MEM_RECLAIM for each device driver. This ensures IBI handling order and improves IBI handling performance: IBI handlers for device B are not blocked by IBI handlers for device A. Original solution (single workqueue in main driver) was able to handle also general IBI (not related to specific device) like HJ or MR. So leaving this for such purposes. Signed-off-by: Zbigniew Lukwinski Link: https://lore.kernel.org/r/20231015222334.1652401-2-zbigniew.lukwinski@linux.intel.com Signed-off-by: Alexandre Belloni --- drivers/i3c/master.c | 14 +++++++++++++- include/linux/i3c/master.h | 4 +++- 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'include/linux') 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; } diff --git a/include/linux/i3c/master.h b/include/linux/i3c/master.h index 4fd6a777150f..349d7d0dda73 100644 --- a/include/linux/i3c/master.h +++ b/include/linux/i3c/master.h @@ -129,6 +129,7 @@ struct i3c_ibi_slot { * rejected by the master * @num_slots: number of IBI slots reserved for this device * @enabled: reflect the IBI status + * @wq: workqueue used to execute IBI handlers. * @handler: IBI handler specified at i3c_device_request_ibi() call time. This * handler will be called from the controller workqueue, and as such * is allowed to sleep (though it is recommended to process the IBI @@ -151,6 +152,7 @@ struct i3c_device_ibi_info { unsigned int max_payload_len; unsigned int num_slots; unsigned int enabled; + struct workqueue_struct *wq; void (*handler)(struct i3c_device *dev, const struct i3c_ibi_payload *payload); }; @@ -469,7 +471,7 @@ struct i3c_master_controller_ops { * @boardinfo.i2c: list of I2C boardinfo objects * @boardinfo: board-level information attached to devices connected on the bus * @bus: I3C bus exposed by this master - * @wq: workqueue used to execute IBI handlers. Can also be used by master + * @wq: workqueue which can be used by master * drivers if they need to postpone operations that need to take place * in a thread context. Typical examples are Hot Join processing which * requires taking the bus lock in maintenance, which in turn, can only -- cgit v1.2.3