On Thu, 2026-09-10 at 10:56 +0300, Alexandru Dadu wrote: > 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]>
Reviewed-by: Alessio Belle <[email protected]> Thanks, Alessio > --- > 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 >
