drivers/watchdog/mei_wdt.c

Source file repositories/reference/linux-study-clean/drivers/watchdog/mei_wdt.c

File Facts

System
Linux kernel
Corpus path
drivers/watchdog/mei_wdt.c
Extension
.c
Size
14953 bytes
Lines
665
Domain
Driver Families
Bucket
drivers/watchdog
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 dbgfs_fops_activation = {
	.open    = simple_open,
	.read    = mei_dbgfs_read_activation,
	.llseek  = generic_file_llseek,
};

static ssize_t mei_dbgfs_read_state(struct file *file, char __user *ubuf,
				    size_t cnt, loff_t *ppos)
{
	struct mei_wdt *wdt = file->private_data;
	char buf[32];
	ssize_t pos;

	pos = scnprintf(buf, sizeof(buf), "state: %s\n",
			mei_wdt_state_str(wdt->state));

	return simple_read_from_buffer(ubuf, cnt, ppos, buf, pos);
}

static const struct file_operations dbgfs_fops_state = {
	.open = simple_open,
	.read = mei_dbgfs_read_state,
	.llseek = generic_file_llseek,
};

static void dbgfs_unregister(struct mei_wdt *wdt)
{
	debugfs_remove_recursive(wdt->dbgfs_dir);
	wdt->dbgfs_dir = NULL;
}

static void dbgfs_register(struct mei_wdt *wdt)
{
	struct dentry *dir;

	dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
	wdt->dbgfs_dir = dir;

	debugfs_create_file("state", S_IRUSR, dir, wdt, &dbgfs_fops_state);

	debugfs_create_file("activation", S_IRUSR, dir, wdt,
			    &dbgfs_fops_activation);
}

#else

static inline void dbgfs_unregister(struct mei_wdt *wdt) {}
static inline void dbgfs_register(struct mei_wdt *wdt) {}
#endif /* CONFIG_DEBUG_FS */

static int mei_wdt_probe(struct mei_cl_device *cldev,
			 const struct mei_cl_device_id *id)
{
	struct mei_wdt *wdt;
	int ret;

	wdt = kzalloc_obj(struct mei_wdt);
	if (!wdt)
		return -ENOMEM;

	wdt->timeout = MEI_WDT_DEFAULT_TIMEOUT;
	wdt->state = MEI_WDT_PROBE;
	wdt->cldev = cldev;
	wdt->resp_required = mei_cldev_ver(cldev) > 0x1;
	mutex_init(&wdt->reg_lock);
	init_completion(&wdt->response);
	INIT_WORK(&wdt->unregister, mei_wdt_unregister_work);

	mei_cldev_set_drvdata(cldev, wdt);

	ret = mei_cldev_enable(cldev);
	if (ret < 0) {
		dev_err(&cldev->dev, "Could not enable cl device\n");
		goto err_out;
	}

	ret = mei_cldev_register_rx_cb(wdt->cldev, mei_wdt_rx);
	if (ret) {
		dev_err(&cldev->dev, "Could not reg rx event ret=%d\n", ret);
		goto err_disable;
	}

	ret = mei_cldev_register_notif_cb(wdt->cldev, mei_wdt_notif);
	/* on legacy devices notification is not supported
	 */
	if (ret && ret != -EOPNOTSUPP) {
		dev_err(&cldev->dev, "Could not reg notif event ret=%d\n", ret);
		goto err_disable;
	}

Annotation

Implementation Notes