[RFC] omap2_mcspi interrupt context execution

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



List,
One of the devices I work with has an ethernet chip connected to an
OMAP2430 by spi and an interrupt gpio. The chip isn't well behaved, so
I end up needing to send spi messages in response to interrupts from
the chip very quickly or it will lose packets.

I've written the high level driver such that it makes spi_async
requests in interrupt context when it gets an interrupt, but it
appears that the omap2_mcspi driver below me is context switching out
of interrupt context to a plain kernel thread. If the scheduler
doesn't run this thread immediately, we overflow the ethernet chip's
buffer and lose packets.

Has anyone looked into making the omap2_mcspi driver run in interrupt
context before? Does anyone have advice how to do so or a similar
driver I could pattern this change after?

Thanks,
David W

PS: Here's the psuedocode I'm imagining for the omap2_mcspi driver.
Maybe it will clarify what I'm thinking.

// Shared fifo of transfers yet to be handled
struct list pending_transfers;
spinlock_t lock;

// Called by upper layer drivers to send spi messages
int omap2_mcspi_transfer(struct spi_transfer * t)
{
      spin_lock(lock);
      empty = list_empty(pending_transfers);
      list_push_back(pending_transfers, t);
      if (empty) {
              start_transfer();
      }
      spin_unlock(lock);

      return status;
}

void start_transfer()
{
      struct spi_transfer * t = pending_transfers.first;
      spi_enable(t.channel);
      spi_setup(t.channel, t.params);

      setup_dma(spi, t.tx_buf, t.rx_buf, t.length, irq_handler);
      spi_start();
}

// Called when dma completes to+from mcspi
void irq_handler()
{
      struct spi_transfer * t = pending_transfers.first;

      spin_lock(lock);
      spi_finish(t);
      spi_disable(t.channel);

      list_remove(pending_transfers, t);
      if !list_empty(pending_transfers) {
              start_transfer();
      }
      spin_unlock(lock);

      // Call back to the driver to let it know we finished
      t.async_callback(t.status);
}
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux