Lines Matching +full:recv +full:- +full:not +full:- +full:empty
1 // SPDX-License-Identifier: GPL-2.0
40 * enum mei_wdt_state - internal watchdog state
43 * @MEI_WDT_IDLE: wd is idle and not opened
47 * @MEI_WDT_NOT_REQUIRED: wd device is not required
79 * struct mei_wdt - mei watchdog driver
109 * struct mei_mc_hdr - Management Control Command Header
124 * struct mei_wdt_start_request - watchdog start/ping
137 * struct mei_wdt_start_response - watchdog start/ping response
150 * struct mei_wdt_stop_request - watchdog stop
159 * mei_wdt_ping - send wd start/ping command
174 req.hdr.bytecount = req_len - offsetof(struct mei_mc_hdr, subcommand); in mei_wdt_ping()
177 req.timeout = wdt->timeout; in mei_wdt_ping()
179 ret = mei_cldev_send(wdt->cldev, (u8 *)&req, req_len); in mei_wdt_ping()
187 * mei_wdt_stop - send wd stop command
202 req.hdr.bytecount = req_len - offsetof(struct mei_mc_hdr, subcommand); in mei_wdt_stop()
206 ret = mei_cldev_send(wdt->cldev, (u8 *)&req, req_len); in mei_wdt_stop()
214 * mei_wdt_ops_start - wd start command from the watchdog core.
218 * Return: 0 on success or -ENODEV;
224 wdt->state = MEI_WDT_START; in mei_wdt_ops_start()
225 wdd->timeout = wdt->timeout; in mei_wdt_ops_start()
230 * mei_wdt_ops_stop - wd stop command from the watchdog core.
241 if (wdt->state != MEI_WDT_RUNNING) in mei_wdt_ops_stop()
244 wdt->state = MEI_WDT_STOPPING; in mei_wdt_ops_stop()
250 wdt->state = MEI_WDT_IDLE; in mei_wdt_ops_stop()
256 * mei_wdt_ops_ping - wd ping command from the watchdog core.
267 if (wdt->state != MEI_WDT_START && wdt->state != MEI_WDT_RUNNING) in mei_wdt_ops_ping()
270 if (wdt->resp_required) in mei_wdt_ops_ping()
271 init_completion(&wdt->response); in mei_wdt_ops_ping()
273 wdt->state = MEI_WDT_RUNNING; in mei_wdt_ops_ping()
278 if (wdt->resp_required) in mei_wdt_ops_ping()
279 ret = wait_for_completion_killable(&wdt->response); in mei_wdt_ops_ping()
285 * mei_wdt_ops_set_timeout - wd set timeout command from the watchdog core.
299 wdt->timeout = timeout; in mei_wdt_ops_set_timeout()
300 wdd->timeout = timeout; in mei_wdt_ops_set_timeout()
313 /* not const as the firmware_version field need to be retrieved */
322 * __mei_wdt_is_registered - check if wdt is registered
327 * Locking: should be called under wdt->reg_lock
331 return !!watchdog_get_drvdata(&wdt->wdd); in __mei_wdt_is_registered()
335 * mei_wdt_unregister - unregister from the watchdog subsystem
341 mutex_lock(&wdt->reg_lock); in mei_wdt_unregister()
344 watchdog_unregister_device(&wdt->wdd); in mei_wdt_unregister()
345 watchdog_set_drvdata(&wdt->wdd, NULL); in mei_wdt_unregister()
346 memset(&wdt->wdd, 0, sizeof(wdt->wdd)); in mei_wdt_unregister()
349 mutex_unlock(&wdt->reg_lock); in mei_wdt_unregister()
353 * mei_wdt_register - register with the watchdog subsystem
364 if (!wdt || !wdt->cldev) in mei_wdt_register()
365 return -EINVAL; in mei_wdt_register()
367 dev = &wdt->cldev->dev; in mei_wdt_register()
369 mutex_lock(&wdt->reg_lock); in mei_wdt_register()
376 wdt->wdd.info = &wd_info; in mei_wdt_register()
377 wdt->wdd.ops = &wd_ops; in mei_wdt_register()
378 wdt->wdd.parent = dev; in mei_wdt_register()
379 wdt->wdd.timeout = MEI_WDT_DEFAULT_TIMEOUT; in mei_wdt_register()
380 wdt->wdd.min_timeout = MEI_WDT_MIN_TIMEOUT; in mei_wdt_register()
381 wdt->wdd.max_timeout = MEI_WDT_MAX_TIMEOUT; in mei_wdt_register()
383 watchdog_set_drvdata(&wdt->wdd, wdt); in mei_wdt_register()
384 watchdog_stop_on_reboot(&wdt->wdd); in mei_wdt_register()
385 watchdog_stop_on_unregister(&wdt->wdd); in mei_wdt_register()
387 ret = watchdog_register_device(&wdt->wdd); in mei_wdt_register()
389 watchdog_set_drvdata(&wdt->wdd, NULL); in mei_wdt_register()
391 wdt->state = MEI_WDT_IDLE; in mei_wdt_register()
394 mutex_unlock(&wdt->reg_lock); in mei_wdt_register()
406 * mei_wdt_rx - callback for data receive
417 ret = mei_cldev_recv(wdt->cldev, (u8 *)&res, res_len); in mei_wdt_rx()
419 dev_err(&cldev->dev, "failure in recv %d\n", ret); in mei_wdt_rx()
423 /* Empty response can be sent on stop */ in mei_wdt_rx()
428 dev_err(&cldev->dev, "recv small data %d\n", ret); in mei_wdt_rx()
434 dev_err(&cldev->dev, "wrong command received\n"); in mei_wdt_rx()
439 dev_warn(&cldev->dev, "unsupported command %d :%s[%d]\n", in mei_wdt_rx()
441 mei_wdt_state_str(wdt->state), in mei_wdt_rx()
442 wdt->state); in mei_wdt_rx()
450 if (wdt->state == MEI_WDT_RUNNING) { in mei_wdt_rx()
452 wdt->state = MEI_WDT_NOT_REQUIRED; in mei_wdt_rx()
453 schedule_work(&wdt->unregister); in mei_wdt_rx()
458 if (wdt->state == MEI_WDT_PROBE) { in mei_wdt_rx()
460 wdt->state = MEI_WDT_NOT_REQUIRED; in mei_wdt_rx()
469 dev_warn(&cldev->dev, "not in correct state %s[%d]\n", in mei_wdt_rx()
470 mei_wdt_state_str(wdt->state), wdt->state); in mei_wdt_rx()
473 if (!completion_done(&wdt->response)) in mei_wdt_rx()
474 complete(&wdt->response); in mei_wdt_rx()
478 * mei_wdt_notif - callback for event notification
486 if (wdt->state != MEI_WDT_NOT_REQUIRED) in mei_wdt_notif()
497 struct mei_wdt *wdt = file->private_data; in mei_dbgfs_read_activation()
502 mutex_lock(&wdt->reg_lock); in mei_dbgfs_read_activation()
505 mutex_unlock(&wdt->reg_lock); in mei_dbgfs_read_activation()
519 struct mei_wdt *wdt = file->private_data; in mei_dbgfs_read_state()
524 mei_wdt_state_str(wdt->state)); in mei_dbgfs_read_state()
537 debugfs_remove_recursive(wdt->dbgfs_dir); in dbgfs_unregister()
538 wdt->dbgfs_dir = NULL; in dbgfs_unregister()
546 wdt->dbgfs_dir = dir; in dbgfs_register()
568 return -ENOMEM; in mei_wdt_probe()
570 wdt->timeout = MEI_WDT_DEFAULT_TIMEOUT; in mei_wdt_probe()
571 wdt->state = MEI_WDT_PROBE; in mei_wdt_probe()
572 wdt->cldev = cldev; in mei_wdt_probe()
573 wdt->resp_required = mei_cldev_ver(cldev) > 0x1; in mei_wdt_probe()
574 mutex_init(&wdt->reg_lock); in mei_wdt_probe()
575 init_completion(&wdt->response); in mei_wdt_probe()
576 INIT_WORK(&wdt->unregister, mei_wdt_unregister_work); in mei_wdt_probe()
582 dev_err(&cldev->dev, "Could not enable cl device\n"); in mei_wdt_probe()
586 ret = mei_cldev_register_rx_cb(wdt->cldev, mei_wdt_rx); in mei_wdt_probe()
588 dev_err(&cldev->dev, "Could not reg rx event ret=%d\n", ret); in mei_wdt_probe()
592 ret = mei_cldev_register_notif_cb(wdt->cldev, mei_wdt_notif); in mei_wdt_probe()
593 /* on legacy devices notification is not supported in mei_wdt_probe()
595 if (ret && ret != -EOPNOTSUPP) { in mei_wdt_probe()
596 dev_err(&cldev->dev, "Could not reg notif event ret=%d\n", ret); in mei_wdt_probe()
602 if (wdt->resp_required) in mei_wdt_probe()
628 if (!completion_done(&wdt->response)) in mei_wdt_remove()
629 complete(&wdt->response); in mei_wdt_remove()
631 cancel_work_sync(&wdt->unregister); in mei_wdt_remove()