drivers/video/fbdev/goldfishfb.c
Source file repositories/reference/linux-study-clean/drivers/video/fbdev/goldfishfb.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/video/fbdev/goldfishfb.c- Extension
.c- Size
- 8268 bytes
- Lines
- 318
- Domain
- Driver Families
- Bucket
- drivers/video
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/module.hlinux/kernel.hlinux/dma-mapping.hlinux/errno.hlinux/string.hlinux/slab.hlinux/delay.hlinux/mm.hlinux/fb.hlinux/init.hlinux/interrupt.hlinux/ioport.hlinux/platform_device.hlinux/acpi.h
Detected Declarations
struct goldfish_fbfunction goldfish_fb_interruptfunction convert_bitfieldfunction goldfish_fb_setcolregfunction goldfish_fb_check_varfunction goldfish_fb_set_parfunction goldfish_fb_pan_displayfunction goldfish_fb_blankfunction goldfish_fb_probefunction goldfish_fb_remove
Annotated Snippet
struct goldfish_fb {
void __iomem *reg_base;
int irq;
spinlock_t lock;
wait_queue_head_t wait;
int base_update_count;
int rotation;
struct fb_info fb;
u32 cmap[16];
};
static irqreturn_t goldfish_fb_interrupt(int irq, void *dev_id)
{
unsigned long irq_flags;
struct goldfish_fb *fb = dev_id;
u32 status;
spin_lock_irqsave(&fb->lock, irq_flags);
status = readl(fb->reg_base + FB_INT_STATUS);
if (status & FB_INT_BASE_UPDATE_DONE) {
fb->base_update_count++;
wake_up(&fb->wait);
}
spin_unlock_irqrestore(&fb->lock, irq_flags);
return status ? IRQ_HANDLED : IRQ_NONE;
}
static inline u32 convert_bitfield(int val, struct fb_bitfield *bf)
{
unsigned int mask = (1 << bf->length) - 1;
return (val >> (16 - bf->length) & mask) << bf->offset;
}
static int
goldfish_fb_setcolreg(unsigned int regno, unsigned int red, unsigned int green,
unsigned int blue, unsigned int transp, struct fb_info *info)
{
struct goldfish_fb *fb = container_of(info, struct goldfish_fb, fb);
if (regno < 16) {
fb->cmap[regno] = convert_bitfield(transp, &fb->fb.var.transp) |
convert_bitfield(blue, &fb->fb.var.blue) |
convert_bitfield(green, &fb->fb.var.green) |
convert_bitfield(red, &fb->fb.var.red);
return 0;
} else {
return 1;
}
}
static int goldfish_fb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info)
{
if ((var->rotate & 1) != (info->var.rotate & 1)) {
if ((var->xres != info->var.yres) ||
(var->yres != info->var.xres) ||
(var->xres_virtual != info->var.yres) ||
(var->yres_virtual > info->var.xres * 2) ||
(var->yres_virtual < info->var.xres)) {
return -EINVAL;
}
} else {
if ((var->xres != info->var.xres) ||
(var->yres != info->var.yres) ||
(var->xres_virtual != info->var.xres) ||
(var->yres_virtual > info->var.yres * 2) ||
(var->yres_virtual < info->var.yres)) {
return -EINVAL;
}
}
if ((var->xoffset != info->var.xoffset) ||
(var->bits_per_pixel != info->var.bits_per_pixel) ||
(var->grayscale != info->var.grayscale)) {
return -EINVAL;
}
return 0;
}
static int goldfish_fb_set_par(struct fb_info *info)
{
struct goldfish_fb *fb = container_of(info, struct goldfish_fb, fb);
if (fb->rotation != fb->fb.var.rotate) {
info->fix.line_length = info->var.xres * 2;
fb->rotation = fb->fb.var.rotate;
writel(fb->rotation, fb->reg_base + FB_SET_ROTATION);
}
return 0;
}
Annotation
- Immediate include surface: `linux/module.h`, `linux/kernel.h`, `linux/dma-mapping.h`, `linux/errno.h`, `linux/string.h`, `linux/slab.h`, `linux/delay.h`, `linux/mm.h`.
- Detected declarations: `struct goldfish_fb`, `function goldfish_fb_interrupt`, `function convert_bitfield`, `function goldfish_fb_setcolreg`, `function goldfish_fb_check_var`, `function goldfish_fb_set_par`, `function goldfish_fb_pan_display`, `function goldfish_fb_blank`, `function goldfish_fb_probe`, `function goldfish_fb_remove`.
- Atlas domain: Driver Families / drivers/video.
- Implementation status: source 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.