static int bd9576_wdt_probe()

in bd9576_wdt.c [202:277]


static int bd9576_wdt_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->parent->of_node;
	struct bd9576_wdt_priv *priv;
	u32 hw_margin[2];
	u32 hw_margin_max = BD957X_WDT_DEFAULT_MARGIN, hw_margin_min = 0;
	int ret;

	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	platform_set_drvdata(pdev, priv);

	priv->dev = dev;
	priv->regmap = dev_get_regmap(dev->parent, NULL);
	if (!priv->regmap) {
		dev_err(dev, "No regmap found\n");
		return -ENODEV;
	}

	priv->gpiod_en = devm_gpiod_get_from_of_node(dev, dev->parent->of_node,
						     "rohm,watchdog-enable-gpios",
						     0, GPIOD_OUT_LOW,
						     "watchdog-enable");
	if (IS_ERR(priv->gpiod_en))
		return dev_err_probe(dev, PTR_ERR(priv->gpiod_en),
			      "getting watchdog-enable GPIO failed\n");

	priv->gpiod_ping = devm_gpiod_get_from_of_node(dev, dev->parent->of_node,
						     "rohm,watchdog-ping-gpios",
						     0, GPIOD_OUT_LOW,
						     "watchdog-ping");
	if (IS_ERR(priv->gpiod_ping))
		return dev_err_probe(dev, PTR_ERR(priv->gpiod_ping),
				     "getting watchdog-ping GPIO failed\n");

	ret = of_property_read_variable_u32_array(np, "rohm,hw-timeout-ms",
						  &hw_margin[0], 1, 2);
	if (ret < 0 && ret != -EINVAL)
		return ret;

	if (ret == 1)
		hw_margin_max = hw_margin[0];

	if (ret == 2) {
		hw_margin_max = hw_margin[1];
		hw_margin_min = hw_margin[0];
	}

	ret = bd957x_set_wdt_mode(priv, hw_margin_max, hw_margin_min);
	if (ret)
		return ret;

	priv->always_running = of_property_read_bool(np, "always-running");

	watchdog_set_drvdata(&priv->wdd, priv);

	priv->wdd.info			= &bd957x_wdt_ident;
	priv->wdd.ops			= &bd957x_wdt_ops;
	priv->wdd.min_hw_heartbeat_ms	= hw_margin_min;
	priv->wdd.max_hw_heartbeat_ms	= hw_margin_max;
	priv->wdd.parent		= dev;
	priv->wdd.timeout		= WATCHDOG_TIMEOUT;

	watchdog_init_timeout(&priv->wdd, 0, dev);
	watchdog_set_nowayout(&priv->wdd, nowayout);

	watchdog_stop_on_reboot(&priv->wdd);

	if (priv->always_running)
		bd9576_wdt_start(&priv->wdd);

	return devm_watchdog_register_device(dev, &priv->wdd);
}