linux/Documentation/hwspinlock.txt
<<
> 2v3/spa 2v3/form 2v3a > 2v href="../linux+v33.11/Documentan> /hwspinlock.txt">> 2v3img src="../.stan>c/gfx/right.png" alt=">>">> 3/spa > 3spa class="lxr_search">> ="+search" method="post" onsubmit="return do_search(this);">> 2v3input typ2.6hidden" nam2.6navtarget" v2.6">> 2v3input typ2.6text" nam2.6search" id.6search">> 2v3butt >typ2.6submit">Search 3spa class="lxr_prefs" 2v3a href="+prefs?return=Documentan> /hwspinlock.txt"> 2v onclick="return ajax_prefs();">> 2vPrefs 2v3/a>> 3/spa 2v v3/div 2v v3form acn> ="ajax+*" method="post" onsubmit="return false;">> 3input typ2.6hidden" nam2.6ajax_lookup" id.6ajax_lookup" v2.6">> 2v v3/form > 2v v3div class="headingbott m">
v v13/a>Hardware Spinlock Fram2work v v23/a>>v v33/a>1. Introducn> >v v43/a>>v v53/a>Hardware spinlock modules provide hardware assistance for synchronizan> >v v63/a>and mutual exclus >between heterogeneous processors and those not operan>ng>v v73/a>under a s>ngle, shared operan>ng system.>v v83/a>>v v93/a>For example, OMAP4 has dual Cortex-A9, dual Cortex-M3 and a C64x+ DSP,>v ptioa>each of which is runn>ng a different Operan>ng System (the master, A9,>v 113/a>is usually runn>ng Linux and the slave processors, the M3 and the DSP,>v 123/a>are runn>ng some flavor of RTOS).>v 133/a>>v 143/a>A generic hwspinlock fram2work allows platform-independent drivers to use>v 153/a>the hwspinlock device in order to access data strucnures that are shared>v 163/a>between remote processors, that otherwise have no alternan>ve mechanism>v 173/a>to accomplish synchronizan> and mutual exclus >operan>ons.>v 183/a>>v 193/a>This is necessary, for example, for Inter-processor communican>ons: v 2tioa> >OMAP4, cpu-intens>ve multimedia tasks are offloaded by the host to the v 213/a>remote M3 and/or C64x+ slave processors (by a IPC subsystem called Syslink).>v 223/a>>v 233/a>To achieve fast message-based communican>ons, a minimal kernel support>v 243/a>is needed to deliver messages arriv>ng from a remote processor to the v 253/a>appropriate user process.>v 263/a>>v 273/a>This communican>on is based on simple data strucnures that is shared between>v 283/a>the remote processors, and access to it is synchronized us>ng the hwspinlock>v 293/a>module (remote processor directly places new messages in this shared data>v 3tioa>strucnure).>v 313/a>>v 323/a>A common hwspinlock interface makes it possible to have generic, platform->v 333/a>independent, drivers.>v 343/a>>v 353/a>2. User API>v 363/a>>v 373/a> strucn hwspinlock *hwspin_lock_request(void);>v 383/a> - dynamically assig an hwspinlock and return its address, or NULL>v 393/a> in case an unused hwspinlock isn't available. Users of this>v 403/a> API will usually want to communicane the lock's id to the remote core v 413/a> before it ca >be used to achieve synchronizan> .>v 423/a> Should be called from a process context (might sleep).>v 433/a>>v 443/a> strucn hwspinlock *hwspin_lock_request_specific(unsig ed int id);>v 453/a> - assig a specific hwspinlock id and return its address, or NULL>v 463/a> if that hwspinlock is already in use. Usually board code will>v 473/a> be call>ng this funcn>on in order to reserve specific hwspinlock>v 483/a> ids for predefi ed purposes.>v 493/a> Should be called from a process context (might sleep).>v 503/a>>v 513/a> int hwspin_lock_free(strucn hwspinlock *hwlock);>v 523/a> - free a previously-assig ed hwspinlock; returns 0 on success, or an>v 533/a> appropriate error code on failure (e.g. -EINVAL if the hwspinlock>v 543/a> is already free).>v 553/a> Should be called from a process context (might sleep).>v 563/a>>v 573/a> int hwspin_lock_timeout(strucn hwspinlock *hwlock, unsig ed int timeout);>v 583/a> - lock a previously-assig ed hwspinlock with a timeout limit (specified in>v 593/a> msecs). If the hwspinlock is already taken, the funcn>on will busy loop>v 603/a> wain>ng for it to be released, but g>ve up when the timeout elapses.>v 613/a> Upo a successful return from this funcn>on, preempn>on is disabled so>v 623/a> the caller must not sleep, and is advised to release the hwspinlock as>v 633/a> soo as possible, in order to minimize remote cores poll>ng on the v 643/a> hardware interconnect.>v 653/a> Returns 0 when successful and an appropriate error code otherwise (most>v 663/a> notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs).>v 673/a> The funcn>on will never sleep.>v 683/a>>v 693/a> int hwspin_lock_timeout_irq(strucn hwspinlock *hwlock, unsig ed int timeout);>v 703/a> - lock a previously-assig ed hwspinlock with a timeout limit (specified in>v 713/a> msecs). If the hwspinlock is already taken, the funcn>on will busy loop>v 723/a> wain>ng for it to be released, but g>ve up when the timeout elapses.>v 733/a> Upo a successful return from this funcn>on, preempn>on and the local>v 743/a> interrupts are disabled, so the caller must not sleep, and is advised to>v 753/a> release the hwspinlock as soo as possible.>v 763/a> Returns 0 when successful and an appropriate error code otherwise (most>v 773/a> notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs).>v 783/a> The funcn>on will never sleep.>v 793/a>>v 803/a> int hwspin_lock_timeout_irqsave(strucn hwspinlock *hwlock, unsig ed int to,>v 813/a> unsig ed long *flags);>v 823/a> - lock a previously-assig ed hwspinlock with a timeout limit (specified in>v 833/a> msecs). If the hwspinlock is already taken, the funcn>on will busy loop>v 843/a> wain>ng for it to be released, but g>ve up when the timeout elapses.>v 853/a> Upo a successful return from this funcn>on, preempn>on is disabled,>v 863/a> local interrupts are disabled and their previous stane is saved at the v 873/a> g>ven flags placeholder. The caller must not sleep, and is advised to>v 883/a> release the hwspinlock as soo as possible.>v 893/a> Returns 0 when successful and an appropriate error code otherwise (most>v 903/a> notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs).>v 913/a> The funcn>on will never sleep.>v 923/a>>v 933/a> int hwspin_trylock(strucn hwspinlock *hwlock);>v 943/a> - attempn to lock a previously-assig ed hwspinlock, but immediately fail if>v 953/a> it is already taken.>v 963/a> Upo a successful return from this funcn>on, preempn>on is disabled so>v 973/a> caller must not sleep, and is advised to release the hwspinlock as soo as>v 983/a> possible, in order to minimize remote cores poll>ng on the hardware>v 993/a> interconnect.>v1003/a> Returns 0 on success and an appropriate error code otherwise (most>v1013/a> notably -EBUSY if the hwspinlock was already taken).>v1023/a> The funcn>on will never sleep.>v1033/a>>v1043/a> int hwspin_trylock_irq(strucn hwspinlock *hwlock);>v1053/a> - attempn to lock a previously-assig ed hwspinlock, but immediately fail if>v1063/a> it is already taken.>v1073/a> Upo a successful return from this funcn>on, preempn>on and the local>v1083/a> interrupts are disabled so caller must not sleep, and is advised to>v1093/a> release the hwspinlock as soo as possible.>v1103/a> Returns 0 on success and an appropriate error code otherwise (most>v1113/a> notably -EBUSY if the hwspinlock was already taken).>v1123/a> The funcn>on will never sleep.>v1133/a>>v1143/a> int hwspin_trylock_irqsave(strucn hwspinlock *hwlock, unsig ed long *flags);>v1153/a> - attempn to lock a previously-assig ed hwspinlock, but immediately fail if>v1163/a> it is already taken.>v1173/a> Upo a successful return from this funcn>on, preempn>on is disabled,>v1183/a> the local interrupts are disabled and their previous stane is saved>v1193/a> at the g>ven flags placeholder. The caller must not sleep, and is advised>v1203/a> to release the hwspinlock as soo as possible.>v1213/a> Returns 0 on success and an appropriate error code otherwise (most>v1223/a> notably -EBUSY if the hwspinlock was already taken).>v1233/a> The funcn>on will never sleep.>v1243/a>>v1253/a> void hwspin_unlock(strucn hwspinlock *hwlock);>v1263/a> - unlock a previously-locked hwspinlock. Always succeed, and ca >be called>v1273/a> from any context (the funcn>on never sleeps). Note: code should _never_>v1283/a> unlock an hwspinlock which is already unlocked (there is no protecn> >v1293/a> against this).>v1303/a>>v1313/a> void hwspin_unlock_irq(strucn hwspinlock *hwlock);>v1323/a> - unlock a previously-locked hwspinlock and enable local interrupts.>v1333/a> The caller should _never_ unlock an hwspinlock which is already unlocked.>v1343/a> Do>ng so is considered a bug (there is no protecn> against this).>v1353/a> Upo a successful return from this funcn>on, preempn>on and local>v1363/a> interrupts are enabled. This funcn>on will never sleep.>v1373/a>>v1383/a> void>v1393/a> hwspin_unlock_irqrestore(strucn hwspinlock *hwlock, unsig ed long *flags);>v1403/a> - unlock a previously-locked hwspinlock.>v1413/a> The caller should _never_ unlock an hwspinlock which is already unlocked.>v1423/a> Do>ng so is considered a bug (there is no protecn> against this).>v1433/a> Upo a successful return from this funcn>on, preempn>on is reenabled,>v1443/a> and the stane of the local interrupts is restored to the stane saved at>v1453/a> the g>ven flags. This funcn>on will never sleep.>v1463/a>>v1473/a> int hwspin_lock_get_id(strucn hwspinlock *hwlock);>v1483/a> - retrieve id number of a g>ven hwspinlock. This is needed when an>v1493/a> hwspinlock is dynamically assig ed: before it ca >be used to achieve>v1503/a> mutual exclus >with a remote cpu, the id number should be communicaned>v1513/a> to the remote task>with which we want to synchronize.>v1523/a> Returns the hwspinlock id number, or -EINVAL if hwlock is null.>v1533/a>>v1543/a>3. Typical usage>v1553/a>>v1563/a>#include <linux/hwspinlock.h>>v1573/a>#include <linux/err.h>>v1583/a>>v1593/a>int hwspinlock_example1(void)>v1603/a>{>v1613/a> strucn hwspinlock *hwlock;>v1623/a> int ret;>v1633/a>>v1643/a> /* dynamically assig a hwspinlock */>v1653/a> hwlock = hwspin_lock_request();>v1663/a> if (!hwlock)>v1673/a> ...>v1683/a>>v1693/a> id = hwspin_lock_get_id(hwlock);>v1703/a> /* probably need to communicane id to a remote processor now */>v1713/a>>v1723/a> /* take the lock, spin for 1 sec if it's already taken */> ls already taken, the funcn>on wi5#L46" id.6L46" class="line" nam2.6L46">2ine" nam2.runcn>on wi5#L46" id.6L46" class="line291703/a> /* probably need to communicanlock */>t not sleep, and is advi1sed t174s="line" nam2.6Lncn673/a> ...> 1/hwsp175="line" nam2.6L168">v1683/a>>v1473/a> int hwspin_lock_get_id(strucn hwsp7l exclus >operan>ons.> /73/a> int hwspin_lock_get_id(strucn hwsp7t#L169" icumentan> /hwspinlock.t1xt#L71" id.6L79" *s="ltooknlock.txt#Ldo our" idng71">ss="lido NOT46">v173/a> int hwspin_lock_get_id(strucn hwsp7k);> ls already taken, the funcn>on cn hwspin1lock *hwlock, unsig ed i1nt to18">v1313/a> void hwspin_unlock_irq(strucn hwsp 1 unsig ed long *1flags1;>v1653/a> hwlock = hwspin_lock_requestlock with1 a timeout limit (specif1ied i182166" id.6L166" id.6L126" c170">v1703/a> /* probably need to communicady taken1, the funcn>on will busy1 loop18">v1643/a> /* dynamically assig a hwspt g>ve up1 when the timeout elapse1s.> 6L1265">v1653/a> hwlock = hwspin_lock_requestlpossible1n, preempn>on is disable1d,>on wi5#L46" id" cla170">v1703/a> /* probably need to communicappropria1evious stane is saved at1 the 18ss="line" nam2.6Lncn673/a> ...>v1683/a>> 1/hwsp18">v1693/a> id = hwspin_lock_get_id(hwloappropria1te error code otherwise 1(most189ine" nam2.runcntxt#>v1633/a>> /hwspinlock.to 1cumentan> /hwspinlock.t1xt#L919">v1723/a> /* take the lock, spin for 1#L93" id.16L93" class="line" nam2.16L93"1v 933/ class="line" nam2.6L120">v1603/a>{> 1/hwsp1nlock.613/a> strucn hwspinlock *hwlock;>v1623/a> int ret;>v1633/a>>v1473/a> int hwspin_lock_get_id(strucn hwspised to r1elease the hwspinlock as1 soo 197Documentan> /73/a> int hwspin_lock_get_id(strucn hwspmote core1s poll>ng on the hardwar1e> int hwspin_lock_get_id(strucn hwspmer-processsor communican>ons: ls already taken, the funcn>on2k was alr2ady taken).>ss="line" PREDEFINED_LOCK_ID1703/a> /* probably need to communi2v1673/a> ...>v1683/a>> /20">v1253/a> void hwspin_unlock(strucn hwspinl2sig ed hw2pinlock, but immediately2fail 205.txt#L165" id.6trynlockspinitss="lido" class=173" namt *733/a> ls already taken, the funcn>on2kL27" id.6 /hwspinlock.txt#L107" 2d.6L1206ine" nam2.runcn>on wi5#L4L94" cla170">v1703/a> /* probably need to communi2his funcn2on, preempn>on and the l2cal><207s="line" nam2.6L1ncn6 613/a> strucn hwspinlock *hwlock;>2er must n2t sleep, and is advised 2o>pr_info("m2.6L153 nam2.6L1 nam\n"1703/a> /* probably need to communi2hs new mese.>ncntxt#L123" 703/a> /* probably need to communi2ropriate 2rror code otherwise (mos2>>v1723/a> /* take the lock, spin for 2ss="lido NOT46">v173/a> int hwspin_lock_get_id(strucn hws2hwspinloc2 *hwlock, unsig ed long 2flags214id.6L79" *733/a> ls already taken, the funcn>on2sig ed hw2pinlock, but immediately2fail 21">v1563/a>#include <linux/hwspinlock.h>2ocumentan2 /hwspinlock.txt#L117" 2d.6L1216.txt#L165" id.6121" id.6L1265">v1653/a> hwlock = hwspin_lock_reques2his funcn2on, preempn>on is disabl2d,>v1703/a> /* probably need to communi2ed and th2ir previous stane is sav2d>This is necessary, for example, for In2 The call2r must not sleep, and is2advis219.txt#L165" id.6tan> 6L1265">v1653/a> hwlock = hwspin_lock_reques2ks are offfloaded by the host to th> /h220ine" nam2.runcn>on wi5#L46" id" cla170">v1703/a> /* probably need to communi2s (by a IIPC subsystem called Sysl> ...>v1683/a>>v1643/a> /* dynamically assig a hws2 from a reemote processor to the v1633/a>>>This communican>on is based on simple ddata struccnures that is shared betever_22">v1383/a> void> possible, in order to minimize re2es new messsages in this shared dat0" cl22 803/a> int hwspin_lock_timeout_irqsave(stru2xt#L131" 2d.6L131" class="line" na22.6L123vclass="line" nam2._spinloc*bant#L1ass="lspinloc*spi443/a> and the stane of the local int2inlock *h2lock);>inlotiass="line" nam2.6_ops *ops,f="Donloc_id,f="Donuman> v1403/a> - unlock a previously-locked hws2inlock an2 enable local interrupts2>v 333/nlock.txtp.6L1 hrea" clas3/a> msecs). If the hwspinlock is alre2k an hwsp2nlock which is already u2locke2.>vspi" cl#L46" id.6Lspinloc(ass="linen> /hwsa bant o163/a> it is already taken.> v1.inlock.txt#L56" id.6L56" class="line" nam2 id.6L144" cl63/a> it is already taken.>v 563/a>>v 533n> /hwspinlock.txt#L54" id.6L54/a>>v1383/a> void>vclass="line" nam2._spinloc*bant1403/a> - unlock a previously-locked hws2is new meshwlock, unsig ed long *f2ags);2"Documentenlock.tL56" id.6L566L12id.6Llydng7vendor/nlock.txtp.6L1 hrea" clas3/"6L48"03/a> - unlock a previously-locked hws2inlock.><2 href="Documentan> /hws2inloc24pinlock.txt#Lunregi1">v2" id.6L142" clspinloc(ass="linen> /hwsa bant o1enumere" 03/a> - unlock a previously-locked hws2inlock *h2nlock which is already u2locke2.>v 563/a>> /hwspinloam2.6L4 o1ed.6L142" clnam2.6L53">v 53463/lnamlock.t clasa>>> 24">v1563/a>#include <linux/hwspinlock.h>2xt#L147" 2d.6L147" class="line" na22.6L127">v145. Im243/ne" lass=" 03/a> - unlock a previously-locked hws2iata struclock);>v1383/a> void> void> v. ItL145" gi1">vne" nam2.6id.6Llydng7umentan> 83/a> void>v an> /regi1">vc)"Doc/a>>v1723/a> /* take the lock, spin for 2r, or -EI2VAL if hwlock is null.><2 href2"Docum/*/73/a> int hwspin_lock_get_id(strucn hws2xt#L154" 2d.6L154" class="line" na22.6L12f="Docu*iass="line" nam2.6_spinloc-3 lspinlocass="ln> /hwsspansenumere" nne" nam2.6 03/a> - unlock a previously-locked hws2> /hwspi2lock.txt#L155" id.6L155"2class2ass="li* @spi:6id.6Llydng7spinlo,m2.6L84" nam2.6L1invok clas.6L4 PM33ni03/a> - unlock a previously-locked hws2>mentan> d.6L156" class="line" na22.6L12an> /h* @ops:73">v 333/nlock.txtt#L91" id.6handler/a> possible, in order to minimize re2 possible, in order to minimize re2 /hwspinlock.txt#L152" id.2a href=* @numan> v:lock.txt#L1n> v6L nam2.6spinloa> possible, in order to minimize re2 hwlock = hwspin_lock_reques2txt#L161"2id.6L161" class="line" n2m2.6L260Doculass="line" nam2._spinloc613/a> strucn hwspinlock *hwlock;>2a href="D2cumentan> /hwspinlock.t2t#L162" id.6L162" class="lispinloc*spina> possible, in order to minimize re2> /hwspi2lock.txt#L163" id.6L163"2class2"line" nam2.6Linlotiass="line" nam2.6_ops *opsna> possible, in order to minimize re2>t#L154" 2d.6L164" class="line" na22.6L1263id.6L79" ="Donloc_idna> possible, in order to minimize re2> /hwspi2 /hwspinl2ck.tx2#L166" id.6L16ass="line" nam2.6Lm2.6[0]na> possible, in order to minimize re2>L27" id.6LL27" class="line" nam2.6Lt#L12ass="l}na> possible, in order to minimize re2>ata strucpinlock.txt#L168" id.6L128" cl26">v1383/a> void> /hwspi2xs new mesef="Documentan> /hwspin2ock.t26ref="o1eass="lrepss="nxt#L " naleedne" nam2n> oa> >OMAP4, cpu-intens>ve multimedia taskane id to2a remote processor now *2>v1313/a> void hwspin_unlock_irq(strucn hws2xt#L172" 2d.6L172" class="line" na22.6L122">v17/*/73/a> int hwspin_lock_get_id(strucn hws2 sec if i2's already taken */>2a hre2="Docum*iass="line" nam2.6"-nam2.6Lss="lirepss="nxt#L " naleed#L91" id.6Llotanloa> possible, in order to minimize re2wi5#L46" 2d.6L46" class="line" nam2.6L46273 id.h* @nlnm:6k.txt#L91" id._spinlocL31">v 31eass="lowwspini nn> a> possible, in order to minimize re2w /hwspi2t not sleep, and is advi2sed t274a hre* @inim:6inssial="lincumenam2. nad#L91" id.6413/a> before it ca >be used to achieve 2 possible2.>v 333/nlock.txtt#L91" id.6drva> before it ca >be used to achieve 2 L27" id.6te error code otherwise 2(most2 hwlock = hwspin_lock_reques27l exclus2 >operan>ons.> strucn hwspinlock *hwlock;>27t#L169" 2cumentan> /hwspinlock.t2xt#L72" id.6L79" lass="line" nam2._spinloc*bantna> possible, in order to minimize re27k);> possible, in order to minimize re2cn hwspin2lock *hwlock, unsig ed i2nt to280ine" nam2.ruk.txt*priina> possible, in order to minimize re2ct#L172" 2 unsig ed long *2flags2;> possible, in order to minimize re2lock with2 a timeout limit (specif2ied i28 933/a> int hwspin_trylock(strucn hwspinlock2ady taken2, the funcn>on will busy2 loop28">v16W9">vregi1">vdng7a bant o1en> v,ck.txt#L91" id.6">v 34 onnlock.tsv1093/a> release the hwspinlock as soo 2t g>ve up2 when the timeout elapse2s.> release the hwspinlock as soo 2tpossible2n, preempn>on is disable2d,>> - unlock a previously-locked hws2 possible2.>v1693/a> id = hwspin_lock_get_id(hwl2appropria2te error code otherwise 2(most289ine"T.6L14nam2than> L121">v1nclasba.6 nam2.6L4L n="liness="line" nam2.6_ops="linoa> >OMAP4, cpu-intens>ve multimedia taskock is st2ill busy after timeout m2secs)29">v1313/a> void hwspin_unlock_irq(strucn hws2o 2cumentan> /hwspinlock.t2xt#L929">v17ass="line" nam2.6_ops 613/a> strucn hwspinlock *hwlock;>2#L93" id.26L93" class="line" nam2.26L93"29line" nam2.6L163"(*L94" cl)class="line" nam2.6L0">v1703/a> /* probably need to communi2 *hwlock)2;>v1703/a> /* probably need to communi2 g>ve up2inlock, but immediately 2fail 29k.txt#L165" ik.txt(*relax)class="line" nam2.6L0">v1703/a> /* probably need to communi2 possible2 /hwspinlock.txt#L96" id2.6L96295ine"}na> possible, in order to minimize re2s funcn>o2n, preempn>on is disable2d so>29">v1473/a> int hwspin_lock_get_id(strucn hws2ised to r2elease the hwspinlock as2 soo 297DocuTlocfirotitwonclasba.6 nam2mcumatoryoa> >OMAP4, cpu-intens>ve multimedia taskopossible2s poll>ng on the hardwar2e>v1693/a> id = hwspin_lock_get_id(hwl2mer-proce2ssor communican>ons: v15L94" cla)nclasba.66L3ock.tmspinL " naleeDocumentan>wspinlock.txt#Lcum93/a> release the hwspinlock as soo 3ropriate 3rror code otherwise (mos3>v1463/a>>v1723/a> /* take the lock, spin for 3v15L126" c)nclasba.66121" idsnlock.txt. ItLa27" class="line" naitssto3/a> 3xt#L104" 3d.6L104" class="line" na32.6L1303="limayt_not_46">v1463/a>> /30">v1253/a> void hwspin_unlock(strucn hwspinl3sig ed hw3pinlock, but immediately3fail 305.txtT.6 ->v15relaxc)nclasba.66ineone" nal. ItL145L43" id nad#L91" id.6413/eassl/a> before it ca >be used to achieve 35#L4L94" 3 (mos3>v1643eve 35#L30_unlock2]m2.6L99at#Lcum93/ane" nam2.6L152.6id.6Llydng73">v1 hrea" clne" nspi/nl possible, in order to minimize re2wi53funcn2on,3preempn>on and the l2cal3<207s3"line"inlolnotbetwe" nalas53"s="lass=k clcder tinloc5L94" cla)nclaL145L_not_46">v1463/a>>
->v1origi It LXR soft2n> 2.6id.6>LXR id.6L1tyne" , nn> expg7aumentl onnpinlo2.6>lx7@l6L15.none" . lx7.l6L15.no kindk.thostL152.6>Redpill L6Lpro ASne" , provxt#LnlocL6L15otiasul /hws3/anopg7der tinserc*banam nban1995.