drivers/watchdog/sc1200wdt.c

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

File Facts

System
Linux kernel
Corpus path
drivers/watchdog/sc1200wdt.c
Extension
.c
Size
11175 bytes
Lines
475
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 sc1200wdt_fops = {
	.owner		= THIS_MODULE,
	.write		= sc1200wdt_write,
	.unlocked_ioctl = sc1200wdt_ioctl,
	.compat_ioctl	= compat_ptr_ioctl,
	.open		= sc1200wdt_open,
	.release	= sc1200wdt_release,
};

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


static int __init sc1200wdt_probe(void)
{
	/* The probe works by reading the PMC3 register's default value of 0x0e
	 * there is one caveat, if the device disables the parallel port or any
	 * of the UARTs we won't be able to detect it.
	 * NB. This could be done with accuracy by reading the SID registers,
	 * but we don't have access to those io regions.
	 */

	unsigned char reg;

	sc1200wdt_read_data(PMC3, &reg);
	reg &= 0x0f;		/* we don't want the UART busy bits */
	return (reg == 0x0e) ? 0 : -ENODEV;
}


#if defined CONFIG_PNP

static const struct pnp_device_id scl200wdt_pnp_devices[] = {
	/* National Semiconductor PC87307/PC97307 watchdog component */
	{ .id = "NSC0800" },
	{ }
};

static int scl200wdt_pnp_probe(struct pnp_dev *dev,
					const struct pnp_device_id *dev_id)
{
	/* this driver only supports one card at a time */
	if (wdt_dev || !isapnp)
		return -EBUSY;

	wdt_dev = dev;
	io = pnp_port_start(wdt_dev, 0);
	io_len = pnp_port_len(wdt_dev, 0);

	if (!request_region(io, io_len, SC1200_MODULE_NAME)) {
		pr_err("Unable to register IO port %#x\n", io);
		return -EBUSY;
	}

	pr_info("PnP device found at io port %#x/%d\n", io, io_len);
	return 0;
}

static void scl200wdt_pnp_remove(struct pnp_dev *dev)
{
	if (wdt_dev) {
		release_region(io, io_len);
		wdt_dev = NULL;
	}
}

static struct pnp_driver scl200wdt_pnp_driver = {
	.name		= "scl200wdt",
	.id_table	= scl200wdt_pnp_devices,
	.probe		= scl200wdt_pnp_probe,
	.remove		= scl200wdt_pnp_remove,
};

#endif /* CONFIG_PNP */


static int __init sc1200wdt_init(void)
{
	int ret;

	pr_info("%s\n", SC1200_MODULE_VER);

#if defined CONFIG_PNP
	if (isapnp) {
		ret = pnp_register_driver(&scl200wdt_pnp_driver);
		if (ret)
			goto out_clean;

Annotation

Implementation Notes