drivers/gpu/drm/arm/hdlcd_drv.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/arm/hdlcd_drv.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/arm/hdlcd_drv.c
Extension
.c
Size
10387 bytes
Lines
422
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.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <linux/aperture.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/clk.h>
#include <linux/component.h>
#include <linux/console.h>
#include <linux/dma-mapping.h>
#include <linux/list.h>
#include <linux/of_graph.h>
#include <linux/of_reserved_mem.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>

#include <drm/clients/drm_client_setup.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_debugfs.h>
#include <drm/drm_drv.h>
#include <drm/drm_fbdev_dma.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_modeset_helper.h>
#include <drm/drm_module.h>
#include <drm/drm_of.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h>

#include "hdlcd_drv.h"
#include "hdlcd_regs.h"

static irqreturn_t hdlcd_irq(int irq, void *arg)
{
	struct hdlcd_drm_private *hdlcd = arg;
	unsigned long irq_status;

	irq_status = hdlcd_read(hdlcd, HDLCD_REG_INT_STATUS);

#ifdef CONFIG_DEBUG_FS
	if (irq_status & HDLCD_INTERRUPT_UNDERRUN)
		atomic_inc(&hdlcd->buffer_underrun_count);

	if (irq_status & HDLCD_INTERRUPT_DMA_END)
		atomic_inc(&hdlcd->dma_end_count);

	if (irq_status & HDLCD_INTERRUPT_BUS_ERROR)
		atomic_inc(&hdlcd->bus_error_count);

	if (irq_status & HDLCD_INTERRUPT_VSYNC)
		atomic_inc(&hdlcd->vsync_count);

#endif
	if (irq_status & HDLCD_INTERRUPT_VSYNC)
		drm_crtc_handle_vblank(&hdlcd->crtc);

	/* acknowledge interrupt(s) */
	hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status);

	return IRQ_HANDLED;
}

static int hdlcd_irq_install(struct hdlcd_drm_private *hdlcd)
{
	int ret;

	/* Ensure interrupts are disabled */
	hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, 0);
	hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, ~0);

	ret = request_irq(hdlcd->irq, hdlcd_irq, 0, "hdlcd", hdlcd);
	if (ret)
		return ret;

#ifdef CONFIG_DEBUG_FS
	/* enable debug interrupts */
	hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, HDLCD_DEBUG_INT_MASK);
#endif

	return 0;
}

static void hdlcd_irq_uninstall(struct hdlcd_drm_private *hdlcd)
{
	/* disable all the interrupts that we might have enabled */
	hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, 0);

	free_irq(hdlcd->irq, hdlcd);
}

static int hdlcd_load(struct drm_device *drm, unsigned long flags)

Annotation

Implementation Notes