diff options
Diffstat (limited to 'drivers/spi/spi.c')
-rw-r--r-- | drivers/spi/spi.c | 193 |
1 files changed, 137 insertions, 56 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index b5a78a1f4421..2e13a14bba3f 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -28,12 +28,8 @@ | |||
28 | #include <linux/mod_devicetable.h> | 28 | #include <linux/mod_devicetable.h> |
29 | #include <linux/spi/spi.h> | 29 | #include <linux/spi/spi.h> |
30 | #include <linux/of_spi.h> | 30 | #include <linux/of_spi.h> |
31 | #include <linux/pm_runtime.h> | ||
31 | 32 | ||
32 | |||
33 | /* SPI bustype and spi_master class are registered after board init code | ||
34 | * provides the SPI device tables, ensuring that both are present by the | ||
35 | * time controller driver registration causes spi_devices to "enumerate". | ||
36 | */ | ||
37 | static void spidev_release(struct device *dev) | 33 | static void spidev_release(struct device *dev) |
38 | { | 34 | { |
39 | struct spi_device *spi = to_spi_device(dev); | 35 | struct spi_device *spi = to_spi_device(dev); |
@@ -105,9 +101,8 @@ static int spi_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
105 | return 0; | 101 | return 0; |
106 | } | 102 | } |
107 | 103 | ||
108 | #ifdef CONFIG_PM | 104 | #ifdef CONFIG_PM_SLEEP |
109 | 105 | static int spi_legacy_suspend(struct device *dev, pm_message_t message) | |
110 | static int spi_suspend(struct device *dev, pm_message_t message) | ||
111 | { | 106 | { |
112 | int value = 0; | 107 | int value = 0; |
113 | struct spi_driver *drv = to_spi_driver(dev->driver); | 108 | struct spi_driver *drv = to_spi_driver(dev->driver); |
@@ -122,7 +117,7 @@ static int spi_suspend(struct device *dev, pm_message_t message) | |||
122 | return value; | 117 | return value; |
123 | } | 118 | } |
124 | 119 | ||
125 | static int spi_resume(struct device *dev) | 120 | static int spi_legacy_resume(struct device *dev) |
126 | { | 121 | { |
127 | int value = 0; | 122 | int value = 0; |
128 | struct spi_driver *drv = to_spi_driver(dev->driver); | 123 | struct spi_driver *drv = to_spi_driver(dev->driver); |
@@ -137,18 +132,94 @@ static int spi_resume(struct device *dev) | |||
137 | return value; | 132 | return value; |
138 | } | 133 | } |
139 | 134 | ||
135 | static int spi_pm_suspend(struct device *dev) | ||
136 | { | ||
137 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | ||
138 | |||
139 | if (pm) | ||
140 | return pm_generic_suspend(dev); | ||
141 | else | ||
142 | return spi_legacy_suspend(dev, PMSG_SUSPEND); | ||
143 | } | ||
144 | |||
145 | static int spi_pm_resume(struct device *dev) | ||
146 | { | ||
147 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | ||
148 | |||
149 | if (pm) | ||
150 | return pm_generic_resume(dev); | ||
151 | else | ||
152 | return spi_legacy_resume(dev); | ||
153 | } | ||
154 | |||
155 | static int spi_pm_freeze(struct device *dev) | ||
156 | { | ||
157 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | ||
158 | |||
159 | if (pm) | ||
160 | return pm_generic_freeze(dev); | ||
161 | else | ||
162 | return spi_legacy_suspend(dev, PMSG_FREEZE); | ||
163 | } | ||
164 | |||
165 | static int spi_pm_thaw(struct device *dev) | ||
166 | { | ||
167 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | ||
168 | |||
169 | if (pm) | ||
170 | return pm_generic_thaw(dev); | ||
171 | else | ||
172 | return spi_legacy_resume(dev); | ||
173 | } | ||
174 | |||
175 | static int spi_pm_poweroff(struct device *dev) | ||
176 | { | ||
177 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | ||
178 | |||
179 | if (pm) | ||
180 | return pm_generic_poweroff(dev); | ||
181 | else | ||
182 | return spi_legacy_suspend(dev, PMSG_HIBERNATE); | ||
183 | } | ||
184 | |||
185 | static int spi_pm_restore(struct device *dev) | ||
186 | { | ||
187 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | ||
188 | |||
189 | if (pm) | ||
190 | return pm_generic_restore(dev); | ||
191 | else | ||
192 | return spi_legacy_resume(dev); | ||
193 | } | ||
140 | #else | 194 | #else |
141 | #define spi_suspend NULL | 195 | #define spi_pm_suspend NULL |
142 | #define spi_resume NULL | 196 | #define spi_pm_resume NULL |
197 | #define spi_pm_freeze NULL | ||
198 | #define spi_pm_thaw NULL | ||
199 | #define spi_pm_poweroff NULL | ||
200 | #define spi_pm_restore NULL | ||
143 | #endif | 201 | #endif |
144 | 202 | ||
203 | static const struct dev_pm_ops spi_pm = { | ||
204 | .suspend = spi_pm_suspend, | ||
205 | .resume = spi_pm_resume, | ||
206 | .freeze = spi_pm_freeze, | ||
207 | .thaw = spi_pm_thaw, | ||
208 | .poweroff = spi_pm_poweroff, | ||
209 | .restore = spi_pm_restore, | ||
210 | SET_RUNTIME_PM_OPS( | ||
211 | pm_generic_runtime_suspend, | ||
212 | pm_generic_runtime_resume, | ||
213 | pm_generic_runtime_idle | ||
214 | ) | ||
215 | }; | ||
216 | |||
145 | struct bus_type spi_bus_type = { | 217 | struct bus_type spi_bus_type = { |
146 | .name = "spi", | 218 | .name = "spi", |
147 | .dev_attrs = spi_dev_attrs, | 219 | .dev_attrs = spi_dev_attrs, |
148 | .match = spi_match_device, | 220 | .match = spi_match_device, |
149 | .uevent = spi_uevent, | 221 | .uevent = spi_uevent, |
150 | .suspend = spi_suspend, | 222 | .pm = &spi_pm, |
151 | .resume = spi_resume, | ||
152 | }; | 223 | }; |
153 | EXPORT_SYMBOL_GPL(spi_bus_type); | 224 | EXPORT_SYMBOL_GPL(spi_bus_type); |
154 | 225 | ||
@@ -202,11 +273,16 @@ EXPORT_SYMBOL_GPL(spi_register_driver); | |||
202 | 273 | ||
203 | struct boardinfo { | 274 | struct boardinfo { |
204 | struct list_head list; | 275 | struct list_head list; |
205 | unsigned n_board_info; | 276 | struct spi_board_info board_info; |
206 | struct spi_board_info board_info[0]; | ||
207 | }; | 277 | }; |
208 | 278 | ||
209 | static LIST_HEAD(board_list); | 279 | static LIST_HEAD(board_list); |
280 | static LIST_HEAD(spi_master_list); | ||
281 | |||
282 | /* | ||
283 | * Used to protect add/del opertion for board_info list and | ||
284 | * spi_master list, and their matching process | ||
285 | */ | ||
210 | static DEFINE_MUTEX(board_lock); | 286 | static DEFINE_MUTEX(board_lock); |
211 | 287 | ||
212 | /** | 288 | /** |
@@ -300,16 +376,16 @@ int spi_add_device(struct spi_device *spi) | |||
300 | */ | 376 | */ |
301 | status = spi_setup(spi); | 377 | status = spi_setup(spi); |
302 | if (status < 0) { | 378 | if (status < 0) { |
303 | dev_err(dev, "can't %s %s, status %d\n", | 379 | dev_err(dev, "can't setup %s, status %d\n", |
304 | "setup", dev_name(&spi->dev), status); | 380 | dev_name(&spi->dev), status); |
305 | goto done; | 381 | goto done; |
306 | } | 382 | } |
307 | 383 | ||
308 | /* Device may be bound to an active driver when this returns */ | 384 | /* Device may be bound to an active driver when this returns */ |
309 | status = device_add(&spi->dev); | 385 | status = device_add(&spi->dev); |
310 | if (status < 0) | 386 | if (status < 0) |
311 | dev_err(dev, "can't %s %s, status %d\n", | 387 | dev_err(dev, "can't add %s, status %d\n", |
312 | "add", dev_name(&spi->dev), status); | 388 | dev_name(&spi->dev), status); |
313 | else | 389 | else |
314 | dev_dbg(dev, "registered child %s\n", dev_name(&spi->dev)); | 390 | dev_dbg(dev, "registered child %s\n", dev_name(&spi->dev)); |
315 | 391 | ||
@@ -371,6 +447,20 @@ struct spi_device *spi_new_device(struct spi_master *master, | |||
371 | } | 447 | } |
372 | EXPORT_SYMBOL_GPL(spi_new_device); | 448 | EXPORT_SYMBOL_GPL(spi_new_device); |
373 | 449 | ||
450 | static void spi_match_master_to_boardinfo(struct spi_master *master, | ||
451 | struct spi_board_info *bi) | ||
452 | { | ||
453 | struct spi_device *dev; | ||
454 | |||
455 | if (master->bus_num != bi->bus_num) | ||
456 | return; | ||
457 | |||
458 | dev = spi_new_device(master, bi); | ||
459 | if (!dev) | ||
460 | dev_err(master->dev.parent, "can't create new device for %s\n", | ||
461 | bi->modalias); | ||
462 | } | ||
463 | |||
374 | /** | 464 | /** |
375 | * spi_register_board_info - register SPI devices for a given board | 465 | * spi_register_board_info - register SPI devices for a given board |
376 | * @info: array of chip descriptors | 466 | * @info: array of chip descriptors |
@@ -393,43 +483,25 @@ EXPORT_SYMBOL_GPL(spi_new_device); | |||
393 | int __init | 483 | int __init |
394 | spi_register_board_info(struct spi_board_info const *info, unsigned n) | 484 | spi_register_board_info(struct spi_board_info const *info, unsigned n) |
395 | { | 485 | { |
396 | struct boardinfo *bi; | 486 | struct boardinfo *bi; |
487 | int i; | ||
397 | 488 | ||
398 | bi = kmalloc(sizeof(*bi) + n * sizeof *info, GFP_KERNEL); | 489 | bi = kzalloc(n * sizeof(*bi), GFP_KERNEL); |
399 | if (!bi) | 490 | if (!bi) |
400 | return -ENOMEM; | 491 | return -ENOMEM; |
401 | bi->n_board_info = n; | ||
402 | memcpy(bi->board_info, info, n * sizeof *info); | ||
403 | |||
404 | mutex_lock(&board_lock); | ||
405 | list_add_tail(&bi->list, &board_list); | ||
406 | mutex_unlock(&board_lock); | ||
407 | return 0; | ||
408 | } | ||
409 | 492 | ||
410 | /* FIXME someone should add support for a __setup("spi", ...) that | 493 | for (i = 0; i < n; i++, bi++, info++) { |
411 | * creates board info from kernel command lines | 494 | struct spi_master *master; |
412 | */ | ||
413 | |||
414 | static void scan_boardinfo(struct spi_master *master) | ||
415 | { | ||
416 | struct boardinfo *bi; | ||
417 | 495 | ||
418 | mutex_lock(&board_lock); | 496 | memcpy(&bi->board_info, info, sizeof(*info)); |
419 | list_for_each_entry(bi, &board_list, list) { | 497 | mutex_lock(&board_lock); |
420 | struct spi_board_info *chip = bi->board_info; | 498 | list_add_tail(&bi->list, &board_list); |
421 | unsigned n; | 499 | list_for_each_entry(master, &spi_master_list, list) |
422 | 500 | spi_match_master_to_boardinfo(master, &bi->board_info); | |
423 | for (n = bi->n_board_info; n > 0; n--, chip++) { | 501 | mutex_unlock(&board_lock); |
424 | if (chip->bus_num != master->bus_num) | ||
425 | continue; | ||
426 | /* NOTE: this relies on spi_new_device to | ||
427 | * issue diagnostics when given bogus inputs | ||
428 | */ | ||
429 | (void) spi_new_device(master, chip); | ||
430 | } | ||
431 | } | 502 | } |
432 | mutex_unlock(&board_lock); | 503 | |
504 | return 0; | ||
433 | } | 505 | } |
434 | 506 | ||
435 | /*-------------------------------------------------------------------------*/ | 507 | /*-------------------------------------------------------------------------*/ |
@@ -512,6 +584,7 @@ int spi_register_master(struct spi_master *master) | |||
512 | { | 584 | { |
513 | static atomic_t dyn_bus_id = ATOMIC_INIT((1<<15) - 1); | 585 | static atomic_t dyn_bus_id = ATOMIC_INIT((1<<15) - 1); |
514 | struct device *dev = master->dev.parent; | 586 | struct device *dev = master->dev.parent; |
587 | struct boardinfo *bi; | ||
515 | int status = -ENODEV; | 588 | int status = -ENODEV; |
516 | int dynamic = 0; | 589 | int dynamic = 0; |
517 | 590 | ||
@@ -547,8 +620,12 @@ int spi_register_master(struct spi_master *master) | |||
547 | dev_dbg(dev, "registered master %s%s\n", dev_name(&master->dev), | 620 | dev_dbg(dev, "registered master %s%s\n", dev_name(&master->dev), |
548 | dynamic ? " (dynamic)" : ""); | 621 | dynamic ? " (dynamic)" : ""); |
549 | 622 | ||
550 | /* populate children from any spi device tables */ | 623 | mutex_lock(&board_lock); |
551 | scan_boardinfo(master); | 624 | list_add_tail(&master->list, &spi_master_list); |
625 | list_for_each_entry(bi, &board_list, list) | ||
626 | spi_match_master_to_boardinfo(master, &bi->board_info); | ||
627 | mutex_unlock(&board_lock); | ||
628 | |||
552 | status = 0; | 629 | status = 0; |
553 | 630 | ||
554 | /* Register devices from the device tree */ | 631 | /* Register devices from the device tree */ |
@@ -579,6 +656,10 @@ void spi_unregister_master(struct spi_master *master) | |||
579 | { | 656 | { |
580 | int dummy; | 657 | int dummy; |
581 | 658 | ||
659 | mutex_lock(&board_lock); | ||
660 | list_del(&master->list); | ||
661 | mutex_unlock(&board_lock); | ||
662 | |||
582 | dummy = device_for_each_child(&master->dev, NULL, __unregister); | 663 | dummy = device_for_each_child(&master->dev, NULL, __unregister); |
583 | device_unregister(&master->dev); | 664 | device_unregister(&master->dev); |
584 | } | 665 | } |
@@ -652,7 +733,7 @@ int spi_setup(struct spi_device *spi) | |||
652 | */ | 733 | */ |
653 | bad_bits = spi->mode & ~spi->master->mode_bits; | 734 | bad_bits = spi->mode & ~spi->master->mode_bits; |
654 | if (bad_bits) { | 735 | if (bad_bits) { |
655 | dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n", | 736 | dev_err(&spi->dev, "setup: unsupported mode bits %x\n", |
656 | bad_bits); | 737 | bad_bits); |
657 | return -EINVAL; | 738 | return -EINVAL; |
658 | } | 739 | } |
@@ -876,7 +957,7 @@ EXPORT_SYMBOL_GPL(spi_sync); | |||
876 | * drivers may DMA directly into and out of the message buffers. | 957 | * drivers may DMA directly into and out of the message buffers. |
877 | * | 958 | * |
878 | * This call should be used by drivers that require exclusive access to the | 959 | * This call should be used by drivers that require exclusive access to the |
879 | * SPI bus. It has to be preceeded by a spi_bus_lock call. The SPI bus must | 960 | * SPI bus. It has to be preceded by a spi_bus_lock call. The SPI bus must |
880 | * be released by a spi_bus_unlock call when the exclusive access is over. | 961 | * be released by a spi_bus_unlock call when the exclusive access is over. |
881 | * | 962 | * |
882 | * It returns zero on success, else a negative error code. | 963 | * It returns zero on success, else a negative error code. |
@@ -966,8 +1047,8 @@ static u8 *buf; | |||
966 | * spi_{async,sync}() calls with dma-safe buffers. | 1047 | * spi_{async,sync}() calls with dma-safe buffers. |
967 | */ | 1048 | */ |
968 | int spi_write_then_read(struct spi_device *spi, | 1049 | int spi_write_then_read(struct spi_device *spi, |
969 | const u8 *txbuf, unsigned n_tx, | 1050 | const void *txbuf, unsigned n_tx, |
970 | u8 *rxbuf, unsigned n_rx) | 1051 | void *rxbuf, unsigned n_rx) |
971 | { | 1052 | { |
972 | static DEFINE_MUTEX(lock); | 1053 | static DEFINE_MUTEX(lock); |
973 | 1054 | ||