drivers/misc/tps6594-pfsm.c

Source file repositories/reference/linux-study-clean/drivers/misc/tps6594-pfsm.c

File Facts

System
Linux kernel
Corpus path
drivers/misc/tps6594-pfsm.c
Extension
.c
Size
8978 bytes
Lines
340
Domain
Driver Families
Bucket
drivers/misc
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 tps6594_pfsm_fops = {
	.owner		= THIS_MODULE,
	.llseek		= generic_file_llseek,
	.read		= tps6594_pfsm_read,
	.write		= tps6594_pfsm_write,
	.unlocked_ioctl	= tps6594_pfsm_ioctl,
	.compat_ioctl   = compat_ptr_ioctl,
};

static irqreturn_t tps6594_pfsm_isr(int irq, void *dev_id)
{
	struct platform_device *pdev = dev_id;
	int i;

	for (i = 0 ; i < pdev->num_resources ; i++) {
		if (irq == platform_get_irq_byname(pdev, pdev->resource[i].name)) {
			dev_err(pdev->dev.parent, "%s event detected\n", pdev->resource[i].name);
			return IRQ_HANDLED;
		}
	}

	return IRQ_NONE;
}

static int tps6594_pfsm_probe(struct platform_device *pdev)
{
	struct tps6594_pfsm *pfsm;
	struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent);
	struct device *dev = &pdev->dev;
	int irq;
	int ret;
	int i;

	pfsm = devm_kzalloc(dev, sizeof(struct tps6594_pfsm), GFP_KERNEL);
	if (!pfsm)
		return -ENOMEM;

	pfsm->regmap = tps->regmap;

	pfsm->miscdev.minor = MISC_DYNAMIC_MINOR;
	pfsm->miscdev.name = devm_kasprintf(dev, GFP_KERNEL, "pfsm-%ld-0x%02x",
					    tps->chip_id, tps->reg);
	if (!pfsm->miscdev.name)
		return -ENOMEM;

	pfsm->miscdev.fops = &tps6594_pfsm_fops;
	pfsm->miscdev.parent = dev->parent;
	pfsm->chip_id = tps->chip_id;

	for (i = 0 ; i < pdev->num_resources ; i++) {
		irq = platform_get_irq_byname(pdev, pdev->resource[i].name);
		if (irq < 0)
			return irq;

		ret = devm_request_threaded_irq(dev, irq, NULL,
						tps6594_pfsm_isr, IRQF_ONESHOT,
						pdev->resource[i].name, pdev);
		if (ret)
			return dev_err_probe(dev, ret, "Failed to request irq\n");
	}

	platform_set_drvdata(pdev, pfsm);

	return misc_register(&pfsm->miscdev);
}

static void tps6594_pfsm_remove(struct platform_device *pdev)
{
	struct tps6594_pfsm *pfsm = platform_get_drvdata(pdev);

	misc_deregister(&pfsm->miscdev);
}

static struct platform_driver tps6594_pfsm_driver = {
	.driver	= {
		.name = "tps6594-pfsm",
	},
	.probe = tps6594_pfsm_probe,
	.remove = tps6594_pfsm_remove,
};

module_platform_driver(tps6594_pfsm_driver);

MODULE_ALIAS("platform:tps6594-pfsm");
MODULE_AUTHOR("Julien Panis <jpanis@baylibre.com>");
MODULE_DESCRIPTION("TPS6594 Pre-configurable Finite State Machine Driver");
MODULE_LICENSE("GPL");

Annotation

Implementation Notes