linux/drivers/watchdog/sc520_wdt.c
<<
ion .4./spa> .4./form .4.a ion .4 href="../linux+ve="v.2/drivers/watchdog/sc520_wdt.c">ion .4.img src="../.static/gfx/right.png" alt=">>">io./spa> io.spa> class="lxr_search">ion ="+search" method="post" onsubmit="return do_search(this);">ion .4.input typ hidden" nam navtarget" ion> ">ion .4.input typ text" nam search" id search">ion .4.buttopttyp submit">Search io.spa> class="lxr_prefs" .4.a href="+prefs?return=drivers/watchdog/sc520_wdt.c"ion .4 onclick="return ajax_prefs();">ion .4Prefs .4./a>io./spa> n .4 4./div n .4 4.form ac >="ajax+*" method="post" onsubmit="return false;">io.input typ hidden" nam ajax_lookup" id ajax_lookup" ion> ">in .4 4./form in .4 4.div class="headingbottom">
.div id file_contents"
4 41./a>.spa> class="comment">/*./spa>
 4 42./a>.spa> class="comment"> *n .4 4AMD Ela> SC520 processor Watchdog Timer driver./spa>
 4 43./a>.spa> class="comment"> *./spa>
 4 44./a>.spa> class="comment"> *n .4 4Based on acquirewdt.c by Ala> Cox,./spa>
 4 45./a>.spa> class="comment"> *n .4 444444and sbc60xxwdt.c by Jakob Oestergaard <jakob@unthought.net>./spa>
 4 46./a>.spa> class="comment"> *./spa>
 4 47./a>.spa> class="comment"> *n .4 4This program is free software; you ca> redistribute it4and/or./spa>
 4 48./a>.spa> class="comment"> *n .4 4modify it4under the terms of the GNU General Public License./spa>
 4 49./a>.spa> class="comment"> *n .4 4as published by the Free Software Founda	  >; either vers  >./spa>
 4 8.10a>.spa> class="comment"> *n .4 42 of the License, or (at your "
	  >)4any later vers  >../spa>
 4 11./a>.spa> class="comment"> *./spa>
 4 12./a>.spa> class="comment"> *n .4 4The authors do NOT admit liability nor provide warranty for./spa>
 4 13./a>.spa> class="comment"> *444444any of this software.4This material is provided "AS-IS" i>./spa>
 4 14./a>.spa> class="comment"> *n .4 4the hope that it may be useful for others../spa>
 4 15./a>.spa> class="comment"> *./spa>
 4 16./a>.spa> class="comment"> *n .4 4(c) Copyright 2001.4 4Scott Jennings <linuxdrivers@oro.net>./spa>
 4 17./a>.spa> class="comment"> *n .4 4444449/27 - 2001.4 4  [Initial release]./spa>
 4 18./a>.spa> class="comment"> *./spa>
 4 19./a>.spa> class="comment"> *n .4 4Addi	  >al fixes Ala> Cox./spa>
 4 2.10a>.spa> class="comment"> *n .4 4- 444444Fixed formatting./spa>
 4 21./a>.spa> class="comment"> *n .4 4- 444444Removed debug printks./spa>
 4 22./a>.spa> class="comment"> *n .4 4- 444444Fixed SMP built kernel deadlock./spa>
 4 23./a>.spa> class="comment"> *444444- 444444Switched to private locks not lock_kernel./spa>
 4 24./a>.spa> class="comment"> *n .4 4- 444444Used ioremap/writew/readw./spa>
 4 25./a>.spa> class="comment"> *n .4 4- 444444Added NOWAYOUT support./spa>
 4 26./a>.spa> class="comment"> *n .4 44/12 - 2002 Changes by Rob Radez <rob@osinvestor.com>./spa>
 4 27./a>.spa> class="comment"> *n .4 4- 444444Change comments./spa>
 4 28./a>.spa> class="comment"> *n .4 4- 444444Eliminate fop_llseek./spa>
 4 29./a>.spa> class="comment"> *n .4 4- 444444Change CONFIG_WATCHDOG_NOWAYOUT semantics./spa>
 4 3.10a>.spa> class="comment"> *n .4 4- 444444Add KERN_* tags to printks./spa>
 4 31./a>.spa> class="comment"> *n .4 4- 444444fix possible wdt_is_ope> race./spa>
 4 32./a>.spa> class="comment"> *n .4 4- 444444Report proper capabilities in watchdog_info./spa>
 4 33./a>.spa> class="comment"> *444444- 444444Add WDIOC_{GETSTATUS, GETBOOTSTATUS, SETTIMEOUT,./spa>
 4 34./a>.spa> class="comment"> *n .4 444444444GETTIMEOUT, SETOPTIONS} ioctls./spa>
 4 35./a>.spa> class="comment"> *n .4 409/8 - 2003 Changes by Wim Va> Sebroeck <wim@iguana.be>./spa>
 4 36./a>.spa> class="comment"> *n .4 4- 444444cleanup of trailing spaces./spa>
 4 37./a>.spa> class="comment"> *n .4 4- 444444added extra printk's for startup problems./spa>
 4 38./a>.spa> class="comment"> *n .4 4- 444444use4module_param./spa>
 4 39./a>.spa> class="comment"> *n .4 4- 444444made timeout (the emulated heartbeat) a4module_param./spa>
 4 4.10a>.spa> class="comment"> *n .4 4- 444444made the keepalive ping a> internal subroutine./spa>
 4 41./a>.spa> class="comment"> *n .4 43/27 - 2004 Changes by Sean Young <sean@mess.org>./spa>
 4 42./a>.spa> class="comment"> *n .4 4- 444444set MMCR_BASE to 0xfffef000./spa>
 4 43./a>.spa> class="comment"> *444444- 444444CBAR does not need to be read./spa>
 4 44./a>.spa> class="comment"> *n .4 4- 444444removed debugging printks./spa>
 4 45./a>.spa> class="comment"> *./spa>
 4 46./a>.spa> class="comment"> *n This WDT driver is different from4most other Linux WDT./spa>
 4 47./a>.spa> class="comment"> *n drivers in that the driver will ping the watchdog by itself,./spa>
 4 48./a>.spa> class="comment"> *n because4this particular WDT has a4very short timeout (v3.1.spa>
 4 49./a>.spa> class="comment"> *n seconds)4and it would be insane to count on any4userspace./spa>
 4 5.10a>.spa> class="comment"> *n daemon always getting scheduled within that time fram
../spa>
 4 51./a>.spa> class="comment"> *./spa>
 4 52./a>.spa> class="comment"> *n This driver uses memory mapped IO,4and spinlock../spa>
 4 53./a>.spa> class="comment"> */./spa>
 4 54./a> 4 55./a>#define4.a href="+code=pr_fmt" class="sref">pr_fmt./a>(.a href="+code=fmt" class="sref">fmt./a>)4.a href="+code=KBUILD_MODNAME" class="sref">KBUILD_MODNAME./a> .spa> class="string">": "./spa>
4.a href="+code=fmt" class="sref">fmt./a> 4 56./a> 4 57./a>#include <linux/module.h./a>> 4 58./a>#include <linux/moduleparam.h./a>> 4 59./a>#include <linux/typ
s.h./a>> 4 60./a>#include <linux/timer.h./a>> 4 61./a>#include <linux/miscdevice.h./a>> 4 62./a>#include <linux/watchdog.h./a>> 4 63./a>#include <linux/fs.h./a>> 4 64./a>#include <linux/ioport.h./a>> 4 65./a>#include <linux/notifier.h./a>> 4 66./a>#include <linux/reboot.h./a>> 4 67./a>#include <linux/init.h./a>> 4 68./a>#include <linux/jiffi
s.h./a>> 4 69./a>#include <linux/io.h./a>> 4 70./a>#include <linux/uaccess.h./a>> 4 71./a> 4 72./a> 4 73./a>.spa> class="comment">/*./spa>
 4 74./a>.spa> class="comment"> *nThe AMD Ela> SC520 timeout ion>
 is 492us times a4power of 2 (0-7)./spa>
 4 75./a>.spa> class="comment"> *./spa>
 4 76./a>.spa> class="comment"> *n .0: 492us    2: 1.01s    4: 4.03s   6: 1v323s./spa>
 4 77./a>.spa> class="comment"> *n .1: 503ms    3: 2.01s    5: 8.05s   7: 32.21s./spa>
 4 78./a>.spa> class="comment"> *./spa>
 4 79./a>.spa> class="comment"> *nWe will program the SC520 watchdog for a timeout of 2.01s../spa>
 4 8.10a>.spa> class="comment"> *nIf we reset the watchdog every ~250ms we should be saf
../spa>
 4 81./a>.spa> class="comment"> */./spa>
 4 82./a> 4 83./a>#define4.a href="+code=WDT_INTERVAL" class="sref">WDT_INTERVAL./a> (.a href="+code=HZ" class="sref">HZ./a>/4+1) 4 84./a> 4 85./a>.spa> class="comment">/*./spa>
 4 86./a>.spa> class="comment"> *nWe must not require too good response from4the userspace daemon../spa>
 4 87./a>.spa> class="comment"> *nHere we require the userspace daemon to send us a heartbeat./spa>
 4 88./a>.spa> class="comment"> *nchar to /dev/watchdog every 30 seconds../spa>
 4 89./a>.spa> class="comment"> */./spa>
 4 90./a> 4 91./a>#define4.a href="+code=WATCHDOG_TIMEOUT" class="sref">WATCHDOG_TIMEOUT./a> 30             .spa> class="comment">/* 30 sec default timeout */./spa>
 4 92./a>.spa> class="comment">/* in seconds, will be multiplied by HZ to get seconds to wait for a ping */./spa>
 4 93./a>static int4.a href="+code=timeout" class="sref">timeout./a> =4.a href="+code=WATCHDOG_TIMEOUT" class="sref">WATCHDOG_TIMEOUT./a>; 4 94./a>.a href="+code=module_param" class="sref">module_param./a>(.a href="+code=timeout" class="sref">timeout./a>, int, 0); 4 95./a>.a href="+code=MODULE_PARM_DESC" class="sref">MODULE_PARM_DESC./a>(.a href="+code=timeout" class="sref">timeout./a>, 4 96./a>        .spa> class="string">"Watchdog timeout in seconds. (1 <= timeout <= 3600, default="./spa>
 4 97./a>                                .a href="+code=__MODULE_STRING" class="sref">__MODULE_STRING./a>(.a href="+code=WATCHDOG_TIMEOUT" class="sref">WATCHDOG_TIMEOUT./a>) .spa> class="string">")"./spa>
); 4 98./a> 4 99./a>static .a href="+code=bool" class="sref">bool./a> .a href="+code=nowayout" class="sref">nowayout./a> =4.a href="+code=WATCHDOG_NOWAYOUT" class="sref">WATCHDOG_NOWAYOUT./a>; 4100./a>.a href="+code=module_param" class="sref">module_param./a>(.a href="+code=nowayout" class="sref">nowayout./a>, .a href="+code=bool" class="sref">bool./a>, 0); 4101./a>.a href="+code=MODULE_PARM_DESC" class="sref">MODULE_PARM_DESC./a>(.a href="+code=nowayout" class="sref">nowayout./a>, 4102./a>                .spa> class="string">"Watchdog cannot be stopped once started (default="./spa>
 4103./a>                                .a href="+code=__MODULE_STRING" class="sref">__MODULE_STRING./a>(.a href="+code=WATCHDOG_NOWAYOUT" class="sref">WATCHDOG_NOWAYOUT./a>) .spa> class="string">")"./spa>
); 4104./a> 4105./a>.spa> class="comment">/*./spa>
 4106./a>.spa> class="comment"> *nAMD Ela> SC520 - Watchdog Timer Registers./spa>
 4107./a>.spa> class="comment"> */./spa>
 4108./a>#define4.a href="+code=MMCR_BASE" class="sref">MMCR_BASE./a>       0xfffef000      .spa> class="comment">/* The default base address */./spa>
 4109./a>#define4.a href="+code=OFFS_WDTMRCTL" class="sref">OFFS_WDTMRCTL./a>   0xCB0   .spa> class="comment">/* Watchdog Timer Control Register */./spa>
 4110./a> 4111./a>.spa> class="comment">/* WDT Control Register bit defini	  >s */./spa>
 4112./a>#define4.a href="+code=WDT_EXP_SEL_01" class="sref">WDT_EXP_SEL_01./a>  0x0001.4.spa> class="comment">/* [01] Time-out = 496 us (with 33 Mhz clk). */./spa>
 4113./a>#define4.a href="+code=WDT_EXP_SEL_02" class="sref">WDT_EXP_SEL_02./a>  0x0002.4.spa> class="comment">/* [02] Time-out = 508 ms (with 33 Mhz clk). */./spa>
 4114./a>#define4.a href="+code=WDT_EXP_SEL_03" class="sref">WDT_EXP_SEL_03./a>  0x0004.4.spa> class="comment">/* [03] Time-out = 1.02.s (with 33 Mhz clk). */./spa>
 4115./a>#define4.a href="+code=WDT_EXP_SEL_04" class="sref">WDT_EXP_SEL_04./a>  0x0008.4.spa> class="comment">/* [04] Time-out = 2.03.s (with 33 Mhz clk). */./spa>
 4116./a>#define4.a href="+code=WDT_EXP_SEL_05" class="sref">WDT_EXP_SEL_05./a>  0x0010.4.spa> class="comment">/* [05] Time-out = 4.07.s (with 33 Mhz clk). */./spa>
 4117./a>#define4.a href="+code=WDT_EXP_SEL_06" class="sref">WDT_EXP_SEL_06./a>  0x0020.4.spa> class="comment">/* [06] Time-out = 8.13.s (with 33 Mhz clk). */./spa>
 4118./a>#define4.a href="+code=WDT_EXP_SEL_07" class="sref">WDT_EXP_SEL_07./a>  0x0040.4.spa> class="comment">/* [07] Time-out = 16.27s (with 33 Mhz clk). */./spa>
 4119./a>#define4.a href="+code=WDT_EXP_SEL_08" class="sref">WDT_EXP_SEL_08./a>  0x0080.4.spa> class="comment">/* [08] Time-out = 32.54s (with 33 Mhz clk). */./spa>
 412.10a>#define4.a href="+code=WDT_IRQ_FLG" class="sref">WDT_IRQ_FLG./a>     0x1000  .spa> class="comment">/* [12] Interrupt Request Flag */./spa>
 4121./a>#define4.a href="+code=WDT_WRST_ENB" class="sref">WDT_WRST_ENB./a>    0x4000  .spa> class="comment">/* [14] Watchdog Timer Reset Enable */./spa>
 4122./a>#define4.a href="+code=WDT_ENB" class="sref">WDT_ENB./a>         0x8000  .spa> class="comment">/* [15] Watchdog Timer Enable */./spa>
 4123./a> 4124./a>static .a href="+code=__u16" class="sref">__u16./a> .a href="+code=__iomem" class="sref">__iomem./a> *.a href="+code=wdtmrctl" class="sref">wdtmrctl./a>; 4125./a> 4126./a>static void .a href="+code=wdt_timer_ping" class="sref">wdt_timer_ping./a>(unsigned long); 4127./a>static .a href="+code=DEFINE_TIMER" class="sref">DEFINE_TIMER./a>(.a href="+code=timer" class="sref">timer./a>, .a href="+code=wdt_timer_ping" class="sref">wdt_timer_ping./a>, 0, 0); 4128./a>static unsigned long .a href="+code=next_heartbeat" class="sref">next_heartbeat./a>; 4129./a>static unsigned long .a href="+code=wdt_is_ope>" class="sref">wdt_is_ope>./a>; 413.10a>static char .a href="+code=wdt_expect_close" class="sref">wdt_expect_close./a>; 4131./a>static .a href="+code=DEFINE_SPINLOCK" class="sref">DEFINE_SPINLOCK./a>(.a href="+code=wdt_spinlock" class="sref">wdt_spinlock./a>); 4132./a> 4133./a>.spa> class="comment">/*./spa>
 4134./a>.spa> class="comment"> *n .4 4Whack the dog./spa>
 4135./a>.spa> class="comment"> */./spa>
 4136./a> 4137./a>static void .a href="+code=wdt_timer_ping" class="sref">wdt_timer_ping./a>(unsigned long .a href="+code=data" class="sref">data./a>) 4138./a>{ 4139./a>        .spa> class="comment">/* If we got a heartbeat pulse within the WDT_US_INTERVAL./spa>
 414.10a>.spa> class="comment">         * we agree to ping the WDT./spa>
 4141./a>.spa> class="comment">         */./spa>
 4142./a>        if (.a href="+code=time_before" class="sref">time_before./a>(.a href="+code=jiffi
s" class="sref">jiffi
s./a>, .a href="+code=next_heartbeat" class="sref">next_heartbeat./a>)) { 4143./a>                .spa> class="comment">/* Ping the WDT */./spa>
 41e4./a>                ..a href="+code./a>_lock" class="sref">./a>_lock./a>(&.a href="+code=wdt_spinlock" class="sref">wdt_spinlock./a>); 4145./a>                ..a href="+codewritew" class="sref">writew./a>(0xAAAA, .a href="+code=wdtmrctl" class="sref">wdtmrctl./a>); 4146./a>                ..a href="+codewritew" class="sref">writew./a>(0x5555, .a href="+code=wdtmrctl" class="sref">wdtmrctl./a>); 4147./a>                ..a href="+code./a>_unlock" class="sref">./a>_unlock./a>(&.a href="+code=wdt_spinlock" class="sref">wdt_spinlock./a>); 4148./a> 4149./a>                .spa> class="comment">/* Re-set the timer interval */./spa>
 415.10a>                ..a href="+codemod_timer" class="sref">mod_timer./a>(&.a href="+code=timer" class="sref">timer./a>, .a href="+code=jiffi
s" class="sref">jiffi
s./a> +4.a href="+code=WDT_INTERVAL" class="sref">WDT_INTERVAL./a>); 415110a>        } else 4152./a>                .a href="+code=pr_war>" class="sref">pr_war>./a>(.spa> class="string">"Heartbeat lost! Will not ping the watchdog\n"./spa>
); 4153./a>} 4154./a> 4155./a>.spa> class="comment">/*./spa>
 4156./a>.spa> class="comment"> *n .4 4Utility routines./spa>
 4157./a>.spa> class="comment"> */./spa>
 4158./a> 4159./a>static void .a href="+code=wdt_config" class="sref">wdt_config./a>(int4.a href="+code=writeval" class="sref">writeval./a>) 4160./a>{ 416110a>        .a href="+code=__u16" class="sref">__u16./a> .a href="+code=dummy" class="sref">dummy./a>; 4162./a>        unsigned long .a href="+code=flags" class="sref">flags./a>; 4163./a> 4164./a>        .spa> class="comment">/* buy some time (ping) */./spa>
 416510a>        .a href="+code=./a>_lock_irqsave" class="sref">./a>_lock_irqsave./a>(&.a href="+code=wdt_spinlock" class="sref">wdt_spinlock./a>, .a href="+code=flags" class="sref">flags./a>); 416610a>        .a href="+code=dummy" class="sref">dummy./a> =4.a href="+code=readw" class="sref">readw./a>(.a href="+code=wdtmrctl" class="sref">wdtmrctl./a>);        .spa> class="comment">/* ensure write synchroniza	  > */./spa>
 416710a>        .a href="+code=writew" class="sref">writew./a>(0xAAAA, .a href="+code=wdtmrctl" class="sref">wdtmrctl./a>); 416810a>        .a href="+code=writew" class="sref">writew./a>(0x5555, .a href="+code=wdtmrctl" class="sref">wdtmrctl./a>); 4169./a>        .spa> class="comment">/* unlock WDT = make WDT configura	  > register writable one time */./spa>
 417010a>        .a href="+code=writew" class="sref">writew./a>(0x3333, .a href="+code=wdtmrctl" class="sref">wdtmrctl./a>); 417110a>        .a href="+code=writew" class="sref">writew./a>(0xCCCC, .a href="+code=wdtmrctl" class="sref">wdtmrctl./a>); 4172./a>        .spa> class="comment">/* write WDT configura	  > register */./spa>
 417310a>        .a href="+code=writew" class="sref">writew./a>(.a href="+code=writeval" class="sref">writeval./a>, .a href="+code=wdtmrctl" class="sref">wdtmrctl./a>); 417410a>        .a href="+code=./a>_unlock_irqrestore" class="sref">./a>_unlock_irqrestore./a>(&.a href="+code=wdt_spinlock" class="sref">wdt_spinlock./a>, .a href="+code=flags" class="sref">flags./a>); 4175./a>} 4176./a> 4177./a>static int4.a href="+code=wdt_startup" class="sref">wdt_startup./a>(void) 4178./a>{ 417910a>        .a href="+code=next_heartbeat" class="sref">next_heartbeat./a> =4.a href="+code=jiffi
s" class="sref">jiffi
s./a> +4(.a href="+code=timeout" class="sref">timeout./a> *n.a href="+code=HZ" class="sref">HZ./a>); 4180./a> 4181./a>        .spa> class="comment">/* Start the timer */./spa>
 418210a>        .a href="+code=mod_timer" class="sref">mod_timer./a>(&.a href="+code=timer" class="sref">timer./a>, .a href="+code=jiffi
s" class="sref">jiffi
s./a> +4.a href="+code=WDT_INTERVAL" class="sref">WDT_INTERVAL./a>); 4183./a> 4184./a>        .spa> class="comment">/* Start the watchdog */./spa>
 418510a>        .a href="+code=wdt_config" class="sref">wdt_config./a>(.a href="+code=WDT_ENB" class="sref">WDT_ENB./a> |4.a href="+code=WDT_WRST_ENB" class="sref">WDT_WRST_ENB./a> |4.a href="+code=WDT_EXP_SEL_04" class="sref">WDT_EXP_SEL_04./a>); 4186./a> 418710a>        .a href="+code=pr_info" class="sref">pr_info./a>(.spa> class="string">"Watchdog timer is now enabled\n"./spa>
); 418810a>        return 0; 4189./a>} 4190./a> 4191./a>static int4.a href="+code=wdt_turnoff" class="sref">wdt_turnoff./a>(void) 4192./a>{ 4193./a>        .spa> class="comment">/* Stop the timer */./spa>
 419410a>        .a href="+code=del_timer" class="sref">del_timer./a>(&.a href="+code=timer" class="sref">timer./a>); 4195./a> 4196./a>        .spa> class="comment">/* Stop the watchdog */./spa>
 419710a>        .a href="+code=wdt_config" class="sref">wdt_config./a>(0); 4198./a> 419910a>        .a href="+code=pr_info" class="sref">pr_info./a>(.spa> class="string">"Watchdog timer is now disabled...\n"./spa>
); 420010a>        return 0; 4201./a>} 4202./a> 4203./a>static int4.a href="+code=wdt_keepalive" class="sref">wdt_keepalive./a>(void) 4204./a>{ 4205./a>        .spa> class="comment">/* user land ping */./spa>
 420610a>        .a href="+code=next_heartbeat" class="sref">next_heartbeat./a> =4.a href="+code=jiffi
s" class="sref">jiffi
s./a> +4(.a href="+code=timeout" class="sref">timeout./a> *n.a href="+code=HZ" class="sref">HZ./a>); 420710a>        return 0; 4208./a>} 4209./a> 4210./a>static int4.a href="+code=wdt_set_heartbeat" class="sref">wdt_set_heartbeat./a>(int4.a href="+code=t" class="sref">t./a>) 4211./a>{ 4212./a>        if ((.a href="+code=t" class="sref">t./a> < 1) ||4(.a href="+code=t" class="sref">t./a> > 3600))      .spa> class="comment">/* arbitrary upper limit */./spa>
 4213./a>                return -.a href="+code=EINVAL" class="sref">EINVAL./a>; 4214./a> 421510a>        .a href="+code=timeout" class="sref">timeout./a> =4.a href="+code=t" class="sref">t./a>; 421610a>        return 0; 4217./a>} 4218./a> 4219./a>.spa> class="comment">/*./spa>
 422.10a>.spa> class="comment"> *n .4 4/dev/watchdog handling./spa>
 4221./a>.spa> class="comment"> */./spa>
 4222./a> 4223./a>static .a href="+code=.size_t" class="sref">.size_t./a> .a href="+code=fop_write" class="sref">fop_write./a>(struct4.a href="+code=file" class="sref">file./a> *.a href="+code=file" class="sref">file./a>, const char .a href="+code=__user" class="sref">__user./a> *.a href="+code=buf" class="sref">buf./a>, 4224./a>                                                .a href="+code=.ize_t" class="sref">.ize_t./a> .a href="+code=count" class="sref">count./a>, .a href="+code=loff_t" class="sref">loff_t./a> *.a href="+code=ppos" class="sref">ppos./a>) 4225./a>{ 4226./a>        .spa> class="comment">/* See if we got the magic character 'V' and reload the timer */./spa>
 4227./a>        if (.a href="+code=count" class="sref">count./a>) { 4228./a>                if (!.a href="+code=nowayout" class="sref">nowayout./a>) { 4229./a>                        .a href="+code=.ize_t" class="sref">.ize_t./a> .a href="+code=ofs" class="sref">ofs./a>; 4230./a> 4231./a>                        .spa> class="comment">/* note: just i> case someone wrote the magic character./spa>
 4232./a>.spa> class="comment">                         * five months ago... */./spa>
 4233./a>                        .a href="+code=wdt_expect_close" class="sref">wdt_expect_close./a> =40; 4234./a> 4235./a>                        .spa> class="comment">/* now sca> */./spa>
 4236./a>                        for (.a href="+code=ofs" class="sref">ofs./a> =40; .a href="+code=ofs" class="sref">ofs./a> !=4.a href="+code=count" class="sref">count./a>; .a href="+code=ofs" class="sref">ofs./a>++) { 4237./a>                                char .a href="+code=c" class="sref">c./a>; 4238./a>                                if (.a href="+code=get_user" class="sref">get_user./a>(.a href="+code=c" class="sref">c./a>, .a href="+code=buf" class="sref">buf./a> +4.a href="+code=ofs" class="sref">ofs./a>)) 4239./a>                                        return -.a href="+code=EFAULT" class="sref">EFAULT./a>; 424.10a>                                if (.a href="+code=c" class="sref">c./a> == .spa> class="string">'V'./spa>
) 4241./a>                                        .a href="+code=wdt_expect_close" class="sref">wdt_expect_close./a> =442; 4242./a>                        } 4243./a>                } 4244./a> 4245./a>                .spa> class="comment">/* Well,4anyhow someone wrote to us, we should./spa>
 4246./a>.spa> class="comment">                   return that favour */./spa>
 4247./a>                ..a href="+codewdt_keepalive" class="sref">wdt_keepalive./a>(); 4248./a>        } 4249./a>        return .a href="+code=count" class="sref">count./a>; 425.10a>} 4251./a> 4252./a>static int4.a href="+code=fop_ope>" class="sref">fop_ope>./a>(struct4.a href="+code=inode" class="sref">inode./a> *.a href="+code=inode" class="sref">inode./a>, struct4.a href="+code=file" class="sref">file./a> *.a href="+code=file" class="sref">file./a>) 4253./a>{ 4254./a>        .spa> class="comment">/* Just i> case we're already talking to someone... */./spa>
 4255./a>        if (.a href="+code=test_and_set_bit" class="sref">test_and_set_bit./a>(0, &.a href="+code=wdt_is_ope>" class="sref">wdt_is_ope>./a>)) 4256./a>                return -.a href="+code=EBUSY" class="sref">EBUSY./a>; 4257./a>        if (.a href="+code=nowayout" class="sref">nowayout./a>) 4258./a>                .a href="+code=__module_get" class="sref">__module_get./a>(.a href="+code=THIS_MODULE" class="sref">THIS_MODULE./a>); 4259./a> 4260./a>        .spa> class="comment">/* Good, fire up the show */./spa>
 426110a>        .a href="+code=wdt_startup" class="sref">wdt_startup./a>(); 4262./a>        return .a href="+code=nonseekable_ope>" class="sref">nonseekable_ope>./a>(.a href="+code=inode" class="sref">inode./a>, .a href="+code=file" class="sref">file./a>); 4263./a>} 4264./a> 426510a>static int4.a href="+code=fop_close" class="sref">fop_close./a>(struct4.a href="+code=inode" class="sref">inode./a> *.a href="+code=inode" class="sref">inode./a>, struct4.a href="+code=file" class="sref">file./a> *.a href="+code=file" class="sref">file./a>) 426610a>{ 4267./a>        if (.a href="+code=wdt_expect_close" class="sref">wdt_expect_close./a> ==442) 4268./a>                .a href="+code=wdt_turnoff" class="sref">wdt_turnoff./a>(); 4269./a>        else { 427.10a>                ..a href="+codepr_crit" class="sref">pr_crit./a>(.spa> class="string">"Unexpected close, not stopping watchdog!\n"./spa>
); 4271./a>                ..a href="+codewdt_keepalive" class="sref">wdt_keepalive./a>(); 4272./a>        } 427310a>        .a href="+code=clear_bit" class="sref">clear_bit./a>(0, &.a href="+code=wdt_is_ope>" class="sref">wdt_is_ope>./a>); 427410a>        .a href="+code=wdt_expect_close" class="sref">wdt_expect_close./a> =40; 4275./a>        return 0; 4276./a>} 4277./a> 4278./a>static long .a href="+code=fop_ioctl" class="sref">fop_ioctl./a>(struct4.a href="+code=file" class="sref">file./a> *.a href="+code=file" class="sref">file./a>, unsigned int4.a href="+code=cmd" class="sref">cmd./a>, unsigned long .a href="+code=arg" class="sref">arg./a>) 427910a>{ 428.10a>        void .a href="+code=__user" class="sref">__user./a> *.a href="+code=argp" class="sref">argp./a> =4(void .a href="+code=__user" class="sref">__user./a> *).a href="+code=arg" class="sref">arg./a>; 4281./a>        int4.a href="+code=__user" class="sref">__user./a> *.a href="+code=p" class="sref">p./a> =4.a href="+code=argp" class="sref">argp./a>; 428210a>        static const struct4.a href="+code=watchdog_info" class="sref">watchdog_info./a> .a href="+code=ident" class="sref">ident./a> =4{ 4283./a>                ..a href="+code=op	  >s" class="sref">op	  >s./a> =4.a href="+code=WDIOF_KEEPALIVEPING" class="sref">WDIOF_KEEPALIVEPING./a> |4.a href="+code=WDIOF_SETTIMEOUT" class="sref">WDIOF_SETTIMEOUT./a> 4284./a>                                                        |4.a href="+code=WDIOF_MAGICCLOSE" class="sref">WDIOF_MAGICCLOSE./a>, 4285./a>                ..a href="+code=firmware_vers  >" class="sref">firmware_vers  >./a> =41, 4286./a>                ..a href="+code=identity" class="sref">identity./a> =4.spa> class="string">"SC520"./spa>
, 428710a>        }; 4288./a> 4289./a>        switch (.a href="+code=cmd" class="sref">cmd./a>) { 429.10a>        case .a href="+code=WDIOC_GETSUPPORT" class="sref">WDIOC_GETSUPPORT10a>: 4291./a>                return .a href="+code=copy_to_user" class="sref">copy_to_user./a>(.a href="+code=argp" class="sref">argp./a>, &.a href="+code=ident" class="sref">ident./a>, .izeof(.a href="+code=ident" class="sref">ident./a>)) ? -.a href="+code=EFAULT" class="sref">EFAULT./a> : 0; 429210a>        case .a href="+code=WDIOC_GETSTATUS" class="sref">WDIOC_GETSTATUS10a>: 4293./a>        case .a href="+code=WDIOC_GETBOOTSTATUS" class="sref">WDIOC_GETBOOTSTATUS10a>: 4294./a>                return .a href="+code=put_user" class="sref">put_user./a>(0, .a href="+code=p" class="sref">p./a>); 4295./a>        case .a href="+code=WDIOC_SETOPTIONS" class="sref">WDIOC_SETOPTIONS10a>: 4296./a>        { 4297./a>                int4.a href="+code=new_op	  >s" class="sref">new_op	  >s./a>, .a href="+code=retval" class="sref">retval./a> =4-.a href="+code=EINVAL" class="sref">EINVAL./a>; 4298./a> 4299./a>                if (.a href="+code=get_user" class="sref">get_user./a>(.a href="+code=new_op	  >s" class="sref">new_op	  >s./a>, .a href="+code=p" class="sref">p./a>)) 430.10a>                        return -.a href="+code=EFAULT" class="sref">EFAULT./a>; 4301./a> 4302./a>                if (.a href="+code=new_op	  >s" class="sref">new_op	  >s./a> & .a href="+code=WDIOS_DISABLECARD" class="sref">WDIOS_DISABLECARD./a>) { 4303./a>                        .a href="+code=wdt_turnoff" class="sref">wdt_turnoff./a>(); 4304./a>                        .a href="+code=retval" class="sref">retval./a> =40; 4305./a>                } 4306./a> 4307./a>                if (.a href="+code=new_op	  >s" class="sref">new_op	  >s./a> & .a href="+code=WDIOS_ENABLECARD" class="sref">WDIOS_ENABLECARD./a>) { 4308./a>                        .a href="+code=wdt_startup" class="sref">wdt_startup./a>(); 4309./a>                        .a href="+code=retval" class="sref">retval./a> =40; 431.10a>                } 4311./a> 4312./a>                return .a href="+code=retval" class="sref">retval./a>; 4313./a>        } 4314./a>        case .a href="+code=WDIOC_KEEPALIVE" class="sref">WDIOC_KEEPALIVE10a>: 4315./a>                ..a href="+codewdt_keepalive" class="sref">wdt_keepalive./a>(); 4316./a>                return 0; 4317./a>        case .a href="+code=WDIOC_SETTIMEOUT" class="sref">WDIOC_SETTIMEOUT./a>: 4318./a>        { 4319./a>                int4.a href="+code=new_timeout" class="sref">new_timeout./a>; 4320./a> 4321./a>                if (.a href="+code=get_user" class="sref">get_user./a>(.a href="+code=new_timeout" class="sref">new_timeout./a>, .a href="+code=p" class="sref">p./a>)) 4322./a>                        return -.a href="+code=EFAULT" class="sref">EFAULT./a>; 4323./a> 4324./a>                if (.a href="+code=wdt_set_heartbeat" class="sref">wdt_set_heartbeat./a>(.a href="+code=new_timeout" class="sref">new_timeout./a>)) 4325./a>                        return -.a href="+code=EINVAL" class="sref">EINVAL./a>; 4326./a> 4327./a>                ..a href="+codewdt_keepalive" class="sref">wdt_keepalive./a>(); 4328./a>                .spa> class="comment">/* Fall through */./spa>
 4329./a>        } 433.10a>        case .a href="+code=WDIOC_GETTIMEOUT" class="sref">WDIOC_GETTIMEOUT./a>: 4331./a>                return .a href="+code=put_user" class="sref">put_user./a>(.a href="+code=timeout" class="sref">timeout./a>, .a href="+code=p" class="sref">p./a>); 4332./a>        default: 4333./a>                return -.a href="+code=ENOTTY" class="sref">ENOTTY./a>; 4334./a>        } 4335./a>} 4336./a> 4337./a>static const struct4.a href="+code=file_opera	  >s" class="sref">file_opera	  >s./a> .a href="+code=wdt_fops" class="sref">wdt_fops./a> =4{ 4338./a>        ..a href="+code=owner" class="sref">owner./a>          =4.a href="+code=THIS_MODULE" class="sref">THIS_MODULE./a>, 4339./a>        ..a href="+code=llseek" class="sref">llseek./a>         =4.a href="+code=no_llseek" class="sref">no_llseek./a>, 434.10a>        ..a href="+code=write" class="sref">write./a>          =4.a href="+code=fop_write" class="sref">fop_write./a>, 4341./a>        ..a href="+code=ope>" class="sref">ope>./a>           =4.a href="+code=fop_ope>" class="sref">fop_ope>./a>, 4342./a>        ..a href="+code=release" class="sref">release./a>        =4.a href="+code=fop_close" class="sref">fop_close./a>, 4343./a>        ..a href="+code=unlocked_ioctl" class="sref">unlocked_ioctl./a> =4.a href="+code=fop_ioctl" class="sref">fop_ioctl./a>, 4344./a>}; 4345./a> 4346./a>static struct4.a href="+code=miscdevice" class="sref">miscdevice./a> .a href="+code=wdt_miscdev" class="sref">wdt_miscdev./a> =4{ 4347./a>        ..a href="+code=minor" class="sref">minor./a>  =4.a href="+code=WATCHDOG_MINOR" class="sref">WATCHDOG_MINOR./a>, 4348./a>        ..a href="+code=nam
" class="sref">nam
./a>   =4.spa> class="string">"watchdog"./spa>
, 4349./a>        ..a href="+code=fops" class="sref">fops./a>   =4&.a href="+code=wdt_fops" class="sref">wdt_fops./a>, 435.10a>}; 4351./a> 4352./a>.spa> class="comment">/*./spa>
 4353./a>.spa> class="comment"> *n .4 4Notifier for system down./spa>
 4354./a>.spa> class="comment"> */./spa>
 4355./a> 4356./a>static int4.a href="+code=wdt_notify_sys" class="sref">wdt_notify_sys./a>(struct4.a href="+code=notifier_block" class="sref">notifier_block./a> *.a href="+code=this" class="sref">this./a>, unsigned long .a href="+code=code" class="sref">code./a>, 4357./a>        void *.a href="+code=unused" class="sref">unused./a>) 4358./a>{ 4359./a>        if (.a href="+code=code" class="sref">code./a> == .a href="+code=SYS_DOWN" class="sref">SYS_DOWN./a> ||4.a href="+code=code" class="sref">code./a> == .a href="+code=SYS_HALT" class="sref">SYS_HALT./a>) 436.10a>                ..a href="+codewdt_turnoff" class="sref">wdt_turnoff./a>(); 436110a>        return .a href="+code=NOTIFY_DONE" class="sref">NOTIFY_DONE./a>; 4362./a>} 4363./a> 4364./a>.spa> class="comment">/*./spa>
 436510a>.spa> class="comment"> *n .4 4The WDT needs to learn about soft shutdowns i> order to./spa>
 4366./a>.spa> class="comment"> *n .4 4turn the timebomb registers off../spa>
 4367./a>.spa> class="comment"> */./spa>
 4368./a> 4369./a>static struct4.a href="+code=notifier_block" class="sref">notifier_block./a> .a href="+code=wdt_notifier" class="sref">wdt_notifier./a> =4{ 437.10a>        ..a href="+code=notifier_call" class="sref">notifier_call./a> =4.a href="+code=wdt_notify_sys" class="sref">wdt_notify_sys./a>, 4371./a>}; 4372./a> 4373./a>static void .a href="+code=__exit" class="sref">__exit./a> .a href="+code=sc520_wdt_unload" class="sref">sc520_wdt_unload./a>(void) 4374./a>{ 4375./a>        if (!.a href="+code=nowayout" class="sref">nowayout./a>) 4376./a>                ..a href="+codewdt_turnoff" class="sref">wdt_turnoff./a>(); 4377./a> 4378./a>        .spa> class="comment">/* Deregister */./spa>
 437910a>        .a href="+code=misc_deregister" class="sref">misc_deregister./a>(&.a href="+code=wdt_miscdev" class="sref">wdt_miscdev./a>); 438.10a>        .a href="+code=unregister_reboot_notifier" class="sref">unregister_reboot_notifier./a>(&.a href="+code=wdt_notifier" class="sref">wdt_notifier./a>); 438110a>        .a href="+code=iounmap" class="sref">iounmap./a>(.a href="+code=wdtmrctl" class="sref">wdtmrctl./a>); 4382./a>} 4383./a> 4384./a>static int4.a href="+code=__init" class="sref">__init./a> .a href="+code=sc520_wdt_init" class="sref">sc520_wdt_init./a>(void) 4385./a>{ 4386./a>        int4.a href="+code=rc" class="sref">rc./a> = -.a href="+code=EBUSY" class="sref">EBUSY./a>; 4387./a> 4388./a>        .spa> class="comment">/* Check that the timeout value is withi> it's range ;./spa>
 4389./a>.spa> class="comment">           if not reset to the default */./spa>
 439.10a>        if (.a href="+code=wdt_set_heartbeat" class="sref">wdt_set_heartbeat./a>(.a href="+code=timeout" class="sref">timeout./a>)) { 4391./a>                .a href="+code=wdt_set_heartbeat" class="sref">wdt_set_heartbeat./a>(.a href="+code=WATCHDOG_TIMEOUT" class="sref">WATCHDOG_TIMEOUT./a>); 4392./a>                .a href="+code=pr_info" class="sref">pr_info./a>(.spa> class="string">"timeout value must be 1 <= timeout <= 3600, using %d\n"./spa>
, 4393./a>                        .a href="+code=WATCHDOG_TIMEOUT" class="sref">WATCHDOG_TIMEOUT./a>); 4394./a>        } 4395./a> 439610a>        .a href="+code=wdtmrctl" class="sref">wdtmrctl./a> =4.a href="+code=ioremap" class="sref">ioremap./a>(.a href="+code=MMCR_BASE" class="sref">MMCR_BASE./a> +4.a href="+code=OFFS_WDTMRCTL" class="sref">OFFS_WDTMRCTL./a>, 2); 4397./a>        if (!.a href="+code=wdtmrctl" class="sref">wdtmrctl./a>) { 4398./a>                .a href="+code=pr_err" class="sref">pr_err./a>(.spa> class="string">"Unable to remap memory\n"./spa>
); 4399./a>                .a href="+code=rc" class="sref">rc./a> = -.a href="+code=ENOMEM" class="sref">ENOMEM./a>; 440.10a>                goto .a href="+code=err_out_region2" class="sref">err_out_region2./a>; 4401./a>        } 4402./a> 440310a>        .a href="+code=rc" class="sref">rc./a> = .a href="+code=register_reboot_notifier" class="sref">register_reboot_notifier./a>(&.a href="+code=wdt_notifier" class="sref">wdt_notifier./a>); 4404./a>        if (.a href="+code=rc" class="sref">rc./a>) { 4405./a>                .a href="+code=pr_err" class="sref">pr_err./a>(.spa> class="string">"cannot register reboot notifier (err=%d)\n"./spa>
, .a href="+code=rc" class="sref">rc./a>); 4406./a>                goto .a href="+code=err_out_ioremap" class="sref">err_out_ioremap./a>; 4407./a>        } 4408./a> 440910a>        .a href="+code=rc" class="sref">rc./a> = .a href="+code=misc_register" class="sref">misc_register./a>(&.a href="+code=wdt_miscdev" class="sref">wdt_miscdev./a>); 441.10a>        if (.a href="+code=rc" class="sref">rc./a>) { 4411./a>                .a href="+code=pr_err" class="sref">pr_err./a>(.spa> class="string">"cannot register miscdev on minor=%d (err=%d)\n"./spa>
, 4412./a>                       .a href="+code=WATCHDOG_MINOR" class="sref">WATCHDOG_MINOR./a>, .a href="+code=rc" class="sref">rc./a>); 4413./a>                goto .a href="+code=err_out_notifier" class="sref">err_out_notifier./a>; 4414./a>        } 4415./a> 441610a>        .a href="+code=pr_info" class="sref">pr_info./a>(.spa> class="string">"WDT driver for SC520 initialised. timeout=%d sec (nowayout=%d)\n"./spa>
, 4417./a>                ..a href="+codetimeout" class="sref">timeout./a>, .a href="+code=nowayout" class="sref">nowayout./a>); 4418./a> 4419./a>        return 0; 4420./a> 4421./a>.a href="+code=err_out_notifier" class="sref">err_out_notifier./a>: 4422./a>        .a href="+code=unregister_reboot_notifier" class="sref">unregister_reboot_notifier./a>(&.a href="+code=wdt_notifier" class="sref">wdt_notifier./a>); 4423./a>.a href="+code=err_out_ioremap" class="sref">err_out_ioremap./a>: 4424./a>        .a href="+code=iounmap" class="sref">iounmap./a>(.a href="+code=wdtmrctl" class="sref">wdtmrctl./a>); 4425./a>.a href="+code=err_out_region2" class="sref">err_out_region2./a>: 4426./a>        return .a href="+code=rc" class="sref">rc./a>; 4427./a>} 4428./a> 4429./a>.a href="+code=module_init" class="sref">module_init./a>(.a href="+code=sc520_wdt_init" class="sref">sc520_wdt_init./a>); 443.10a>.a href="+code=module_exit" class="sref">module_exit./a>(.a href="+code=sc520_wdt_unload" class="sref">sc520_wdt_unload./a>); 4431./a> 4432./a>.a href="+code=MODULE_AUTHOR" class="sref">MODULE_AUTHOR./a>(.spa> class="string">"Scott and Bill Jennings"./spa>
); 4433./a>.a href="+code=MODULE_DESCRIPTION" class="sref">MODULE_DESCRIPTION./a>( 4434./a>        .spa> class="string">"Driver for watchdog timer i> AMD \"Elan\" SC520 uProcessor"./spa>
); 4435./a>.a href="+code=MODULE_LICENSE" class="sref">MODULE_LICENSE./a>(.spa> class="string">"GPL"./spa>
); 4436./a>.a href="+code=MODULE_ALIAS_MISCDEV" class="sref">MODULE_ALIAS_MISCDEV./a>(.a href="+code=WATCHDOG_MINOR" class="sref">WATCHDOG_MINOR./a>); 4437./a>
lxr.linux.no kindly hosted by Redpill Linpro AS./a>, provider of Linux consulting and opera >s services since 1995.