diff options
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 { struct spi_bitbang bitbang; struct spi_gpio_platform_data pdata; struct platform_device *pdev; - int cs_gpios[0]; + unsigned long cs_gpios[0]; }; /*----------------------------------------------------------------------*/ @@ -220,7 +220,7 @@ static u32 spi_gpio_spec_txrx_word_mode3(struct spi_device *spi, static void spi_gpio_chipselect(struct spi_device *spi, int is_active) { struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); - unsigned int cs = spi_gpio->cs_gpios[spi->chip_select]; + unsigned long cs = spi_gpio->cs_gpios[spi->chip_select]; /* set initial clock polarity */ if (is_active) @@ -234,7 +234,7 @@ static void spi_gpio_chipselect(struct spi_device *spi, int is_active) static int spi_gpio_setup(struct spi_device *spi) { - unsigned int cs; + unsigned long cs; int status = 0; struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); struct device_node *np = spi->master->dev.of_node; @@ -249,7 +249,7 @@ static int spi_gpio_setup(struct spi_device *spi) /* * ... otherwise, take it from spi->controller_data */ - cs = (unsigned int)(uintptr_t) spi->controller_data; + cs = (uintptr_t) spi->controller_data; } if (!spi->controller_state) { @@ -277,7 +277,7 @@ static int spi_gpio_setup(struct spi_device *spi) static void spi_gpio_cleanup(struct spi_device *spi) { struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); - unsigned int cs = spi_gpio->cs_gpios[spi->chip_select]; + unsigned long cs = spi_gpio->cs_gpios[spi->chip_select]; if (cs != SPI_GPIO_NO_CHIPSELECT) gpio_free(cs); @@ -413,6 +413,7 @@ static int spi_gpio_probe(struct platform_device *pdev) struct spi_gpio_platform_data *pdata; u16 master_flags = 0; bool use_of = 0; + int num_devices; status = spi_gpio_probe_dt(pdev); if (status < 0) @@ -422,16 +423,21 @@ static int spi_gpio_probe(struct platform_device *pdev) pdata = dev_get_platdata(&pdev->dev); #ifdef GENERIC_BITBANG - if (!pdata || !pdata->num_chipselect) + if (!pdata || (!use_of && !pdata->num_chipselect)) return -ENODEV; #endif + if (use_of && !SPI_N_CHIPSEL) + num_devices = 1; + else + num_devices = SPI_N_CHIPSEL; + status = spi_gpio_request(pdata, dev_name(&pdev->dev), &master_flags); if (status < 0) return status; master = spi_alloc_master(&pdev->dev, sizeof(*spi_gpio) + - (sizeof(int) * SPI_N_CHIPSEL)); + (sizeof(unsigned long) * num_devices)); if (!master) { status = -ENOMEM; goto gpio_free; @@ -446,7 +452,7 @@ static int spi_gpio_probe(struct platform_device *pdev) master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); master->flags = master_flags; master->bus_num = pdev->id; - master->num_chipselect = SPI_N_CHIPSEL; + master->num_chipselect = num_devices; master->setup = spi_gpio_setup; master->cleanup = spi_gpio_cleanup; #ifdef CONFIG_OF @@ -461,9 +467,18 @@ static int spi_gpio_probe(struct platform_device *pdev) * property of the node. */ - for (i = 0; i < SPI_N_CHIPSEL; i++) - spi_gpio->cs_gpios[i] = - of_get_named_gpio(np, "cs-gpios", i); + if (!SPI_N_CHIPSEL) + spi_gpio->cs_gpios[0] = SPI_GPIO_NO_CHIPSELECT; + else + for (i = 0; i < SPI_N_CHIPSEL; i++) { + status = of_get_named_gpio(np, "cs-gpios", i); + if (status < 0) { + dev_err(&pdev->dev, + "invalid cs-gpios property\n"); + goto gpio_free; + } + spi_gpio->cs_gpios[i] = status; + } } #endif |