drivers/video/fbdev/cirrusfb.c

Source file repositories/reference/linux-study-clean/drivers/video/fbdev/cirrusfb.c

File Facts

System
Linux kernel
Corpus path
drivers/video/fbdev/cirrusfb.c
Extension
.c
Size
77130 bytes
Lines
2955
Domain
Driver Families
Bucket
drivers/video
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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.

Dependency Surface

Detected Declarations

Annotated Snippet

static struct pci_driver cirrusfb_pci_driver = {
	.name		= "cirrusfb",
	.id_table	= cirrusfb_pci_table,
	.probe		= cirrusfb_pci_register,
	.remove		= cirrusfb_pci_unregister,
};
#endif /* CONFIG_PCI */

#ifdef CONFIG_ZORRO
static int cirrusfb_zorro_register(struct zorro_dev *z,
				   const struct zorro_device_id *ent)
{
	struct fb_info *info;
	int error;
	const struct zorrocl *zcl;
	enum cirrus_board btype;
	unsigned long regbase, ramsize, rambase;
	struct cirrusfb_info *cinfo;

	info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
	if (!info)
		return -ENOMEM;

	zcl = (const struct zorrocl *)ent->driver_data;
	btype = zcl->type;
	regbase = zorro_resource_start(z) + zcl->regoffset;
	ramsize = zcl->ramsize;
	if (ramsize) {
		rambase = zorro_resource_start(z) + zcl->ramoffset;
		if (zorro_resource_len(z) == 64 * MB_) {
			/* Quirk for 64 MiB Picasso IV */
			rambase += zcl->ramoffset;
		}
	} else {
		struct zorro_dev *ram = zorro_find_device(zcl->ramid, NULL);
		if (!ram || !zorro_resource_len(ram)) {
			dev_err(info->device, "No video RAM found\n");
			error = -ENODEV;
			goto err_release_fb;
		}
		rambase = zorro_resource_start(ram);
		ramsize = zorro_resource_len(ram);
		if (zcl->ramid2 &&
		    (ram = zorro_find_device(zcl->ramid2, NULL))) {
			if (zorro_resource_start(ram) != rambase + ramsize) {
				dev_warn(info->device,
					 "Skipping non-contiguous RAM at %pR\n",
					 &ram->resource);
			} else {
				ramsize += zorro_resource_len(ram);
			}
		}
	}

	dev_info(info->device,
		 "%s board detected, REG at 0x%lx, %lu MiB RAM at 0x%lx\n",
		 cirrusfb_board_info[btype].name, regbase, ramsize / MB_,
		 rambase);

	if (!zorro_request_device(z, "cirrusfb")) {
		dev_err(info->device, "Cannot reserve %pR\n", &z->resource);
		error = -EBUSY;
		goto err_release_fb;
	}

	cinfo = info->par;
	cinfo->btype = btype;

	info->fix.mmio_start = regbase;
	cinfo->regbase = regbase > 16 * MB_ ? ioremap(regbase, 64 * 1024)
					    : ZTWO_VADDR(regbase);
	if (!cinfo->regbase) {
		dev_err(info->device, "Cannot map registers\n");
		error = -EIO;
		goto err_release_dev;
	}

	info->fix.smem_start = rambase;
	info->screen_size = ramsize;
	info->screen_base = rambase > 16 * MB_ ? ioremap(rambase, ramsize)
					       : ZTWO_VADDR(rambase);
	if (!info->screen_base) {
		dev_err(info->device, "Cannot map video RAM\n");
		error = -EIO;
		goto err_unmap_reg;
	}

	cinfo->unmap = cirrusfb_zorro_unmap;

	dev_info(info->device,

Annotation

Implementation Notes