drivers/gpu/drm/tve200/tve200_drv.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/tve200/tve200_drv.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/tve200/tve200_drv.c
Extension
.c
Size
7027 bytes
Lines
281
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

if (IS_ERR(bridge)) {
			ret = PTR_ERR(bridge);
			goto out_bridge;
		}
	} else {
		/*
		 * TODO: when we are using a different bridge than a panel
		 * (such as a dumb VGA connector) we need to devise a different
		 * method to get the connector out of the bridge.
		 */
		dev_err(dev->dev, "the bridge is not a panel\n");
		ret = -EINVAL;
		goto out_bridge;
	}

	ret = tve200_display_init(dev);
	if (ret) {
		dev_err(dev->dev, "failed to init display\n");
		goto out_bridge;
	}

	ret = drm_simple_display_pipe_attach_bridge(&priv->pipe,
						    bridge);
	if (ret) {
		dev_err(dev->dev, "failed to attach bridge\n");
		goto out_bridge;
	}

	priv->panel = panel;
	priv->connector = drm_panel_bridge_connector(bridge);
	priv->bridge = bridge;

	dev_info(dev->dev, "attached to panel %s\n",
		 dev_name(panel->dev));

	ret = drm_vblank_init(dev, 1);
	if (ret) {
		dev_err(dev->dev, "failed to init vblank\n");
		goto out_bridge;
	}

	drm_mode_config_reset(dev);
	drm_kms_helper_poll_init(dev);

	goto finish;

out_bridge:
	if (panel)
		drm_panel_bridge_remove(bridge);
	drm_mode_config_cleanup(dev);
finish:
	return ret;
}

DEFINE_DRM_GEM_DMA_FOPS(drm_fops);

static const struct drm_driver tve200_drm_driver = {
	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
	.ioctls = NULL,
	.fops = &drm_fops,
	.name = "tve200",
	.desc = DRIVER_DESC,
	.major = 1,
	.minor = 0,
	.patchlevel = 0,
	DRM_GEM_DMA_DRIVER_OPS,
	DRM_FBDEV_DMA_DRIVER_OPS,
};

static int tve200_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct tve200_drm_dev_private *priv;
	struct drm_device *drm;
	int irq;
	int ret;

	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	drm = drm_dev_alloc(&tve200_drm_driver, dev);
	if (IS_ERR(drm))
		return PTR_ERR(drm);
	platform_set_drvdata(pdev, drm);
	priv->drm = drm;
	drm->dev_private = priv;

	/* Clock the silicon so we can access the registers */
	priv->pclk = devm_clk_get(dev, "PCLK");

Annotation

Implementation Notes