From: Matt Coster <[email protected]> There's one FW object attached to KCCB usage (the return buffer) that is separately initialised in pvr_fw_init(). Move this initialisation to pvr_kccb_init() alongside the initialisation of rest of the members of struct pvr_device->kccb.
Signed-off-by: Matt Coster <[email protected]> Signed-off-by: Alexandru Dadu <[email protected]> --- drivers/gpu/drm/imagination/pvr_ccb.c | 38 +++++++++++++++++++++++++++++++---- drivers/gpu/drm/imagination/pvr_fw.c | 17 +--------------- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/imagination/pvr_ccb.c b/drivers/gpu/drm/imagination/pvr_ccb.c index b702d122d791..3b5942b674be 100644 --- a/drivers/gpu/drm/imagination/pvr_ccb.c +++ b/drivers/gpu/drm/imagination/pvr_ccb.c @@ -17,6 +17,7 @@ #include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/mutex.h> +#include <linux/overflow.h> #include <linux/types.h> #include <linux/workqueue.h> @@ -527,6 +528,7 @@ void pvr_kccb_wake_up_waiters(struct pvr_device *pvr_dev) */ void pvr_kccb_fini(struct pvr_device *pvr_dev) { + pvr_fw_object_unmap_and_destroy(pvr_dev->kccb.rtn_obj); pvr_ccb_fini(&pvr_dev->kccb.ccb); WARN_ON(!list_empty(&pvr_dev->kccb.waiters)); WARN_ON(pvr_dev->kccb.reserved_count); @@ -543,14 +545,42 @@ void pvr_kccb_fini(struct pvr_device *pvr_dev) int pvr_kccb_init(struct pvr_device *pvr_dev) { - pvr_dev->kccb.slot_count = 1 << ROGUE_FWIF_KCCB_NUMCMDS_LOG2_DEFAULT; + const u32 num_slots_log2 = ROGUE_FWIF_KCCB_NUMCMDS_LOG2_DEFAULT; + const u32 num_slots = 1 << num_slots_log2; + u32 rtn_size; + int err; + + /* + * The inputs here are compile-time constants; there's no reason to try + * to gracefully handle overflow at runtime. + */ + BUILD_BUG_ON(check_mul_overflow(num_slots, sizeof(*pvr_dev->kccb.rtn), &rtn_size)); + + pvr_dev->kccb.slot_count = num_slots; INIT_LIST_HEAD(&pvr_dev->kccb.waiters); pvr_dev->kccb.fence_ctx.id = dma_fence_context_alloc(1); spin_lock_init(&pvr_dev->kccb.fence_ctx.lock); - return pvr_ccb_init(pvr_dev, &pvr_dev->kccb.ccb, - ROGUE_FWIF_KCCB_NUMCMDS_LOG2_DEFAULT, - sizeof(struct rogue_fwif_kccb_cmd)); + err = pvr_ccb_init(pvr_dev, &pvr_dev->kccb.ccb, num_slots_log2, + sizeof(struct rogue_fwif_kccb_cmd)); + if (err) + return err; + + /* Allocate memory for KCCB return slots. */ + pvr_dev->kccb.rtn = pvr_fw_object_create_and_map(pvr_dev, rtn_size, + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, + NULL, NULL, &pvr_dev->kccb.rtn_obj); + if (IS_ERR(pvr_dev->kccb.rtn)) { + err = PTR_ERR(pvr_dev->kccb.rtn); + goto err_ccb_fini; + } + + return 0; + +err_ccb_fini: + pvr_ccb_fini(&pvr_dev->kccb.ccb); + + return err; } /** diff --git a/drivers/gpu/drm/imagination/pvr_fw.c b/drivers/gpu/drm/imagination/pvr_fw.c index 850a3ec8e775..cec17352cf90 100644 --- a/drivers/gpu/drm/imagination/pvr_fw.c +++ b/drivers/gpu/drm/imagination/pvr_fw.c @@ -945,8 +945,6 @@ pvr_fw_init(struct pvr_device *pvr_dev) [PVR_FW_PROCESSOR_TYPE_RISCV] = &pvr_fw_defs_riscv, }; - u32 kccb_size_log2 = ROGUE_FWIF_KCCB_NUMCMDS_LOG2_DEFAULT; - u32 kccb_rtn_size = (1 << kccb_size_log2) * sizeof(*pvr_dev->kccb.rtn); struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; int err; @@ -981,18 +979,9 @@ pvr_fw_init(struct pvr_device *pvr_dev) if (err) goto err_kccb_fini; - /* Allocate memory for KCCB return slots. */ - pvr_dev->kccb.rtn = pvr_fw_object_create_and_map(pvr_dev, kccb_rtn_size, - PVR_BO_FW_FLAGS_DEVICE_UNCACHED, - NULL, NULL, &pvr_dev->kccb.rtn_obj); - if (IS_ERR(pvr_dev->kccb.rtn)) { - err = PTR_ERR(pvr_dev->kccb.rtn); - goto err_fwccb_fini; - } - err = pvr_fw_create_structures(pvr_dev); if (err) - goto err_kccb_rtn_release; + goto err_fwccb_fini; err = pvr_fw_start(pvr_dev); if (err) @@ -1014,9 +1003,6 @@ pvr_fw_init(struct pvr_device *pvr_dev) err_destroy_structures: pvr_fw_destroy_structures(pvr_dev); -err_kccb_rtn_release: - pvr_fw_object_unmap_and_destroy(pvr_dev->kccb.rtn_obj); - err_fwccb_fini: pvr_ccb_fini(&pvr_dev->fwccb); @@ -1047,7 +1033,6 @@ pvr_fw_fini(struct pvr_device *pvr_dev) WRITE_ONCE(fw_dev->initialised, false); pvr_fw_destroy_structures(pvr_dev); - pvr_fw_object_unmap_and_destroy(pvr_dev->kccb.rtn_obj); /* * Ensure FWCCB worker has finished executing before destroying FWCCB. The IRQ handler has -- 2.43.0
