diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-11 15:03:34 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-11 15:03:34 -0500 |
| commit | b859e7d13bcc18b56faa7e2f78db5ba8ab874a15 (patch) | |
| tree | 2762ac481bc2b2a472832473b888fff3d7d9b9d4 /drivers/spi/spi-gpio.c | |
| parent | 709d9f09b6aee5828cb8f168f63030608176cd0e (diff) | |
| parent | 0e647037fed5632e7c5989ec359ab84c676888ac (diff) | |
Merge tag 'spi-v3.19' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi updates from Mark Brown:
"Not a huge amount going on this release, mainly new drivers (there's a
couple more waiting that didn't quite make the cut for this release
too):
- An interface for querying if the current transfer is the last in a
message, allowing controllers that need special handling for the
final transfer to use the core message parsing.
- Support for Amlogic Meson SPIFC, Imagination Technologies SFPI,
Intel Quark X1000 and Samsung Exynos 7 controllers"
* tag 'spi-v3.19' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (38 commits)
spi/s3c64xx: Remove redundant runtime PM management
spi: fsl-spi: remove unused variable assignment
spi: spi-fsl-spi: Return an error code in fsl_spi_do_one_msg()
spi: core: Do not mangle error code from kthread_run()
spi: fsl-espi: add (un)prepare_transfer_hardware calls to save power if SPI is not in use
spi: fsl-(e)spi: migrate to generic master queueing
spi/txx9: Deletion of an unnecessary check before the function call "clk_disable"
spi: cadence: Fix 3-to-8 mux mode
spi: cadence: Init HW after reading devicetree attributes
spi: meson: Select REGMAP_MMIO
spi: s3c64xx: add support for exynos7 SPI controller
spi: spi-pxa2xx: SPI support for Intel Quark X1000
spi: meson: meson_spifc_setup_speed() can be static
spi: spi-pxa2xx: Add helpers for regiseters' accessing
spi: spi-mxs: Fix mapping from vmalloc-ed buffer to scatter list
spi: atmel: introduce probe deferring
spi: atmel: remove compat for non DT board when requesting dma chan
spi: meson: Add support for Amlogic Meson SPIFC
spi: meson: Add device tree bindings documentation for SPIFC
spi: core: Add spi_transfer_is_last() helper
...
Diffstat (limited to 'drivers/spi/spi-gpio.c')
| -rw-r--r-- | drivers/spi/spi-gpio.c | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c index 9f595535cf27..4b600d4f8548 100644 --- a/drivers/spi/spi-gpio.c +++ b/drivers/spi/spi-gpio.c | |||
| @@ -48,7 +48,7 @@ struct spi_gpio { | |||
| 48 | struct spi_bitbang bitbang; | 48 | struct spi_bitbang bitbang; |
| 49 | struct spi_gpio_platform_data pdata; | 49 | struct spi_gpio_platform_data pdata; |
| 50 | struct platform_device *pdev; | 50 | struct platform_device *pdev; |
| 51 | int cs_gpios[0]; | 51 | unsigned long cs_gpios[0]; |
| 52 | }; | 52 | }; |
| 53 | 53 | ||
| 54 | /*----------------------------------------------------------------------*/ | 54 | /*----------------------------------------------------------------------*/ |
| @@ -220,7 +220,7 @@ static u32 spi_gpio_spec_txrx_word_mode3(struct spi_device *spi, | |||
| 220 | static void spi_gpio_chipselect(struct spi_device *spi, int is_active) | 220 | static void spi_gpio_chipselect(struct spi_device *spi, int is_active) |
| 221 | { | 221 | { |
| 222 | struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); | 222 | struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); |
| 223 | unsigned int cs = spi_gpio->cs_gpios[spi->chip_select]; | 223 | unsigned long cs = spi_gpio->cs_gpios[spi->chip_select]; |
| 224 | 224 | ||
| 225 | /* set initial clock polarity */ | 225 | /* set initial clock polarity */ |
| 226 | if (is_active) | 226 | if (is_active) |
| @@ -234,7 +234,7 @@ static void spi_gpio_chipselect(struct spi_device *spi, int is_active) | |||
| 234 | 234 | ||
| 235 | static int spi_gpio_setup(struct spi_device *spi) | 235 | static int spi_gpio_setup(struct spi_device *spi) |
| 236 | { | 236 | { |
| 237 | unsigned int cs; | 237 | unsigned long cs; |
| 238 | int status = 0; | 238 | int status = 0; |
| 239 | struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); | 239 | struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); |
| 240 | struct device_node *np = spi->master->dev.of_node; | 240 | struct device_node *np = spi->master->dev.of_node; |
| @@ -249,7 +249,7 @@ static int spi_gpio_setup(struct spi_device *spi) | |||
| 249 | /* | 249 | /* |
| 250 | * ... otherwise, take it from spi->controller_data | 250 | * ... otherwise, take it from spi->controller_data |
| 251 | */ | 251 | */ |
| 252 | cs = (unsigned int)(uintptr_t) spi->controller_data; | 252 | cs = (uintptr_t) spi->controller_data; |
| 253 | } | 253 | } |
| 254 | 254 | ||
| 255 | if (!spi->controller_state) { | 255 | if (!spi->controller_state) { |
| @@ -277,7 +277,7 @@ static int spi_gpio_setup(struct spi_device *spi) | |||
| 277 | static void spi_gpio_cleanup(struct spi_device *spi) | 277 | static void spi_gpio_cleanup(struct spi_device *spi) |
| 278 | { | 278 | { |
| 279 | struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); | 279 | struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); |
| 280 | unsigned int cs = spi_gpio->cs_gpios[spi->chip_select]; | 280 | unsigned long cs = spi_gpio->cs_gpios[spi->chip_select]; |
| 281 | 281 | ||
| 282 | if (cs != SPI_GPIO_NO_CHIPSELECT) | 282 | if (cs != SPI_GPIO_NO_CHIPSELECT) |
| 283 | gpio_free(cs); | 283 | gpio_free(cs); |
| @@ -413,6 +413,7 @@ static int spi_gpio_probe(struct platform_device *pdev) | |||
| 413 | struct spi_gpio_platform_data *pdata; | 413 | struct spi_gpio_platform_data *pdata; |
| 414 | u16 master_flags = 0; | 414 | u16 master_flags = 0; |
| 415 | bool use_of = 0; | 415 | bool use_of = 0; |
| 416 | int num_devices; | ||
| 416 | 417 | ||
| 417 | status = spi_gpio_probe_dt(pdev); | 418 | status = spi_gpio_probe_dt(pdev); |
| 418 | if (status < 0) | 419 | if (status < 0) |
| @@ -422,16 +423,21 @@ static int spi_gpio_probe(struct platform_device *pdev) | |||
| 422 | 423 | ||
| 423 | pdata = dev_get_platdata(&pdev->dev); | 424 | pdata = dev_get_platdata(&pdev->dev); |
| 424 | #ifdef GENERIC_BITBANG | 425 | #ifdef GENERIC_BITBANG |
| 425 | if (!pdata || !pdata->num_chipselect) | 426 | if (!pdata || (!use_of && !pdata->num_chipselect)) |
| 426 | return -ENODEV; | 427 | return -ENODEV; |
| 427 | #endif | 428 | #endif |
| 428 | 429 | ||
| 430 | if (use_of && !SPI_N_CHIPSEL) | ||
| 431 | num_devices = 1; | ||
| 432 | else | ||
| 433 | num_devices = SPI_N_CHIPSEL; | ||
| 434 | |||
| 429 | status = spi_gpio_request(pdata, dev_name(&pdev->dev), &master_flags); | 435 | status = spi_gpio_request(pdata, dev_name(&pdev->dev), &master_flags); |
| 430 | if (status < 0) | 436 | if (status < 0) |
| 431 | return status; | 437 | return status; |
| 432 | 438 | ||
| 433 | master = spi_alloc_master(&pdev->dev, sizeof(*spi_gpio) + | 439 | master = spi_alloc_master(&pdev->dev, sizeof(*spi_gpio) + |
| 434 | (sizeof(int) * SPI_N_CHIPSEL)); | 440 | (sizeof(unsigned long) * num_devices)); |
| 435 | if (!master) { | 441 | if (!master) { |
| 436 | status = -ENOMEM; | 442 | status = -ENOMEM; |
| 437 | goto gpio_free; | 443 | goto gpio_free; |
| @@ -446,7 +452,7 @@ static int spi_gpio_probe(struct platform_device *pdev) | |||
| 446 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); | 452 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); |
| 447 | master->flags = master_flags; | 453 | master->flags = master_flags; |
| 448 | master->bus_num = pdev->id; | 454 | master->bus_num = pdev->id; |
| 449 | master->num_chipselect = SPI_N_CHIPSEL; | 455 | master->num_chipselect = num_devices; |
| 450 | master->setup = spi_gpio_setup; | 456 | master->setup = spi_gpio_setup; |
| 451 | master->cleanup = spi_gpio_cleanup; | 457 | master->cleanup = spi_gpio_cleanup; |
| 452 | #ifdef CONFIG_OF | 458 | #ifdef CONFIG_OF |
| @@ -461,9 +467,18 @@ static int spi_gpio_probe(struct platform_device *pdev) | |||
| 461 | * property of the node. | 467 | * property of the node. |
| 462 | */ | 468 | */ |
| 463 | 469 | ||
| 464 | for (i = 0; i < SPI_N_CHIPSEL; i++) | 470 | if (!SPI_N_CHIPSEL) |
| 465 | spi_gpio->cs_gpios[i] = | 471 | spi_gpio->cs_gpios[0] = SPI_GPIO_NO_CHIPSELECT; |
| 466 | of_get_named_gpio(np, "cs-gpios", i); | 472 | else |
| 473 | for (i = 0; i < SPI_N_CHIPSEL; i++) { | ||
| 474 | status = of_get_named_gpio(np, "cs-gpios", i); | ||
| 475 | if (status < 0) { | ||
| 476 | dev_err(&pdev->dev, | ||
| 477 | "invalid cs-gpios property\n"); | ||
| 478 | goto gpio_free; | ||
| 479 | } | ||
| 480 | spi_gpio->cs_gpios[i] = status; | ||
| 481 | } | ||
| 467 | } | 482 | } |
| 468 | #endif | 483 | #endif |
| 469 | 484 | ||
