diff options
author | David Brownell <david-b@pacbell.net> | 2006-01-08 16:34:25 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-13 19:29:55 -0500 |
commit | 0c868461fcb8413cb9f691d68e5b99b0fd3c0737 (patch) | |
tree | b43db6239f5d72a279b35b14de85cf34d8f6bc74 /include/linux/spi | |
parent | b885244eb2628e0b8206e7edaaa6a314da78e9a4 (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/linux/spi')
-rw-r--r-- | include/linux/spi/spi.h | 75 |
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 | ||
212 | static inline void *spi_master_get_devdata(struct spi_master *master) | ||
213 | { | ||
214 | return class_get_devdata(&master->cdev); | ||
215 | } | ||
216 | |||
217 | static inline void spi_master_set_devdata(struct spi_master *master, void *data) | ||
218 | { | ||
219 | class_set_devdata(&master->cdev, data); | ||
220 | } | ||
221 | |||
222 | static 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 | |||
229 | static 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 */ |
213 | extern struct spi_master * | 237 | extern struct spi_master * |
214 | spi_alloc_master(struct device *host, unsigned size); | 238 | spi_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 | */ |
275 | struct spi_transfer { | 304 | struct 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 | */ |
306 | struct spi_message { | 341 | struct 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 | |||
378 | static 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 | |||
392 | static 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! */ | ||
448 | extern int spi_write_then_read(struct spi_device *spi, | 510 | extern 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 | */ |
561 | extern struct spi_device * | 624 | extern struct spi_device * |
562 | spi_new_device(struct spi_master *, struct spi_board_info *); | 625 | spi_new_device(struct spi_master *, struct spi_board_info *); |