diff options
author | Jason-JH.Lin <jason-jh.lin@mediatek.com> | 2024-03-07 09:34:58 +0800 |
---|---|---|
committer | AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> | 2024-04-23 12:16:55 +0200 |
commit | 69ff68332dc5005539ac37c5c85444aaaec7c914 (patch) | |
tree | 0e3fd0078084c76c90ed4e5f1f7b443b327e17d3 | |
parent | 400e2fa8058e7032974a892c7336b3ea20e24cfd (diff) |
soc: mediatek: mtk-cmdq: Add cmdq_pkt_acquire_event() function
Add cmdq_pkt_acquire_event() function to support CMDQ user making
an instruction for acquiring event.
CMDQ users can use cmdq_pkt_acquire_event() as `mutex_lock`
and cmdq_pkt_clear_event() as `mutex_unlock` to protect the global
resource modified instructions between them.
cmdq_pkt_acquire_event() would wait for event to be cleared.
After event is cleared by cmdq_pkt_clear_event() in other GCE threads,
cmdq_pkt_acquire_event() would set event and keep executing next
instruction. So the mutex would work like this:
cmdq_pkt_acquire_event() /* mutex lock */
/* critical secton instructions that modified global resource */
cmdq_pkt_clear_event() /* mutex unlock */
Prevent the critical section instructions from being affected by other
GCE threads.
Signed-off-by: Jason-JH.Lin <jason-jh.lin@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://lore.kernel.org/r/20240307013458.23550-5-jason-jh.lin@mediatek.com
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-rw-r--r-- | drivers/soc/mediatek/mtk-cmdq-helper.c | 15 | ||||
-rw-r--r-- | include/linux/soc/mediatek/mtk-cmdq.h | 15 |
2 files changed, 30 insertions, 0 deletions
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c index ee55992f6491..d1ca4b21587e 100644 --- a/drivers/soc/mediatek/mtk-cmdq-helper.c +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c @@ -334,6 +334,21 @@ int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear) } EXPORT_SYMBOL(cmdq_pkt_wfe); +int cmdq_pkt_acquire_event(struct cmdq_pkt *pkt, u16 event) +{ + struct cmdq_instruction inst = {}; + + if (event >= CMDQ_MAX_EVENT) + return -EINVAL; + + inst.op = CMDQ_CODE_WFE; + inst.value = CMDQ_WFE_UPDATE | CMDQ_WFE_UPDATE_VALUE | CMDQ_WFE_WAIT; + inst.event = event; + + return cmdq_pkt_append_command(pkt, inst); +} +EXPORT_SYMBOL(cmdq_pkt_acquire_event); + int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event) { struct cmdq_instruction inst = { {0} }; diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h index f59f42e46ef1..d4a8e34505e6 100644 --- a/include/linux/soc/mediatek/mtk-cmdq.h +++ b/include/linux/soc/mediatek/mtk-cmdq.h @@ -207,6 +207,21 @@ int cmdq_pkt_mem_move(struct cmdq_pkt *pkt, dma_addr_t src_addr, dma_addr_t dst_ int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear); /** + * cmdq_pkt_acquire_event() - append acquire event command to the CMDQ packet + * @pkt: the CMDQ packet + * @event: the desired event to be acquired + * + * User can use cmdq_pkt_acquire_event() as `mutex_lock` and cmdq_pkt_clear_event() + * as `mutex_unlock` to protect some `critical section` instructions between them. + * cmdq_pkt_acquire_event() would wait for event to be cleared. + * After event is cleared by cmdq_pkt_clear_event in other GCE threads, + * cmdq_pkt_acquire_event() would set event and keep executing next instruction. + * + * Return: 0 for success; else the error code is returned + */ +int cmdq_pkt_acquire_event(struct cmdq_pkt *pkt, u16 event); + +/** * cmdq_pkt_clear_event() - append clear event command to the CMDQ packet * @pkt: the CMDQ packet * @event: the desired event to be cleared |