diff options
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/Kconfig | 2 | ||||
-rw-r--r-- | drivers/spi/spi-rspi.c | 14 | ||||
-rw-r--r-- | drivers/spi/spi-sc18is602.c | 9 | ||||
-rw-r--r-- | drivers/spi/spi-st-ssc4.c | 19 |
4 files changed, 33 insertions, 11 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index a49343ba1e63..b7995474148c 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -566,7 +566,7 @@ config SPI_SC18IS602 config SPI_SH_MSIOF tristate "SuperH MSIOF SPI controller" depends on HAVE_CLK && HAS_DMA - depends on SUPERH || ARCH_RENESAS || COMPILE_TEST + depends on ARCH_SHMOBILE || ARCH_RENESAS || COMPILE_TEST help SPI driver for SuperH and SH Mobile MSIOF blocks. diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 818843336932..a816f07e168e 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -295,14 +295,24 @@ static int rspi_set_config_register(struct rspi_data *rspi, int access_size) static int rspi_rz_set_config_register(struct rspi_data *rspi, int access_size) { int spbr; + int div = 0; + unsigned long clksrc; /* Sets output mode, MOSI signal, and (optionally) loopback */ rspi_write8(rspi, rspi->sppcr, RSPI_SPPCR); + clksrc = clk_get_rate(rspi->clk); + while (div < 3) { + if (rspi->max_speed_hz >= clksrc/4) /* 4=(CLK/2)/2 */ + break; + div++; + clksrc /= 2; + } + /* Sets transfer bit rate */ - spbr = DIV_ROUND_UP(clk_get_rate(rspi->clk), - 2 * rspi->max_speed_hz) - 1; + spbr = DIV_ROUND_UP(clksrc, 2 * rspi->max_speed_hz) - 1; rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR); + rspi->spcmd |= div << 2; /* Disable dummy transmission, set byte access */ rspi_write8(rspi, SPDCR_SPLBYTE, RSPI_SPDCR); diff --git a/drivers/spi/spi-sc18is602.c b/drivers/spi/spi-sc18is602.c index 36af4d48a700..f63714ffb62f 100644 --- a/drivers/spi/spi-sc18is602.c +++ b/drivers/spi/spi-sc18is602.c @@ -23,6 +23,7 @@ #include <linux/pm_runtime.h> #include <linux/of.h> #include <linux/platform_data/sc18is602.h> +#include <linux/gpio/consumer.h> enum chips { sc18is602, sc18is602b, sc18is603 }; @@ -50,6 +51,8 @@ struct sc18is602 { u8 buffer[SC18IS602_BUFSIZ + 1]; int tlen; /* Data queued for tx in buffer */ int rindex; /* Receive data index in buffer */ + + struct gpio_desc *reset; }; static int sc18is602_wait_ready(struct sc18is602 *hw, int len) @@ -257,6 +260,12 @@ static int sc18is602_probe(struct i2c_client *client, hw = spi_master_get_devdata(master); i2c_set_clientdata(client, hw); + /* assert reset and then release */ + hw->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(hw->reset)) + return PTR_ERR(hw->reset); + gpiod_set_value_cansleep(hw->reset, 0); + hw->master = master; hw->client = client; hw->dev = dev; diff --git a/drivers/spi/spi-st-ssc4.c b/drivers/spi/spi-st-ssc4.c index a56eca0e95a6..e54b59638458 100644 --- a/drivers/spi/spi-st-ssc4.c +++ b/drivers/spi/spi-st-ssc4.c @@ -175,10 +175,7 @@ static int spi_st_transfer_one(struct spi_master *master, static void spi_st_cleanup(struct spi_device *spi) { - int cs = spi->cs_gpio; - - if (gpio_is_valid(cs)) - devm_gpio_free(&spi->dev, cs); + gpio_free(spi->cs_gpio); } /* the spi->mode bits understood by this driver: */ @@ -201,14 +198,15 @@ static int spi_st_setup(struct spi_device *spi) return -EINVAL; } - if (devm_gpio_request(&spi->dev, cs, dev_name(&spi->dev))) { + ret = gpio_request(cs, dev_name(&spi->dev)); + if (ret) { dev_err(&spi->dev, "could not request gpio:%d\n", cs); - return -EINVAL; + return ret; } ret = gpio_direction_output(cs, spi->mode & SPI_CS_HIGH); if (ret) - return ret; + goto out_free_gpio; spi_st_clk = clk_get_rate(spi_st->clk); @@ -217,7 +215,8 @@ static int spi_st_setup(struct spi_device *spi) if (sscbrg < 0x07 || sscbrg > BIT(16)) { dev_err(&spi->dev, "baudrate %d outside valid range %d\n", sscbrg, hz); - return -EINVAL; + ret = -EINVAL; + goto out_free_gpio; } spi_st->baud = spi_st_clk / (2 * sscbrg); @@ -266,6 +265,10 @@ static int spi_st_setup(struct spi_device *spi) readl_relaxed(spi_st->base + SSC_RBUF); return 0; + +out_free_gpio: + gpio_free(cs); + return ret; } /* Interrupt fired when TX shift register becomes empty */ |