drivers/gpu/drm/imagination/pvr_ccb.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/imagination/pvr_ccb.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/imagination/pvr_ccb.c- Extension
.c- Size
- 17627 bytes
- Lines
- 668
- Domain
- Driver Families
- Bucket
- drivers/gpu
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
pvr_ccb.hpvr_device.hpvr_drv.hpvr_dump.hpvr_free_list.hpvr_fw.hpvr_gem.hpvr_power.hdrm/drm_managed.hdrm/drm_print.hlinux/compiler.hlinux/delay.hlinux/jiffies.hlinux/kernel.hlinux/mutex.hlinux/types.hlinux/workqueue.h
Detected Declarations
struct pvr_kccb_fencefunction ccb_ctrl_initfunction pvr_ccb_initfunction pvr_ccb_finifunction pvr_ccb_slot_available_lockedfunction process_fwccb_commandfunction pvr_fwccb_processfunction pvr_kccb_capacityfunction pvr_kccb_used_slot_count_lockedfunction pvr_kccb_send_cmd_reserved_poweredfunction pvr_kccb_try_reserve_slotfunction pvr_kccb_reserve_slot_syncfunction pvr_kccb_send_cmd_poweredfunction pvr_kccb_send_cmdfunction pvr_kccb_wait_for_completionfunction pvr_kccb_is_idlefunction pvr_kccb_fence_get_driver_namefunction pvr_kccb_fence_get_timeline_namefunction pvr_kccb_wake_up_waitersfunction pvr_kccb_finifunction pvr_kccb_initfunction pvr_kccb_fence_allocfunction pvr_kccb_fence_putfunction pvr_kccb_reserve_slotfunction pvr_kccb_release_slotfunction pvr_fwccb_init
Annotated Snippet
struct pvr_kccb_fence {
/** @base: Base dma_fence object. */
struct dma_fence base;
/** @node: Node used to insert the fence in the pvr_device::kccb::waiters list. */
struct list_head node;
};
/**
* pvr_kccb_wake_up_waiters() - Check the KCCB waiters
* @pvr_dev: Target PowerVR device
*
* Signal as many KCCB fences as we have slots available.
*/
void pvr_kccb_wake_up_waiters(struct pvr_device *pvr_dev)
{
struct pvr_kccb_fence *fence, *tmp_fence;
u32 used_count, available_count;
/* Wake up those waiting for KCCB slot execution. */
wake_up_all(&pvr_dev->kccb.rtn_q);
/* Then iterate over all KCCB fences and signal as many as we can. */
mutex_lock(&pvr_dev->kccb.ccb.lock);
used_count = pvr_kccb_used_slot_count_locked(pvr_dev);
if (WARN_ON(used_count + pvr_dev->kccb.reserved_count > pvr_kccb_capacity(pvr_dev)))
goto out_unlock;
available_count = pvr_kccb_capacity(pvr_dev) - used_count - pvr_dev->kccb.reserved_count;
list_for_each_entry_safe(fence, tmp_fence, &pvr_dev->kccb.waiters, node) {
if (!available_count)
break;
list_del(&fence->node);
pvr_dev->kccb.reserved_count++;
available_count--;
dma_fence_signal(&fence->base);
dma_fence_put(&fence->base);
}
out_unlock:
mutex_unlock(&pvr_dev->kccb.ccb.lock);
}
/**
* pvr_kccb_fini() - Cleanup device KCCB
* @pvr_dev: Target PowerVR device
*/
void pvr_kccb_fini(struct pvr_device *pvr_dev)
{
pvr_ccb_fini(&pvr_dev->kccb.ccb);
WARN_ON(!list_empty(&pvr_dev->kccb.waiters));
WARN_ON(pvr_dev->kccb.reserved_count);
}
/**
* pvr_kccb_init() - Initialise device KCCB
* @pvr_dev: Target PowerVR device
*
* Returns:
* * 0 on success, or
* * Any error returned by pvr_ccb_init().
*/
int
pvr_kccb_init(struct pvr_device *pvr_dev)
{
pvr_dev->kccb.slot_count = 1 << ROGUE_FWIF_KCCB_NUMCMDS_LOG2_DEFAULT;
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));
}
/**
* pvr_kccb_fence_alloc() - Allocate a pvr_kccb_fence object
*
* Return:
* * NULL if the allocation fails, or
* * A valid dma_fence pointer otherwise.
*/
struct dma_fence *pvr_kccb_fence_alloc(void)
{
struct pvr_kccb_fence *kccb_fence;
kccb_fence = kzalloc_obj(*kccb_fence);
if (!kccb_fence)
Annotation
- Immediate include surface: `pvr_ccb.h`, `pvr_device.h`, `pvr_drv.h`, `pvr_dump.h`, `pvr_free_list.h`, `pvr_fw.h`, `pvr_gem.h`, `pvr_power.h`.
- Detected declarations: `struct pvr_kccb_fence`, `function ccb_ctrl_init`, `function pvr_ccb_init`, `function pvr_ccb_fini`, `function pvr_ccb_slot_available_locked`, `function process_fwccb_command`, `function pvr_fwccb_process`, `function pvr_kccb_capacity`, `function pvr_kccb_used_slot_count_locked`, `function pvr_kccb_send_cmd_reserved_powered`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.