微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARMLinux驱动Watch Dog Timer(看门狗)驱动分析

ARMLinux驱动Watch Dog Timer(看门狗)驱动分析

时间:11-19 来源:互联网 点击:
equest_mem_region(res->start, size, pdev->name);if (wdt_mem == NULL) {dev_err(dev, "failed to get memory region\n");ret = -ENOENT;goto err_req;}//地址映射,wdt_base为基地址wdt_base = ioremap(res->start, size);if (wdt_base == NULL) {dev_err(dev, "failed to ioremap() region\n");ret = -EINVAL;goto err_req;}DBG("probe: mapped wdt_base=%p\n", wdt_base);//从平台设备中获取中断号wdt_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);if (wdt_irq == NULL) {dev_err(dev, "no irq resource specified\n");ret = -ENOENT;goto err_map;}//注册中断,中断处理函数s3c2410wdt_irq()ret = request_irq(wdt_irq->start, s3c2410wdt_irq, 0, pdev->name, pdev);if (ret != 0) {dev_err(dev, "failed to install irq (%d)\n", ret);goto err_map;}//获取系统时钟wdt_clock = clk_get(&pdev->dev, "watchdog");if (IS_ERR(wdt_clock)) {dev_err(dev, "failed to find watchdog clock source\n");ret = PTR_ERR(wdt_clock);goto err_irq;}//使能时钟clk_enable(wdt_clock);/* see if we can actually set the requested timer margin, and if* not, try the default value */if (s3c2410wdt_set_heartbeat(tmr_margin)) {//这里第一次设置计时周期为tmr_margin,如果设置不成功,则重新设置为默认值started = s3c2410wdt_set_heartbeat(CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME);if (started == 0)dev_info(dev,"tmr_margin value out of range, default %d used\n",CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME);elsedev_info(dev, "default timer value is out of range, cannot start\n");}//注册设备ret = misc_register(&s3c2410wdt_miscdev);if (ret) {dev_err(dev, "cannot register miscdev on minor=%d (%d)\n",WATCHDOG_MINOR, ret);goto err_clk;}if (tmr_atboot && started == 0) {dev_info(dev, "starting watchdog timer\n");s3c2410wdt_start();//启动看门狗} else if (!tmr_atboot) {/* if were not enabling the watchdog, then ensure it is* disabled if it has been left running from the bootloader* or other source */s3c2410wdt_stop();}/* print out a statement of readiness */wtcon = readl(wdt_base + S3C2410_WTCON);dev_info(dev, "watchdog %sactive, reset %sabled, irq %sabled\n",(wtcon & S3C2410_WTCON_ENABLE) ? "" : "in",(wtcon & S3C2410_WTCON_RSTEN) ? "" : "dis",(wtcon & S3C2410_WTCON_INTEN) ? "" : "en");//设置GPB10端口为输出端口,用于点亮LED10s3c2410_gpio_cfgpin(S3C2410_GPB10,S3C2410_GPB10_OUTP);return 0;//出错跳转表,异常处理err_clk:clk_disable(wdt_clock);clk_put(wdt_clock);err_irq:free_irq(wdt_irq->start, pdev);err_map:iounmap(wdt_base);err_req:release_resource(wdt_mem);kfree(wdt_mem);return ret;}//设备移除函数,释放资源和映射static int s3c2410wdt_remove(struct platform_device *dev){release_resource(wdt_mem);kfree(wdt_mem);wdt_mem = NULL;free_irq(wdt_irq->start, dev);wdt_irq = NULL;clk_disable(wdt_clock);clk_put(wdt_clock);wdt_clock = NULL;iounmap(wdt_base);misc_deregister(&s3c2410wdt_miscdev);return 0;}//关闭看门狗static void s3c2410wdt_shutdown(struct platform_device *dev){s3c2410wdt_stop();}//定义平台设备驱动static struct platform_driver s3c2410wdt_driver = {.probe = s3c2410wdt_probe,.remove = s3c2410wdt_remove,.shutdown = s3c2410wdt_shutdown,.driver = {.owner = THIS_MODULE,.name = "s3c2410-wdt",//该名称参照内核源码中该资源的名称,两者必须一致},};static char banner[] __initdata =KERN_INFO "S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics\n";//驱动安装时执行static int __init watchdog_init(void){printk(banner);return platform_driver_register(&s3c2410wdt_driver);//注册设备}//驱动移除是执行static void __exit watchdog_exit(void){platform_driver_unregister(&s3c2410wdt_driver);//移除设备}module_init(watchdog_init);module_exit(watchdog_exit);MODULE_AUTHOR("Yan Ming");MODULE_DESCRIPTION("S3C2410 Watchdog Device Driver");MODULE_LICENSE("GPL");MODU

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top