linux/Documentation/hwspinlock.txt
<<
tion3.1/spa > 3.1/form> 3.1a tion3. href="../linux+v3.9.1/Documenta /hwspinlock.txt">tion3.1img src="../.sta c/gfx/right.png" alt=">>">ti1/spa > ti1spa class="lxr_search">tiontion3.1input typn> hidden" namn> navtarget" ption> ">tion3.1input typn> text" namn> search" id> search">tion3.1butt submit">Search 3.1/form> 1/spa > ti1spa class="lxr_prefs"> 3.1a href="+prefs?return=Documenta /hwspinlock.txt"tion3. onclick="return ajax_prefs();">tion3.Prefs 3.1/a>ti1/spa > on3. .1/div> on3. .1form ac ="ajax+*" method="post" onsubmit="return false;">ti1input typn> hidden" namn> ajax_lookup" id> ajax_lookup" ption> ">ton3. .1/form> ton3. .1div class="headingbott
on3.
on3. 3. .1div id> search_results" class="search_results" 3> on3. .1/div> 1div id> content"> 1div id> file_contents">
9c/a7/a5d6cce9c5078a036e49bd25e75f1c3f907d_3/0">
L1" class="line" namn>
L1">. .11/a>Hardware Spinlock Framnwork

L2" class="line" namn>
L2">. .21/a>t
L3" class="line" namn>
L3">. .31/a>1. Introduc
	  t
L4" class="line" namn>
L4">. .41/a>t
L5" class="line" namn>
L5">. .51/a>Hardware spinlock modules provide hardware assistance for synchroniza
	  t
L6" class="line" namn>
L6">. .61/a>and mutual exclus2
L7" class="line" namn>
L7">. .71/a>under a s	ngle, shared opera
	ng system.t
L8" class="line" namn>
L8">. .81/a>t
L9" class="line" namn>
L9">. .91/a>For example, OMAP4 has dual Cortex-A9, dual Cortex-M3 and a C64x+ DSP,t
L10" class="line" namn>
L10">. 18.1a>each of which is runn	ng a different Opera
	ng System (the master, A9,t
L11" class="line" namn>
L11">. 111/a>is usually runn	ng Linux and the slave processors, the M3 and the DSP,t
L12" class="line" namn>
L12">. 121/a>are runn	ng some flavor of RTOS).t
L13" class="line" namn>
L13">. 131/a>t
L14" class="line" namn>
L14">. 141/a>A generic hwspinlock framnwork allows platform-independent drivers to uset
L15" class="line" namn>
L15">. 151/a>the hwspinlock device in order to access data struc
ures that are sharedt
L16" class="line" namn>
L16">. 161/a>between remote processors, that otherwise have no alterna
	ve mechanismt
L17" class="line" namn>
L17">. 171/a>to accomplish synchroniza
	   and mutual exclus2
L18" class="line" namn>
L18">. 181/a>t
L19" class="line" namn>
L19">. 191/a>This is necessary, for example, for Inter-processor communica
	ons:

L20" class="line" namn>
L20">. 28.1a>
L21" class="line" namn>
L21">. 211/a>remote M3 and/or C64x+ slave processors (by a  IPC subsystem called Syslink).t
L22" class="line" namn>
L22">. 221/a>t
L23" class="line" namn>
L23">. 231/a>To achieve fast message-based communica
	ons, a minimal kernel supportt
L24" class="line" namn>
L24">. 241/a>is needed to deliver messages arriv	ng from a remote processor to the

L25" class="line" namn>
L25">. 251/a>appropriate user process.t
L26" class="line" namn>
L26">. 261/a>t
L27" class="line" namn>
L27">. 271/a>This communica
	on is based on simple data struc
ures that is shared betweent
L28" class="line" namn>
L28">. 281/a>the remote processors, and access to it is synchronized us	ng the hwspinlockt
L29" class="line" namn>
L29">. 291/a>module (remote processor directly places new messages in this shared datat
L30" class="line" namn>
L30">. 38.1a>struc
ure).t
L31" class="line" namn>
L31">. 311/a>t
L32" class="line" namn>
L32">. 321/a>A common hwspinlock interface makes it possible to have generic, platform-t
L33" class="line" namn>
L33">. 331/a>independent, drivers.t
L34" class="line" namn>
L34">. 341/a>t
L35" class="line" namn>
L35">. 351/a>2. User APIt
L36" class="line" namn>
L36">. 361/a>t
L37" class="line" namn>
L37">. 371/a>  struc
 hwspinlock *hwspin_lock_request(void);t
L38" class="line" namn>
L38">. 381/a>   - dynamically assig  an hwspinlock and return its address, or NULLt
L39" class="line" namn>
L39">. 391/a>     in case an unused hwspinlock isn't available. Users of thist
L40" class="line" namn>
L40">. 401/a>     API will usually want to communica
e the lock's id to the remote core

L41" class="line" namn>
L41">. 411/a>     before it ca/obe used to achieve synchroniza
	  .t
L42" class="line" namn>
L42">. 421/a>     Should be called from a process context (might sleep).t
L43" class="line" namn>
L43">. 431/a>t
L44" class="line" namn>
L44">. 441/a>  struc
 hwspinlock *hwspin_lock_request_specific(unsig ed int id);t
L45" class="line" namn>
L45">. 451/a>   - assig  a specific hwspinlock id and return its address, or NULLt
L46" class="line" namn>
L46">. 461/a>     if that hwspinlock is already in use. Usually board code willt
L47" class="line" namn>
L47">. 471/a>     be call	ng this func
	on in order to reserve specific hwspinlockt
L48" class="line" namn>
L48">. 481/a>     ids for predefi ed purposes.t
L49" class="line" namn>
L49">. 491/a>     Should be called from a process context (might sleep).t
L50" class="line" namn>
L50">. 501/a>t
L51" class="line" namn>
L51">. 511/a>  int hwspin_lock_free(struc
 hwspinlock *hwlock);t
L52" class="line" namn>
L52">. 521/a>   - free a previously-assig ed hwspinlock; returns 0 on success, or ant
L53" class="line" namn>
L53">. 531/a>     appropriate error code on failure (e.g. -EINVAL if the hwspinlockt
L54" class="line" namn>
L54">. 541/a>     is already free).t
L55" class="line" namn>
L55">. 551/a>     Should be called from a process context (might sleep).t
L56" class="line" namn>
L56">. 561/a>t
L57" class="line" namn>
L57">. 571/a>  int hwspin_lock_timeout(struc
 hwspinlock *hwlock, unsig ed int timeout);t
L58" class="line" namn>
L58">. 581/a>   - lock a previously-assig ed hwspinlock with a timeout limit (specified int
L59" class="line" namn>
L59">. 591/a>     msecs). If the hwspinlock is already taken, the func
	on will busy loopt
L60" class="line" namn>
L60">. 601/a>     wai
	ng for it to be released, but g	ve up when the timeout elapses.t
L61" class="line" namn>
L61">. 611/a>     Upo  a successful return from this func
	on, preemp
	on is disabled sot
L62" class="line" namn>
L62">. 621/a>     the caller must not sleep, and is advised to release the hwspinlock ast
L63" class="line" namn>
L63">. 631/a>     soo  as possible, in order to minimize remote cores poll	ng on the

L64" class="line" namn>
L64">. 641/a>     hardware interconnect.t
L65" class="line" namn>
L65">. 651/a>     Returns 0 when successful and an appropriate error code otherwise (mostt
L66" class="line" namn>
L66">. 661/a>     notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs).t
L67" class="line" namn>
L67">. 671/a>     The func
	on will never sleep.t
L68" class="line" namn>
L68">. 681/a>t
L69" class="line" namn>
L69">. 691/a>  int hwspin_lock_timeout_irq(struc
 hwspinlock *hwlock, unsig ed int timeout);t
L70" class="line" namn>
L70">. 701/a>   - lock a previously-assig ed hwspinlock with a timeout limit (specified int
L71" class="line" namn>
L71">. 711/a>     msecs). If the hwspinlock is already taken, the func
	on will busy loopt
L72" class="line" namn>
L72">. 721/a>     wai
	ng for it to be released, but g	ve up when the timeout elapses.t
L73" class="line" namn>
L73">. 731/a>     Upo  a successful return from this func
	on, preemp
	on and the localt
L74" class="line" namn>
L74">. 741/a>     interrupts are disabled, so the caller must not sleep, and is advised tot
L75" class="line" namn>
L75">. 751/a>     release the hwspinlock as soo  as possible.t
L76" class="line" namn>
L76">. 761/a>     Returns 0 when successful and an appropriate error code otherwise (mostt
L77" class="line" namn>
L77">. 771/a>     notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs).t
L78" class="line" namn>
L78">. 781/a>     The func
	on will never sleep.t
L79" class="line" namn>
L79">. 791/a>t
L80" class="line" namn>
L80">. 801/a>  int hwspin_lock_timeout_irqsave(struc
 hwspinlock *hwlock, unsig ed int to,t
L81" class="line" namn>
L81">. 811/a>                                                        unsig ed long *flags);t
L82" class="line" namn>
L82">. 821/a>   - lock a previously-assig ed hwspinlock with a timeout limit (specified int
L83" class="line" namn>
L83">. 831/a>     msecs). If the hwspinlock is already taken, the func
	on will busy loopt
L84" class="line" namn>
L84">. 841/a>     wai
	ng for it to be released, but g	ve up when the timeout elapses.t
L85" class="line" namn>
L85">. 851/a>     Upo  a successful return from this func
	on, preemp
	on is disabled,t
L86" class="line" namn>
L86">. 861/a>     local interrupts are disabled and their previous sta
e is saved at the

L87" class="line" namn>
L87">. 871/a>     g	ven flags placeholder. The caller must not sleep, and is advised tot
L88" class="line" namn>
L88">. 881/a>     release the hwspinlock as soo  as possible.t
L89" class="line" namn>
L89">. 891/a>     Returns 0 when successful and an appropriate error code otherwise (mostt
L90" class="line" namn>
L90">. 901/a>     notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs).t
L91" class="line" namn>
L91">. 911/a>     The func
	on will never sleep.t
L92" class="line" namn>
L92">. 921/a>t
L93" class="line" namn>
L93">. 931/a>  int hwspin_trylock(struc
 hwspinlock *hwlock);t
L94" class="line" namn>
L94">. 941/a>   - attemp
 to lock a previously-assig ed hwspinlock, but immediately fail ift
L95" class="line" namn>
L95">. 951/a>     it is already taken.t
L96" class="line" namn>
L96">. 961/a>     Upo  a successful return from this func
	on, preemp
	on is disabled sot
L97" class="line" namn>
L97">. 971/a>     caller must not sleep, and is advised to release the hwspinlock as soo  ast
L98" class="line" namn>
L98">. 981/a>     possible, in order to minimize remote cores poll	ng on the hardwaret
L99" class="line" namn>
L99">. 991/a>     interconnect.t
L100" class="line" namn>
L100">.1001/a>     Returns 0 on success and an appropriate error code otherwise (mostt
L101" class="line" namn>
L101">.1011/a>     notably -EBUSY if the hwspinlock was already taken).t
L102" class="line" namn>
L102">.1021/a>     The func
	on will never sleep.t
L103" class="line" namn>
L103">.1031/a>t
L104" class="line" namn>
L104">.1041/a>  int hwspin_trylock_irq(struc
 hwspinlock *hwlock);t
L105" class="line" namn>
L105">.1051/a>   - attemp
 to lock a previously-assig ed hwspinlock, but immediately fail ift
L106" class="line" namn>
L106">.1061/a>     it is already taken.t
L107" class="line" namn>
L107">.1071/a>     Upo  a successful return from this func
	on, preemp
	on and the localt
L108" class="line" namn>
L108">.1081/a>     interrupts are disabled so caller must not sleep, and is advised tot
L109" class="line" namn>
L109">.1091/a>     release the hwspinlock as soo  as possible.t
L110" class="line" namn>
L110">.1101/a>     Returns 0 on success and an appropriate error code otherwise (mostt
L111" class="line" namn>
L111">.1111/a>     notably -EBUSY if the hwspinlock was already taken).t
L112" class="line" namn>
L112">.1121/a>     The func
	on will never sleep.t
L113" class="line" namn>
L113">.1131/a>t
L114" class="line" namn>
L114">.1141/a>  int hwspin_trylock_irqsave(struc
 hwspinlock *hwlock, unsig ed long *flags);t
L115" class="line" namn>
L115">.1151/a>   - attemp
 to lock a previously-assig ed hwspinlock, but immediately fail ift
L116" class="line" namn>
L116">.1161/a>     it is already taken.t
L117" class="line" namn>
L117">.1171/a>     Upo  a successful return from this func
	on, preemp
	on is disabled,t
L118" class="line" namn>
L118">.1181/a>     the local interrupts are disabled and their previous sta
e is savedt
L119" class="line" namn>
L119">.1191/a>     at the g	ven flags placeholder. The caller must not sleep, and is advisedt
L120" class="line" namn>
L120">.1201/a>     to release the hwspinlock as soo  as possible.t
L121" class="line" namn>
L121">.1211/a>     Returns 0 on success and an appropriate error code otherwise (mostt
L122" class="line" namn>
L122">.1221/a>     notably -EBUSY if the hwspinlock was already taken).t
L123" class="line" namn>
L123">.1231/a>     The func
	on will never sleep.t
L124" class="line" namn>
L124">.1241/a>t
L125" class="line" namn>
L125">.1251/a>  void hwspin_unlock(struc
 hwspinlock *hwlock);t
L126" class="line" namn>
L126">.1261/a>   - unlock a previously-locked hwspinlock. Always succeed, and ca/obe calledt
L127" class="line" namn>
L127">.1271/a>     from any context (the func
	on never sleeps). Note: code should _never_t
L128" class="line" namn>
L128">.1281/a>     unlock an hwspinlock which is already unlocked (there is no protec
	  t
L129" class="line" namn>
L129">.1291/a>     against this).t
L130" class="line" namn>
L130">.1301/a>t
L131" class="line" namn>
L131">.1311/a>  void hwspin_unlock_irq(struc
 hwspinlock *hwlock);t
L132" class="line" namn>
L132">.1321/a>   - unlock a previously-locked hwspinlock and enable local interrupts.t
L133" class="line" namn>
L133">.1331/a>     The caller should _never_ unlock an hwspinlock which is already unlocked.t
L134" class="line" namn>
L134">.1341/a>     Do	ng so is considered a bug (there is no protec
	   against this).t
L135" class="line" namn>
L135">.1351/a>     Upo  a successful return from this func
	on, preemp
	on and localt
L136" class="line" namn>
L136">.1361/a>     interrupts are enabled. This func
	on will never sleep.t
L137" class="line" namn>
L137">.1371/a>t
L138" class="line" namn>
L138">.1381/a>  voidt
L139" class="line" namn>
L139">.1391/a>  hwspin_unlock_irqrestore(struc
 hwspinlock *hwlock, unsig ed long *flags);t
L140" class="line" namn>
L140">.1401/a>   - unlock a previously-locked hwspinlock.t
L141" class="line" namn>
L141">.1411/a>     The caller should _never_ unlock an hwspinlock which is already unlocked.t
L142" class="line" namn>
L142">.1421/a>     Do	ng so is considered a bug (there is no protec
	   against this).t
L143" class="line" namn>
L143">.1431/a>     Upo  a successful return from this func
	on, preemp
	on is reenabled,t
L144" class="line" namn>
L144">.1441/a>     and the sta
e of the local interrupts is restored to the sta
e saved att
L145" class="line" namn>
L145">.1451/a>     the g	ven flags. This func
	on will never sleep.t
L146" class="line" namn>
L146">.1461/a>t
L147" class="line" namn>
L147">.1471/a>  int hwspin_lock_get_id(struc
 hwspinlock *hwlock);t
L148" class="line" namn>
L148">.1481/a>   - retrieve id number of a g	ven hwspinlock. This is needed when ant
L149" class="line" namn>
L149">.1491/a>     hwspinlock is dynamically assig ed: before it ca/obe used to achievet
L150" class="line" namn>
L150">.1501/a>     mutual exclus2
L151" class="line" namn>
L151">.1511/a>     to the remote taskowith which we want to synchronize.t
L152" class="line" namn>
L152">.1521/a>     Returns the hwspinlock id number, or -EINVAL if hwlock is null.t
L153" class="line" namn>
L153">.1531/a>t
L154" class="line" namn>
L154">.1541/a>3. Typical usaget
L155" class="line" namn>
L155">.1551/a>t
L156" class="line" namn>
L156">.1561/a>#include <linux/hwspinlock.h>t
L157" class="line" namn>
L157">.1571/a>#include <linux/err.h>t
L158" class="line" namn>
L158">.1581/a>t
L159" class="line" namn>
L159">.1591/a>int hwspinlock_example1(void)t
L160" class="line" namn>
L160">.1601/a>{t
L161" class="line" namn>
L161">.1611/a>        struc
 hwspinlock *hwlock;t
L162" class="line" namn>
L162">.1621/a>        int ret;t
L163" class="line" namn>
L163">.1631/a>t
L164" class="line" namn>
L164">.1641/a>        /* dynamically assig  a hwspinlock */t
L165" class="line" namn>
L165">.1651/a>        hwlock = hwspin_lock_request();t
L166" class="line" namn>
L166">.1661/a>        if (!hwlock)t
L167" class="line" namn>
L167">.1671/a>                ...t
L168" class="line" namn>
L168">.1681/a>t
L169" class="line" namn>
L169">.1691/a>        id = hwspin_lock_get_id(hwlock);t
L170" class="line" namn>
L170">.1701/a>        /* probably need to communica
e id to a remote processor now */t
L171" class="line" namn>
L171">.1711/a>t
L172" class="line" namn>
L172">.1721/a>        /* take the lock, spin for 1 sec if it's already taken */t
L173" class="line" namn>
L173">.1731/a>        ret = hwspin_lock_timeout(hwlock, 1000);t
L174" class="line" namn>
L174">.1741/a>        if (ret)t
L175" class="line" namn>
L175">.1751/a>                ...t
L176" class="line" namn>
L176">.1761/a>t
L177" class="line" namn>
L177">.1771/a>        /*t
L178" class="line" namn>
L178">.1781/a>         * we took the lock, do our thing now, but do NOT sleept
L179" class="line" namn>
L179">.1791/a>         */t
L180" class="line" namn>
L180">.1801/a>t
L181" class="line" namn>
L181">.1811/a>        /* release the lock */t
L182" class="line" namn>
L182">.1821/a>        hwspin_unlock(hwlock);t
L183" class="line" namn>
L183">.1831/a>t
L184" class="line" namn>
L184">.1841/a>        /* free the lock */t
L185" class="line" namn>
L185">.1851/a>        ret = hwspin_lock_free(hwlock);t
L186" class="line" namn>
L186">.1861/a>        if (ret)t
L187" class="line" namn>
L187">.1871/a>                ...t
L188" class="line" namn>
L188">.1881/a>t
L189" class="line" namn>
L189">.1891/a>        return ret;t
L190" class="line" namn>
L190">.1901/a>}t
L191" class="line" namn>
L191">.1911/a>t
L192" class="line" namn>
L192">.1921/a>int hwspinlock_example2(void)t
L193" class="line" namn>
L193">.1931/a>{t
L194" class="line" namn>
L194">.1941/a>        struc
 hwspinlock *hwlock;t
L195" class="line" namn>
L195">.1951/a>        int ret;t
L196" class="line" namn>
L196">.1961/a>t
L197" class="line" namn>
L197">.1971/a>        /*t
L198" class="line" namn>
L198">.1981/a>         * assig  a specific hwspinlock id - this should be called earlyt
L199" class="line" namn>
L199">.1991/a>         * by board init code.t
L200" class="line" namn>
L200">.2001/a>         */t
L201" class="line" namn>
L201">.2011/a>        hwlock = hwspin_lock_request_specific(PREDEFINED_LOCK_ID);t
L202" class="line" namn>
L202">.2021/a>        if (!hwlock)t
L203" class="line" namn>
L203">.2031/a>                ...t
L204" class="line" namn>
L204">.2041/a>t
L205" class="line" namn>
L205">.2051/a>        /* try to take it, but don't spin on it */t
L206" class="line" namn>
L206">.2061/a>        ret = hwspin_trylock(hwlock);t
L207" class="line" namn>
L207">.2071/a>        if (!ret) {t
L208" class="line" namn>
L208">.2081/a>                pr_info("lock is already taken\n");t
L209" class="line" namn>
L209">.2091/a>                return -EBUSY;t
L210" class="line" namn>
L210">.2101/a>        }t
L211" class="line" namn>
L211">.2111/a>t
L212" class="line" namn>
L212">.2121/a>        /*t
L213" class="line" namn>
L213">.2131/a>         * we took the lock, do our thing now, but do NOT sleept
L214" class="line" namn>
L214">.2141/a>         */t
L215" class="line" namn>
L215">.2151/a>t
L216" class="line" namn>
L216">.2161/a>        /* release the lock */t
L217" class="line" namn>
L217">.2171/a>        hwspin_unlock(hwlock);t
L218" class="line" namn>
L218">.2181/a>t
L219" class="line" namn>
L219">.2191/a>        /* free the lock */t
L220" class="line" namn>
L220">.2201/a>        ret = hwspin_lock_free(hwlock);t
L221" class="line" namn>
L221">.2211/a>        if (ret)t
L222" class="line" namn>
L222">.2221/a>                ...t
L223" class="line" namn>
L223">.2231/a>t
L224" class="line" namn>
L224">.2241/a>        return ret;t
L225" class="line" namn>
L225">.2251/a>}t
L226" class="line" namn>
L226">.2261/a>t
L227" class="line" namn>
L227">.2271/a>t
L228" class="line" namn>
L228">.2281/a>4. API for implementorst
L229" class="line" namn>
L229">.2291/a>t
L230" class="line" namn>
L230">.2301/a>  int hwspin_lock_register(struc
 hwspinlock_device *bank, struc
 device *dev,t
L231" class="line" namn>
L231">.2311/a>                const struc
 hwspinlock_ops *ops, int base_id, int num_locks);t
L232" class="line" namn>
L232">.2321/a>   - to be called from the underlying platform-specific implementa
	on, int
L233" class="line" namn>
L233">.2331/a>     order to register a new hwspinlock device (which is usually a bank oft
L234" class="line" namn>
L234">.2341/a>     numerous locks). Should be called from a process context (this func
	ont
L235" class="line" namn>
L235">.2351/a>     might sleep).t
L236" class="line" namn>
L236">.2361/a>     Returns 0 on success, or appropriate error code on failure.t
L237" class="line" namn>
L237">.2371/a>t
L238" class="line" namn>
L238">.2381/a>  int hwspin_lock_unregister(struc
 hwspinlock_device *bank);t
L239" class="line" namn>
L239">.2391/a>   - to be called from the underlying vendor-specific implementa
	on, in ordert
L240" class="line" namn>
L240">.2401/a>     to unregister an hwspinlock device (which is usually a bank of numeroust
L241" class="line" namn>
L241">.2411/a>     locks).t
L242" class="line" namn>
L242">.2421/a>     Should be called from a process context (this func
	on might sleep).t
L243" class="line" namn>
L243">.2431/a>     Returns the address of hwspinlock on success, or NULL on error (e.g.t
L244" class="line" namn>
L244">.2441/a>     if the hwspinlock is sill in use).t
L245" class="line" namn>
L245">.2451/a>t
L246" class="line" namn>
L246">.2461/a>5. Important struc
st
L247" class="line" namn>
L247">.2471/a>t
L248" class="line" namn>
L248">.2481/a>struc
 hwspinlock_device is a device which usually contains a bankt
L249" class="line" namn>
L249">.2491/a>of hardware locks. It is registered by the underlying hwspinlockt
L250" class="line" namn>
L250">.2501/a>implementa
	on us	ng the hwspin_lock_register() API.t
L251" class="line" namn>
L251">.2511/a>t
L252" class="line" namn>
L252">.2521/a>/**t
L253" class="line" namn>
L253">.2531/a> * struc
 hwspinlock_device - a device which usually spans numerous hwspinlockst
L254" class="line" namn>
L254">.2541/a> * @dev: underlying device, will be used to invoke runtime PM apit
L255" class="line" namn>
L255">.2551/a> * @ops: platform-specific hwspinlock handlerst
L256" class="line" namn>
L256">.2561/a> * @base_id: id index of the first lock in this devicet
L257" class="line" namn>
L257">.2571/a> * @num_locks: number of locks in this devicet
L258" class="line" namn>
L258">.2581/a> * @lock: dynamically alloca
ed array of 'struc
 hwspinlock't
L259" class="line" namn>
L259">.2591/a> */t
L260" class="line" namn>
L260">.2601/a>struc
 hwspinlock_device {t
L261" class="line" namn>
L261">.2611/a>        struc
 device *dev;t
L262" class="line" namn>
L262">.2621/a>        const struc
 hwspinlock_ops *ops;t
L263" class="line" namn>
L263">.2631/a>        int base_id;t
L264" class="line" namn>
L264">.2641/a>        int num_locks;t
L265" class="line" namn>
L265">.2651/a>        struc
 hwspinlock lock[0];t
L266" class="line" namn>
L266">.2661/a>};t
L267" class="line" namn>
L267">.2671/a>t
L268" class="line" namn>
L268">.2681/a>struc
 hwspinlock_device contains an array of hwspinlock struc
s, eacht
L269" class="line" namn>
L269">.2691/a>of which represents a s	ngle hardware lock:

L270" class="line" namn>
L270">.2701/a>t
L271" class="line" namn>
L271">.2711/a>/**t
L272" class="line" namn>
L272">.2721/a> * struc
 hwspinlock - this struc
 represents a s	ngle hwspinlock instancet
L273" class="line" namn>
L273">.2731/a> * @bank: the hwspinlock_device struc
ure which owns this lockt
L274" class="line" namn>
L274">.2741/a> * @lock: initialized and used by hwspinlock core

L275" class="line" namn>
L275">.2751/a> * @priv: private data, owned by the underlying platform-specific hwspinlock drv

L276" class="line" namn>
L276">.2761/a> */t
L277" class="line" namn>
L277">.2771/a>struc
 hwspinlock {t
L278" class="line" namn>
L278">.2781/a>        struc
 hwspinlock_device *bank;t
L279" class="line" namn>
L279">.2791/a>        spinlock_t lock;t
L280" class="line" namn>
L280">.2801/a>        void *priv;t
L281" class="line" namn>
L281">.2811/a>};t
L282" class="line" namn>
L282">.2821/a>t
L283" class="line" namn>
L283">.2831/a>When registering a bank of locks, the hwspinlock driver only needs tot
L284" class="line" namn>
L284">.2841/a>set the priv members of the locks. The rest of the members are set andt
L285" class="line" namn>
L285">.2851/a>initialized by the hwspinlock core itself.t
L286" class="line" namn>
L286">.2861/a>t
L287" class="line" namn>
L287">.2871/a>6. Implementa
	on callbackst
L288" class="line" namn>
L288">.2881/a>t
L289" class="line" namn>
L289">.2891/a>There are three possible callbacks defi ed in 'struc
 hwspinlock_ops':

L290" class="line" namn>
L290">.2901/a>t
L291" class="line" namn>
L291">.2911/a>struc
 hwspinlock_ops {t
L292" class="line" namn>
L292">.2921/a>        int (*trylock)(struc
 hwspinlock *lock);t
L293" class="line" namn>
L293">.2931/a>        void (*unlock)(struc
 hwspinlock *lock);t
L294" class="line" namn>
L294">.2941/a>        void (*relax)(struc
 hwspinlock *lock);t
L295" class="line" namn>
L295">.2951/a>};t
L296" class="line" namn>
L296">.2961/a>t
L297" class="line" namn>
L297">.2971/a>The first two callbacks are mandatory:

L298" class="line" namn>
L298">.2981/a>t
L299" class="line" namn>
L299">.2991/a>The ->trylock() callback should make a s	ngle attemp
 to take the lock, andt
L300" class="line" namn>
L300">.3001/a>return 0 on failure and 1 on success. This callback may _not_ sleep.t
L301" class="line" namn>
L301">.3011/a>t
L302" class="line" namn>
L302">.3021/a>The ->unlock() callback releases the lock. It always succeed, and it, too,t
L303" class="line" namn>
L303">.3031/a>may _not_ sleep.t
L304" class="line" namn>
L304">.3041/a>t
L305" class="line" namn>
L305">.3051/a>The ->relax() callback is op
	onal. It is called by hwspinlock core while

L306" class="line" namn>
L306">.3061/a>spinn	ng on a lock, and ca/obe used by the underlying implementa
	on to forcet
L307" class="line" namn>
L307">.3071/a>a delay between two success	ve invoca
	  s of ->trylock(). It may _not_ sleep.t
L308" class="line" namn>
L308">.3081/a>
lxr.linux.no kindly hosted by Redpill Linpro AS1/a>, provider of Linux consul ng and opera s services since 1995.