drivers/char/powernv-op-panel.c

Source file repositories/reference/linux-study-clean/drivers/char/powernv-op-panel.c

File Facts

System
Linux kernel
Corpus path
drivers/char/powernv-op-panel.c
Extension
.c
Size
5199 bytes
Lines
225
Domain
Driver Families
Bucket
drivers/char
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct file_operations oppanel_fops = {
	.owner		= THIS_MODULE,
	.llseek		= oppanel_llseek,
	.read		= oppanel_read,
	.write		= oppanel_write,
	.open		= oppanel_open,
	.release	= oppanel_release
};

static struct miscdevice oppanel_dev = {
	.minor		= MISC_DYNAMIC_MINOR,
	.name		= "op_panel",
	.fops		= &oppanel_fops
};

static int oppanel_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	u32 line_len;
	int rc, i;

	rc = of_property_read_u32(np, "#length", &line_len);
	if (rc) {
		pr_err_ratelimited("Operator panel length property not found\n");
		return rc;
	}
	rc = of_property_read_u32(np, "#lines", &num_lines);
	if (rc) {
		pr_err_ratelimited("Operator panel lines property not found\n");
		return rc;
	}
	oppanel_size = line_len * num_lines;

	pr_devel("Operator panel of size %u found with %u lines of length %u\n",
			oppanel_size, num_lines, line_len);

	oppanel_data = kcalloc(oppanel_size, sizeof(*oppanel_data), GFP_KERNEL);
	if (!oppanel_data)
		return -ENOMEM;

	oppanel_lines = kzalloc_objs(oppanel_line_t, num_lines);
	if (!oppanel_lines) {
		rc = -ENOMEM;
		goto free_oppanel_data;
	}

	memset(oppanel_data, ' ', oppanel_size);
	for (i = 0; i < num_lines; i++) {
		oppanel_lines[i].line_len = cpu_to_be64(line_len);
		oppanel_lines[i].line = cpu_to_be64(__pa(&oppanel_data[i *
						line_len]));
	}

	rc = misc_register(&oppanel_dev);
	if (rc) {
		pr_err_ratelimited("Failed to register as misc device\n");
		goto free_oppanel;
	}

	return 0;

free_oppanel:
	kfree(oppanel_lines);
free_oppanel_data:
	kfree(oppanel_data);
	return rc;
}

static void oppanel_remove(struct platform_device *pdev)
{
	misc_deregister(&oppanel_dev);
	kfree(oppanel_lines);
	kfree(oppanel_data);
}

static const struct of_device_id oppanel_match[] = {
	{ .compatible = "ibm,opal-oppanel" },
	{ },
};

static struct platform_driver oppanel_driver = {
	.driver	= {
		.name		= "powernv-op-panel",
		.of_match_table	= oppanel_match,
	},
	.probe	= oppanel_probe,
	.remove	= oppanel_remove,
};

module_platform_driver(oppanel_driver);

Annotation

Implementation Notes