drivers/greybus/svc_watchdog.c
Source file repositories/reference/linux-study-clean/drivers/greybus/svc_watchdog.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/greybus/svc_watchdog.c- Extension
.c- Size
- 4458 bytes
- Lines
- 198
- Domain
- Driver Families
- Bucket
- drivers/greybus
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/delay.hlinux/suspend.hlinux/workqueue.hlinux/greybus.h
Detected Declarations
struct gb_svc_watchdogfunction svc_watchdog_pm_notifierfunction greybus_resetfunction do_workfunction gb_svc_watchdog_createfunction gb_svc_watchdog_destroyfunction gb_svc_watchdog_enabledfunction gb_svc_watchdog_enablefunction gb_svc_watchdog_disable
Annotated Snippet
struct gb_svc_watchdog {
struct delayed_work work;
struct gb_svc *svc;
bool enabled;
struct notifier_block pm_notifier;
};
static struct delayed_work reset_work;
static int svc_watchdog_pm_notifier(struct notifier_block *notifier,
unsigned long pm_event, void *unused)
{
struct gb_svc_watchdog *watchdog =
container_of(notifier, struct gb_svc_watchdog, pm_notifier);
switch (pm_event) {
case PM_SUSPEND_PREPARE:
gb_svc_watchdog_disable(watchdog->svc);
break;
case PM_POST_SUSPEND:
gb_svc_watchdog_enable(watchdog->svc);
break;
default:
break;
}
return NOTIFY_DONE;
}
static void greybus_reset(struct work_struct *work)
{
static char const start_path[] = "/system/bin/start";
static char *envp[] = {
"HOME=/",
"PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin",
NULL,
};
static char *argv[] = {
(char *)start_path,
"unipro_reset",
NULL,
};
pr_err("svc_watchdog: calling \"%s %s\" to reset greybus network!\n",
argv[0], argv[1]);
call_usermodehelper(start_path, argv, envp, UMH_WAIT_EXEC);
}
static void do_work(struct work_struct *work)
{
struct gb_svc_watchdog *watchdog;
struct gb_svc *svc;
int retval;
watchdog = container_of(work, struct gb_svc_watchdog, work.work);
svc = watchdog->svc;
dev_dbg(&svc->dev, "%s: ping.\n", __func__);
retval = gb_svc_ping(svc);
if (retval) {
/*
* Something went really wrong, let's warn userspace and then
* pull the plug and reset the whole greybus network.
* We need to do this outside of this workqueue as we will be
* tearing down the svc device itself. So queue up
* yet-another-callback to do that.
*/
dev_err(&svc->dev,
"SVC ping has returned %d, something is wrong!!!\n",
retval);
if (svc->action == GB_SVC_WATCHDOG_BITE_PANIC_KERNEL) {
panic("SVC is not responding\n");
} else if (svc->action == GB_SVC_WATCHDOG_BITE_RESET_UNIPRO) {
dev_err(&svc->dev, "Resetting the greybus network, watch out!!!\n");
INIT_DELAYED_WORK(&reset_work, greybus_reset);
schedule_delayed_work(&reset_work, HZ / 2);
/*
* Disable ourselves, we don't want to trip again unless
* userspace wants us to.
*/
watchdog->enabled = false;
}
}
/* resubmit our work to happen again, if we are still "alive" */
if (watchdog->enabled)
schedule_delayed_work(&watchdog->work, SVC_WATCHDOG_PERIOD);
Annotation
- Immediate include surface: `linux/delay.h`, `linux/suspend.h`, `linux/workqueue.h`, `linux/greybus.h`.
- Detected declarations: `struct gb_svc_watchdog`, `function svc_watchdog_pm_notifier`, `function greybus_reset`, `function do_work`, `function gb_svc_watchdog_create`, `function gb_svc_watchdog_destroy`, `function gb_svc_watchdog_enabled`, `function gb_svc_watchdog_enable`, `function gb_svc_watchdog_disable`.
- Atlas domain: Driver Families / drivers/greybus.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.