On 19/01/2024 09:43, Lukasz Majczak wrote: > Embedded Controller (EC) present on Chromebook devices > can be used as a watchdog. > Implement a driver to support it. > ... > +static int cros_ec_wdt_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct cros_ec_dev *ec_dev = dev_get_drvdata(dev->parent); > + struct cros_ec_device *cros_ec = ec_dev->ec_dev; > + struct watchdog_device *wdd; > + union cros_ec_wdt_data arg; > + int ret = 0; > + > + wdd = devm_kzalloc(&pdev->dev, sizeof(struct watchdog_device), GFP_KERNEL); sizeof(*) > + if (!wdd) > + return -ENOMEM; > + > + arg.req.command = EC_HANG_DETECT_CMD_GET_STATUS; > + ret = cros_ec_wdt_send_cmd(cros_ec, &arg); > + if (ret < 0) > + return dev_err_probe(dev, ret, "Failed to get watchdog bootstatus"); > + > + wdd->parent = &pdev->dev; > + wdd->info = &cros_ec_wdt_ident; > + wdd->ops = &cros_ec_wdt_ops; > + wdd->timeout = CROS_EC_WATCHDOG_DEFAULT_TIME; > + wdd->min_timeout = EC_HANG_DETECT_MIN_TIMEOUT; > + wdd->max_timeout = EC_HANG_DETECT_MAX_TIMEOUT; > + if (arg.resp.status == EC_HANG_DETECT_AP_BOOT_EC_WDT) > + wdd->bootstatus = WDIOF_CARDRESET; > + > + arg.req.command = EC_HANG_DETECT_CMD_CLEAR_STATUS; > + ret = cros_ec_wdt_send_cmd(cros_ec, &arg); > + if (ret < 0) > + return dev_err_probe(dev, ret, "Failed to clear watchdog bootstatus"); > + > + watchdog_stop_on_reboot(wdd); > + watchdog_stop_on_unregister(wdd); > + watchdog_set_drvdata(wdd, cros_ec); > + platform_set_drvdata(pdev, wdd); > + > + return devm_watchdog_register_device(dev, wdd); > +} > + > +static int __maybe_unused cros_ec_wdt_suspend(struct platform_device *pdev, pm_message_t state) > +{ > + struct watchdog_device *wdd = platform_get_drvdata(pdev); > + int ret = 0; > + > + if (watchdog_active(wdd)) > + ret = cros_ec_wdt_stop(wdd); > + > + return ret; > +} > + > +static int __maybe_unused cros_ec_wdt_resume(struct platform_device *pdev) > +{ > + struct watchdog_device *wdd = platform_get_drvdata(pdev); > + int ret = 0; > + > + if (watchdog_active(wdd)) > + ret = cros_ec_wdt_start(wdd); > + > + return ret; > +} > + > +static struct platform_driver cros_ec_wdt_driver = { > + .probe = cros_ec_wdt_probe, > + .suspend = pm_ptr(cros_ec_wdt_suspend), > + .resume = pm_ptr(cros_ec_wdt_resume), > + .driver = { > + .name = DRV_NAME, > + }, > +}; > + > +module_platform_driver(cros_ec_wdt_driver); > + > +static const struct platform_device_id cros_ec_wdt_id[] = { > + { DRV_NAME, 0 }, > + {} > +}; > +MODULE_DEVICE_TABLE(platform, cros_ec_wdt_id); device_id is not placed here, please open existing drivers for reference. Why this isn't referenced in driver structure? > +MODULE_DESCRIPTION("Cros EC Watchdog Device Driver"); > +MODULE_LICENSE("GPL"); Best regards, Krzysztof