Hi!

I saw the mokopatches git tree today, which I guess is the patches
destined for upstream submission. There I saw that the accelerometer
driver once again schedules work in a work queue in the interrupt
handler.

I understand that the implementation in the stable tree is too
moko-specific to be accepted by upstream. Anyhow, as we discussed in an
email thread earlier, there is a race condition also in this
implementation (if an interrupt occurs after enable_irq() in
lis302dl_work).


Thinking that this cannot be a unique problem, I browsed the spi code.
I'm now particularly interested in spi_async(). This is used in
ads7846.c and I think something similar could be used in the lis302dl
interrupt handler, e.g.:

   interrupt_handler(..) {
        struct spi_message  *m = /* get from queue */;
        struct spi_transfer *xfer = /* Also get from the same queue */

        xfer->len = 1;
        xfer->tx_buf = /* Pointer to LIS302DL_REG_OUT_X */
        xfer->rx_buf = /* Somewhere to store the result */
        /* Same for OUT_Y, OUT_Z, ... */

        m->complete = lis302dl_work;
        m->context = lis;
        spi_message_add_tail(xfer, m);
        spi_async(spi_dev, m);
   }

   void lis320dl_work(void *p) {
        struct spi_message  *m = /* get from queue */;
        struct spi_transfer *xfer = /* get from m */;
        u8 *val = xfer->rx_buf;

        input_report_rel(REL_X, *val);
        ...
   }

Getting new interrupts while running lis302dl_work() would now just
enqueue another message with spi_async, and should therefore be safe.
Lots of implementation details left, obviously, but do you think this
would be a possible implementation (acceptable by upstream)?

// Simon

Reply via email to