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 /drivers/spi/spi.c | |
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 'drivers/spi/spi.c')
-rw-r--r-- | drivers/spi/spi.c | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 2ecb86cb3689..3ecedccdb96c 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -38,7 +38,7 @@ static void spidev_release(struct device *dev) | |||
38 | if (spi->master->cleanup) | 38 | if (spi->master->cleanup) |
39 | spi->master->cleanup(spi); | 39 | spi->master->cleanup(spi); |
40 | 40 | ||
41 | class_device_put(&spi->master->cdev); | 41 | spi_master_put(spi->master); |
42 | kfree(dev); | 42 | kfree(dev); |
43 | } | 43 | } |
44 | 44 | ||
@@ -90,7 +90,7 @@ static int spi_suspend(struct device *dev, pm_message_t message) | |||
90 | int value; | 90 | int value; |
91 | struct spi_driver *drv = to_spi_driver(dev->driver); | 91 | struct spi_driver *drv = to_spi_driver(dev->driver); |
92 | 92 | ||
93 | if (!drv || !drv->suspend) | 93 | if (!drv->suspend) |
94 | return 0; | 94 | return 0; |
95 | 95 | ||
96 | /* suspend will stop irqs and dma; no more i/o */ | 96 | /* suspend will stop irqs and dma; no more i/o */ |
@@ -105,7 +105,7 @@ static int spi_resume(struct device *dev) | |||
105 | int value; | 105 | int value; |
106 | struct spi_driver *drv = to_spi_driver(dev->driver); | 106 | struct spi_driver *drv = to_spi_driver(dev->driver); |
107 | 107 | ||
108 | if (!drv || !drv->resume) | 108 | if (!drv->resume) |
109 | return 0; | 109 | return 0; |
110 | 110 | ||
111 | /* resume may restart the i/o queue */ | 111 | /* resume may restart the i/o queue */ |
@@ -198,7 +198,7 @@ spi_new_device(struct spi_master *master, struct spi_board_info *chip) | |||
198 | 198 | ||
199 | /* NOTE: caller did any chip->bus_num checks necessary */ | 199 | /* NOTE: caller did any chip->bus_num checks necessary */ |
200 | 200 | ||
201 | if (!class_device_get(&master->cdev)) | 201 | if (!spi_master_get(master)) |
202 | return NULL; | 202 | return NULL; |
203 | 203 | ||
204 | proxy = kzalloc(sizeof *proxy, GFP_KERNEL); | 204 | proxy = kzalloc(sizeof *proxy, GFP_KERNEL); |
@@ -244,7 +244,7 @@ spi_new_device(struct spi_master *master, struct spi_board_info *chip) | |||
244 | return proxy; | 244 | return proxy; |
245 | 245 | ||
246 | fail: | 246 | fail: |
247 | class_device_put(&master->cdev); | 247 | spi_master_put(master); |
248 | kfree(proxy); | 248 | kfree(proxy); |
249 | return NULL; | 249 | return NULL; |
250 | } | 250 | } |
@@ -324,8 +324,6 @@ static void spi_master_release(struct class_device *cdev) | |||
324 | struct spi_master *master; | 324 | struct spi_master *master; |
325 | 325 | ||
326 | master = container_of(cdev, struct spi_master, cdev); | 326 | master = container_of(cdev, struct spi_master, cdev); |
327 | put_device(master->cdev.dev); | ||
328 | master->cdev.dev = NULL; | ||
329 | kfree(master); | 327 | kfree(master); |
330 | } | 328 | } |
331 | 329 | ||
@@ -339,8 +337,9 @@ static struct class spi_master_class = { | |||
339 | /** | 337 | /** |
340 | * spi_alloc_master - allocate SPI master controller | 338 | * spi_alloc_master - allocate SPI master controller |
341 | * @dev: the controller, possibly using the platform_bus | 339 | * @dev: the controller, possibly using the platform_bus |
342 | * @size: how much driver-private data to preallocate; a pointer to this | 340 | * @size: how much driver-private data to preallocate; the pointer to this |
343 | * memory in the class_data field of the returned class_device | 341 | * memory is in the class_data field of the returned class_device, |
342 | * accessible with spi_master_get_devdata(). | ||
344 | * | 343 | * |
345 | * This call is used only by SPI master controller drivers, which are the | 344 | * This call is used only by SPI master controller drivers, which are the |
346 | * only ones directly touching chip registers. It's how they allocate | 345 | * only ones directly touching chip registers. It's how they allocate |
@@ -350,14 +349,17 @@ static struct class spi_master_class = { | |||
350 | * master structure on success, else NULL. | 349 | * master structure on success, else NULL. |
351 | * | 350 | * |
352 | * The caller is responsible for assigning the bus number and initializing | 351 | * The caller is responsible for assigning the bus number and initializing |
353 | * the master's methods before calling spi_add_master(), or else (on error) | 352 | * the master's methods before calling spi_add_master(); and (after errors |
354 | * calling class_device_put() to prevent a memory leak. | 353 | * adding the device) calling spi_master_put() to prevent a memory leak. |
355 | */ | 354 | */ |
356 | struct spi_master * __init_or_module | 355 | struct spi_master * __init_or_module |
357 | spi_alloc_master(struct device *dev, unsigned size) | 356 | spi_alloc_master(struct device *dev, unsigned size) |
358 | { | 357 | { |
359 | struct spi_master *master; | 358 | struct spi_master *master; |
360 | 359 | ||
360 | if (!dev) | ||
361 | return NULL; | ||
362 | |||
361 | master = kzalloc(size + sizeof *master, SLAB_KERNEL); | 363 | master = kzalloc(size + sizeof *master, SLAB_KERNEL); |
362 | if (!master) | 364 | if (!master) |
363 | return NULL; | 365 | return NULL; |
@@ -365,7 +367,7 @@ spi_alloc_master(struct device *dev, unsigned size) | |||
365 | class_device_initialize(&master->cdev); | 367 | class_device_initialize(&master->cdev); |
366 | master->cdev.class = &spi_master_class; | 368 | master->cdev.class = &spi_master_class; |
367 | master->cdev.dev = get_device(dev); | 369 | master->cdev.dev = get_device(dev); |
368 | class_set_devdata(&master->cdev, &master[1]); | 370 | spi_master_set_devdata(master, &master[1]); |
369 | 371 | ||
370 | return master; | 372 | return master; |
371 | } | 373 | } |
@@ -387,6 +389,8 @@ EXPORT_SYMBOL_GPL(spi_alloc_master); | |||
387 | * | 389 | * |
388 | * This must be called from context that can sleep. It returns zero on | 390 | * This must be called from context that can sleep. It returns zero on |
389 | * success, else a negative error code (dropping the master's refcount). | 391 | * success, else a negative error code (dropping the master's refcount). |
392 | * After a successful return, the caller is responsible for calling | ||
393 | * spi_unregister_master(). | ||
390 | */ | 394 | */ |
391 | int __init_or_module | 395 | int __init_or_module |
392 | spi_register_master(struct spi_master *master) | 396 | spi_register_master(struct spi_master *master) |
@@ -396,6 +400,9 @@ spi_register_master(struct spi_master *master) | |||
396 | int status = -ENODEV; | 400 | int status = -ENODEV; |
397 | int dynamic = 0; | 401 | int dynamic = 0; |
398 | 402 | ||
403 | if (!dev) | ||
404 | return -ENODEV; | ||
405 | |||
399 | /* convention: dynamically assigned bus IDs count down from the max */ | 406 | /* convention: dynamically assigned bus IDs count down from the max */ |
400 | if (master->bus_num == 0) { | 407 | if (master->bus_num == 0) { |
401 | master->bus_num = atomic_dec_return(&dyn_bus_id); | 408 | master->bus_num = atomic_dec_return(&dyn_bus_id); |
@@ -425,7 +432,7 @@ EXPORT_SYMBOL_GPL(spi_register_master); | |||
425 | static int __unregister(struct device *dev, void *unused) | 432 | static int __unregister(struct device *dev, void *unused) |
426 | { | 433 | { |
427 | /* note: before about 2.6.14-rc1 this would corrupt memory: */ | 434 | /* note: before about 2.6.14-rc1 this would corrupt memory: */ |
428 | device_unregister(dev); | 435 | spi_unregister_device(to_spi_device(dev)); |
429 | return 0; | 436 | return 0; |
430 | } | 437 | } |
431 | 438 | ||
@@ -440,8 +447,9 @@ static int __unregister(struct device *dev, void *unused) | |||
440 | */ | 447 | */ |
441 | void spi_unregister_master(struct spi_master *master) | 448 | void spi_unregister_master(struct spi_master *master) |
442 | { | 449 | { |
443 | class_device_unregister(&master->cdev); | ||
444 | (void) device_for_each_child(master->cdev.dev, NULL, __unregister); | 450 | (void) device_for_each_child(master->cdev.dev, NULL, __unregister); |
451 | class_device_unregister(&master->cdev); | ||
452 | master->cdev.dev = NULL; | ||
445 | } | 453 | } |
446 | EXPORT_SYMBOL_GPL(spi_unregister_master); | 454 | EXPORT_SYMBOL_GPL(spi_unregister_master); |
447 | 455 | ||
@@ -487,6 +495,9 @@ EXPORT_SYMBOL_GPL(spi_busnum_to_master); | |||
487 | * by leaving it selected in anticipation that the next message will go | 495 | * by leaving it selected in anticipation that the next message will go |
488 | * to the same chip. (That may increase power usage.) | 496 | * to the same chip. (That may increase power usage.) |
489 | * | 497 | * |
498 | * Also, the caller is guaranteeing that the memory associated with the | ||
499 | * message will not be freed before this call returns. | ||
500 | * | ||
490 | * The return value is a negative error code if the message could not be | 501 | * The return value is a negative error code if the message could not be |
491 | * submitted, else zero. When the value is zero, then message->status is | 502 | * submitted, else zero. When the value is zero, then message->status is |
492 | * also defined: it's the completion code for the transfer, either zero | 503 | * also defined: it's the completion code for the transfer, either zero |
@@ -524,9 +535,9 @@ static u8 *buf; | |||
524 | * is zero for success, else a negative errno status code. | 535 | * is zero for success, else a negative errno status code. |
525 | * This call may only be used from a context that may sleep. | 536 | * This call may only be used from a context that may sleep. |
526 | * | 537 | * |
527 | * Parameters to this routine are always copied using a small buffer, | 538 | * Parameters to this routine are always copied using a small buffer; |
528 | * large transfers should use use spi_{async,sync}() calls with | 539 | * performance-sensitive or bulk transfer code should instead use |
529 | * dma-safe buffers. | 540 | * spi_{async,sync}() calls with dma-safe buffers. |
530 | */ | 541 | */ |
531 | int spi_write_then_read(struct spi_device *spi, | 542 | int spi_write_then_read(struct spi_device *spi, |
532 | const u8 *txbuf, unsigned n_tx, | 543 | const u8 *txbuf, unsigned n_tx, |