drivers/watchdog/pc87413_wdt.c

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

File Facts

System
Linux kernel
Corpus path
drivers/watchdog/pc87413_wdt.c
Extension
.c
Size
14150 bytes
Lines
592
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 pc87413_fops = {
	.owner		= THIS_MODULE,
	.write		= pc87413_write,
	.unlocked_ioctl	= pc87413_ioctl,
	.compat_ioctl	= compat_ptr_ioctl,
	.open		= pc87413_open,
	.release	= pc87413_release,
};

static struct notifier_block pc87413_notifier = {
	.notifier_call  = pc87413_notify_sys,
};

static struct miscdevice pc87413_miscdev = {
	.minor          = WATCHDOG_MINOR,
	.name           = "watchdog",
	.fops           = &pc87413_fops,
};

/* -- Module init functions -------------------------------------*/

/**
 *	pc87413_init: module's "constructor"
 *
 *	Set up the WDT watchdog board. All we have to do is grab the
 *	resources we require and bitch if anyone beat us to them.
 *	The open() function will actually kick the board off.
 */

static int __init pc87413_init(void)
{
	int ret;

	pr_info("Version " VERSION " at io 0x%X\n",
							WDT_INDEX_IO_PORT);

	if (!request_muxed_region(io, 2, MODNAME))
		return -EBUSY;

	ret = register_reboot_notifier(&pc87413_notifier);
	if (ret != 0)
		pr_err("cannot register reboot notifier (err=%d)\n", ret);

	ret = misc_register(&pc87413_miscdev);
	if (ret != 0) {
		pr_err("cannot register miscdev on minor=%d (err=%d)\n",
		       WATCHDOG_MINOR, ret);
		goto reboot_unreg;
	}
	pr_info("initialized. timeout=%d min\n", timeout);

	pc87413_select_wdt_out();
	pc87413_enable_swc();
	pc87413_get_swc_base_addr();

	if (!request_region(swc_base_addr, 0x20, MODNAME)) {
		pr_err("cannot request SWC region at 0x%x\n", swc_base_addr);
		ret = -EBUSY;
		goto misc_unreg;
	}

	pc87413_enable();

	release_region(io, 2);
	return 0;

misc_unreg:
	misc_deregister(&pc87413_miscdev);
reboot_unreg:
	unregister_reboot_notifier(&pc87413_notifier);
	release_region(io, 2);
	return ret;
}

/**
 *	pc87413_exit: module's "destructor"
 *
 *	Unload the watchdog. You cannot do this with any file handles open.
 *	If your watchdog is set to continue ticking on close and you unload
 *	it, well it keeps ticking. We won't get the interrupt but the board
 *	will not touch PC memory so all is fine. You just have to load a new
 *	module in 60 seconds or reboot.
 */

static void __exit pc87413_exit(void)
{
	/* Stop the timer before we leave */
	if (!nowayout) {
		pc87413_disable();
		pr_info("Watchdog disabled\n");

Annotation

Implementation Notes