drivers/video/aperture.c

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

File Facts

System
Linux kernel
Corpus path
drivers/video/aperture.c
Extension
.c
Size
11815 bytes
Lines
375
Domain
Driver Families
Bucket
drivers/video
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct aperture_range {
	struct device *dev;
	resource_size_t base;
	resource_size_t size;
	struct list_head lh;
	void (*detach)(struct device *dev);
};

static LIST_HEAD(apertures);
static DEFINE_MUTEX(apertures_lock);

static bool overlap(resource_size_t base1, resource_size_t end1,
		    resource_size_t base2, resource_size_t end2)
{
	return (base1 < end2) && (end1 > base2);
}

static void devm_aperture_acquire_release(void *data)
{
	struct aperture_range *ap = data;
	bool detached = !ap->dev;

	if (detached)
		return;

	mutex_lock(&apertures_lock);
	list_del(&ap->lh);
	mutex_unlock(&apertures_lock);
}

static int devm_aperture_acquire(struct device *dev,
				 resource_size_t base, resource_size_t size,
				 void (*detach)(struct device *))
{
	size_t end = base + size;
	struct list_head *pos;
	struct aperture_range *ap;

	mutex_lock(&apertures_lock);

	list_for_each(pos, &apertures) {
		ap = container_of(pos, struct aperture_range, lh);
		if (overlap(base, end, ap->base, ap->base + ap->size)) {
			mutex_unlock(&apertures_lock);
			return -EBUSY;
		}
	}

	ap = devm_kzalloc(dev, sizeof(*ap), GFP_KERNEL);
	if (!ap) {
		mutex_unlock(&apertures_lock);
		return -ENOMEM;
	}

	ap->dev = dev;
	ap->base = base;
	ap->size = size;
	ap->detach = detach;
	INIT_LIST_HEAD(&ap->lh);

	list_add(&ap->lh, &apertures);

	mutex_unlock(&apertures_lock);

	return devm_add_action_or_reset(dev, devm_aperture_acquire_release, ap);
}

static void aperture_detach_platform_device(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);

	/*
	 * Remove the device from the device hierarchy. This is the right thing
	 * to do for firmware-based fb drivers, such as EFI, VESA or VGA. After
	 * the new driver takes over the hardware, the firmware device's state
	 * will be lost.
	 *
	 * For non-platform devices, a new callback would be required.
	 *
	 * If the aperture helpers ever need to handle native drivers, this call
	 * would only have to unplug the DRM device, so that the hardware device
	 * stays around after detachment.
	 */
	platform_device_unregister(pdev);
}

/**
 * devm_aperture_acquire_for_platform_device - Acquires ownership of an aperture
 *                                             on behalf of a platform device.
 * @pdev:	the platform device to own the aperture

Annotation

Implementation Notes