高通watchdog

代码及内容声明:全部来自opensource 开源代码。

喂狗:

设置一个喂狗的work,每10s调度一次,

狗bark:

10秒没喂狗就会Bark,然后直接bite。


一般而言pet的时间是10s, bark的时间是11s,一般而言主要实在device tree里面有定义。


devices_tree 如下:

qcom,wdt@f9017000 {
compatible = "qcom,msm-watchdog";
reg = <0xf9017000 0x1000>;
interrupts = <0 3 0 0 4 0>;
qcom,bark-time = <11000>;
qcom,pet-time = <10000>;
qcom,ipi-ping = <1>;
};


/kernel/arch/arm/mach-msm/msm-watchdog_v2.c

static int __devinit msm_watchdog_probe(struct platform_device *pdev)
{
int ret;
struct msm_watchdog_data *wdog_dd;


if (!pdev->dev.of_node || !enable)
return -ENODEV;
wdog_dd = kzalloc(sizeof(struct msm_watchdog_data), GFP_KERNEL);
if (!wdog_dd)
return -EIO;
ret = msm_wdog_dt_to_pdata(pdev, wdog_dd);
if (ret)
goto err;
wdog_dd->dev = &pdev->dev;
platform_set_drvdata(pdev, wdog_dd);
ret = devm_request_irq(&pdev->dev, wdog_dd->bark_irq, wdog_bark_handler,
IRQF_TRIGGER_RISING, "apps_wdog_bark", wdog_dd);
if (ret) {
dev_err(&pdev->dev, "failed to request bark irq\n");
ret = -ENXIO;
goto err;
}
cpumask_clear(&wdog_dd->alive_mask);
INIT_WORK(&wdog_dd->init_dogwork_struct, init_watchdog_work);
INIT_DELAYED_WORK(&wdog_dd->dogwork_struct, pet_watchdog_work);
schedule_work_on(0, &wdog_dd->init_dogwork_struct);
return 0;
err:
kzfree(wdog_dd);
return ret;
}

static void init_watchdog_work(struct work_struct *work)
{
struct msm_watchdog_data *wdog_dd = container_of(work,
struct msm_watchdog_data,
init_dogwork_struct);
unsigned long delay_time;
u64 timeout;
delay_time = msecs_to_jiffies(wdog_dd->pet_time);
wdog_dd->min_slack_ticks = UINT_MAX;
wdog_dd->min_slack_ns = ULLONG_MAX;
timeout = (wdog_dd->bark_time * WDT_HZ)/1000;
__raw_writel(timeout, wdog_dd->base + WDT0_BARK_TIME);
__raw_writel(timeout + 3*WDT_HZ, wdog_dd->base + WDT0_BITE_TIME);


wdog_dd->panic_blk.notifier_call = panic_wdog_handler;
atomic_notifier_chain_register(&panic_notifier_list,
      &wdog_dd->panic_blk);
schedule_delayed_work(&wdog_dd->dogwork_struct, delay_time);


__raw_writel(1, wdog_dd->base + WDT0_EN);
__raw_writel(1, wdog_dd->base + WDT0_RST);
wdog_dd->last_pet = sched_clock();
printk(KERN_INFO "MSM Watchdog Initialized\n");
return;
}

static void pet_watchdog_work(struct work_struct *work)
{
unsigned long delay_time;
struct delayed_work *delayed_work = to_delayed_work(work);
struct msm_watchdog_data *wdog_dd = container_of(delayed_work,
struct msm_watchdog_data,
dogwork_struct);
delay_time = msecs_to_jiffies(wdog_dd->pet_time);
if (wdog_dd->do_ipi_ping)
ping_other_cpus(wdog_dd);
pet_watchdog(wdog_dd);
if (wdog_dd->do_ipi_ping)
dump_cpu_alive_mask(wdog_dd);
if (enable)
schedule_delayed_work(&wdog_dd->dogwork_struct,
delay_time);

}

static void pet_watchdog(struct msm_watchdog_data *wdog_dd)
{
int slack;
unsigned long long time_ns;
unsigned long long slack_ns;
unsigned long long bark_time_ns = wdog_dd->bark_time * 1000000ULL;


slack = __raw_readl(wdog_dd->base + WDT0_STS) >> 3;
slack = ((wdog_dd->bark_time*WDT_HZ)/1000) - slack;
if (slack < wdog_dd->min_slack_ticks)
wdog_dd->min_slack_ticks = slack;
__raw_writel(1, wdog_dd->base + WDT0_RST);
time_ns = sched_clock();
slack_ns = (wdog_dd->last_pet + bark_time_ns) - time_ns;
if (slack_ns < wdog_dd->min_slack_ns)
wdog_dd->min_slack_ns = slack_ns;
wdog_dd->last_pet = time_ns;
}



  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值