diff options
Diffstat (limited to 'drivers/spi/spi-gpio.c')
| -rw-r--r-- | drivers/spi/spi-gpio.c | 59 |
1 files changed, 35 insertions, 24 deletions
diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c index c7cf0b7a069..9f595535cf2 100644 --- a/drivers/spi/spi-gpio.c +++ b/drivers/spi/spi-gpio.c @@ -19,9 +19,9 @@ */ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/platform_device.h> #include <linux/gpio.h> +#include <linux/of.h> #include <linux/of_device.h> #include <linux/of_gpio.h> @@ -114,17 +114,17 @@ spi_to_pdata(const struct spi_device *spi) static inline void setsck(const struct spi_device *spi, int is_on) { - gpio_set_value(SPI_SCK_GPIO, is_on); + gpio_set_value_cansleep(SPI_SCK_GPIO, is_on); } static inline void setmosi(const struct spi_device *spi, int is_on) { - gpio_set_value(SPI_MOSI_GPIO, is_on); + gpio_set_value_cansleep(SPI_MOSI_GPIO, is_on); } static inline int getmiso(const struct spi_device *spi) { - return !!gpio_get_value(SPI_MISO_GPIO); + return !!gpio_get_value_cansleep(SPI_MISO_GPIO); } #undef pdata @@ -228,7 +228,7 @@ static void spi_gpio_chipselect(struct spi_device *spi, int is_active) if (cs != SPI_GPIO_NO_CHIPSELECT) { /* SPI is normally active-low */ - gpio_set_value(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active); + gpio_set_value_cansleep(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active); } } @@ -239,9 +239,6 @@ static int spi_gpio_setup(struct spi_device *spi) struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); struct device_node *np = spi->master->dev.of_node; - if (spi->bits_per_word > 32) - return -EINVAL; - if (np) { /* * In DT environments, the CS GPIOs have already been @@ -252,7 +249,7 @@ static int spi_gpio_setup(struct spi_device *spi) /* * ... otherwise, take it from spi->controller_data */ - cs = (unsigned int) spi->controller_data; + cs = (unsigned int)(uintptr_t) spi->controller_data; } if (!spi->controller_state) { @@ -265,9 +262,9 @@ static int spi_gpio_setup(struct spi_device *spi) } } if (!status) { - status = spi_bitbang_setup(spi); /* in case it was initialized from static board data */ spi_gpio->cs_gpios[spi->chip_select] = cs; + status = spi_bitbang_setup(spi); } if (status) { @@ -343,7 +340,7 @@ done: } #ifdef CONFIG_OF -static struct of_device_id spi_gpio_dt_ids[] = { +static const struct of_device_id spi_gpio_dt_ids[] = { { .compatible = "spi-gpio" }, {} }; @@ -365,9 +362,26 @@ static int spi_gpio_probe_dt(struct platform_device *pdev) if (!pdata) return -ENOMEM; - pdata->sck = of_get_named_gpio(np, "gpio-sck", 0); - pdata->miso = of_get_named_gpio(np, "gpio-miso", 0); - pdata->mosi = of_get_named_gpio(np, "gpio-mosi", 0); + ret = of_get_named_gpio(np, "gpio-sck", 0); + if (ret < 0) { + dev_err(&pdev->dev, "gpio-sck property not found\n"); + goto error_free; + } + pdata->sck = ret; + + ret = of_get_named_gpio(np, "gpio-miso", 0); + if (ret < 0) { + dev_info(&pdev->dev, "gpio-miso property not found, switching to no-rx mode\n"); + pdata->miso = SPI_GPIO_NO_MISO; + } else + pdata->miso = ret; + + ret = of_get_named_gpio(np, "gpio-mosi", 0); + if (ret < 0) { + dev_info(&pdev->dev, "gpio-mosi property not found, switching to no-tx mode\n"); + pdata->mosi = SPI_GPIO_NO_MOSI; + } else + pdata->mosi = ret; ret = of_property_read_u32(np, "num-chipselects", &tmp); if (ret < 0) { @@ -406,7 +420,7 @@ static int spi_gpio_probe(struct platform_device *pdev) if (status > 0) use_of = 1; - pdata = pdev->dev.platform_data; + pdata = dev_get_platdata(&pdev->dev); #ifdef GENERIC_BITBANG if (!pdata || !pdata->num_chipselect) return -ENODEV; @@ -429,6 +443,7 @@ static int spi_gpio_probe(struct platform_device *pdev) if (pdata) spi_gpio->pdata = *pdata; + 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; @@ -452,7 +467,7 @@ static int spi_gpio_probe(struct platform_device *pdev) } #endif - spi_gpio->bitbang.master = spi_master_get(master); + spi_gpio->bitbang.master = master; spi_gpio->bitbang.chipselect = spi_gpio_chipselect; if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) { @@ -471,7 +486,6 @@ static int spi_gpio_probe(struct platform_device *pdev) status = spi_bitbang_start(&spi_gpio->bitbang); if (status < 0) { - spi_master_put(spi_gpio->bitbang.master); gpio_free: if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO) gpio_free(SPI_MISO_GPIO); @@ -488,24 +502,21 @@ static int spi_gpio_remove(struct platform_device *pdev) { struct spi_gpio *spi_gpio; struct spi_gpio_platform_data *pdata; - int status; spi_gpio = platform_get_drvdata(pdev); - pdata = pdev->dev.platform_data; + pdata = dev_get_platdata(&pdev->dev); /* stop() unregisters child devices too */ - status = spi_bitbang_stop(&spi_gpio->bitbang); - spi_master_put(spi_gpio->bitbang.master); - - platform_set_drvdata(pdev, NULL); + spi_bitbang_stop(&spi_gpio->bitbang); if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO) gpio_free(SPI_MISO_GPIO); if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI) gpio_free(SPI_MOSI_GPIO); gpio_free(SPI_SCK_GPIO); + spi_master_put(spi_gpio->bitbang.master); - return status; + return 0; } MODULE_ALIAS("platform:" DRIVER_NAME); |
