<p><br>
On Feb 1, 2014 2:48 PM, &quot;m silverstri&quot; &lt;<a href="mailto:michael.j.silverstri@gmail.com">michael.j.silverstri@gmail.com</a>&gt; wrote:<br>
&gt;<br>
&gt; By driver code , I mean the code which set the register values and<br>
&gt; wait till the values is set (via an interrupt handler) before<br>
&gt; continues doing something else<br>
&gt;<br>
&gt;<br>
&gt; On Sat, Feb 1, 2014 at 1:06 AM, anish singh &lt;<a href="mailto:anish198519851985@gmail.com">anish198519851985@gmail.com</a>&gt; wrote:<br>
&gt; &gt; On Sat, Feb 1, 2014 at 1:03 AM, m silverstri<br>
&gt; &gt; &lt;<a href="mailto:michael.j.silverstri@gmail.com">michael.j.silverstri@gmail.com</a>&gt; wrote:<br>
&gt; &gt;&gt; On Sat, Feb 1, 2014 at 12:48 AM, anish singh<br>
&gt; &gt;&gt; &lt;<a href="mailto:anish198519851985@gmail.com">anish198519851985@gmail.com</a>&gt; wrote:<br>
&gt; &gt;&gt;&gt; On Sat, Feb 1, 2014 at 12:32 AM, m silverstri<br>
&gt; &gt;&gt;&gt; &lt;<a href="mailto:michael.j.silverstri@gmail.com">michael.j.silverstri@gmail.com</a>&gt; wrote:<br>
&gt; &gt;&gt;&gt; don&#39;t top-post<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;&gt; In my driver code,<br>
&gt; &gt;&gt;&gt;&gt; I want to set a bit in a  HW Register 1. HW will send an interrupt<br>
&gt; &gt;&gt;&gt; Yes this is how most drivers work.<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;&gt; when setting the register is done.<br>
&gt; &gt;&gt;&gt;&gt; I don&#39;t want my driver code to block until the interrupt is sent from the HW.<br>
&gt; &gt;&gt;&gt; so i suppose this is what you want to do.<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; write -&gt;register-&gt;interrupt happens-&gt;disable register -&gt;handle interrupt<br>
&gt; &gt;&gt;&gt; ---&gt;enable register.<br>
&gt; &gt;&gt;&gt; Look at any driver code from linux kernel code and it mostly does this.<br>
&gt; &gt;&gt;&gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Thanks.<br>
&gt; &gt;&gt; But I want my driver code to block until I get the interrupt from HW.<br>
&gt; &gt;<br>
&gt; &gt; if (driver code == interrupt handler) {<br>
&gt; &gt;    it_is_not_running_anyway_as_there_is_no_interrupt<br>
&gt; &gt; } else {<br>
&gt; &gt;    i don&#39;t know what you mean by driver code here?<br>
&gt; &gt; }<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;&gt; On Sat, Feb 1, 2014 at 12:06 AM, anish singh<br>
&gt; &gt;&gt;&gt;&gt; &lt;<a href="mailto:anish198519851985@gmail.com">anish198519851985@gmail.com</a>&gt; wrote:<br>
&gt; &gt;&gt;&gt;&gt;&gt; On Fri, Jan 31, 2014 at 11:55 PM, m silverstri<br>
&gt; &gt;&gt;&gt;&gt;&gt; &lt;<a href="mailto:michael.j.silverstri@gmail.com">michael.j.silverstri@gmail.com</a>&gt; wrote:<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; Hi,<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; I read this article <a href="http://www.linuxjournal.com/article/5833">http://www.linuxjournal.com/article/5833</a> to learn<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; about spinlock. I try this to use it in my kernel driver.<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; Here is what my driver code needs to do:<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; In f1(), it will get the spin lock, and caller can call f2() will wait<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; for the lock since the spin lock is not being unlock. The spin lock<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; will be unlock in my interrupt handler (triggered by the HW).<br>
&gt; &gt;&gt;&gt;&gt;&gt; Wrong design!!!<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; void f1() {<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; spin_lock(&amp;mylock);<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; // write hardware<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; REG_ADDR += FLAG_A;<br>
&gt; &gt;&gt;&gt;&gt;&gt; So here you take spinlock and release in interrupt handler.What<br>
&gt; &gt;&gt;&gt;&gt;&gt; if there is no interrupt handler and someone calls this fucntion<br>
&gt; &gt;&gt;&gt;&gt;&gt; he will blocked forever.<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; }<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; void f2() {<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; spin_lock(&amp;mylock);<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; //...<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; }<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; The hardware will send the application an interrupt and my interrupt<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; handler will call spin_unlock(&amp;mylock);<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; My question is if I call<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; f1()<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; f2() // i want this to block until the interrupt return saying settingyou</p>
<p>I think you want to block a task for an event to happen. That event is triggered by HW. </p>
<p>What i would suggest is that you use completion variable which would be per request. Don&#39;t make it global otherwise you&#39;ll again need locks to protect global variable. Try to pass this completion variable along with request to your driver.</p>

<p>Also i suppose that your driver could implement a list where requests from tasks can be queued and each task would wait for completion which already is per task embedded in its request.</p>
<p>The driver would deque requests one by one or depending on how many requests can your hw handle and will trigger completion waking up the task that triggered it.</p>
<p>So you&#39;ll have a clean api design where locks are held and unlocked at same layer instead of current design.<br><br></p>
<p>&gt; &gt;&gt;&gt;&gt;&gt;&gt; REG_ADDR is done.<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; when I run this, I get an exception in kernel saying a deadlock &quot;<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; INFO: possible recursive locking detected&quot;<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; How  can I re-write my code so that kernel does not think I have a deadlock?<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; I want my driver code to wait until HW sends me an interrupt saying<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; setting REG_ADDR is done.<br>
&gt; &gt;&gt;&gt;&gt;&gt; Let us know what is your requirement?I am sure there must be a simple<br>
&gt; &gt;&gt;&gt;&gt;&gt; way to handle than this magic done here.<br>
&gt; &gt;&gt;&gt;&gt;&gt; Explain what are you trying to do in detail and I am sure lot of<br>
&gt; &gt;&gt;&gt;&gt;&gt; people will jump<br>
&gt; &gt;&gt;&gt;&gt;&gt; to help.<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; Thank you.<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; _______________________________________________<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; Kernelnewbies mailing list<br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; <a href="mailto:Kernelnewbies@kernelnewbies.org">Kernelnewbies@kernelnewbies.org</a><br>
&gt; &gt;&gt;&gt;&gt;&gt;&gt; <a href="http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies">http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies</a><br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; Kernelnewbies mailing list<br>
&gt; <a href="mailto:Kernelnewbies@kernelnewbies.org">Kernelnewbies@kernelnewbies.org</a><br>
&gt; <a href="http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies">http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies</a></p>
<p>    ---P.K.S</p>