drivers/gpu/drm/sysfb/ofdrm.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/sysfb/ofdrm.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/sysfb/ofdrm.c
Extension
.c
Size
31642 bytes
Lines
1167
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

struct ofdrm_device_funcs {
	void __iomem *(*cmap_ioremap)(struct ofdrm_device *odev,
				      struct device_node *of_node,
				      u64 fb_bas);
	void (*cmap_write)(struct ofdrm_device *odev, unsigned char index,
			   unsigned char r, unsigned char g, unsigned char b);
};

struct ofdrm_device {
	struct drm_sysfb_device sysfb;

	const struct ofdrm_device_funcs *funcs;

	/* colormap */
	void __iomem *cmap_base;

	u8 edid[EDID_LENGTH];

	/* modesetting */
	u32 formats[DRM_SYSFB_PLANE_NFORMATS(1)];
	struct drm_plane primary_plane;
	struct drm_crtc crtc;
	struct drm_encoder encoder;
	struct drm_connector connector;
};

static struct ofdrm_device *ofdrm_device_of_dev(struct drm_device *dev)
{
	return container_of(to_drm_sysfb_device(dev), struct ofdrm_device, sysfb);
}

/*
 * Hardware
 */

#if defined(CONFIG_PCI)
static struct pci_dev *display_get_pci_dev_of(struct drm_device *dev, struct device_node *of_node)
{
	const __be32 *vendor_p, *device_p;
	u32 vendor, device;
	struct pci_dev *pcidev;

	vendor_p = of_get_property(of_node, "vendor-id", NULL);
	if (!vendor_p)
		return ERR_PTR(-ENODEV);
	vendor = be32_to_cpup(vendor_p);

	device_p = of_get_property(of_node, "device-id", NULL);
	if (!device_p)
		return ERR_PTR(-ENODEV);
	device = be32_to_cpup(device_p);

	pcidev = pci_get_device(vendor, device, NULL);
	if (!pcidev)
		return ERR_PTR(-ENODEV);

	return pcidev;
}

static void ofdrm_pci_release(void *data)
{
	struct pci_dev *pcidev = data;

	pci_disable_device(pcidev);
	pci_dev_put(pcidev);
}

static int ofdrm_device_init_pci(struct ofdrm_device *odev)
{
	struct drm_device *dev = &odev->sysfb.dev;
	struct platform_device *pdev = to_platform_device(dev->dev);
	struct device_node *of_node = pdev->dev.of_node;
	struct pci_dev *pcidev;
	int ret;

	/*
	 * Never use pcim_ or other managed helpers on the returned PCI
	 * device. Otherwise, probing the native driver will fail for
	 * resource conflicts. PCI-device management has to be tied to
	 * the lifetime of the platform device until the native driver
	 * takes over.
	 */
	pcidev = display_get_pci_dev_of(dev, of_node);
	if (IS_ERR(pcidev))
		return 0; /* no PCI device found; ignore the error */

	ret = pci_enable_device(pcidev);
	if (ret) {
		drm_err(dev, "pci_enable_device(%s) failed: %d\n",
			dev_name(&pcidev->dev), ret);

Annotation

Implementation Notes