in st_lpc_wdt.c [150:240]
static int st_wdog_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
const struct of_device_id *match;
struct device_node *np = dev->of_node;
struct st_wdog *st_wdog;
struct regmap *regmap;
struct clk *clk;
void __iomem *base;
uint32_t mode;
int ret;
ret = of_property_read_u32(np, "st,lpc-mode", &mode);
if (ret) {
dev_err(dev, "An LPC mode must be provided\n");
return -EINVAL;
}
/* LPC can either run as a Clocksource or in RTC or WDT mode */
if (mode != ST_LPC_MODE_WDT)
return -ENODEV;
st_wdog = devm_kzalloc(dev, sizeof(*st_wdog), GFP_KERNEL);
if (!st_wdog)
return -ENOMEM;
match = of_match_device(st_wdog_match, dev);
if (!match) {
dev_err(dev, "Couldn't match device\n");
return -ENODEV;
}
st_wdog->syscfg = (struct st_wdog_syscfg *)match->data;
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
if (IS_ERR(regmap)) {
dev_err(dev, "No syscfg phandle specified\n");
return PTR_ERR(regmap);
}
clk = devm_clk_get(dev, NULL);
if (IS_ERR(clk)) {
dev_err(dev, "Unable to request clock\n");
return PTR_ERR(clk);
}
st_wdog->dev = dev;
st_wdog->base = base;
st_wdog->clk = clk;
st_wdog->regmap = regmap;
st_wdog->warm_reset = of_property_read_bool(np, "st,warm_reset");
st_wdog->clkrate = clk_get_rate(st_wdog->clk);
if (!st_wdog->clkrate) {
dev_err(dev, "Unable to fetch clock rate\n");
return -EINVAL;
}
st_wdog_dev.max_timeout = 0xFFFFFFFF / st_wdog->clkrate;
st_wdog_dev.parent = dev;
ret = clk_prepare_enable(clk);
if (ret) {
dev_err(dev, "Unable to enable clock\n");
return ret;
}
ret = devm_add_action_or_reset(dev, st_clk_disable_unprepare, clk);
if (ret)
return ret;
watchdog_set_drvdata(&st_wdog_dev, st_wdog);
watchdog_set_nowayout(&st_wdog_dev, WATCHDOG_NOWAYOUT);
/* Init Watchdog timeout with value in DT */
ret = watchdog_init_timeout(&st_wdog_dev, 0, dev);
if (ret)
return ret;
ret = devm_watchdog_register_device(dev, &st_wdog_dev);
if (ret)
return ret;
st_wdog_setup(st_wdog, true);
dev_info(dev, "LPC Watchdog driver registered, reset type is %s",
st_wdog->warm_reset ? "warm" : "cold");
return ret;
}