in cadence_wdt.c [291:373]
static int cdns_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
int ret, irq;
unsigned long clock_f;
struct cdns_wdt *wdt;
struct watchdog_device *cdns_wdt_device;
wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
cdns_wdt_device = &wdt->cdns_wdt_device;
cdns_wdt_device->info = &cdns_wdt_info;
cdns_wdt_device->ops = &cdns_wdt_ops;
cdns_wdt_device->timeout = CDNS_WDT_DEFAULT_TIMEOUT;
cdns_wdt_device->min_timeout = CDNS_WDT_MIN_TIMEOUT;
cdns_wdt_device->max_timeout = CDNS_WDT_MAX_TIMEOUT;
wdt->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->regs))
return PTR_ERR(wdt->regs);
/* Register the interrupt */
wdt->rst = of_property_read_bool(dev->of_node, "reset-on-timeout");
irq = platform_get_irq(pdev, 0);
if (!wdt->rst && irq >= 0) {
ret = devm_request_irq(dev, irq, cdns_wdt_irq_handler, 0,
pdev->name, pdev);
if (ret) {
dev_err(dev,
"cannot register interrupt handler err=%d\n",
ret);
return ret;
}
}
/* Initialize the members of cdns_wdt structure */
cdns_wdt_device->parent = dev;
watchdog_init_timeout(cdns_wdt_device, wdt_timeout, dev);
watchdog_set_nowayout(cdns_wdt_device, nowayout);
watchdog_stop_on_reboot(cdns_wdt_device);
watchdog_set_drvdata(cdns_wdt_device, wdt);
wdt->clk = devm_clk_get(dev, NULL);
if (IS_ERR(wdt->clk))
return dev_err_probe(dev, PTR_ERR(wdt->clk),
"input clock not found\n");
ret = clk_prepare_enable(wdt->clk);
if (ret) {
dev_err(dev, "unable to enable clock\n");
return ret;
}
ret = devm_add_action_or_reset(dev, cdns_clk_disable_unprepare,
wdt->clk);
if (ret)
return ret;
clock_f = clk_get_rate(wdt->clk);
if (clock_f <= CDNS_WDT_CLK_75MHZ) {
wdt->prescaler = CDNS_WDT_PRESCALE_512;
wdt->ctrl_clksel = CDNS_WDT_PRESCALE_SELECT_512;
} else {
wdt->prescaler = CDNS_WDT_PRESCALE_4096;
wdt->ctrl_clksel = CDNS_WDT_PRESCALE_SELECT_4096;
}
spin_lock_init(&wdt->io_lock);
watchdog_stop_on_reboot(cdns_wdt_device);
watchdog_stop_on_unregister(cdns_wdt_device);
ret = devm_watchdog_register_device(dev, cdns_wdt_device);
if (ret)
return ret;
platform_set_drvdata(pdev, wdt);
dev_info(dev, "Xilinx Watchdog Timer with timeout %ds%s\n",
cdns_wdt_device->timeout, nowayout ? ", nowayout" : "");
return 0;
}