aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorDavid Brownell <david-b@pacbell.net>2006-01-08 16:34:25 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-01-13 19:29:55 -0500
commit0c868461fcb8413cb9f691d68e5b99b0fd3c0737 (patch)
treeb43db6239f5d72a279b35b14de85cf34d8f6bc74 /include
parentb885244eb2628e0b8206e7edaaa6a314da78e9a4 (diff)
[PATCH] SPI core tweaks, bugfix
This includes various updates to the SPI core: - Fixes a driver model refcount bug in spi_unregister_master() paths. - The spi_master structures now have wrappers which help keep drivers from needing class-level get/put for device data or for refcounts. - Check for a few setup errors that would cause oopsing later. - Docs say more about memory management. Highlights the use of DMA-safe i/o buffers, and zero-initializing spi_message and such metadata. - Provide a simple alloc/free for spi_message and its spi_transfer; this is only one of the possible memory management policies. Nothing to break code that already works. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'include')
-rw-r--r--include/linux/spi/spi.h75
1 files changed, 69 insertions, 6 deletions
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index c851b3d13208..6a41e2650b2e 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -60,8 +60,8 @@ struct spi_device {
60 u8 mode; 60 u8 mode;
61#define SPI_CPHA 0x01 /* clock phase */ 61#define SPI_CPHA 0x01 /* clock phase */
62#define SPI_CPOL 0x02 /* clock polarity */ 62#define SPI_CPOL 0x02 /* clock polarity */
63#define SPI_MODE_0 (0|0) 63#define SPI_MODE_0 (0|0) /* (original MicroWire) */
64#define SPI_MODE_1 (0|SPI_CPHA) /* (original MicroWire) */ 64#define SPI_MODE_1 (0|SPI_CPHA)
65#define SPI_MODE_2 (SPI_CPOL|0) 65#define SPI_MODE_2 (SPI_CPOL|0)
66#define SPI_MODE_3 (SPI_CPOL|SPI_CPHA) 66#define SPI_MODE_3 (SPI_CPOL|SPI_CPHA)
67#define SPI_CS_HIGH 0x04 /* chipselect active high? */ 67#define SPI_CS_HIGH 0x04 /* chipselect active high? */
@@ -209,6 +209,30 @@ struct spi_master {
209 void (*cleanup)(const struct spi_device *spi); 209 void (*cleanup)(const struct spi_device *spi);
210}; 210};
211 211
212static inline void *spi_master_get_devdata(struct spi_master *master)
213{
214 return class_get_devdata(&master->cdev);
215}
216
217static inline void spi_master_set_devdata(struct spi_master *master, void *data)
218{
219 class_set_devdata(&master->cdev, data);
220}
221
222static inline struct spi_master *spi_master_get(struct spi_master *master)
223{
224 if (!master || !class_device_get(&master->cdev))
225 return NULL;
226 return master;
227}
228
229static inline void spi_master_put(struct spi_master *master)
230{
231 if (master)
232 class_device_put(&master->cdev);
233}
234
235
212/* the spi driver core manages memory for the spi_master classdev */ 236/* the spi driver core manages memory for the spi_master classdev */
213extern struct spi_master * 237extern struct spi_master *
214spi_alloc_master(struct device *host, unsigned size); 238spi_alloc_master(struct device *host, unsigned size);
@@ -271,11 +295,17 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum);
271 * stay selected until the next transfer. This is purely a performance 295 * stay selected until the next transfer. This is purely a performance
272 * hint; the controller driver may need to select a different device 296 * hint; the controller driver may need to select a different device
273 * for the next message. 297 * for the next message.
298 *
299 * The code that submits an spi_message (and its spi_transfers)
300 * to the lower layers is responsible for managing its memory.
301 * Zero-initialize every field you don't set up explicitly, to
302 * insulate against future API updates.
274 */ 303 */
275struct spi_transfer { 304struct spi_transfer {
276 /* it's ok if tx_buf == rx_buf (right?) 305 /* it's ok if tx_buf == rx_buf (right?)
277 * for MicroWire, one buffer must be null 306 * for MicroWire, one buffer must be null
278 * buffers must work with dma_*map_single() calls 307 * buffers must work with dma_*map_single() calls, unless
308 * spi_message.is_dma_mapped reports a pre-existing mapping
279 */ 309 */
280 const void *tx_buf; 310 const void *tx_buf;
281 void *rx_buf; 311 void *rx_buf;
@@ -302,6 +332,11 @@ struct spi_transfer {
302 * @status: zero for success, else negative errno 332 * @status: zero for success, else negative errno
303 * @queue: for use by whichever driver currently owns the message 333 * @queue: for use by whichever driver currently owns the message
304 * @state: for use by whichever driver currently owns the message 334 * @state: for use by whichever driver currently owns the message
335 *
336 * The code that submits an spi_message (and its spi_transfers)
337 * to the lower layers is responsible for managing its memory.
338 * Zero-initialize every field you don't set up explicitly, to
339 * insulate against future API updates.
305 */ 340 */
306struct spi_message { 341struct spi_message {
307 struct spi_transfer *transfers; 342 struct spi_transfer *transfers;
@@ -336,6 +371,29 @@ struct spi_message {
336 void *state; 371 void *state;
337}; 372};
338 373
374/* It's fine to embed message and transaction structures in other data
375 * structures so long as you don't free them while they're in use.
376 */
377
378static inline struct spi_message *spi_message_alloc(unsigned ntrans, gfp_t flags)
379{
380 struct spi_message *m;
381
382 m = kzalloc(sizeof(struct spi_message)
383 + ntrans * sizeof(struct spi_transfer),
384 flags);
385 if (m) {
386 m->transfers = (void *)(m + 1);
387 m->n_transfer = ntrans;
388 }
389 return m;
390}
391
392static inline void spi_message_free(struct spi_message *m)
393{
394 kfree(m);
395}
396
339/** 397/**
340 * spi_setup -- setup SPI mode and clock rate 398 * spi_setup -- setup SPI mode and clock rate
341 * @spi: the device whose settings are being modified 399 * @spi: the device whose settings are being modified
@@ -363,7 +421,10 @@ spi_setup(struct spi_device *spi)
363 * The completion callback is invoked in a context which can't sleep. 421 * The completion callback is invoked in a context which can't sleep.
364 * Before that invocation, the value of message->status is undefined. 422 * Before that invocation, the value of message->status is undefined.
365 * When the callback is issued, message->status holds either zero (to 423 * When the callback is issued, message->status holds either zero (to
366 * indicate complete success) or a negative error code. 424 * indicate complete success) or a negative error code. After that
425 * callback returns, the driver which issued the transfer request may
426 * deallocate the associated memory; it's no longer in use by any SPI
427 * core or controller driver code.
367 * 428 *
368 * Note that although all messages to a spi_device are handled in 429 * Note that although all messages to a spi_device are handled in
369 * FIFO order, messages may go to different devices in other orders. 430 * FIFO order, messages may go to different devices in other orders.
@@ -445,6 +506,7 @@ spi_read(struct spi_device *spi, u8 *buf, size_t len)
445 return spi_sync(spi, &m); 506 return spi_sync(spi, &m);
446} 507}
447 508
509/* this copies txbuf and rxbuf data; for small transfers only! */
448extern int spi_write_then_read(struct spi_device *spi, 510extern int spi_write_then_read(struct spi_device *spi,
449 const u8 *txbuf, unsigned n_tx, 511 const u8 *txbuf, unsigned n_tx,
450 u8 *rxbuf, unsigned n_rx); 512 u8 *rxbuf, unsigned n_rx);
@@ -555,8 +617,9 @@ spi_register_board_info(struct spi_board_info const *info, unsigned n)
555 617
556 618
557/* If you're hotplugging an adapter with devices (parport, usb, etc) 619/* If you're hotplugging an adapter with devices (parport, usb, etc)
558 * use spi_new_device() to describe each device. You would then call 620 * use spi_new_device() to describe each device. You can also call
559 * spi_unregister_device() to start making that device vanish. 621 * spi_unregister_device() to start making that device vanish, but
622 * normally that would be handled by spi_unregister_master().
560 */ 623 */
561extern struct spi_device * 624extern struct spi_device *
562spi_new_device(struct spi_master *, struct spi_board_info *); 625spi_new_device(struct spi_master *, struct spi_board_info *);