in f71808e_wdt.c [445:535]
static int fintek_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct fintek_wdt_pdata *pdata;
struct watchdog_device *wdd;
struct fintek_wdt *wd;
int wdt_conf, err = 0;
struct resource *res;
int sioaddr;
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
if (!res)
return -ENXIO;
sioaddr = res->start;
wd = devm_kzalloc(dev, sizeof(*wd), GFP_KERNEL);
if (!wd)
return -ENOMEM;
pdata = dev->platform_data;
wd->type = pdata->type;
wd->sioaddr = sioaddr;
wd->ident.options = WDIOF_SETTIMEOUT
| WDIOF_MAGICCLOSE
| WDIOF_KEEPALIVEPING
| WDIOF_CARDRESET;
snprintf(wd->ident.identity,
sizeof(wd->ident.identity), "%s watchdog",
fintek_wdt_names[wd->type]);
err = superio_enter(sioaddr);
if (err)
return err;
superio_select(wd->sioaddr, SIO_F71808FG_LD_WDT);
wdt_conf = superio_inb(sioaddr, F71808FG_REG_WDT_CONF);
/*
* We don't want WDTMOUT_STS to stick around till regular reboot.
* Write 1 to the bit to clear it to zero.
*/
superio_outb(sioaddr, F71808FG_REG_WDT_CONF,
wdt_conf | BIT(F71808FG_FLAG_WDTMOUT_STS));
wdd = &wd->wdd;
if (fintek_wdt_is_running(wd, wdt_conf))
set_bit(WDOG_HW_RUNNING, &wdd->status);
superio_exit(sioaddr);
wdd->parent = dev;
wdd->info = &wd->ident;
wdd->ops = &fintek_wdt_ops;
wdd->min_timeout = 1;
wdd->max_timeout = WATCHDOG_MAX_TIMEOUT;
watchdog_set_drvdata(wdd, wd);
watchdog_set_nowayout(wdd, nowayout);
watchdog_stop_on_unregister(wdd);
watchdog_stop_on_reboot(wdd);
watchdog_init_timeout(wdd, start_withtimeout ?: timeout, NULL);
if (wdt_conf & BIT(F71808FG_FLAG_WDTMOUT_STS))
wdd->bootstatus = WDIOF_CARDRESET;
/*
* WATCHDOG_HANDLE_BOOT_ENABLED can result in keepalive being directly
* called without a set_timeout before, so it needs to be done here
* unconditionally.
*/
fintek_wdt_set_timeout(wdd, wdd->timeout);
fintek_wdt_set_pulse_width(wd, pulse_width);
if (start_withtimeout) {
err = fintek_wdt_start(wdd);
if (err) {
dev_err(dev, "cannot start watchdog timer\n");
return err;
}
set_bit(WDOG_HW_RUNNING, &wdd->status);
dev_info(dev, "watchdog started with initial timeout of %u sec\n",
start_withtimeout);
}
return devm_watchdog_register_device(dev, wdd);
}