drivers/firmware/google/framebuffer-coreboot.c

Source file repositories/reference/linux-study-clean/drivers/firmware/google/framebuffer-coreboot.c

File Facts

System
Linux kernel
Corpus path
drivers/firmware/google/framebuffer-coreboot.c
Extension
.c
Size
4878 bytes
Lines
188
Domain
Driver Families
Bucket
drivers/firmware
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

// SPDX-License-Identifier: GPL-2.0-only
/*
 * framebuffer-coreboot.c
 *
 * Memory based framebuffer accessed through coreboot table.
 *
 * Copyright 2012-2013 David Herrmann <dh.herrmann@gmail.com>
 * Copyright 2017 Google Inc.
 * Copyright 2017 Samuel Holland <samuel@sholland.org>
 */

#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/platform_data/simplefb.h>
#include <linux/platform_device.h>
#include <linux/sysfb.h>

#include "coreboot_table.h"

#if defined(CONFIG_PCI)
static bool framebuffer_pci_dev_is_enabled(struct pci_dev *pdev)
{
	/*
	 * TODO: Try to integrate this code into the PCI subsystem
	 */
	int ret;
	u16 command;

	ret = pci_read_config_word(pdev, PCI_COMMAND, &command);
	if (ret != PCIBIOS_SUCCESSFUL)
		return false;
	if (!(command & PCI_COMMAND_MEMORY))
		return false;
	return true;
}

static struct pci_dev *framebuffer_parent_pci_dev(struct resource *res)
{
	struct pci_dev *pdev = NULL;
	const struct resource *r = NULL;

	while (!r && (pdev = pci_get_base_class(PCI_BASE_CLASS_DISPLAY, pdev)))
		r = pci_find_resource(pdev, res);

	if (!r || !pdev)
		return NULL; /* not found; not an error */

	if (!framebuffer_pci_dev_is_enabled(pdev)) {
		pci_dev_put(pdev);
		return ERR_PTR(-ENODEV);
	}

	return pdev;
}
#else
static struct pci_dev *framebuffer_parent_pci_dev(struct resource *res)
{
	return NULL;
}
#endif

static struct device *framebuffer_parent_dev(struct resource *res)
{
	struct pci_dev *pdev;

	pdev = framebuffer_parent_pci_dev(res);
	if (IS_ERR(pdev))
		return ERR_CAST(pdev);
	else if (pdev)
		return &pdev->dev;

	return NULL;
}

static int framebuffer_probe(struct coreboot_device *dev)
{
	struct lb_framebuffer *fb = &dev->framebuffer;
	struct device *parent;
	struct platform_device *pdev;
	struct resource res;
	int ret;
#if !IS_ENABLED(CONFIG_DRM_COREBOOTDRM)
	struct simplefb_platform_data pdata = {
		.width = fb->x_resolution,
		.height = fb->y_resolution,
		.stride = fb->bytes_per_line,

Annotation

Implementation Notes