linux/drivers/watchdog/bfin_wdt.c
<<
> > p/spa pspa class="lxr_search"> > ="+search" method="post" onsubmit="return do_search(this);"> > > > Search > p/spa > ="ajax+*" method="post" onsubmit="return false;"> pinput typ"v4hidden" nam"v4ajax_lookup" idv4ajax_lookup" lue="v4"> >
pdiv idv4file_contents"
o o1p/a>pspa
 class="comment">/*p/spa
  o o2p/a>pspa
 class="comment"> * Blackfin On-Chip Watchdog Driverp/spa
  o o3p/a>pspa
 class="comment"> *p/spa
  o o4p/a>pspa
 class="comment"> * Originally based on softdog.cp/spa
  o o5p/a>pspa
 class="comment"> * Copyright 2006-2010 Analog Devices Inc.p/spa
  o o6p/a>pspa
 class="comment"> * Copyright 2006-2007 Michele d'Amicop/spa
  o o7p/a>pspa
 class="comment"> * Copyright 1996 Ala
 Cox <ala
@lxorguk.ukuu.org.uk>p/spa
  o o8p/a>pspa
 class="comment"> *p/spa
  o o9p/a>pspa
 class="comment"> * Enter bugs at http://blackfin.uclinux.org/p/spa
  o pspa
 class="comment"> *p/spa
  o 11p/a>pspa
 class="comment"> * Licensed under the GPL-2 or later.p/spa
  o 12p/a>pspa
 class="comment"> */p/spa
  o 13p/a> o 14p/a>#defineopa href="+code=pr_fmt" class="sref">pr_fmtp/a>(pa href="+code=fmt" class="sref">fmtp/a>)opa href="+code=KBUILD_MODNAME" class="sref">KBUILD_MODNAMEp/a> pspa
 class="string">": "p/spa
 opa href="+code=fmt" class="sref">fmtp/a> o 15p/a> o 16p/a>#include <linux/platform_device.hp/a>> o 17p/a>#include <linux/module.hp/a>> o 18p/a>#include <linux/moduleparam.hp/a>> o 19p/a>#include <linux/typ"s.hp/a>> o 20p/a>#include <linux/timer.hp/a>> o 21p/a>#include <linux/miscdevice.hp/a>> o 22p/a>#include <linux/watchdog.hp/a>> o 23p/a>#include <linux/fs.hp/a>> o 24p/a>#include <linux/init.hp/a>> o 25p/a>#include <linux/interrupt.hp/a>> o 26p/a>#include <linux/uaccess.hp/a>> o 27p/a>#include <asm/blackfin.hp/a>> o 28p/a>#include <asm/bfin_watchdog.hp/a>> o 29p/a> o 30p/a>#defineopa href="+code=stamp" class="sref">stampp/a>(pa href="+code=fmt" class="sref">fmtp/a>,opa href="+code=args" class="sref">argsp/a>...) \ o 31p/a>        pa href="+code=pr_debug" class="sref">pr_debugp/a>(pspa
 class="string">"%s:%i: "p/spa
 opa href="+code=fmt" class="sref">fmtp/a> pspa
 class="string">"\n"p/spa
 ,opa href="+code=__func__" class="sref">__func__p/a>,opa href="+code=__LINE__" class="sref">__LINE__p/a>,o##opa href="+code=args" class="sref">argsp/a>) o 32p/a>#defineopa href="+code=stampit" class="sref">stampitp/a>()opa href="+code=stamp" class="sref">stampp/a>(pspa
 class="string">"here i am"p/spa
 ) o 33p/a> o 34p/a>#defineopa href="+code=WATCHDOG_NAME" class="sref">WATCHDOG_NAMEp/a> pspa
 class="string">"bfin-wdt"p/spa
  o 35p/a> o 36p/a>pspa
 class="comment">/* The BF561 has two watchdogs (oneoper core), but since Linuxp/spa
  o 37p/a>pspa
 class="comment"> * only runs on core A, we'll just work with that one.p/spa
  o 38p/a>pspa
 class="comment"> */p/spa
  o 39p/a>#ifdefopa href="+code=BF561_FAMILY" class="sref">BF561_FAMILYp/a> o 40p/a># defineopa href="+code=bfin_read_WDOG_CTL" class="sref">bfin_read_WDOG_CTLp/a>()o   pa href="+code=bfin_read_WDOGA_CTL" class="sref">bfin_read_WDOGA_CTLp/a>() o 41p/a># defineopa href="+code=bfin_read_WDOG_CNT" class="sref">bfin_read_WDOG_CNTp/a>()o   pa href="+code=bfin_read_WDOGA_CNT" class="sref">bfin_read_WDOGA_CNTp/a>() o 42p/a># defineopa href="+code=bfin_read_WDOG_STAT" class="sref">bfin_read_WDOG_STATp/a>()o  pa href="+code=bfin_read_WDOGA_STAT" class="sref">bfin_read_WDOGA_STATp/a>() o 43p/a># defineopa href="+code=bfin_write_WDOG_CTL" class="sref">bfin_write_WDOG_CTLp/a>(pa href="+code=x" class="sref">xp/a>)oopa href="+code=bfin_write_WDOGA_CTL" class="sref">bfin_write_WDOGA_CTLp/a>(pa href="+code=x" class="sref">xp/a>) o 44p/a># defineopa href="+code=bfin_write_WDOG_CNT" class="sref">bfin_write_WDOG_CNTp/a>(pa href="+code=x" class="sref">xp/a>)oopa href="+code=bfin_write_WDOGA_CNT" class="sref">bfin_write_WDOGA_CNTp/a>(pa href="+code=x" class="sref">xp/a>) o 45p/a># defineopa href="+code=bfin_write_WDOG_STAT" class="sref">bfin_write_WDOG_STATp/a>(pa href="+code=x" class="sref">xp/a>)opa href="+code=bfin_write_WDOGA_STAT" class="sref">bfin_write_WDOGA_STATp/a>(pa href="+code=x" class="sref">xp/a>) o 46p/a>#endif o 47p/a> o 48p/a>pspa
 class="comment">/* some defaults */p/spa
  o 49p/a>#defineopa href="+code=WATCHDOG_TIMEOUT" class="sref">WATCHDOG_TIMEOUTp/a> 20 o 50p/a> o 51p/a>static unsigned intopa href="+code=timeout" class="sref">timeoutp/a> =opa href="+code=WATCHDOG_TIMEOUT" class="sref">WATCHDOG_TIMEOUTp/a>; o 52p/a>static pa href="+code=bool" class="sref">boolp/a> pa href="+code=nowayout" class="sref">nowayoutp/a> =opa href="+code=WATCHDOG_NOWAYOUT" class="sref">WATCHDOG_NOWAYOUTp/a>; o 53p/a>static const structopa href="+code=watchdog_info" class="sref">watchdog_infop/a> pa href="+code=bfin_wdt_info" class="sref">bfin_wdt_infop/a>; o 54p/a>static unsigned long pa href="+code=open_check" class="sref">open_checkp/a>; o 55p/a>static char pa href="+code=expect_close" class="sref">expect_closep/a>; o 56p/a>static pa href="+code=DEFINE_SPINLOCK" class="sref">DEFINE_SPINLOCKp/a>(pa href="+code=bfin_wdt_spinlock" class="sref">bfin_wdt_spinlockp/a>); o 57p/a> o 58p/a>pspa
 class="comment">/**p/spa
  o 59p/a>pspa
 class="comment"> *      bfin_wdt_keepalive - Keep the Userspace Watchdog Alivep/spa
  o 6/opa>pspa
 class="comment"> *p/spa
  o 61p/a>pspa
 class="comment"> *      The Userspace watchdog got a KeepAlive: schedule the next timeout.p/spa
  o 62p/a>pspa
 class="comment"> */p/spa
  o 63p/a>static intopa href="+code=bfin_wdt_keepalive" class="sref">bfin_wdt_keepalivep/a>(void) o 64p/a>{ o 65p/a>        pa href="+code=stampit" class="sref">stampitp/a>(); o 66p/a>        pa href="+code=bfin_write_WDOG_STAT" class="sref">bfin_write_WDOG_STATp/a>(0); o 67p/a>        return 0; o 68p/a>} o 69p/a> o 7/opa>pspa
 class="comment">/**p/spa
  o 71p/a>pspa
 class="comment"> *      bfin_wdt_stop - Stop the Watchdogp/spa
  o 72p/a>pspa
 class="comment"> *p/spa
  o 73p/a>pspa
 class="comment"> *      Stops the on-chip watchdog.p/spa
  o 74p/a>pspa
 class="comment"> */p/spa
  o 75p/a>static intopa href="+code=bfin_wdt_stop" class="sref">bfin_wdt_stopp/a>(void) o 76p/a>{ o 77p/a>        pa href="+code=stampit" class="sref">stampitp/a>(); o 78p/a>        pa href="+code=bfin_write_WDOG_CTL" class="sref">bfin_write_WDOG_CTLp/a>(pa href="+code=WDEN_DISABLE" class="sref">WDEN_DISABLEp/a>); o 79p/a>        return 0; o 80p/a>} o 81p/a> o 82p/a>pspa
 class="comment">/**p/spa
  o 83p/a>pspa
 class="comment"> *      bfin_wdt_start - Start the Watchdogp/spa
  o 84p/a>pspa
 class="comment"> *p/spa
  o 85p/a>pspa
 class="comment"> *      Starts the on-chip watchdog.  Automatically loads WDOG_CNTp/spa
  o 86p/a>pspa
 class="comment"> *      into WDOG_STAT for us.p/spa
  o 87p/a>pspa
 class="comment"> */p/spa
  o 88p/a>static intopa href="+code=bfin_wdt_start" class="sref">bfin_wdt_startp/a>(void) o 89p/a>{ o 90p/a>        pa href="+code=stampit" class="sref">stampitp/a>(); o 91p/a>        pa href="+code=bfin_write_WDOG_CTL" class="sref">bfin_write_WDOG_CTLp/a>(pa href="+code=WDEN_ENABLE" class="sref">WDEN_ENABLEp/a> | pa href="+code=ICTL_RESET" class="sref">ICTL_RESETp/a>); o 92p/a>        return 0; o 93p/a>} o 94p/a> o 95p/a>pspa
 class="comment">/**p/spa
  o 96p/a>pspa
 class="comment"> *      bfin_wdt_running - Check Watchdog statusp/spa
  o 97p/a>pspa
 class="comment"> *p/spa
  o 98p/a>pspa
 class="comment"> *      See if the watchdog is running.p/spa
  o 99p/a>pspa
 class="comment"> */p/spa
  o100p/a>static intopa href="+code=bfin_wdt_running" class="sref">bfin_wdt_runningp/a>(void) o101p/a>{ o102p/a>        pa href="+code=stampit" class="sref">stampitp/a>(); o103p/a>        return ((pa href="+code=bfin_read_WDOG_CTL" class="sref">bfin_read_WDOG_CTLp/a>()o&opa href="+code=WDEN_MASK" class="sref">WDEN_MASKp/a>)o!=opa href="+code=WDEN_DISABLE" class="sref">WDEN_DISABLEp/a>); o104p/a>} o105p/a> o106p/a>pspa
 class="comment">/**p/spa
  o107p/a>pspa
 class="comment"> *      bfin_wdt_set_timeout - Set the Userspace Watchdog timeoutp/spa
  o108p/a>pspa
 class="comment"> *      @t: new timeout lue=" (in seconds)p/spa
  o109p/a>pspa
 class="comment"> *p/spa
  o1pspa
 class="comment"> *      Translate the specified timeout in seconds into System Clockp/spa
  o111p/a>pspa
 class="comment"> *      terms which is what the on-chip Watchdog requires.p/spa
  o112p/a>pspa
 class="comment"> */p/spa
  o113p/a>static intopa href="+code=bfin_wdt_set_timeout" class="sref">bfin_wdt_set_timeoutp/a>(unsigned long pa href="+code=t" class="sref">tp/a>) o114p/a>{ o115p/a>        pa href="+code=u32" class="sref">u32p/a> pa href="+code=cnt" class="sref">cntp/a>,opa href="+code=max_t" class="sref">max_tp/a>,opa href="+code=sclk" class="sref">sclkp/a>; o116p/a>        unsigned long pa href="+code=flags" class="sref">flagsp/a>; o117p/a> o118p/a>        pa href="+code=sclk" class="sref">sclkp/a> =opa href="+code=get_sclk" class="sref">get_sclkp/a>(); o119p/a>        pa href="+code=max_t" class="sref">max_tp/a> =o-1 /opa href="+code=sclk" class="sref">sclkp/a>; o120p/a>        pa href="+code=cnt" class="sref">cntp/a> =opa href="+code=t" class="sref">tp/a> * pa href="+code=sclk" class="sref">sclkp/a>; o121p/a>        pa href="+code=stamp" class="sref">stampp/a>(pspa
 class="string">"maxtimeout=%us newtimeout=%lus (cnt=%#x)"p/spa
 ,opa href="+code=max_t" class="sref">max_tp/a>,opa href="+code=t" class="sref">tp/a>,opa href="+code=cnt" class="sref">cntp/a>); o122p/a> o123p/a>        if (pa href="+code=t" class="sref">tp/a> >opa href="+code=max_t" class="sref">max_tp/a>) { o124p/a>                pa href="+code=pr_warn" class="sref">pr_warnp/a>(pspa
 class="string">"timeout lue=" is too large\n"p/spa
 ); o125p/a>                return -pa href="+code=EINVAL" class="sref">EINVALp/a>; o126p/a>        } o127p/a> o128p/a>        pa href="+code=spin_lock_irqsave" class="sref">spin_lock_irqsavep/a>(&pa href="+code=bfin_wdt_spinlock" class="sref">bfin_wdt_spinlockp/a>,opa href="+code=flags" class="sref">flagsp/a>); o129p/a>        { o130p/a>                intopa href="+code=run" class="sref">runp/a> =opa href="+code=bfin_wdt_running" class="sref">bfin_wdt_runningp/a>(); o131p/a>                pa href="+code=bfin_wdt_stop" class="sref">bfin_wdt_stopp/a>(); o132p/a>                pa href="+code=bfin_write_WDOG_CNT" class="sref">bfin_write_WDOG_CNTp/a>(pa href="+code=cnt" class="sref">cntp/a>); o133p/a>                if (pa href="+code=run" class="sref">runp/a>) o134p/a>                        pa href="+code=bfin_wdt_start" class="sref">bfin_wdt_startp/a>(); o135p/a>        } o136p/a>        pa href="+code=spin_unlock_irqrestore" class="sref">spin_unlock_irqrestorep/a>(&pa href="+code=bfin_wdt_spinlock" class="sref">bfin_wdt_spinlockp/a>,opa href="+code=flags" class="sref">flagsp/a>); o137p/a> o138p/a>        pa href="+code=timeout" class="sref">timeoutp/a> =opa href="+code=t" class="sref">tp/a>; o139p/a> o140p/a>        return 0; o141p/a>} o142p/a> o143p/a>pspa
 class="comment">/**p/spa
  o144p/a>pspa
 class="comment"> *      bfin_wdt_open - Open the Devicep/spa
  o145p/a>pspa
 class="comment"> *      @inode: inode of devicep/spa
  o146p/a>pspa
 class="comment"> *      @file: file handle of devicep/spa
  o147p/a>pspa
 class="comment"> *p/spa
  o148p/a>pspa
 class="comment"> *      Watchdog device is opened and started.p/spa
  o149p/a>pspa
 class="comment"> */p/spa
  o150p/a>static intopa href="+code=bfin_wdt_open" class="sref">bfin_wdt_openp/a>(structopa href="+code=inode" class="sref">inodep/a> *pa href="+code=inode" class="sref">inodep/a>, structopa href="+code=file" class="sref">filep/a> *pa href="+code=file" class="sref">filep/a>) o151p/a>{ o152p/a>        pa href="+code=stampit" class="sref">stampitp/a>(); o153p/a> o154p/a>        if (pa href="+code=test_and_set_bit" class="sref">test_and_set_bitp/a>(0, &pa href="+code=open_check" class="sref">open_checkp/a>)) o155p/a>                return -pa href="+code=EBUSY" class="sref">EBUSYp/a>; o156p/a> o157p/a>        if (pa href="+code=nowayout" class="sref">nowayoutp/a>) o158p/a>                pa href="+code=__module_get" class="sref">__module_getp/a>(pa href="+code=THIS_MODULE" class="sref">THIS_MODULEp/a>); o159p/a> o160p/a>        pa href="+code=bfin_wdt_keepalive" class="sref">bfin_wdt_keepalivep/a>(); o161p/a>        pa href="+code=bfin_wdt_start" class="sref">bfin_wdt_startp/a>(); o162p/a> o163p/a>        return pa href="+code=nonseekable_open" class="sref">nonseekable_openp/a>(pa href="+code=inode" class="sref">inodep/a>, pa href="+code=file" class="sref">filep/a>); o164p/a>} o165p/a> o166p/a>pspa
 class="comment">/**p/spa
  o167p/a>pspa
 class="comment"> *      bfin_wdt_close - Close the Devicep/spa
  o168p/a>pspa
 class="comment"> *      @inode: inode of devicep/spa
  o169p/a>pspa
 class="comment"> *      @file: file handle of devicep/spa
  o17/opa>pspa
 class="comment"> *p/spa
  o171p/a>pspa
 class="comment"> *      Watchdog device is closed and stopped.p/spa
  o172p/a>pspa
 class="comment"> */p/spa
  o173p/a>static intopa href="+code=bfin_wdt_release" class="sref">bfin_wdt_releasep/a>(structopa href="+code=inode" class="sref">inodep/a> *pa href="+code=inode" class="sref">inodep/a>, structopa href="+code=file" class="sref">filep/a> *pa href="+code=file" class="sref">filep/a>) o174p/a>{ o175p/a>        pa href="+code=stampit" class="sref">stampitp/a>(); o176p/a> o177p/a>        if (pa href="+code=expect_close" class="sref">expect_closep/a> == 42) o178p/a>                pa href="+code=bfin_wdt_stop" class="sref">bfin_wdt_stopp/a>(); o179p/a>        else { o180p/a>                pa href="+code=pr_crit" class="sref">pr_critp/a>(pspa
 class="string">"Unexpected close, not stopping watchdog!\n"p/spa
 ); o181p/a>                pa href="+code=bfin_wdt_keepalive" class="sref">bfin_wdt_keepalivep/a>(); o182p/a>        } o183p/a>        pa href="+code=expect_close" class="sref">expect_closep/a> = 0; o184p/a>        pa href="+code=clear_bit" class="sref">clear_bitp/a>(0, &pa href="+code=open_check" class="sref">open_checkp/a>); o185p/a>        return 0; o186p/a>} o187p/a> o188p/a>pspa
 class="comment">/**p/spa
  o189p/a>pspa
 class="comment"> *      bfin_wdt_write - Write to Devicep/spa
  o19/opa>pspa
 class="comment"> *      @file: file handle of devicep/spa
  o191p/a>pspa
 class="comment"> *      @buf: buffer to writep/spa
  o192p/a>pspa
 class="comment"> *      @count: length of bufferp/spa
  o193p/a>pspa
 class="comment"> *      @ppos: offsetp/spa
  o194p/a>pspa
 class="comment"> *p/spa
  o195p/a>pspa
 class="comment"> *      Pings the watchdog on write.p/spa
  o196p/a>pspa
 class="comment"> */p/spa
  o197p/a>static pa href="+code=ssize_t" class="sref">ssize_tp/a> pa href="+code=bfin_wdt_write" class="sref">bfin_wdt_writep/a>(structopa href="+code=file" class="sref">filep/a> *pa href="+code=file" class="sref">filep/a>, const char pa href="+code=__user" class="sref">__userp/a> *pa href="+code=data" class="sref">datap/a>, o198p/a>                                                pa href="+code=size_t" class="sref">size_tp/a> pa href="+code=len" class="sref">lenp/a>, pa href="+code=loff_t" class="sref">loff_tp/a> *pa href="+code=ppos" class="sref">pposp/a>) o199p/a>{ o200p/a>        pa href="+code=stampit" class="sref">stampitp/a>(); o201p/a> o202p/a>        if (pa href="+code=len" class="sref">lenp/a>) { o203p/a>                if (!pa href="+code=nowayout" class="sref">nowayoutp/a>) { o204p/a>                        pa href="+code=size_t" class="sref">size_tp/a> pa href="+code=i" class="sref">ip/a>; o205p/a> o206p/a>                        pspa
 class="comment">/* I
 case it was set long ago */p/spa
  o207p/a>                        pa href="+code=expect_close" class="sref">expect_closep/a> = 0; o208p/a> o209p/a>                        for (pa href="+code=i" class="sref">ip/a> = 0; pa href="+code=i" class="sref">ip/a>o!=opa href="+code=len" class="sref">lenp/a>; pa href="+code=i" class="sref">ip/a>++) { o210p/a>                                char pa href="+code=c" class="sref">cp/a>; o211p/a>                                if (pa href="+code=get_user" class="sref">get_userp/a>(pa href="+code=c" class="sref">cp/a>, pa href="+code=data" class="sref">datap/a> + pa href="+code=i" class="sref">ip/a>)) o212p/a>                                        return -pa href="+code=EFAULT" class="sref">EFAULTp/a>; o213p/a>                                if (pa href="+code=c" class="sref">cp/a> == pspa
 class="string">'V'p/spa
 ) o214p/a>                                        pa href="+code=expect_close" class="sref">expect_closep/a> = 42; o215p/a>                        } o216p/a>                } o217p/a>                pa href="+code=bfin_wdt_keepalive" class="sref">bfin_wdt_keepalivep/a>(); o218p/a>        } o219p/a> o220p/a>        return pa href="+code=len" class="sref">lenp/a>; o221p/a>} o222p/a> o223p/a>pspa
 class="comment">/**p/spa
  o224p/a>pspa
 class="comment"> *      bfin_wdt_ioctl - Query Devicep/spa
  o225p/a>pspa
 class="comment"> *      @file: file handle of devicep/spa
  o226p/a>pspa
 class="comment"> *      @cmd: watchdog commandp/spa
  o227p/a>pspa
 class="comment"> *      @arg: argumentp/spa
  o228p/a>pspa
 class="comment"> *p/spa
  o229p/a>pspa
 class="comment"> *      Query basic information from the device or ping it, as outlined by thep/spa
  o23/opa>pspa
 class="comment"> *      watchdog API.p/spa
  o231p/a>pspa
 class="comment"> */p/spa
  o232p/a>static long pa href="+code=bfin_wdt_ioctl" class="sref">bfin_wdt_ioctlp/a>(structopa href="+code=file" class="sref">filep/a> *pa href="+code=file" class="sref">filep/a>, o233p/a>                                unsigned intopa href="+code=cmd" class="sref">cmdp/a>, unsigned long pa href="+code=arg" class="sref">argp/a>) o234p/a>{ o235p/a>        void pa href="+code=__user" class="sref">__userp/a> *pa href="+code=argp" class="sref">argpp/a> = (void pa href="+code=__user" class="sref">__userp/a> *)pa href="+code=arg" class="sref">argp/a>; o236p/a>        intopa href="+code=__user" class="sref">__userp/a> *pa href="+code=p" class="sref">pp/a> = pa href="+code=argp" class="sref">argpp/a>; o237p/a> o238p/a>        pa href="+code=stampit" class="sref">stampitp/a>(); o239p/a> o240p/a>        switch (pa href="+code=cmd" class="sref">cmdp/a>) { o241p/a>        case pa href="+code=WDIOC_GETSUPPORT" class="sref">WDIOC_GETSUPPORTp/a>: o242p/a>                if (pa href="+code=copy_to_user" class="sref">copy_to_userp/a>(pa href="+code=argp" class="sref">argpp/a>, &pa href="+code=bfin_wdt_info" class="sref">bfin_wdt_infop/a>, sizeof(pa href="+code=bfin_wdt_info" class="sref">bfin_wdt_infop/a>))) o243p/a>                        return -pa href="+code=EFAULT" class="sref">EFAULTp/a>; o244p/a>                else o245p/a>                        return 0; o246p/a>        case pa href="+code=WDIOC_GETSTATUS" class="sref">WDIOC_GETSTATUSp/a>: o247p/a>        case pa href="+code=WDIOC_GETBOOTSTATUS" class="sref">WDIOC_GETBOOTSTATUSp/a>: o248p/a>                return pa href="+code=put_user" class="sref">put_userp/a>(!!(pa href="+code=_bfin_swrst" class="sref">_bfin_swrstp/a> &opa href="+code=SWRST_RESET_WDOG" class="sref">SWRST_RESET_WDOGp/a>), pa href="+code=p" class="sref">pp/a>); o249p/a>        case pa href="+code=WDIOC_SETOPTIONS" class="sref">WDIOC_SETOPTIONSp/a>: { o250p/a>                unsigned long pa href="+code=flags" class="sref">flagsp/a>; o2a                     intopa href="+code=options" class="sref">optionsp/a>, pa href="+code=ret" class="sref">retp/a> =o-pa href="+code=EINVAL" class="sref">EINVALp/a>; o252p/a> o253p/a>                if (pa href="+code=get_user" class="sref">get_userp/a>(pa href="+code=options" class="sref">optionsp/a>, pa href="+code=p" class="sref">pp/a>)) o254p/a>                        return -pa href="+code=EFAULT" class="sref">EFAULTp/a>; o255p/a> o256p/a>                pa href="+code=spin_lock_irqsave" class="sref">spin_lock_irqsavep/a>(&pa href="+code=bfin_wdt_spinlock" class="sref">bfin_wdt_spinlockp/a>,opa href="+code=flags" class="sref">flagsp/a>); o257p/a>                if (pa href="+code=options" class="sref">optionsp/a>o&opa href="+code=WDIOS_DISABLECARD" class="sref">WDIOS_DISABLECARDp/a>) { o258p/a>                        pa href="+code=bfin_wdt_stop" class="sref">bfin_wdt_stopp/a>(); o259p/a>                        pa href="+code=ret" class="sref">retp/a> =o0; o260p/a>                } o26                     if (pa href="+code=options" class="sref">optionsp/a>o&opa href="+code=WDIOS_ENABLECARD" class="sref">WDIOS_ENABLECARDp/a>) { o262p/a>                        pa href="+code=bfin_wdt_start" class="sref">bfin_wdt_startp/a>(); o263p/a>                        pa href="+code=ret" class="sref">retp/a> =o0; o264p/a>                } o265p/a>                pa href="+code=spin_unlock_irqrestore" class="sref">spin_unlock_irqrestorep/a>(&pa href="+code=bfin_wdt_spinlock" class="sref">bfin_wdt_spinlockp/a>,opa href="+code=flags" class="sref">flagsp/a>); o266p/a>                return pa href="+code=ret" class="sref">retp/a>; o267p/a>        } o268p/a>        case pa href="+code=WDIOC_KEEPALIVE" class="sref">WDIOC_KEEPALIVEp/a>: o269p/a>                pa href="+code=bfin_wdt_keepalive" class="sref">bfin_wdt_keepalivep/a>(); o270p/a>                return 0; o271p/a>        case pa href="+code=WDIOC_SETTIMEOUT" class="sref">WDIOC_SETTIMEOUTp/a>: { o272p/a>                intopa href="+code=new_timeout" class="sref">new_timeoutp/a>; o273p/a> o274p/a>                if (pa href="+code=get_user" class="sref">get_userp/a>(pa href="+code=new_timeout" class="sref">new_timeoutp/a>, pa href="+code=p" class="sref">pp/a>)) o275p/a>                        return -pa href="+code=EFAULT" class="sref">EFAULTp/a>; o276p/a>                if (pa href="+code=bfin_wdt_set_timeout" class="sref">bfin_wdt_set_timeoutp/a>(pa href="+code=new_timeout" class="sref">new_timeoutp/a>)) o277p/a>                        return -pa href="+code=EINVAL" class="sref">EINVALp/a>; o278p/a>        } o279p/a>        pspa
 class="comment">/* Fall */p/spa
  o280p/a>        case pa href="+code=WDIOC_GETTIMEOUT" class="sref">WDIOC_GETTIMEOUTp/a>: o281p/a>                return pa href="+code=put_user" class="sref">put_userp/a>(pa href="+code=timeout" class="sref">timeoutp/a>, pa href="+code=p" class="sref">pp/a>); o282p/a>        default: o283p/a>                return -pa href="+code=ENOTTY" class="sref">ENOTTYp/a>; o284p/a>        } o285p/a>} o286p/a> o287p/a>#ifdef pa href="+code=CONFIG_PM" class="sref">CONFIG_PMp/a> o288p/a>static intopa href="+code=state_before_suspend" class="sref">state_before_suspendp/a>; o289p/a> o29/opa>pspa
 class="comment">/**p/spa
  o291p/a>pspa
 class="comment"> *      bfin_wdt_suspend - suspend the watchdogp/spa
  o292p/a>pspa
 class="comment"> *      @pdev: device being suspendedp/spa
  o293p/a>pspa
 class="comment"> *      @state: requested suspend statep/spa
  o294p/a>pspa
 class="comment"> *p/spa
  o295p/a>pspa
 class="comment"> *      Remember if the watchdog was running and stop it.p/spa
  o296p/a>pspa
 class="comment"> *      TODO: is this even right?  Doesn't seem to be anyp/spa
  o297p/a>pspa
 class="comment"> *            standard in the watchdog world ...p/spa
  o298p/a>pspa
 class="comment"> */p/spa
  o299p/a>static intopa href="+code=bfin_wdt_suspend" class="sref">bfin_wdt_suspendp/a>(structopa href="+code=platform_device" class="sref">platform_devicep/a> *pa href="+code=pdev" class="sref">pdevp/a>, pa href="+code=pm_message_t" class="sref">pm_message_tp/a> pa href="+code=state" class="sref">statep/a>) o300p/a>{ o301p/a>        pa href="+code=stampit" class="sref">stampitp/a>(); o302p/a> o303p/a>        pa href="+code=state_before_suspend" class="sref">state_before_suspendp/a> =opa href="+code=bfin_wdt_running" class="sref">bfin_wdt_runningp/a>(); o304p/a>        pa href="+code=bfin_wdt_stop" class="sref">bfin_wdt_stopp/a>(); o305p/a> o306p/a>        return 0; o307p/a>} o308p/a> o309p/a>pspa
 class="comment">/**p/spa
  o3pspa
 class="comment"> *      bfin_wdt_resume - resume the watchdogp/spa
  o311p/a>pspa
 class="comment"> *      @pdev: device being resumedp/spa
  o312p/a>pspa
 class="comment"> *p/spa
  o313p/a>pspa
 class="comment"> *      If the watchdog was running, turn it back on.p/spa
  o314p/a>pspa
 class="comment"> */p/spa
  o315p/a>static intopa href="+code=bfin_wdt_resume" class="sref">bfin_wdt_resumep/a>(structopa href="+code=platform_device" class="sref">platform_devicep/a> *pa href="+code=pdev" class="sref">pdevp/a>) o316p/a>{ o317p/a>        pa href="+code=stampit" class="sref">stampitp/a>(); o318p/a> o319p/a>        if (pa href="+code=state_before_suspend" class="sref">state_before_suspendp/a>) { o320p/a>                pa href="+code=bfin_wdt_set_timeout" class="sref">bfin_wdt_set_timeoutp/a>(pa href="+code=timeout" class="sref">timeoutp/a>); o321p/a>                pa href="+code=bfin_wdt_start" class="sref">bfin_wdt_startp/a>(); o322p/a>        } o323p/a> o324p/a>        return 0; o325p/a>} o326p/a>#else o327p/a># defineopa href="+code=bfin_wdt_suspend" class="sref">bfin_wdt_suspendp/a>opa href="+code=NULL" class="sref">NULLp/a> o328p/a># defineopa href="+code=bfin_wdt_resume" class="sref">bfin_wdt_resumep/a>opa href="+code=NULL" class="sref">NULLp/a> o329p/a>#endif o33/opa> o331p/a>static const structopa href="+code=file_operations" class="sref">file_operationsp/a>opa href="+code=bfin_wdt_fops" class="sref">bfin_wdt_fopsp/a> =o{ o332p/a>        .pa href="+code=owner" class="sref">ownerp/a>          =opa href="+code=THIS_MODULE" class="sref">THIS_MODULEp/a>, o333p/a>        .pa href="+code=llseek" class="sref">llseekp/a>         =opa href="+code=no_llseek" class="sref">no_llseekp/a>, o334p/a>        .pa href="+code=write" class="sref">writep/a>          =opa href="+code=bfin_wdt_write" class="sref">bfin_wdt_writep/a>, o335p/a>        .pa href="+code=unlocked_ioctl" class="sref">unlocked_ioctlp/a> =opa href="+code=bfin_wdt_ioctl" class="sref">bfin_wdt_ioctlp/a>, o336p/a>        .pa href="+code=open" class="sref">openp/a>           =opa href="+code=bfin_wdt_open" class="sref">bfin_wdt_openp/a>, o337p/a>        .pa href="+code=release" class="sref">releasep/a>        =opa href="+code=bfin_wdt_release" class="sref">bfin_wdt_releasep/a>, o338p/a>}; o339p/a> o340p/a>static structopa href="+code=miscdevice" class="sref">miscdevicep/a>opa href="+code=bfin_wdt_miscdev" class="sref">bfin_wdt_miscdevp/a> =o{ o341p/a>        .pa href="+code=minor" class="sref">minorp/a>    =opa href="+code=WATCHDOG_MINOR" class="sref">WATCHDOG_MINORp/a>, o342p/a>        .pa href="+code=nam"" class="sref">namep/a>     = pspa
 class="string">"watchdog"p/spa
 , o343p/a>        .pa href="+code=fops" class="sref">fopsp/a>     = &pa href="+code=bfin_wdt_fops" class="sref">bfin_wdt_fopsp/a>, o344p/a>}; o345p/a> o346p/a>static const structopa href="+code=watchdog_info" class="sref">watchdog_infop/a>opa href="+code=bfin_wdt_info" class="sref">bfin_wdt_infop/a> =o{ o347p/a>        .pa href="+code=identity" class="sref">identityp/a> =opspa
 class="string">"Blackfin Watchdog"p/spa
 , o348p/a>        .pa href="+code=options" class="sref">optionsp/a>o =opa href="+code=WDIOF_SETTIMEOUT" class="sref">WDIOF_SETTIMEOUTp/a> | o349p/a>                    pa href="+code=WDIOF_KEEPALIVEPING" class="sref">WDIOF_KEEPALIVEPINGp/a> | o350p/a>                    pa href="+code=WDIOF_MAGICCLOSE" class="sref">WDIOF_MAGICCLOSEp/a>, o3a     }; o352p/a> o353p/a>pspa
 class="comment">/**p/spa
  o354p/a>pspa
 class="comment"> *      bfin_wdt_probe - Initialize modulep/spa
  o355p/a>pspa
 class="comment"> *p/spa
  o356p/a>pspa
 class="comment"> *      Registers the misc device.  Actual devicep/spa
  o357p/a>pspa
 class="comment"> *      initialization is handled by bfin_wdt_open().p/spa
  o358p/a>pspa
 class="comment"> */p/spa
  o359p/a>static intopa href="+code=bfin_wdt_probe" class="sref">bfin_wdt_probep/a>(structopa href="+code=platform_device" class="sref">platform_devicep/a> *pa href="+code=pdev" class="sref">pdevp/a>) o360p/a>{ o36             intopa href="+code=ret" class="sref">retp/a>; o362p/a> o363p/a>        pa href="+code=ret" class="sref">retp/a> =opa href="+code=misc_register" class="sref">misc_registerp/a>(&pa href="+code=bfin_wdt_miscdev" class="sref">bfin_wdt_miscdevp/a>); o364p/a>        if (pa href="+code=ret" class="sref">retp/a>) { o365p/a>                pa href="+code=pr_err" class="sref">pr_errp/a>(pspa
 class="string">"cannot register miscdev on minor=%d (err=%d)\n"p/spa
 , o366p/a>                       pa href="+code=WATCHDOG_MINOR" class="sref">WATCHDOG_MINORp/a>, pa href="+code=ret" class="sref">retp/a>); o367p/a>                return pa href="+code=ret" class="sref">retp/a>; o368p/a>        } o369p/a> o370p/a>        pa href="+code=pr_info" class="sref">pr_infop/a>(pspa
 class="string">"initialized: timeout=%d sec (nowayout=%d)\n"p/spa
 , o371p/a>                pa href="+code=timeout" class="sref">timeoutp/a>, pa href="+code=nowayout" class="sref">nowayoutp/a>); o372p/a> o373p/a>        return 0; o374p/a>} o375p/a> o376p/a>pspa
 class="comment">/**p/spa
  o377p/a>pspa
 class="comment"> *      bfin_wdt_remove - Initialize modulep/spa
  o378p/a>pspa
 class="comment"> *p/spa
  o379p/a>pspa
 class="comment"> *      Unregisters the misc device.  Actual devicep/spa
  o38/opa>pspa
 class="comment"> *      deinitialization is handled by bfin_wdt_close().p/spa
  o381p/a>pspa
 class="comment"> */p/spa
  o382p/a>static intopa href="+code=bfin_wdt_remove" class="sref">bfin_wdt_removep/a>(structopa href="+code=platform_device" class="sref">platform_devicep/a> *pa href="+code=pdev" class="sref">pdevp/a>) o383p/a>{ o384p/a>        pa href="+code=misc_deregister" class="sref">misc_deregisterp/a>(&pa href="+code=bfin_wdt_miscdev" class="sref">bfin_wdt_miscdevp/a>); o385p/a>        return 0; o386p/a>} o387p/a> o388p/a>pspa
 class="comment">/**p/spa
  o389p/a>pspa
 class="comment"> *      bfin_wdt_shutdown - Soft Shutdown Handlerp/spa
  o39/opa>pspa
 class="comment"> *p/spa
  o391p/a>pspa
 class="comment"> *      Handles the soft shutdown event.p/spa
  o392p/a>pspa
 class="comment"> */p/spa
  o393p/a>static void pa href="+code=bfin_wdt_shutdown" class="sref">bfin_wdt_shutdownp/a>(structopa href="+code=platform_device" class="sref">platform_devicep/a> *pa href="+code=pdev" class="sref">pdevp/a>) o394p/a>{ o395p/a>        pa href="+code=stampit" class="sref">stampitp/a>(); o396p/a> o397p/a>        pa href="+code=bfin_wdt_stop" class="sref">bfin_wdt_stopp/a>(); o398p/a>} o399p/a> o400p/a>static structopa href="+code=platform_device" class="sref">platform_devicep/a> *pa href="+code=bfin_wdt_device" class="sref">bfin_wdt_devicep/a>; o401p/a> o402p/a>static structopa href="+code=platform_driver" class="sref">platform_driverp/a>opa href="+code=bfin_wdt_driver" class="sref">bfin_wdt_driverp/a> =o{ o403p/a>        .pa href="+code=probe" class="sref">probep/a>     =opa href="+code=bfin_wdt_probe" class="sref">bfin_wdt_probep/a>, o404p/a>        .pa href="+code=remove" class="sref">removep/a>    =opa href="+code=bfin_wdt_remove" class="sref">bfin_wdt_removep/a>, o405p/a>        .pa href="+code=shutdown" class="sref">shutdownp/a>  =opa href="+code=bfin_wdt_shutdown" class="sref">bfin_wdt_shutdownp/a>, o406p/a>        .pa href="+code=suspend" class="sref">suspendp/a>o  =opa href="+code=bfin_wdt_suspend" class="sref">bfin_wdt_suspendp/a>, o407p/a>        .pa href="+code=resume" class="sref">resumep/a>o   =opa href="+code=bfin_wdt_resume" class="sref">bfin_wdt_resumep/a>, o408p/a>        .pa href="+code=driver" class="sref">driverp/a>    =o{ o409p/a>                .pa href="+code=nam"" class="sref">namep/a>  =opa href="+code=WATCHDOG_NAME" class="sref">WATCHDOG_NAMEp/a>, o410p/a>                .pa href="+code=owner" class="sref">ownerp/a> =opa href="+code=THIS_MODULE" class="sref">THIS_MODULEp/a>, o411p/a>        }, o412p/a>}; o413p/a> o414p/a>pspa
 class="comment">/**p/spa
  o415p/a>pspa
 class="comment"> *      bfin_wdt_init - Initialize modulep/spa
  o416p/a>pspa
 class="comment"> *p/spa
  o417p/a>pspa
 class="comment"> *      Checks the module params and registers the platform device &odriver.p/spa
  o418p/a>pspa
 class="comment"> *      Real work is in the platform probe function.p/spa
  o419p/a>pspa
 class="comment"> */p/spa
  o420p/a>static intopa href="+code=__init" class="sref">__initp/a>opa href="+code=bfin_wdt_init" class="sref">bfin_wdt_initp/a>(void) o421p/a>{ o422p/a>        intopa href="+code=ret" class="sref">retp/a>; o423p/a> o424p/a>        pa href="+code=stampit" class="sref">stampitp/a>(); o425p/a> o426p/a>        pspa
 class="comment">/* Check that the timeout value is within range */p/spa
  o427p/a>        if (pa href="+code=bfin_wdt_set_timeout" class="sref">bfin_wdt_set_timeoutp/a>(pa href="+code=timeout" class="sref">timeoutp/a>)) o428p/a>                return -pa href="+code=EINVAL" class="sref">EINVALp/a>; o429p/a> o430p/a>        pspa
 class="comment">/* Since this is an on-chip device and needs no board-specificp/spa
  o431p/a>pspa
 class="comment">         * resources, we'll handle all the platform device stuff here.p/spa
  o432p/a>pspa
 class="comment">         */p/spa
  o433p/a>        pa href="+code=ret" class="sref">retp/a> =opa href="+code=platform_driver_register" class="sref">platform_driver_registerp/a>(&pa href="+code=bfin_wdt_driver" class="sref">bfin_wdt_driverp/a>); o434p/a>        if (pa href="+code=ret" class="sref">retp/a>) { o435p/a>                pa href="+code=pr_err" class="sref">pr_errp/a>(pspa
 class="string">"unable to register driver\n"p/spa
 ); o436p/a>                return pa href="+code=ret" class="sref">retp/a>; o437p/a>        } o438p/a> o439p/a>        pa href="+code=bfin_wdt_device" class="sref">bfin_wdt_devicep/a> =opa href="+code=platform_device_register_simple" class="sref">platform_device_register_simplep/a>(pa href="+code=WATCHDOG_NAME" class="sref">WATCHDOG_NAMEp/a>, o440p/a>                                                                -1, pa href="+code=NULL" class="sref">NULLp/a>, 0); o441p/a>        if (pa href="+code=IS_ERR" class="sref">IS_ERRp/a>(pa href="+code=bfin_wdt_device" class="sref">bfin_wdt_devicep/a>)) { o442p/a>                pa href="+code=pr_err" class="sref">pr_errp/a>(pspa
 class="string">"unable to register device\n"p/spa
 ); o443p/a>                pa href="+code=platform_driver_unregister" class="sref">platform_driver_unregisterp/a>(&pa href="+code=bfin_wdt_driver" class="sref">bfin_wdt_driverp/a>); o444p/a>                return pa href="+code=PTR_ERR" class="sref">PTR_ERRp/a>(pa href="+code=bfin_wdt_device" class="sref">bfin_wdt_devicep/a>); o445p/a>        } o446p/a> o447p/a>        return 0; o448p/a>} o449p/a> o45/opa>pspa
 class="comment">/**p/spa
  o451p/a>pspa
 class="comment"> *      bfin_wdt_exit - Deinitialize modulep/spa
  o452p/a>pspa
 class="comment"> *p/spa
  o453p/a>pspa
 class="comment"> *      Back out the platform device &odriver steps.  Real work is in thep/spa
  o454p/a>pspa
 class="comment"> *      platform remove function.p/spa
  o455p/a>pspa
 class="comment"> */p/spa
  o456p/a>static void pa href="+code=__exit" class="sref">__exitp/a>opa href="+code=bfin_wdt_exit" class="sref">bfin_wdt_exitp/a>(void) o457p/a>{ o458p/a>        pa href="+code=platform_device_unregister" class="sref">platform_device_unregisterp/a>(pa href="+code=bfin_wdt_device" class="sref">bfin_wdt_devicep/a>); o459p/a>        pa href="+code=platform_driver_unregister" class="sref">platform_driver_unregisterp/a>(&pa href="+code=bfin_wdt_driver" class="sref">bfin_wdt_driverp/a>); o460p/a>} o461p/a> o462p/a>pa href="+code=module_init" class="sref">module_initp/a>(pa href="+code=bfin_wdt_init" class="sref">bfin_wdt_initp/a>); o463p/a>pa href="+code=module_exit" class="sref">module_exitp/a>(pa href="+code=bfin_wdt_exit" class="sref">bfin_wdt_exitp/a>); o464p/a> o465p/a>pa href="+code=MODULE_AUTHOR" class="sref">MODULE_AUTHORp/a>(pspa
 class="string">"Michele d'Amico, Mike Frysinger <vapier@gentoo.org>"p/spa
 ); o466p/a>pa href="+code=MODULE_DESCRIPTION" class="sref">MODULE_DESCRIPTIONp/a>(pspa
 class="string">"Blackfin Watchdog Device Driver"p/spa
 ); o467p/a>pa href="+code=MODULE_LICENSE" class="sref">MODULE_LICENSEp/a>(pspa
 class="string">"GPL"p/spa
 ); o468p/a>pa href="+code=MODULE_ALIAS_MISCDEV" class="sref">MODULE_ALIAS_MISCDEVp/a>(pa href="+code=WATCHDOG_MINOR" class="sref">WATCHDOG_MINORp/a>); o469p/a> o470p/a>pa href="+code=module_param" class="sref">module_paramp/a>(pa href="+code=timeout" class="sref">timeoutp/a>, pa href="+code=uint" class="sref">uintp/a>, 0); o471p/a>pa href="+code=MODULE_PARM_DESC" class="sref">MODULE_PARM_DESCp/a>(pa href="+code=timeout" class="sref">timeoutp/a>, o472p/a>        pspa
 class="string">"Watchdog timeout in seconds. (1<=timeout<=((2^32)/SCLK), default="p/spa
  o473p/a>                pa href="+code=__MODULE_STRING" class="sref">__MODULE_STRINGp/a>(pa href="+code=WATCHDOG_TIMEOUT" class="sref">WATCHDOG_TIMEOUTp/a>) pspa
 class="string">")"p/spa
 ); o474p/a> o475p/a>pa href="+code=module_param" class="sref">module_paramp/a>(pa href="+code=nowayout" class="sref">nowayoutp/a>, pa href="+code=bool" class="sref">boolp/a>, 0); o476p/a>pa href="+code=MODULE_PARM_DESC" class="sref">MODULE_PARM_DESCp/a>(pa href="+code=nowayout" class="sref">nowayoutp/a>, o477p/a>        pspa
 class="string">"Watchdog cannot be stopped once started (default="p/spa
  o478p/a>                pa href="+code=__MODULE_STRING" class="sref">__MODULE_STRINGp/a>(pa href="+code=WATCHDOG_NOWAYOUT" class="sref">WATCHDOG_NOWAYOUTp/a>) pspa
 class="string">")"p/spa
 ); o479p/a>p/pre>p/div>


p/div>