public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH/RFC 0/2] simple SPI framework, refresh + ads7864 driver
@ 2005-10-04 18:02 David Brownell
  2005-10-04 19:08 ` Vitaly Wool
  2005-10-05  7:56 ` Vitaly Wool
  0 siblings, 2 replies; 14+ messages in thread
From: David Brownell @ 2005-10-04 18:02 UTC (permalink / raw)
  To: linux-kernel; +Cc: spi-devel-general, basicmark, stephen, dpervushin

Following this will be two patches, refreshing the minimalist SPI stack
I've sent before.  Notable changes are:

  - Various updates to support real hardware, including reporting the
    IRQ associated with an SPI slave chip, providing void* handles for
    various flavors of board and controller state, dma_addr_t for I/O
    buffers, some control over protocol delays, and more.

  - New spi_alloc_master().  The driver model is happier if drivers
    don't allocate the class devices; this helps "rmmod" and friends,
    kind of handy for debugging drivers.  It allocates controller
    specific memory not unlike alloc_netdev().

  - Various cleanup, notably removing Kconfig for all those drivers
    that don't yet exist.  That was added purely to illustrate the
    potential scope of an SPI framework, when more folk were asking
    just why a Serial Peripheral Interface (*) was useful.

  - More kerneldoc.  No Documentation/DocBook/spi.html though.

  - Now there's a real ADS7864 touchscreen/sensor driver; lightly
    tested, but it emits the right sort of input events and gives
    syfs access to the temperature, battery, and voltage sensors.

This version seems real enough to integrate with.

One goal is promote reuse of driver code -- for SPI controllers and
slave chips connected using SPI -- while fitting them better into the
driver model framework.  Today, SPI devices only seem to get drivers
that are board-specific; there's a fair amount of reinvent-the-wheel,
and drivers that are unsuitable for upstream merging.

I can now report this seems to be working with real controllers and
real slave chips ... two of each to start with, but as yet there's no
mix'n'match (with e.g. that touchscreen driver being used with a PXA
SSP controller, not just OMAP MicroWire).  That should just take a
little bit of time and debugging.

- Dave

(*) And distinguish it from Singapore Paranormal Investigators.  ;)


^ permalink raw reply	[flat|nested] 14+ messages in thread
* Re: [PATCH/RFC 0/2] simple SPI framework, refresh + ads7864 driver
@ 2005-10-04 20:18 David Brownell
  2005-10-05  8:07 ` Vitaly Wool
  0 siblings, 1 reply; 14+ messages in thread
From: David Brownell @ 2005-10-04 20:18 UTC (permalink / raw)
  To: Vitaly Wool; +Cc: linux-kernel

Hi Vitaly,

> can you please describe the data flow in case of DMA transfer? Thanks!

In the current model, the controller driver handles it (assuming
that it uses DMA not PIO):

 - Use dma_map_single() at some point between the master->transfer()
   call and the time the DMA address is handed to DMA hardware.

 - Probably store those addresses in the spi_transfer struct, using
   rx_dma and/or tx_dma as appropriate.

 - After the DMA transfer completes, call dma_unmap_single() before
   calling spi_message.complete(spi_message.context).

There are two fancier approaches to consider for sometime later, both
of which have been used for several years now by host-side USB.

  * SPI controller drivers could require the mappings to already
    have been done, and stored in {rx,tx}_dma fields.  When those
    drivers are using DMA, they'd only use those DMA addresses.

    The way host-side USB does that is by having usbcore do work
    on all the submit and giveback paths.  Currently this SPI
    framework doesn't do "core" work on those paths; spi_async()
    just calls directly to the controller driver (no overhead!)
    and the completion reports likewise go right from controller
    driver back to the submitter (also, no overhead).

  * Drivers for SPI slave chips might sometimes want to provide their
    own rx_dma and/or tx_dma values ... either because they mapped the
    buffers themselves -- great for dma_map_sg()! -- or because the
    memory came from dma_alloc_coherent().

    This implies that the controller drivers are ready to accept
    those DMA addresses, and that there are per-buffer flags saying
    whether its DMA address is also valid (vs just its CPU address).
    
Note that the slave-side USB support only supports the latter, which
means the USB peripheral controller drivers with DMA support decide
on a per-request basis whether to do the DMA mappings.  I'd lean
towards doing that with SPI; it's a bunch simpler.

Right now DMA isn't on my priority list, but I'd be glad to see
someone else take further steps there.  Anyone doing bulk I/O to an
SPI flash chip at 50 MHz is surely going to want DMA for it!

- Dave

p.s. Please be sure to CC me on replies, so I'm sure to see them...


^ permalink raw reply	[flat|nested] 14+ messages in thread
* Re: [PATCH/RFC 0/2] simple SPI framework, refresh + ads7864 driver
@ 2005-10-05 15:10 David Brownell
  2005-10-13 19:37 ` Lee Revell
  0 siblings, 1 reply; 14+ messages in thread
From: David Brownell @ 2005-10-05 15:10 UTC (permalink / raw)
  To: vwool; +Cc: linux-kernel

> BTW, haven't seen any place where message->complete() is called... Can 
> you please point out one?

There are calls to that from the pxa2xx_spi_ssp.c controller driver
which Stephen Street posted.

  http://marc.theaimsgroup.com/?l=linux-kernel&m=112846505323865&w=2

Unfortunately he's struggling with mailers that are mangling
his patches (tabs-to-spaces, quoted-printable, base64, etc)
so you'll have to cope for a while with wrong-formatting.

I didn't post the OMAP MicroWire driver since I've not yet split
it out from the previous non-drivermodel support, so the patch
would be useless to anyone not working with the Linux-OMAP tree.

- Dave


^ permalink raw reply	[flat|nested] 14+ messages in thread
* Re: [PATCH/RFC 0/2] simple SPI framework, refresh + ads7864 driver
@ 2005-10-05 15:18 David Brownell
  0 siblings, 0 replies; 14+ messages in thread
From: David Brownell @ 2005-10-05 15:18 UTC (permalink / raw)
  To: vwool; +Cc: linux-kernel

> > > can you please describe the data flow in case of DMA transfer? Thanks!
> >
> > In the current model, the controller driver handles it (assuming
> > that it uses DMA not PIO):
> >
> >  - Use dma_map_single() at some point between the master->transfer()
> >    call and the time the DMA address is handed to DMA hardware.

> So that implies calling dma_map_single() for the memory allocated in stack?

Calling that for whatever is passed, certainly.

But the <linux/spi.h> header does have a comment right next to the
declarations of spi_transfer.tx_buf and rx_buf, saying that "buffers
must work with dma_*map_single() calls.

In general all APIs that use DMA will follow the rules listed under
"What memory is DMA'able?" in:

  linux/Documentation/DMA-mapping.txt

The rest of that file is a bit PCI-centric, but that section remains
the primary description of what can be DMA'd.  I had assumed that went
without saying; permaps wrongly.

- Dave


^ permalink raw reply	[flat|nested] 14+ messages in thread
* Re: [PATCH/RFC 0/2] simple SPI framework, refresh + ads7864 driver
@ 2005-10-05 16:21 David Brownell
  2005-10-05 16:24 ` Russell King
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: David Brownell @ 2005-10-05 16:21 UTC (permalink / raw)
  To: vwool; +Cc: linux-kernel

> Of course we want to use scatter-gather lists.

The only way "of course" applies is if you're accepting requests
from the block layer, which talks in terms of "struct scatterlist".

In my investigations of SPI, I don't happen to have come across any
SPI slave device that would naturally be handled as a block device.
There's lots of flash (and dataflash); that's MTD, not block.


>	The DMA controller 
> mentioned above can handle only 0xFFF transfer units at a transfer so we 
> have to split the large transfers into SG lists.

Odd, I've seen plenty other drivers that just segment large buffers
into multiple DMA transfers ... without wanting "struct scatterlist".

  - Sometimes they turn them into lists of DMA descriptors handled
    by their DMA controller.  Even the silicon designers who talk
    to Linux developers wouldn't choose "struct scatterlist" to
    hold those descriptors

  - More often they just break big buffers into lots of little
    transfers.  Just like PIO, but faster.  (And in fact, they may
    need to prime the pump with some PIO to align the buffer.)

  - Sometimes they just reject segments that are too large to
    handle cleanly at a low level, and require higher level code
    to provide more byte-sized blocks of I/O.

If "now" _were_ the point we need to handle scatterlists, I've shown
a nice efficient way to handle them, already well proven in the context
of another serial bus protocol (USB).


> Moreover, that looks like it may imply redundant data copying.

Absolutely not.  Everything was aimed at zero-copy I/O; why do
you think I carefully described "DMA mapping" everywhere, rather
than "memcpy"?


> Can you please elaborate what you meant by 'readiness to accept DMA 
> addresses' for the controller drivers?

Go look at the parts of the USB stack I mentioned.  That's what I mean.

 - In the one case, DMA-aware controller drivers look at each buffer
   to determine whether they have to manage the mappings themselves.
   If the caller provided the DMA address, they won't set up mappings.

 - In the other case, they always expect their caller to have set
   up the DMA mappings.  (Where "caller" is infrastructure code,
   not the actual driver issuing the I/O request.)

The guts of such drivers would only talk in terms of DMA; the way those
cases differ is how the driver entry/exit points ensure that can be done.


> As far as I see it now, the whole thing looks wrong. The thing that we 
> suggest (i. e. abstract handles for memory allocation set to kmalloc by 
> default) is looking far better IMHO and doesn't require any flags which 
> usage increases uncertainty in the core.

You are conflating memory allocation with DMA mapping.  Those notions
are quite distinct, except for dma_alloc_coherent() where one operation
does both.

The normal goal for drivers is to accept buffers allocated from anywhere
that Documentation/DMA-mapping.txt describes as being DMA-safe ... and
less often, message passing frameworks will do what USB does and accept
DMA addresses rather than CPU addresses.

- Dave


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2005-10-13 19:53 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-10-04 18:02 [PATCH/RFC 0/2] simple SPI framework, refresh + ads7864 driver David Brownell
2005-10-04 19:08 ` Vitaly Wool
2005-10-05  7:56 ` Vitaly Wool
  -- strict thread matches above, loose matches on Subject: below --
2005-10-04 20:18 David Brownell
2005-10-05  8:07 ` Vitaly Wool
2005-10-05 15:10 David Brownell
2005-10-13 19:37 ` Lee Revell
2005-10-05 15:18 David Brownell
2005-10-05 16:21 David Brownell
2005-10-05 16:24 ` Russell King
2005-10-05 17:27   ` David Brownell
2005-10-06  4:57 ` Vitaly Wool
2005-10-06 18:13 ` Mark Underwood
2005-10-06 18:20   ` Vitaly Wool

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox