drivers/gpu/drm/imagination/pvr_device.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/imagination/pvr_device.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/imagination/pvr_device.c- Extension
.c- Size
- 25248 bytes
- Lines
- 923
- Domain
- Driver Families
- Bucket
- drivers/gpu
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
pvr_device.hpvr_device_info.hpvr_fw.hpvr_power.hpvr_queue.hpvr_rogue_cr_defs.hpvr_stream.hpvr_vm.hdrm/drm_print.hlinux/bitfield.hlinux/clk.hlinux/compiler_attributes.hlinux/compiler_types.hlinux/dma-mapping.hlinux/err.hlinux/firmware.hlinux/gfp.hlinux/interrupt.hlinux/of.hlinux/platform_device.hlinux/pm_runtime.hlinux/reset.hlinux/slab.hlinux/stddef.hlinux/types.hlinux/workqueue.hkunit/visibility.h
Detected Declarations
enum pvr_gpu_support_levelfunction pvr_device_reg_initfunction pvr_device_clk_initfunction pvr_device_process_active_queuesfunction pvr_device_safety_irq_pendingfunction pvr_device_safety_irq_clearfunction pvr_device_handle_safety_eventsfunction pvr_device_irq_thread_handlerfunction pvr_device_irq_handlerfunction pvr_device_safety_irq_initfunction pvr_device_irq_initfunction pvr_device_irq_finifunction pvr_build_firmware_filenamefunction pvr_release_firmwarefunction pvr_request_firmwarefunction pvr_gpuid_decode_regfunction pvr_gpuid_decode_stringfunction strscpyfunction pvr_gpu_support_levelfunction pvr_check_gpu_supportedfunction pvr_load_gpu_idfunction pvr_set_dma_infofunction pvr_device_gpu_initfunction pvr_device_gpu_finifunction pvr_device_initfunction pvr_device_finifunction pvr_device_has_uapi_quirkfunction pvr_device_has_uapi_enhancementfunction pvr_device_has_feature
Annotated Snippet
if (READ_ONCE(pvr_dev->fw_dev.initialised)) {
pvr_fwccb_process(pvr_dev);
pvr_kccb_wake_up_waiters(pvr_dev);
pvr_device_process_active_queues(pvr_dev);
}
pm_runtime_mark_last_busy(drm_dev->dev);
ret = IRQ_HANDLED;
}
if (pvr_dev->has_safety_events) {
while (pvr_device_safety_irq_pending(pvr_dev)) {
pvr_device_safety_irq_clear(pvr_dev);
pvr_device_handle_safety_events(pvr_dev);
ret = IRQ_HANDLED;
}
}
return ret;
}
static irqreturn_t pvr_device_irq_handler(int irq, void *data)
{
struct pvr_device *pvr_dev = data;
bool safety_irq_pending = false;
if (pvr_dev->has_safety_events)
safety_irq_pending = pvr_device_safety_irq_pending(pvr_dev);
if (!pvr_fw_irq_pending(pvr_dev) && !safety_irq_pending)
return IRQ_NONE; /* Spurious IRQ - ignore. */
return IRQ_WAKE_THREAD;
}
static void pvr_device_safety_irq_init(struct pvr_device *pvr_dev)
{
u32 num_ecc_rams = 0;
/*
* Safety events are an optional feature of the RogueXE platform. They
* are only enabled if at least one of ECC memory or the watchdog timer
* are present in HW. While safety events can be generated by other
* systems, that will never happen if the above mentioned hardware is
* not present.
*/
if (!PVR_HAS_FEATURE(pvr_dev, roguexe)) {
pvr_dev->has_safety_events = false;
return;
}
PVR_FEATURE_VALUE(pvr_dev, ecc_rams, &num_ecc_rams);
pvr_dev->has_safety_events =
num_ecc_rams > 0 || PVR_HAS_FEATURE(pvr_dev, watchdog_timer);
}
/**
* pvr_device_irq_init() - Initialise IRQ required by a PowerVR device
* @pvr_dev: Target PowerVR device.
*
* Returns:
* * 0 on success,
* * Any error returned by platform_get_irq_byname(), or
* * Any error returned by request_irq().
*/
static int
pvr_device_irq_init(struct pvr_device *pvr_dev)
{
struct drm_device *drm_dev = from_pvr_device(pvr_dev);
struct platform_device *plat_dev = to_platform_device(drm_dev->dev);
init_waitqueue_head(&pvr_dev->kccb.rtn_q);
pvr_device_safety_irq_init(pvr_dev);
pvr_dev->irq = platform_get_irq(plat_dev, 0);
if (pvr_dev->irq < 0)
return pvr_dev->irq;
/* Clear any pending events before requesting the IRQ line. */
pvr_fw_irq_clear(pvr_dev);
if (pvr_dev->has_safety_events)
pvr_device_safety_irq_clear(pvr_dev);
/*
* The ONESHOT flag ensures IRQs are masked while the thread handler is
Annotation
- Immediate include surface: `pvr_device.h`, `pvr_device_info.h`, `pvr_fw.h`, `pvr_power.h`, `pvr_queue.h`, `pvr_rogue_cr_defs.h`, `pvr_stream.h`, `pvr_vm.h`.
- Detected declarations: `enum pvr_gpu_support_level`, `function pvr_device_reg_init`, `function pvr_device_clk_init`, `function pvr_device_process_active_queues`, `function pvr_device_safety_irq_pending`, `function pvr_device_safety_irq_clear`, `function pvr_device_handle_safety_events`, `function pvr_device_irq_thread_handler`, `function pvr_device_irq_handler`, `function pvr_device_safety_irq_init`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.