drivers/gpu/drm/panthor/panthor_pwr.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/panthor/panthor_pwr.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/panthor/panthor_pwr.c- Extension
.c- Size
- 16241 bytes
- Lines
- 577
- 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
linux/platform_device.hlinux/interrupt.hlinux/cleanup.hlinux/iopoll.hlinux/wait.hdrm/drm_managed.hdrm/drm_print.hpanthor_device.hpanthor_gpu_regs.hpanthor_hw.hpanthor_pwr.hpanthor_pwr_regs.h
Detected Declarations
struct panthor_pwrfunction panthor_pwr_irq_handlerfunction panthor_pwr_write_commandfunction reset_irq_raisedfunction reset_pendingfunction panthor_pwr_resetfunction scoped_guardfunction get_domain_basefunction get_domain_ready_regfunction get_domain_pwrtrans_regfunction is_valid_domainfunction has_rtufunction get_domain_subdomainfunction panthor_pwr_domain_wait_transitionfunction panthor_pwr_debug_info_showfunction panthor_pwr_domain_transitionfunction retract_domainfunction delegate_domainfunction panthor_pwr_delegate_domainsfunction panthor_pwr_domain_force_offfunction panthor_pwr_unplugfunction panthor_pwr_initfunction panthor_pwr_reset_softfunction panthor_pwr_l2_power_offfunction panthor_pwr_l2_power_onfunction panthor_pwr_suspendfunction panthor_pwr_resume
Annotated Snippet
struct panthor_pwr {
/** @iomem: CPU mapping of PWR_CONTROL iomem region */
void __iomem *iomem;
/** @irq: PWR irq. */
struct panthor_irq irq;
/** @reqs_lock: Lock protecting access to pending_reqs. */
spinlock_t reqs_lock;
/** @pending_reqs: Pending PWR requests. */
u32 pending_reqs;
/** @reqs_acked: PWR request wait queue. */
wait_queue_head_t reqs_acked;
};
static void panthor_pwr_irq_handler(struct panthor_device *ptdev, u32 status)
{
struct panthor_pwr *pwr = ptdev->pwr;
spin_lock(&ptdev->pwr->reqs_lock);
gpu_write(pwr->irq.iomem, INT_CLEAR, status);
if (unlikely(status & PWR_IRQ_COMMAND_NOT_ALLOWED))
drm_err(&ptdev->base, "PWR_IRQ: COMMAND_NOT_ALLOWED");
if (unlikely(status & PWR_IRQ_COMMAND_INVALID))
drm_err(&ptdev->base, "PWR_IRQ: COMMAND_INVALID");
if (status & ptdev->pwr->pending_reqs) {
ptdev->pwr->pending_reqs &= ~status;
wake_up_all(&ptdev->pwr->reqs_acked);
}
spin_unlock(&ptdev->pwr->reqs_lock);
}
PANTHOR_IRQ_HANDLER(pwr, panthor_pwr_irq_handler);
static void panthor_pwr_write_command(struct panthor_device *ptdev, u32 command, u64 args)
{
struct panthor_pwr *pwr = ptdev->pwr;
if (args)
gpu_write64(pwr->iomem, PWR_CMDARG, args);
gpu_write(pwr->iomem, PWR_COMMAND, command);
}
static bool reset_irq_raised(struct panthor_device *ptdev)
{
struct panthor_pwr *pwr = ptdev->pwr;
return gpu_read(pwr->irq.iomem, INT_RAWSTAT) & PWR_IRQ_RESET_COMPLETED;
}
static bool reset_pending(struct panthor_device *ptdev)
{
return (ptdev->pwr->pending_reqs & PWR_IRQ_RESET_COMPLETED);
}
static int panthor_pwr_reset(struct panthor_device *ptdev, u32 reset_cmd)
{
struct panthor_pwr *pwr = ptdev->pwr;
scoped_guard(spinlock_irqsave, &ptdev->pwr->reqs_lock) {
if (reset_pending(ptdev)) {
drm_WARN(&ptdev->base, 1, "Reset already pending");
} else {
ptdev->pwr->pending_reqs |= PWR_IRQ_RESET_COMPLETED;
gpu_write(pwr->irq.iomem, INT_CLEAR, PWR_IRQ_RESET_COMPLETED);
panthor_pwr_write_command(ptdev, reset_cmd, 0);
}
}
if (!wait_event_timeout(ptdev->pwr->reqs_acked, !reset_pending(ptdev),
msecs_to_jiffies(PWR_RESET_TIMEOUT_MS))) {
guard(spinlock_irqsave)(&ptdev->pwr->reqs_lock);
if (reset_pending(ptdev) && !reset_irq_raised(ptdev)) {
drm_err(&ptdev->base, "RESET timed out (0x%x)", reset_cmd);
return -ETIMEDOUT;
}
ptdev->pwr->pending_reqs &= ~PWR_IRQ_RESET_COMPLETED;
}
return 0;
}
static const char *get_domain_name(u8 domain)
Annotation
- Immediate include surface: `linux/platform_device.h`, `linux/interrupt.h`, `linux/cleanup.h`, `linux/iopoll.h`, `linux/wait.h`, `drm/drm_managed.h`, `drm/drm_print.h`, `panthor_device.h`.
- Detected declarations: `struct panthor_pwr`, `function panthor_pwr_irq_handler`, `function panthor_pwr_write_command`, `function reset_irq_raised`, `function reset_pending`, `function panthor_pwr_reset`, `function scoped_guard`, `function get_domain_base`, `function get_domain_ready_reg`, `function get_domain_pwrtrans_reg`.
- 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.