drivers/watchdog/menf21bmc_wdt.c

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

File Facts

System
Linux kernel
Corpus path
drivers/watchdog/menf21bmc_wdt.c
Extension
.c
Size
4882 bytes
Lines
185
Domain
Driver Families
Bucket
drivers/watchdog
Inferred role
Driver Families: implementation source
Status
source 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

struct menf21bmc_wdt {
	struct watchdog_device wdt;
	struct i2c_client *i2c_client;
};

static int menf21bmc_wdt_set_bootstatus(struct menf21bmc_wdt *data)
{
	int rst_rsn;

	rst_rsn = i2c_smbus_read_byte_data(data->i2c_client, BMC_CMD_RST_RSN);
	if (rst_rsn < 0)
		return rst_rsn;

	if (rst_rsn == 0x02)
		data->wdt.bootstatus |= WDIOF_CARDRESET;
	else if (rst_rsn == 0x05)
		data->wdt.bootstatus |= WDIOF_EXTERN1;
	else if (rst_rsn == 0x06)
		data->wdt.bootstatus |= WDIOF_EXTERN2;
	else if (rst_rsn == 0x0A)
		data->wdt.bootstatus |= WDIOF_POWERUNDER;

	return 0;
}

static int menf21bmc_wdt_start(struct watchdog_device *wdt)
{
	struct menf21bmc_wdt *drv_data = watchdog_get_drvdata(wdt);

	return i2c_smbus_write_byte(drv_data->i2c_client, BMC_CMD_WD_ON);
}

static int menf21bmc_wdt_stop(struct watchdog_device *wdt)
{
	struct menf21bmc_wdt *drv_data = watchdog_get_drvdata(wdt);

	return i2c_smbus_write_byte_data(drv_data->i2c_client,
					 BMC_CMD_WD_OFF, BMC_WD_OFF_VAL);
}

static int
menf21bmc_wdt_settimeout(struct watchdog_device *wdt, unsigned int timeout)
{
	int ret;
	struct menf21bmc_wdt *drv_data = watchdog_get_drvdata(wdt);

	/*
	 *  BMC Watchdog does have a resolution of 100ms.
	 *  Watchdog API defines the timeout in seconds, so we have to
	 *  multiply the value.
	 */
	ret = i2c_smbus_write_word_data(drv_data->i2c_client,
					BMC_CMD_WD_TIME, timeout * 10);
	if (ret < 0)
		return ret;

	wdt->timeout = timeout;

	return 0;
}

static int menf21bmc_wdt_ping(struct watchdog_device *wdt)
{
	struct menf21bmc_wdt *drv_data = watchdog_get_drvdata(wdt);

	return i2c_smbus_write_byte(drv_data->i2c_client, BMC_CMD_WD_TRIG);
}

static const struct watchdog_info menf21bmc_wdt_info = {
	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
	.identity = DEVNAME,
};

static const struct watchdog_ops menf21bmc_wdt_ops = {
	.owner		= THIS_MODULE,
	.start		= menf21bmc_wdt_start,
	.stop		= menf21bmc_wdt_stop,
	.ping		= menf21bmc_wdt_ping,
	.set_timeout	= menf21bmc_wdt_settimeout,
};

static int menf21bmc_wdt_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	int ret, bmc_timeout;
	struct menf21bmc_wdt *drv_data;
	struct i2c_client *i2c_client = to_i2c_client(dev->parent);

	drv_data = devm_kzalloc(dev, sizeof(struct menf21bmc_wdt), GFP_KERNEL);
	if (!drv_data)

Annotation

Implementation Notes