drivers/sbus/char/display7seg.c

Source file repositories/reference/linux-study-clean/drivers/sbus/char/display7seg.c

File Facts

System
Linux kernel
Corpus path
drivers/sbus/char/display7seg.c
Extension
.c
Size
6265 bytes
Lines
268
Domain
Driver Families
Bucket
drivers/sbus
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 d7s_fops = {
	.owner =		THIS_MODULE,
	.unlocked_ioctl =	d7s_ioctl,
	.compat_ioctl =		compat_ptr_ioctl,
	.open =			d7s_open,
	.release =		d7s_release,
	.llseek = noop_llseek,
};

static struct miscdevice d7s_miscdev = {
	.minor		= D7S_MINOR,
	.name		= DRIVER_NAME,
	.fops		= &d7s_fops
};

static int d7s_probe(struct platform_device *op)
{
	struct device_node *opts;
	int err = -EINVAL;
	struct d7s *p;
	u8 regs;

	if (d7s_device)
		goto out;

	p = devm_kzalloc(&op->dev, sizeof(*p), GFP_KERNEL);
	err = -ENOMEM;
	if (!p)
		goto out;

	p->regs = of_ioremap(&op->resource[0], 0, sizeof(u8), "d7s");
	if (!p->regs) {
		printk(KERN_ERR PFX "Cannot map chip registers\n");
		goto out;
	}

	err = misc_register(&d7s_miscdev);
	if (err) {
		printk(KERN_ERR PFX "Unable to acquire miscdevice minor %i\n",
		       D7S_MINOR);
		goto out_iounmap;
	}

	/* OBP option "d7s-flipped?" is honored as default for the
	 * device, and reset default when detached
	 */
	regs = readb(p->regs);
	opts = of_find_node_by_path("/options");
	if (opts)
	    p->flipped = of_property_read_bool(opts, "d7s-flipped?");

	if (p->flipped)
		regs |= D7S_FLIP;
	else
		regs &= ~D7S_FLIP;

	writeb(regs,  p->regs);

	printk(KERN_INFO PFX "7-Segment Display%pOF at [%s:0x%llx] %s\n",
	       op->dev.of_node,
	       (regs & D7S_FLIP) ? " (FLIPPED)" : "",
	       op->resource[0].start,
	       sol_compat ? "in sol_compat mode" : "");

	dev_set_drvdata(&op->dev, p);
	d7s_device = p;
	err = 0;
	of_node_put(opts);

out:
	return err;

out_iounmap:
	of_iounmap(&op->resource[0], p->regs, sizeof(u8));
	goto out;
}

static void d7s_remove(struct platform_device *op)
{
	struct d7s *p = dev_get_drvdata(&op->dev);
	u8 regs = readb(p->regs);

	/* Honor OBP d7s-flipped? unless operating in solaris-compat mode */
	if (sol_compat) {
		if (p->flipped)
			regs |= D7S_FLIP;
		else
			regs &= ~D7S_FLIP;
		writeb(regs, p->regs);
	}

Annotation

Implementation Notes