drivers/watchdog/bcm2835_wdt.c
Source file repositories/reference/linux-study-clean/drivers/watchdog/bcm2835_wdt.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/watchdog/bcm2835_wdt.c- Extension
.c- Size
- 6529 bytes
- Lines
- 238
- Domain
- Driver Families
- Bucket
- drivers/watchdog
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/types.hlinux/mfd/bcm2835-pm.hlinux/module.hlinux/io.hlinux/watchdog.hlinux/platform_device.hlinux/of_address.hlinux/of_platform.hlinux/reboot.h
Detected Declarations
struct bcm2835_wdtfunction bcm2835_wdt_is_runningfunction bcm2835_wdt_startfunction bcm2835_wdt_stopfunction bcm2835_wdt_get_timeleftfunction __bcm2835_restartfunction bcm2835_restartfunction bcm2835_power_offfunction bcm2835_wdt_probe
Annotated Snippet
struct bcm2835_wdt {
void __iomem *base;
spinlock_t lock;
};
static unsigned int heartbeat;
static bool nowayout = WATCHDOG_NOWAYOUT;
static bool bcm2835_wdt_is_running(struct bcm2835_wdt *wdt)
{
uint32_t cur;
cur = readl(wdt->base + PM_RSTC);
return !!(cur & PM_RSTC_WRCFG_FULL_RESET);
}
static int bcm2835_wdt_start(struct watchdog_device *wdog)
{
struct bcm2835_wdt *wdt = watchdog_get_drvdata(wdog);
uint32_t cur;
unsigned long flags;
spin_lock_irqsave(&wdt->lock, flags);
writel_relaxed(PM_PASSWORD | (SECS_TO_WDOG_TICKS(wdog->timeout) &
PM_WDOG_TIME_SET), wdt->base + PM_WDOG);
cur = readl_relaxed(wdt->base + PM_RSTC);
writel_relaxed(PM_PASSWORD | (cur & PM_RSTC_WRCFG_CLR) |
PM_RSTC_WRCFG_FULL_RESET, wdt->base + PM_RSTC);
spin_unlock_irqrestore(&wdt->lock, flags);
return 0;
}
static int bcm2835_wdt_stop(struct watchdog_device *wdog)
{
struct bcm2835_wdt *wdt = watchdog_get_drvdata(wdog);
writel_relaxed(PM_PASSWORD | PM_RSTC_RESET, wdt->base + PM_RSTC);
return 0;
}
static unsigned int bcm2835_wdt_get_timeleft(struct watchdog_device *wdog)
{
struct bcm2835_wdt *wdt = watchdog_get_drvdata(wdog);
uint32_t ret = readl_relaxed(wdt->base + PM_WDOG);
return WDOG_TICKS_TO_SECS(ret & PM_WDOG_TIME_SET);
}
static void __bcm2835_restart(struct bcm2835_wdt *wdt)
{
u32 val;
/* use a timeout of 10 ticks (~150us) */
writel_relaxed(10 | PM_PASSWORD, wdt->base + PM_WDOG);
val = readl_relaxed(wdt->base + PM_RSTC);
val &= PM_RSTC_WRCFG_CLR;
val |= PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET;
writel_relaxed(val, wdt->base + PM_RSTC);
/* No sleeping, possibly atomic. */
mdelay(1);
}
static int bcm2835_restart(struct watchdog_device *wdog,
unsigned long action, void *data)
{
struct bcm2835_wdt *wdt = watchdog_get_drvdata(wdog);
__bcm2835_restart(wdt);
return 0;
}
static const struct watchdog_ops bcm2835_wdt_ops = {
.owner = THIS_MODULE,
.start = bcm2835_wdt_start,
.stop = bcm2835_wdt_stop,
.get_timeleft = bcm2835_wdt_get_timeleft,
.restart = bcm2835_restart,
};
static const struct watchdog_info bcm2835_wdt_info = {
.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE |
WDIOF_KEEPALIVEPING,
.identity = "Broadcom BCM2835 Watchdog timer",
};
Annotation
- Immediate include surface: `linux/delay.h`, `linux/types.h`, `linux/mfd/bcm2835-pm.h`, `linux/module.h`, `linux/io.h`, `linux/watchdog.h`, `linux/platform_device.h`, `linux/of_address.h`.
- Detected declarations: `struct bcm2835_wdt`, `function bcm2835_wdt_is_running`, `function bcm2835_wdt_start`, `function bcm2835_wdt_stop`, `function bcm2835_wdt_get_timeleft`, `function __bcm2835_restart`, `function bcm2835_restart`, `function bcm2835_power_off`, `function bcm2835_wdt_probe`.
- Atlas domain: Driver Families / drivers/watchdog.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.