title: Critical Timing in an ARM Linux Kernel Driver
body: <p>I am running linux on an MX28 (ARMv5), and am using a GPIO line to talk to a device.  Unfortunately, the device has some special timing requirements.  A low on the GPIO line cannot last longer than 7us, highs have no special timing requirements.  The code is implemented as a kernel device driver, and toggles the GPIO with direct register writes rather than going through the kernel GPIO api.  For testing, I am just generating 3 pulses.  The process is as follows, all in one function so it should fit in the instruction cache:</p>
  
  <ul>
  <li>set gpio high </li>
  <li>Save Flags &amp; Disable Interrupts </li>
  <li>gpio low </li>
  <li>pause</li>
  <li>gpio high</li>
  <li>repeat 2x more</li>
  <li>Restore Flags/Reenable Interrups</li>
  </ul>
  
  <p>Here's the output of a logic analyzer tied to the GPIO.</p>
  
  <p><img src="https://i.stack.imgur.com/Mu8fg.png" alt="Picture of three pulses"></p>
  
  <p>Most of the time it works just great, and the pulses last just under 1us.  However, about 10% of the lows last for many, many microseconds. Even though interrupts are disabled, something is causing the flow of the code to be interrupted.  </p>
  
  <p><img src="https://i.stack.imgur.com/Qegys.png" alt="Weird long pulse"></p>
  
  <p>I am at a loss.  RT Linux would likely not help here, because the problem is not latency, it appears to be something happening during the low, even though nothing should interrupt it with the IRQs disabled.  Any suggestions would be greatly, greatly appreciated.</p>