diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-11-01 07:50:43 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-11-01 07:50:43 -0400 |
| commit | 90ae83f7fc32733e5829d806306c0c590f1a383f (patch) | |
| tree | 5b4cd7290c70d9899ca7caa99998395218b15cab | |
| parent | 47c5ba53bc5e5f88b5d1bbb97acd25afc27f74eb (diff) | |
| parent | 65289d6345d93abd860e43fd2119ac176d6cc697 (diff) | |
Merge branch 'next-spi' of git://git.secretlab.ca/git/linux-2.6
* 'next-spi' of git://git.secretlab.ca/git/linux-2.6:
spi/pl022: fix erroneous platform data in U300
spi: fixed odd static string conventions in core code
spi/bfin_spi: only request GPIO on first load
spi/bfin_spi: handle error/status changes after data interrupts
spi: enable spi_board_info to be registered after spi_master
| -rw-r--r-- | arch/arm/mach-u300/spi.c | 2 | ||||
| -rw-r--r-- | drivers/spi/spi.c | 98 | ||||
| -rw-r--r-- | drivers/spi/spi_bfin5xx.c | 22 | ||||
| -rw-r--r-- | include/linux/spi/spi.h | 3 |
4 files changed, 73 insertions, 52 deletions
diff --git a/arch/arm/mach-u300/spi.c b/arch/arm/mach-u300/spi.c index edb2c0d255c2..00869def5420 100644 --- a/arch/arm/mach-u300/spi.c +++ b/arch/arm/mach-u300/spi.c | |||
| @@ -67,7 +67,7 @@ static struct spi_board_info u300_spi_devices[] = { | |||
| 67 | .bus_num = 0, /* Only one bus on this chip */ | 67 | .bus_num = 0, /* Only one bus on this chip */ |
| 68 | .chip_select = 0, | 68 | .chip_select = 0, |
| 69 | /* Means SPI_CS_HIGH, change if e.g low CS */ | 69 | /* Means SPI_CS_HIGH, change if e.g low CS */ |
| 70 | .mode = SPI_MODE_1 | SPI_LSB_FIRST | SPI_LOOP, | 70 | .mode = SPI_MODE_1 | SPI_LOOP, |
| 71 | }, | 71 | }, |
| 72 | #endif | 72 | #endif |
| 73 | }; | 73 | }; |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index b5a78a1f4421..709c836607de 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
| @@ -29,11 +29,6 @@ | |||
| 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 | 31 | ||
| 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) | 32 | static void spidev_release(struct device *dev) |
| 38 | { | 33 | { |
| 39 | struct spi_device *spi = to_spi_device(dev); | 34 | struct spi_device *spi = to_spi_device(dev); |
| @@ -202,11 +197,16 @@ EXPORT_SYMBOL_GPL(spi_register_driver); | |||
| 202 | 197 | ||
| 203 | struct boardinfo { | 198 | struct boardinfo { |
| 204 | struct list_head list; | 199 | struct list_head list; |
| 205 | unsigned n_board_info; | 200 | struct spi_board_info board_info; |
| 206 | struct spi_board_info board_info[0]; | ||
| 207 | }; | 201 | }; |
| 208 | 202 | ||
| 209 | static LIST_HEAD(board_list); | 203 | static LIST_HEAD(board_list); |
| 204 | static LIST_HEAD(spi_master_list); | ||
| 205 | |||
| 206 | /* | ||
| 207 | * Used to protect add/del opertion for board_info list and | ||
| 208 | * spi_master list, and their matching process | ||
| 209 | */ | ||
| 210 | static DEFINE_MUTEX(board_lock); | 210 | static DEFINE_MUTEX(board_lock); |
| 211 | 211 | ||
| 212 | /** | 212 | /** |
| @@ -300,16 +300,16 @@ int spi_add_device(struct spi_device *spi) | |||
| 300 | */ | 300 | */ |
| 301 | status = spi_setup(spi); | 301 | status = spi_setup(spi); |
| 302 | if (status < 0) { | 302 | if (status < 0) { |
| 303 | dev_err(dev, "can't %s %s, status %d\n", | 303 | dev_err(dev, "can't setup %s, status %d\n", |
| 304 | "setup", dev_name(&spi->dev), status); | 304 | dev_name(&spi->dev), status); |
| 305 | goto done; | 305 | goto done; |
| 306 | } | 306 | } |
| 307 | 307 | ||
| 308 | /* Device may be bound to an active driver when this returns */ | 308 | /* Device may be bound to an active driver when this returns */ |
| 309 | status = device_add(&spi->dev); | 309 | status = device_add(&spi->dev); |
| 310 | if (status < 0) | 310 | if (status < 0) |
| 311 | dev_err(dev, "can't %s %s, status %d\n", | 311 | dev_err(dev, "can't add %s, status %d\n", |
| 312 | "add", dev_name(&spi->dev), status); | 312 | dev_name(&spi->dev), status); |
| 313 | else | 313 | else |
| 314 | dev_dbg(dev, "registered child %s\n", dev_name(&spi->dev)); | 314 | dev_dbg(dev, "registered child %s\n", dev_name(&spi->dev)); |
| 315 | 315 | ||
| @@ -371,6 +371,20 @@ struct spi_device *spi_new_device(struct spi_master *master, | |||
| 371 | } | 371 | } |
| 372 | EXPORT_SYMBOL_GPL(spi_new_device); | 372 | EXPORT_SYMBOL_GPL(spi_new_device); |
| 373 | 373 | ||
| 374 | static void spi_match_master_to_boardinfo(struct spi_master *master, | ||
| 375 | struct spi_board_info *bi) | ||
| 376 | { | ||
| 377 | struct spi_device *dev; | ||
| 378 | |||
| 379 | if (master->bus_num != bi->bus_num) | ||
| 380 | return; | ||
| 381 | |||
| 382 | dev = spi_new_device(master, bi); | ||
| 383 | if (!dev) | ||
| 384 | dev_err(master->dev.parent, "can't create new device for %s\n", | ||
| 385 | bi->modalias); | ||
| 386 | } | ||
| 387 | |||
| 374 | /** | 388 | /** |
| 375 | * spi_register_board_info - register SPI devices for a given board | 389 | * spi_register_board_info - register SPI devices for a given board |
| 376 | * @info: array of chip descriptors | 390 | * @info: array of chip descriptors |
| @@ -393,43 +407,25 @@ EXPORT_SYMBOL_GPL(spi_new_device); | |||
| 393 | int __init | 407 | int __init |
| 394 | spi_register_board_info(struct spi_board_info const *info, unsigned n) | 408 | spi_register_board_info(struct spi_board_info const *info, unsigned n) |
| 395 | { | 409 | { |
| 396 | struct boardinfo *bi; | 410 | struct boardinfo *bi; |
| 411 | int i; | ||
| 397 | 412 | ||
| 398 | bi = kmalloc(sizeof(*bi) + n * sizeof *info, GFP_KERNEL); | 413 | bi = kzalloc(n * sizeof(*bi), GFP_KERNEL); |
| 399 | if (!bi) | 414 | if (!bi) |
| 400 | return -ENOMEM; | 415 | return -ENOMEM; |
| 401 | bi->n_board_info = n; | ||
| 402 | memcpy(bi->board_info, info, n * sizeof *info); | ||
| 403 | 416 | ||
| 404 | mutex_lock(&board_lock); | 417 | for (i = 0; i < n; i++, bi++, info++) { |
| 405 | list_add_tail(&bi->list, &board_list); | 418 | struct spi_master *master; |
| 406 | mutex_unlock(&board_lock); | ||
| 407 | return 0; | ||
| 408 | } | ||
| 409 | 419 | ||
| 410 | /* FIXME someone should add support for a __setup("spi", ...) that | 420 | memcpy(&bi->board_info, info, sizeof(*info)); |
| 411 | * creates board info from kernel command lines | 421 | mutex_lock(&board_lock); |
| 412 | */ | 422 | list_add_tail(&bi->list, &board_list); |
| 413 | 423 | list_for_each_entry(master, &spi_master_list, list) | |
| 414 | static void scan_boardinfo(struct spi_master *master) | 424 | spi_match_master_to_boardinfo(master, &bi->board_info); |
| 415 | { | 425 | mutex_unlock(&board_lock); |
| 416 | struct boardinfo *bi; | ||
| 417 | |||
| 418 | mutex_lock(&board_lock); | ||
| 419 | list_for_each_entry(bi, &board_list, list) { | ||
| 420 | struct spi_board_info *chip = bi->board_info; | ||
| 421 | unsigned n; | ||
| 422 | |||
| 423 | for (n = bi->n_board_info; n > 0; n--, chip++) { | ||
| 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 | } | 426 | } |
| 432 | mutex_unlock(&board_lock); | 427 | |
| 428 | return 0; | ||
| 433 | } | 429 | } |
| 434 | 430 | ||
| 435 | /*-------------------------------------------------------------------------*/ | 431 | /*-------------------------------------------------------------------------*/ |
| @@ -512,6 +508,7 @@ int spi_register_master(struct spi_master *master) | |||
| 512 | { | 508 | { |
| 513 | static atomic_t dyn_bus_id = ATOMIC_INIT((1<<15) - 1); | 509 | static atomic_t dyn_bus_id = ATOMIC_INIT((1<<15) - 1); |
| 514 | struct device *dev = master->dev.parent; | 510 | struct device *dev = master->dev.parent; |
| 511 | struct boardinfo *bi; | ||
| 515 | int status = -ENODEV; | 512 | int status = -ENODEV; |
| 516 | int dynamic = 0; | 513 | int dynamic = 0; |
| 517 | 514 | ||
| @@ -547,8 +544,12 @@ int spi_register_master(struct spi_master *master) | |||
| 547 | dev_dbg(dev, "registered master %s%s\n", dev_name(&master->dev), | 544 | dev_dbg(dev, "registered master %s%s\n", dev_name(&master->dev), |
| 548 | dynamic ? " (dynamic)" : ""); | 545 | dynamic ? " (dynamic)" : ""); |
| 549 | 546 | ||
| 550 | /* populate children from any spi device tables */ | 547 | mutex_lock(&board_lock); |
| 551 | scan_boardinfo(master); | 548 | list_add_tail(&master->list, &spi_master_list); |
| 549 | list_for_each_entry(bi, &board_list, list) | ||
| 550 | spi_match_master_to_boardinfo(master, &bi->board_info); | ||
| 551 | mutex_unlock(&board_lock); | ||
| 552 | |||
| 552 | status = 0; | 553 | status = 0; |
| 553 | 554 | ||
| 554 | /* Register devices from the device tree */ | 555 | /* Register devices from the device tree */ |
| @@ -579,7 +580,12 @@ void spi_unregister_master(struct spi_master *master) | |||
| 579 | { | 580 | { |
| 580 | int dummy; | 581 | int dummy; |
| 581 | 582 | ||
| 582 | dummy = device_for_each_child(&master->dev, NULL, __unregister); | 583 | mutex_lock(&board_lock); |
| 584 | list_del(&master->list); | ||
| 585 | mutex_unlock(&board_lock); | ||
| 586 | |||
| 587 | dummy = device_for_each_child(master->dev.parent, &master->dev, | ||
| 588 | __unregister); | ||
| 583 | device_unregister(&master->dev); | 589 | device_unregister(&master->dev); |
| 584 | } | 590 | } |
| 585 | EXPORT_SYMBOL_GPL(spi_unregister_master); | 591 | EXPORT_SYMBOL_GPL(spi_unregister_master); |
| @@ -652,7 +658,7 @@ int spi_setup(struct spi_device *spi) | |||
| 652 | */ | 658 | */ |
| 653 | bad_bits = spi->mode & ~spi->master->mode_bits; | 659 | bad_bits = spi->mode & ~spi->master->mode_bits; |
| 654 | if (bad_bits) { | 660 | if (bad_bits) { |
| 655 | dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n", | 661 | dev_err(&spi->dev, "setup: unsupported mode bits %x\n", |
| 656 | bad_bits); | 662 | bad_bits); |
| 657 | return -EINVAL; | 663 | return -EINVAL; |
| 658 | } | 664 | } |
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c index ab483a0ec6d0..3f223511127b 100644 --- a/drivers/spi/spi_bfin5xx.c +++ b/drivers/spi/spi_bfin5xx.c | |||
| @@ -504,6 +504,15 @@ static irqreturn_t bfin_spi_dma_irq_handler(int irq, void *dev_id) | |||
| 504 | "in dma_irq_handler dmastat:0x%x spistat:0x%x\n", | 504 | "in dma_irq_handler dmastat:0x%x spistat:0x%x\n", |
| 505 | dmastat, spistat); | 505 | dmastat, spistat); |
| 506 | 506 | ||
| 507 | if (drv_data->rx != NULL) { | ||
| 508 | u16 cr = read_CTRL(drv_data); | ||
| 509 | /* discard old RX data and clear RXS */ | ||
| 510 | bfin_spi_dummy_read(drv_data); | ||
| 511 | write_CTRL(drv_data, cr & ~BIT_CTL_ENABLE); /* Disable SPI */ | ||
| 512 | write_CTRL(drv_data, cr & ~BIT_CTL_TIMOD); /* Restore State */ | ||
| 513 | write_STAT(drv_data, BIT_STAT_CLR); /* Clear Status */ | ||
| 514 | } | ||
| 515 | |||
| 507 | clear_dma_irqstat(drv_data->dma_channel); | 516 | clear_dma_irqstat(drv_data->dma_channel); |
| 508 | 517 | ||
| 509 | /* | 518 | /* |
| @@ -1099,12 +1108,15 @@ static int bfin_spi_setup(struct spi_device *spi) | |||
| 1099 | } | 1108 | } |
| 1100 | 1109 | ||
| 1101 | if (chip->chip_select_num >= MAX_CTRL_CS) { | 1110 | if (chip->chip_select_num >= MAX_CTRL_CS) { |
| 1102 | ret = gpio_request(chip->cs_gpio, spi->modalias); | 1111 | /* Only request on first setup */ |
| 1103 | if (ret) { | 1112 | if (spi_get_ctldata(spi) == NULL) { |
| 1104 | dev_err(&spi->dev, "gpio_request() error\n"); | 1113 | ret = gpio_request(chip->cs_gpio, spi->modalias); |
| 1105 | goto pin_error; | 1114 | if (ret) { |
| 1115 | dev_err(&spi->dev, "gpio_request() error\n"); | ||
| 1116 | goto pin_error; | ||
| 1117 | } | ||
| 1118 | gpio_direction_output(chip->cs_gpio, 1); | ||
| 1106 | } | 1119 | } |
| 1107 | gpio_direction_output(chip->cs_gpio, 1); | ||
| 1108 | } | 1120 | } |
| 1109 | 1121 | ||
| 1110 | dev_dbg(&spi->dev, "setup spi chip %s, width is %d, dma is %d\n", | 1122 | dev_dbg(&spi->dev, "setup spi chip %s, width is %d, dma is %d\n", |
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 92e52a1e6af3..b4d7710bc38d 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h | |||
| @@ -204,6 +204,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) | |||
| 204 | /** | 204 | /** |
| 205 | * struct spi_master - interface to SPI master controller | 205 | * struct spi_master - interface to SPI master controller |
| 206 | * @dev: device interface to this driver | 206 | * @dev: device interface to this driver |
| 207 | * @list: link with the global spi_master list | ||
| 207 | * @bus_num: board-specific (and often SOC-specific) identifier for a | 208 | * @bus_num: board-specific (and often SOC-specific) identifier for a |
| 208 | * given SPI controller. | 209 | * given SPI controller. |
| 209 | * @num_chipselect: chipselects are used to distinguish individual | 210 | * @num_chipselect: chipselects are used to distinguish individual |
| @@ -238,6 +239,8 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) | |||
| 238 | struct spi_master { | 239 | struct spi_master { |
| 239 | struct device dev; | 240 | struct device dev; |
| 240 | 241 | ||
| 242 | struct list_head list; | ||
| 243 | |||
| 241 | /* other than negative (== assign one dynamically), bus_num is fully | 244 | /* other than negative (== assign one dynamically), bus_num is fully |
| 242 | * board-specific. usually that simplifies to being SOC-specific. | 245 | * board-specific. usually that simplifies to being SOC-specific. |
| 243 | * example: one SOC has three SPI controllers, numbered 0..2, | 246 | * example: one SOC has three SPI controllers, numbered 0..2, |
