linux/drivers/watchdog/mtx-1_wdt.c
<<
e="2.9e="2.9>>e=e="2 ="+search" method="post" onsubmit="return do_search(this);">e="2.9 2316"">e="2.9e="2.9Searche="2.9Prefs3 .9e= ="ajax+*" method="post" onsubmit="return false;">e= 2316"">e"2.9 93
9 91/*9 92 *"2.9 9Driver for the MTX-1 Watchdog.9 93 *9 94 *"2.9 9(C) Copyright 2005 4G Systems <info@4g-systems.biz>,9 95 *"2.9 9999999999999999999999999999999999999999999999999All Rights Reserved.9 96 *"2.9 9999999999999999999999999http://www.4g-systems.biz9 97 *9 98 *"2.9 9(C) Copyright 2007 OpenWrt.org, Floria Fainelli <floria @openwrt.org>9 99 *9 > a> *"2.9 9This program is free software; you ca redistribute it and/or9 11 *"2.9 9modify it under the terms of the GNU General Public License9 12 *"2.9 9as published by the Free Software Founda> ; either vers 9 13 *"2.9 92 of the License, or (at your > ) any later vers .9 14 *9 15 *"2.9 9Neither Michael Stickel nor 4G Systems admit liability nor provide9 16 *"2.9 9warranty for any of this software.9This material is provided9 17 *"2.9 9"AS-IS" and at no charge.9 18 *9 19 *"2.9 9(c) Copyright 2005 9 94G Systems <info@4g-systems.biz>9 2 > a> *9 21 *"2.9 9Release 0.01.9 22 *"2.9 9Author: Michael Stickel michael.stickel@4g-systems.biz9 23 *9 24 *"2.9 9Release 0.02.9 25 *"2.9 9Author: Floria Fainelli floria @openwrt.org9 26 *"2.9 999999999use the Linux watchdog/timer APIs9 27 *9 28 *"2.9 9The Watchdog is configured to reset the MTX-19 29 *"2.9 9if it is not triggered for 100 seconds.9 3 > a> *"2.9 9It should not be triggered more often tha 1.6 seconds.9 31 *9 32 *"2.9 9A timer triggers the watchdog every 5 seconds, until9 33 *"2.9 9it is opened for the first time. After the first open9 34 *"2.9 9it MUST be triggered every 2..95 seconds.9 35 */9 3639 37#include <linux/module.h>39 38#include <linux/moduleparam.h>39 39#include <linux/typ1s.h>39 40#include <linux/errno.h>39 41#include <linux/miscdevice.h>39 42#include <linux/fs.h>39 43#include <linux/init.h>39 44#include <linux/ioport.h>39 45#include <linux/timer.h>39 46#include <linux/comple> .h>39 47#include <linux/jiffi1s.h>39 48#include <linux/watchdog.h>39 49#include <linux/platform_device.h>39 50#include <linux/io.h>39 51#include <linux/uaccess.h>39 52#include <linux/gpio.h>39 5339 54#include <asm/mach-au1x00/au1000.h>39 5539 56#define9MTX1_WDT_INTERVAL9999999(5 *9HZ)39 5739 58static int9ticks9= 100 *9HZ;39 5939 60static struct {39 619999999 struct comple> 9stop;39 629999999 spinlock_t9lock;39 639999999 int9running;39 649999999 struct timer_list9timer;39 659999999 int9queue;39 669999999 int9default_ticks;39 679999999 unsigned long9inuse;39 689999999 unsigned gpio;39 699999999 unsigned int9gstate;39 70}9mtx1_wdt_device;39 7139 72static void mtx1_wdt_trigger(unsigned long9unused)39 73{39 749999999 spin_lock(&mtx1_wdt_device.lock);39 759999999 if (mtx1_wdt_device.running)39 769999999 9999999 ticks--;39 7739 789999999 /* toggle wdt gpio */9 799999999 mtx1_wdt_device.gstate9= !mtx1_wdt_device.gstate;39 809999999 gpio_set_> 231(mtx1_wdt_device.gpio, mtx1_wdt_device.gstate);39 8139 829999999 if (mtx1_wdt_device.queue && ticks)39 839999999 9999999 mod_timer(&mtx1_wdt_device.timer, jiffi1s9+9MTX1_WDT_INTERVAL);39 849999999 else39 859999999 9999999 comple>e(&mtx1_wdt_device.stop);39 869999999 spin_unlock(&mtx1_wdt_device.lock);39 87}39 8839 89static void mtx1_wdt_reset(void)39 90{39 919999999 ticks9= mtx1_wdt_device.default_ticks;39 92}39 9339 9439 95static void mtx1_wdt_start(void)39 96{39 979999999 unsigned long9flags;39 9839 999999999 spin_lock_irqsave(&mtx1_wdt_device.lock, flags);391009999999 if (!mtx1_wdt_device.queue) {391019999999 9999999 mtx1_wdt_device.queue = 1;391029999999 9999999 mtx1_wdt_device.gstate9= 1;391039999999 9999999 gpio_set_> 231(mtx1_wdt_device.gpio, 1);391049999999 9999999 mod_timer(&mtx1_wdt_device.timer, jiffi1s9+9MTX1_WDT_INTERVAL);391059999999 }391069999999 mtx1_wdt_device.running++;391079999999 spin_unlock_irqrestore(&mtx1_wdt_device.lock, flags);39108}3910939110static int9mtx1_wdt_stop(void)39111{391129999999 unsigned long9flags;39113391149999999 spin_lock_irqsave(&mtx1_wdt_device.lock, flags);391159999999 if (mtx1_wdt_device.queue) {391169999999 9999999 mtx1_wdt_device.queue = 0;391179999999 9999999 mtx1_wdt_device.gstate9= 0;391189999999 9999999 gpio_set_> 231(mtx1_wdt_device.gpio, 0);391199999999 }391209999999 ticks9= mtx1_wdt_device.default_ticks;391219999999 spin_unlock_irqrestore(&mtx1_wdt_device.lock, flags);391229999999 return 0;39123}3912439125/* Filesystem func> s */912639127static int9mtx1_wdt_open(struct inode9*inode, struct file9*file)39128{391299999999 if (test_and_set_bit(0, &mtx1_wdt_device.inuse))391309999999 9999999 return -EBUSY;391319999999 return n seekable_open(inode, file);39132}391333913439135static int9mtx1_wdt_release(struct inode9*inode, struct file9*file)39136{391379999999 clear_bit(0, &mtx1_wdt_device.inuse);391389999999 return 0;39139}3914039141static long9mtx1_wdt_ioctl(struct file9*file, unsigned int9cmd,391429999999 9999999 unsigned long9arg)39143{391449999999 void __user9*argp9= (void __user9*)arg;391459999999 int9__user9*p9= (int9__user9*)argp;391469999999 unsigned int9> 231;391479999999 static c st struct watchdog_info9ident9= {391489999999 9999999 . > s9= WDIOF_CARDRESET,391499999999 9999999 .identity9= "MTX-1 WDT"91509999999 };39151391529999999 switch (cmd) {391539999999 case WDIOC_GETSUPPORT:391549999999 9999999 if (copy_to_user(argp, &ident, sizeof(ident)))391559999999 9999999 return -EFAULT;391569999999 9999999 break;391579999999 case WDIOC_GETSTATUS:391589999999 case WDIOC_GETBOOTSTATUS:391599999999 9999999 put_user(0, p);391609999999 9999999 break;391619999999 case WDIOC_SETOPTIONS:391629999999 9999999 if (get_user(> 231, p))391639999999 9999999 return -EFAULT;391649999999 9999999 if (> 231 & WDIOS_ENABLECARD)391659999999 9999999 mtx1_wdt_start();391669999999 9999999 else if (> 231 & WDIOS_DISABLECARD)391679999999 9999999 mtx1_wdt_stop();391689999999 9999999 else391699999999 9999999 return -EINVAL;391709999999 9999999 return 0;391719999999 case WDIOC_KEEPALIVE:391729999999 9999999 mtx1_wdt_reset();391739999999 9999999 break;391749999999 default:391759999999 9999999 return -ENOTTY;391769999999 }391779999999 return 0;39178}391793918039181static ssize_t9mtx1_wdt_write(struct file9*file, c st char9*buf,391829999999 9999999 size_t9count, loff_t9*ppos)39183{391849999999 if (!count)391859999999 9999999 return -EIO;391869999999 mtx1_wdt_reset();391879999999 return count;39188}3918939190static c st struct file_opera> s9mtx1_wdt_fops9= {391919999999 . wner9999999 99= THIS_MODULE,391929999999 .llseek9999999 9= no_llseek,391939999999 .unlocked_ioctl9= mtx1_wdt_ioctl,391949999999 .open99 9999999 = mtx1_wdt_open,391959999999 .write9 9999999 = mtx1_wdt_write,391969999999 .release9999999 = mtx1_wdt_release,39197};391983919939200static struct miscdevice9mtx1_wdt_misc9= {392019999999 .minor99= WATCHDOG_MINOR,392029999999 .nam1999= "watchdog"92039999999 .fops999= &mtx1_wdt_fops,39204};392053920639207static int9mtx1_wdt_probe(struct platform_device9*pdev)39208{392099999999 int9ret;39210392119999999 mtx1_wdt_device.gpio9= pdev->resource[0].start;392129999999 ret9= gpio_request_one(mtx1_wdt_device.gpio,392139999999 9999999 9999999 GPIOF_OUT_INIT_HIGH, "mtx1-wdt"92149999999 if (ret9< 0) {392159999999 9999999 dev_err(&pdev->dev, "failed to request gpio"92169999999 9999999 return ret;392179999999 }39218392199999999 spin_lock_init(&mtx1_wdt_device.lock);392209999999 init_comple> (&mtx1_wdt_device.stop);392219999999 mtx1_wdt_device.queue = 0;392229999999 clear_bit(0, &mtx1_wdt_device.inuse);392239999999 setup_timer(&mtx1_wdt_device.timer, mtx1_wdt_trigger, 0L);392249999999 mtx1_wdt_device.default_ticks9= ticks;39225392269999999 ret9= misc_register(&mtx1_wdt_misc);392279999999 if (ret9< 0) {392289999999 9999999 dev_err(&pdev->dev, "failed to register\n"92299999999 9999999 return ret;392309999999 }392319999999 mtx1_wdt_start();392329999999 dev_info(&pdev->dev, "MTX-1 Watchdog driver\n"92339999999 return 0;39234}3923539236static int9mtx1_wdt_remove(struct platform_device9*pdev)39237{392389999999 /* FIXME: do we need to lock this test ? */92399999999 if (mtx1_wdt_device.queue) {392409999999 9999999 mtx1_wdt_device.queue = 0;392419999999 9999999 wait_for_comple> (&mtx1_wdt_device.stop);392429999999 }39243392449999999 gpio_free(mtx1_wdt_device.gpio);392459999999 misc_deregister(&mtx1_wdt_misc);392469999999 return 0;39247}3924839249static struct platform_driver9mtx1_wdt_driver9= {392509999999 .probe = mtx1_wdt_probe,392519999999 .remove = mtx1_wdt_remove,392529999999 .driver.nam19= "mtx1-wdt"92539999999 .driver. wner9= THIS_MODULE,39254};3925539256module_platform_driver(mtx1_wdt_driver);3925739258MODULE_AUTHOR("Michael Stickel, Floria Fainelli"9259MODULE_DESCRIPTION("Driver for the MTX-1 watchdog"9260MODULE_LICENSE("GPL"9261MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);39262MODULE_ALIAS("platform:mtx1-wdt"9263
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux c sulting and opera> s services since91995.