From 8d4a6cad7adb3ddac32cd52635f20e11de11a658 Mon Sep 17 00:00:00 2001 From: Jiada Wang Date: Mon, 1 May 2017 03:31:44 -0700 Subject: spi: imx: dynamic burst length adjust for PIO mode previously burst length (BURST_LENGTH) is always set to equal to bits_per_word, causes a 10us gap between each word in transfer, which significantly affects performance. This patch uses 32 bits transfer to simulate lower bits transfer, and adjusts burst length runtimely to use biggeest burst length as possible to reduce the gaps in transfer for PIO mode. Signed-off-by: Jiada Wang Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 149 insertions(+), 8 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index b402530a7a9a..782045f0d79e 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -56,9 +56,11 @@ /* The maximum bytes that a sdma BD can transfer.*/ #define MAX_SDMA_BD_BYTES (1 << 15) +#define MX51_ECSPI_CTRL_MAX_BURST 512 struct spi_imx_config { unsigned int speed_hz; unsigned int bpw; + unsigned int len; }; enum spi_imx_devtype { @@ -97,12 +99,14 @@ struct spi_imx_data { unsigned int bytes_per_word; unsigned int spi_drctl; - unsigned int count; + unsigned int count, count_index; void (*tx)(struct spi_imx_data *); void (*rx)(struct spi_imx_data *); void *rx_buf; const void *tx_buf; unsigned int txfifo; /* number of words pushed in tx FIFO */ + unsigned int dynamic_burst, bpw_rx; + unsigned int bpw_w; /* DMA */ bool usedma; @@ -252,6 +256,7 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, #define MX51_ECSPI_CTRL_PREDIV_OFFSET 12 #define MX51_ECSPI_CTRL_CS(cs) ((cs) << 18) #define MX51_ECSPI_CTRL_BL_OFFSET 20 +#define MX51_ECSPI_CTRL_BL_MASK (0xfff << 20) #define MX51_ECSPI_CONFIG 0x0c #define MX51_ECSPI_CONFIG_SCLKPHA(cs) (1 << ((cs) + 0)) @@ -279,6 +284,71 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, #define MX51_ECSPI_TESTREG 0x20 #define MX51_ECSPI_TESTREG_LBC BIT(31) +static void spi_imx_u32_swap_u8(struct spi_transfer *transfer, u32 *buf) +{ + int i; + + for (i = 0; i < transfer->len / 4; i++) + *(buf + i) = cpu_to_be32(*(buf + i)); +} + +static void spi_imx_u32_swap_u16(struct spi_transfer *transfer, u32 *buf) +{ + int i; + + for (i = 0; i < transfer->len / 4; i++) { + u16 *temp = (u16 *)buf; + + *(temp + i * 2) = cpu_to_be16(*(temp + i * 2)); + *(temp + i * 2 + 1) = cpu_to_be16(*(temp + i * 2 + 1)); + + *(buf + i) = cpu_to_be32(*(buf + i)); + } +} + +static void spi_imx_buf_rx_swap(struct spi_imx_data *spi_imx) +{ + if (!spi_imx->bpw_rx) { + spi_imx_buf_rx_u32(spi_imx); + return; + } + + if (spi_imx->bpw_w == 1) + spi_imx_buf_rx_u8(spi_imx); + else if (spi_imx->bpw_w == 2) + spi_imx_buf_rx_u16(spi_imx); +} + +static void spi_imx_buf_tx_swap(struct spi_imx_data *spi_imx) +{ + u32 ctrl, val; + + if (spi_imx->count == spi_imx->count_index) { + spi_imx->count_index = spi_imx->count > sizeof(u32) ? + spi_imx->count % sizeof(u32) : 0; + ctrl = readl(spi_imx->base + MX51_ECSPI_CTRL); + ctrl &= ~MX51_ECSPI_CTRL_BL_MASK; + if (spi_imx->count >= sizeof(u32)) { + val = spi_imx->count - spi_imx->count_index; + } else { + val = spi_imx->bpw_w; + spi_imx->bpw_rx = 1; + } + ctrl |= ((val * 8 - 1) << MX51_ECSPI_CTRL_BL_OFFSET); + writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL); + } + + if (spi_imx->count >= sizeof(u32)) { + spi_imx_buf_tx_u32(spi_imx); + return; + } + + if (spi_imx->bpw_w == 1) + spi_imx_buf_tx_u8(spi_imx); + else if (spi_imx->bpw_w == 2) + spi_imx_buf_tx_u16(spi_imx); +} + /* MX51 eCSPI */ static unsigned int mx51_ecspi_clkdiv(struct spi_imx_data *spi_imx, unsigned int fspi, unsigned int *fres) @@ -370,7 +440,15 @@ static int mx51_ecspi_config(struct spi_device *spi, /* set chip select to use */ ctrl |= MX51_ECSPI_CTRL_CS(spi->chip_select); - ctrl |= (config->bpw - 1) << MX51_ECSPI_CTRL_BL_OFFSET; + if (spi_imx->dynamic_burst) { + if (config->len > MX51_ECSPI_CTRL_MAX_BURST) + ctrl |= MX51_ECSPI_CTRL_BL_MASK; + else + ctrl |= (((config->len - config->len % 4) * 8 - 1) << + MX51_ECSPI_CTRL_BL_OFFSET); + } else { + ctrl |= (config->bpw - 1) << MX51_ECSPI_CTRL_BL_OFFSET; + } cfg |= MX51_ECSPI_CONFIG_SBBCTRL(spi->chip_select); @@ -805,6 +883,8 @@ static void spi_imx_push(struct spi_imx_data *spi_imx) while (spi_imx->txfifo < spi_imx_get_fifosize(spi_imx)) { if (!spi_imx->count) break; + if (spi_imx->txfifo && (spi_imx->count == spi_imx->count_index)) + break; spi_imx->tx(spi_imx); spi_imx->txfifo++; } @@ -895,8 +975,12 @@ static int spi_imx_setupxfer(struct spi_device *spi, struct spi_imx_config config; int ret; + spi_imx->dynamic_burst = 0; + spi_imx->bpw_rx = 0; + config.bpw = t ? t->bits_per_word : spi->bits_per_word; config.speed_hz = t ? t->speed_hz : spi->max_speed_hz; + config.len = t->len; if (!config.speed_hz) config.speed_hz = spi->max_speed_hz; @@ -905,14 +989,32 @@ static int spi_imx_setupxfer(struct spi_device *spi, /* Initialize the functions for transfer */ if (config.bpw <= 8) { - spi_imx->rx = spi_imx_buf_rx_u8; - spi_imx->tx = spi_imx_buf_tx_u8; + if (t->len >= sizeof(u32) && is_imx51_ecspi(spi_imx)) { + spi_imx->dynamic_burst = 1; + spi_imx->rx = spi_imx_buf_rx_swap; + spi_imx->tx = spi_imx_buf_tx_swap; + } else { + spi_imx->rx = spi_imx_buf_rx_u8; + spi_imx->tx = spi_imx_buf_tx_u8; + } } else if (config.bpw <= 16) { - spi_imx->rx = spi_imx_buf_rx_u16; - spi_imx->tx = spi_imx_buf_tx_u16; + if (t->len >= sizeof(u32) && is_imx51_ecspi(spi_imx)) { + spi_imx->dynamic_burst = 1; + spi_imx->rx = spi_imx_buf_rx_swap; + spi_imx->tx = spi_imx_buf_tx_swap; + } else { + spi_imx->rx = spi_imx_buf_rx_u16; + spi_imx->tx = spi_imx_buf_tx_u16; + } } else { - spi_imx->rx = spi_imx_buf_rx_u32; - spi_imx->tx = spi_imx_buf_tx_u32; + if (is_imx51_ecspi(spi_imx)) { + spi_imx->dynamic_burst = 1; + spi_imx->rx = spi_imx_buf_rx_swap; + spi_imx->tx = spi_imx_buf_tx_swap; + } else { + spi_imx->rx = spi_imx_buf_rx_u32; + spi_imx->tx = spi_imx_buf_tx_u32; + } } if (spi_imx_can_dma(spi_imx->bitbang.master, spi, t)) @@ -920,6 +1022,8 @@ static int spi_imx_setupxfer(struct spi_device *spi, else spi_imx->usedma = 0; + spi_imx->bpw_w = DIV_ROUND_UP(config.bpw, 8); + if (spi_imx->usedma) { ret = spi_imx_dma_configure(spi->master, spi_imx_bytes_per_word(config.bpw)); @@ -1094,6 +1198,27 @@ static int spi_imx_pio_transfer(struct spi_device *spi, spi_imx->count = transfer->len; spi_imx->txfifo = 0; + if (spi_imx->dynamic_burst) { + if (spi_imx->count > MX51_ECSPI_CTRL_MAX_BURST) + spi_imx->count_index = spi_imx->count % + MX51_ECSPI_CTRL_MAX_BURST; + else + spi_imx->count_index = spi_imx->count % sizeof(u32); + + switch (spi_imx->bpw_w) { + case 1: + spi_imx_u32_swap_u8(transfer, + (u32 *)transfer->tx_buf); + break; + case 2: + spi_imx_u32_swap_u16(transfer, + (u32 *)transfer->tx_buf); + break; + default: + break; + } + } + reinit_completion(&spi_imx->xfer_done); spi_imx_push(spi_imx); @@ -1110,6 +1235,22 @@ static int spi_imx_pio_transfer(struct spi_device *spi, return -ETIMEDOUT; } + if (spi_imx->dynamic_burst) { + switch (spi_imx->bpw_w) { + case 1: + spi_imx_u32_swap_u8(transfer, + (u32 *)transfer->rx_buf); + break; + case 2: + spi_imx_u32_swap_u16(transfer, + (u32 *)transfer->rx_buf); + break; + default: + break; + } + spi_imx->dynamic_burst = 0; + } + return transfer->len; } -- cgit v1.2.3 From 179547e143e773f9f866ad3536275ab627711f3a Mon Sep 17 00:00:00 2001 From: Jiada Wang Date: Thu, 18 May 2017 03:01:12 -0700 Subject: spi: imx: fix issue when tx_buf or rx_buf is NULL In case either transfer->tx_buf or transfer->rx_buf is NULL, manipulation of buffer in spi_imx_u32_swap_u[8|16]() will cause NULL pointer dereference crash. Add buffer check at very beginning of spi_imx_u32_swap_u[8|16](), to avoid such crash. Signed-off-by: Jiada Wang Reported-by: Leonard Crestez Tested-by: Leonard Crestez Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 782045f0d79e..19b30cf7d2b7 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -288,6 +288,9 @@ static void spi_imx_u32_swap_u8(struct spi_transfer *transfer, u32 *buf) { int i; + if (!buf) + return; + for (i = 0; i < transfer->len / 4; i++) *(buf + i) = cpu_to_be32(*(buf + i)); } @@ -296,6 +299,9 @@ static void spi_imx_u32_swap_u16(struct spi_transfer *transfer, u32 *buf) { int i; + if (!buf) + return; + for (i = 0; i < transfer->len / 4; i++) { u16 *temp = (u16 *)buf; -- cgit v1.2.3 From 09b3ed2d5916f270ffbc5d002a2196ededf5ec7e Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 23 May 2017 14:38:27 +0200 Subject: spi: imx: Revert "spi: imx: dynamic burst length adjust for PIO mode" This reverts commits 8d4a6cad7adb3ddac32cd52635f20e11de11a658 and 179547e143e773f9f866ad3536275ab627711f3a. Besides the problems already found with this patch it also modifies the spi transfer tx_buf in spi_imx_u32_swap_u8() and spi_imx_u32_swap_u16(). This is hidden from the compiler with an explicit cast from const void* to u32*, so no warning is issued. Signed-off-by: Sascha Hauer Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 163 +++----------------------------------------------- 1 file changed, 8 insertions(+), 155 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 19b30cf7d2b7..b402530a7a9a 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -56,11 +56,9 @@ /* The maximum bytes that a sdma BD can transfer.*/ #define MAX_SDMA_BD_BYTES (1 << 15) -#define MX51_ECSPI_CTRL_MAX_BURST 512 struct spi_imx_config { unsigned int speed_hz; unsigned int bpw; - unsigned int len; }; enum spi_imx_devtype { @@ -99,14 +97,12 @@ struct spi_imx_data { unsigned int bytes_per_word; unsigned int spi_drctl; - unsigned int count, count_index; + unsigned int count; void (*tx)(struct spi_imx_data *); void (*rx)(struct spi_imx_data *); void *rx_buf; const void *tx_buf; unsigned int txfifo; /* number of words pushed in tx FIFO */ - unsigned int dynamic_burst, bpw_rx; - unsigned int bpw_w; /* DMA */ bool usedma; @@ -256,7 +252,6 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, #define MX51_ECSPI_CTRL_PREDIV_OFFSET 12 #define MX51_ECSPI_CTRL_CS(cs) ((cs) << 18) #define MX51_ECSPI_CTRL_BL_OFFSET 20 -#define MX51_ECSPI_CTRL_BL_MASK (0xfff << 20) #define MX51_ECSPI_CONFIG 0x0c #define MX51_ECSPI_CONFIG_SCLKPHA(cs) (1 << ((cs) + 0)) @@ -284,77 +279,6 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, #define MX51_ECSPI_TESTREG 0x20 #define MX51_ECSPI_TESTREG_LBC BIT(31) -static void spi_imx_u32_swap_u8(struct spi_transfer *transfer, u32 *buf) -{ - int i; - - if (!buf) - return; - - for (i = 0; i < transfer->len / 4; i++) - *(buf + i) = cpu_to_be32(*(buf + i)); -} - -static void spi_imx_u32_swap_u16(struct spi_transfer *transfer, u32 *buf) -{ - int i; - - if (!buf) - return; - - for (i = 0; i < transfer->len / 4; i++) { - u16 *temp = (u16 *)buf; - - *(temp + i * 2) = cpu_to_be16(*(temp + i * 2)); - *(temp + i * 2 + 1) = cpu_to_be16(*(temp + i * 2 + 1)); - - *(buf + i) = cpu_to_be32(*(buf + i)); - } -} - -static void spi_imx_buf_rx_swap(struct spi_imx_data *spi_imx) -{ - if (!spi_imx->bpw_rx) { - spi_imx_buf_rx_u32(spi_imx); - return; - } - - if (spi_imx->bpw_w == 1) - spi_imx_buf_rx_u8(spi_imx); - else if (spi_imx->bpw_w == 2) - spi_imx_buf_rx_u16(spi_imx); -} - -static void spi_imx_buf_tx_swap(struct spi_imx_data *spi_imx) -{ - u32 ctrl, val; - - if (spi_imx->count == spi_imx->count_index) { - spi_imx->count_index = spi_imx->count > sizeof(u32) ? - spi_imx->count % sizeof(u32) : 0; - ctrl = readl(spi_imx->base + MX51_ECSPI_CTRL); - ctrl &= ~MX51_ECSPI_CTRL_BL_MASK; - if (spi_imx->count >= sizeof(u32)) { - val = spi_imx->count - spi_imx->count_index; - } else { - val = spi_imx->bpw_w; - spi_imx->bpw_rx = 1; - } - ctrl |= ((val * 8 - 1) << MX51_ECSPI_CTRL_BL_OFFSET); - writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL); - } - - if (spi_imx->count >= sizeof(u32)) { - spi_imx_buf_tx_u32(spi_imx); - return; - } - - if (spi_imx->bpw_w == 1) - spi_imx_buf_tx_u8(spi_imx); - else if (spi_imx->bpw_w == 2) - spi_imx_buf_tx_u16(spi_imx); -} - /* MX51 eCSPI */ static unsigned int mx51_ecspi_clkdiv(struct spi_imx_data *spi_imx, unsigned int fspi, unsigned int *fres) @@ -446,15 +370,7 @@ static int mx51_ecspi_config(struct spi_device *spi, /* set chip select to use */ ctrl |= MX51_ECSPI_CTRL_CS(spi->chip_select); - if (spi_imx->dynamic_burst) { - if (config->len > MX51_ECSPI_CTRL_MAX_BURST) - ctrl |= MX51_ECSPI_CTRL_BL_MASK; - else - ctrl |= (((config->len - config->len % 4) * 8 - 1) << - MX51_ECSPI_CTRL_BL_OFFSET); - } else { - ctrl |= (config->bpw - 1) << MX51_ECSPI_CTRL_BL_OFFSET; - } + ctrl |= (config->bpw - 1) << MX51_ECSPI_CTRL_BL_OFFSET; cfg |= MX51_ECSPI_CONFIG_SBBCTRL(spi->chip_select); @@ -889,8 +805,6 @@ static void spi_imx_push(struct spi_imx_data *spi_imx) while (spi_imx->txfifo < spi_imx_get_fifosize(spi_imx)) { if (!spi_imx->count) break; - if (spi_imx->txfifo && (spi_imx->count == spi_imx->count_index)) - break; spi_imx->tx(spi_imx); spi_imx->txfifo++; } @@ -981,12 +895,8 @@ static int spi_imx_setupxfer(struct spi_device *spi, struct spi_imx_config config; int ret; - spi_imx->dynamic_burst = 0; - spi_imx->bpw_rx = 0; - config.bpw = t ? t->bits_per_word : spi->bits_per_word; config.speed_hz = t ? t->speed_hz : spi->max_speed_hz; - config.len = t->len; if (!config.speed_hz) config.speed_hz = spi->max_speed_hz; @@ -995,32 +905,14 @@ static int spi_imx_setupxfer(struct spi_device *spi, /* Initialize the functions for transfer */ if (config.bpw <= 8) { - if (t->len >= sizeof(u32) && is_imx51_ecspi(spi_imx)) { - spi_imx->dynamic_burst = 1; - spi_imx->rx = spi_imx_buf_rx_swap; - spi_imx->tx = spi_imx_buf_tx_swap; - } else { - spi_imx->rx = spi_imx_buf_rx_u8; - spi_imx->tx = spi_imx_buf_tx_u8; - } + spi_imx->rx = spi_imx_buf_rx_u8; + spi_imx->tx = spi_imx_buf_tx_u8; } else if (config.bpw <= 16) { - if (t->len >= sizeof(u32) && is_imx51_ecspi(spi_imx)) { - spi_imx->dynamic_burst = 1; - spi_imx->rx = spi_imx_buf_rx_swap; - spi_imx->tx = spi_imx_buf_tx_swap; - } else { - spi_imx->rx = spi_imx_buf_rx_u16; - spi_imx->tx = spi_imx_buf_tx_u16; - } + spi_imx->rx = spi_imx_buf_rx_u16; + spi_imx->tx = spi_imx_buf_tx_u16; } else { - if (is_imx51_ecspi(spi_imx)) { - spi_imx->dynamic_burst = 1; - spi_imx->rx = spi_imx_buf_rx_swap; - spi_imx->tx = spi_imx_buf_tx_swap; - } else { - spi_imx->rx = spi_imx_buf_rx_u32; - spi_imx->tx = spi_imx_buf_tx_u32; - } + spi_imx->rx = spi_imx_buf_rx_u32; + spi_imx->tx = spi_imx_buf_tx_u32; } if (spi_imx_can_dma(spi_imx->bitbang.master, spi, t)) @@ -1028,8 +920,6 @@ static int spi_imx_setupxfer(struct spi_device *spi, else spi_imx->usedma = 0; - spi_imx->bpw_w = DIV_ROUND_UP(config.bpw, 8); - if (spi_imx->usedma) { ret = spi_imx_dma_configure(spi->master, spi_imx_bytes_per_word(config.bpw)); @@ -1204,27 +1094,6 @@ static int spi_imx_pio_transfer(struct spi_device *spi, spi_imx->count = transfer->len; spi_imx->txfifo = 0; - if (spi_imx->dynamic_burst) { - if (spi_imx->count > MX51_ECSPI_CTRL_MAX_BURST) - spi_imx->count_index = spi_imx->count % - MX51_ECSPI_CTRL_MAX_BURST; - else - spi_imx->count_index = spi_imx->count % sizeof(u32); - - switch (spi_imx->bpw_w) { - case 1: - spi_imx_u32_swap_u8(transfer, - (u32 *)transfer->tx_buf); - break; - case 2: - spi_imx_u32_swap_u16(transfer, - (u32 *)transfer->tx_buf); - break; - default: - break; - } - } - reinit_completion(&spi_imx->xfer_done); spi_imx_push(spi_imx); @@ -1241,22 +1110,6 @@ static int spi_imx_pio_transfer(struct spi_device *spi, return -ETIMEDOUT; } - if (spi_imx->dynamic_burst) { - switch (spi_imx->bpw_w) { - case 1: - spi_imx_u32_swap_u8(transfer, - (u32 *)transfer->rx_buf); - break; - case 2: - spi_imx_u32_swap_u16(transfer, - (u32 *)transfer->rx_buf); - break; - default: - break; - } - spi_imx->dynamic_burst = 0; - } - return transfer->len; } -- cgit v1.2.3 From 2b747a5f04fbb26ad09241506704ddce462e581b Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Mon, 5 Jun 2017 19:20:40 +0530 Subject: spi: davinci: Fix compilation warning. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If CONFIG_OF is disable, it'll through compilation warning. drivers/spi/spi-davinci.c: In function ‘spi_davinci_get_pdata’: drivers/spi/spi-davinci.c:880:2: warning: return makes pointer from integer without a cast [enabled by default] return -ENODEV; drivers/spi/spi-davinci.c: In function ‘davinci_spi_probe’: drivers/spi/spi-davinci.c:919:7: warning: assignment makes integer from pointer without a cast [enabled by default] ret = spi_davinci_get_pdata(pdev, dspi); Signed-off-by: Arvind Yadav Changes in v2: Add fix for both the warning. Changes in v1: It has fix for first warning. Signed-off-by: Mark Brown --- drivers/spi/spi-davinci.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 595acdcfc7d0..0b4493e7fe9e 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -873,9 +873,8 @@ static int spi_davinci_get_pdata(struct platform_device *pdev, return 0; } #else -static struct davinci_spi_platform_data - *spi_davinci_get_pdata(struct platform_device *pdev, - struct davinci_spi *dspi) +static int spi_davinci_get_pdata(struct platform_device *pdev, + struct davinci_spi *dspi) { return -ENODEV; } -- cgit v1.2.3 From 35fc3b9ff66b907ca7a75c971decf291adf78131 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Mon, 5 Jun 2017 17:36:28 +0530 Subject: spi: davinci: Handle return value of clk_prepare_enable clk_prepare_enable() can fail here and we must check its return value. Signed-off-by: Arvind Yadav Signed-off-by: Mark Brown --- drivers/spi/spi-davinci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 0b4493e7fe9e..6ddb6ef1fda4 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -964,7 +964,9 @@ static int davinci_spi_probe(struct platform_device *pdev) ret = -ENODEV; goto free_master; } - clk_prepare_enable(dspi->clk); + ret = clk_prepare_enable(dspi->clk); + if (ret) + goto free_master; master->dev.of_node = pdev->dev.of_node; master->bus_num = pdev->id; -- cgit v1.2.3 From abb1ff195a21094f3bfb1cf8d425ff360d8a89ee Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 2 Jun 2017 07:37:59 +0200 Subject: spi: imx: Nothing to do in setupxfer when transfer is NULL When the spi_transfer given in spi_imx_setupxfer is NULL then we have nothing to do. Bail out early in this case so that we do not have to test for t != NULL multiple times later. Signed-off-by: Sascha Hauer Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index b402530a7a9a..4b5cd0c84450 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -217,9 +217,6 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, if (!master->dma_rx) return false; - if (!transfer) - return false; - bpw = transfer->bits_per_word; if (!bpw) bpw = spi->bits_per_word; @@ -895,8 +892,11 @@ static int spi_imx_setupxfer(struct spi_device *spi, struct spi_imx_config config; int ret; - config.bpw = t ? t->bits_per_word : spi->bits_per_word; - config.speed_hz = t ? t->speed_hz : spi->max_speed_hz; + if (!t) + return 0; + + config.bpw = t->bits_per_word; + config.speed_hz = t->speed_hz; if (!config.speed_hz) config.speed_hz = spi->max_speed_hz; -- cgit v1.2.3 From 494f3193bd8ca6a15a813bf0f8b5552ec0d173f3 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 2 Jun 2017 07:38:00 +0200 Subject: spi: imx: Drop unnecessary check __spi_validate makes sure that every transfer has a valid bits_per_word and speed_hz setting. We do not need to fallback to values from the spi_device. Signed-off-by: Sascha Hauer Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 4b5cd0c84450..e3bc3d51a2d6 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -218,8 +218,6 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, return false; bpw = transfer->bits_per_word; - if (!bpw) - bpw = spi->bits_per_word; bpw = spi_imx_bytes_per_word(bpw); @@ -898,11 +896,6 @@ static int spi_imx_setupxfer(struct spi_device *spi, config.bpw = t->bits_per_word; config.speed_hz = t->speed_hz; - if (!config.speed_hz) - config.speed_hz = spi->max_speed_hz; - if (!config.bpw) - config.bpw = spi->bits_per_word; - /* Initialize the functions for transfer */ if (config.bpw <= 8) { spi_imx->rx = spi_imx_buf_rx_u8; -- cgit v1.2.3 From d52345b6cf8ecd2c765edf81f49fa62483dd6437 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 2 Jun 2017 07:38:01 +0200 Subject: spi: imx: put struct spi_imx_config members into driver private struct struct spi_imx_config used to hold data specific to the current transfer. However, other data is in the drivers private data struct. Let's drop struct spi_imx_config and put the variables into the drivers private data struct aswell. Signed-off-by: Sascha Hauer Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 50 +++++++++++++++++++++++--------------------------- 1 file changed, 23 insertions(+), 27 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index e3bc3d51a2d6..3fa5ccfb45a1 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -56,10 +56,6 @@ /* The maximum bytes that a sdma BD can transfer.*/ #define MAX_SDMA_BD_BYTES (1 << 15) -struct spi_imx_config { - unsigned int speed_hz; - unsigned int bpw; -}; enum spi_imx_devtype { IMX1_CSPI, @@ -74,7 +70,7 @@ struct spi_imx_data; struct spi_imx_devtype_data { void (*intctrl)(struct spi_imx_data *, int); - int (*config)(struct spi_device *, struct spi_imx_config *); + int (*config)(struct spi_device *); void (*trigger)(struct spi_imx_data *); int (*rx_available)(struct spi_imx_data *); void (*reset)(struct spi_imx_data *); @@ -94,6 +90,8 @@ struct spi_imx_data { unsigned long spi_clk; unsigned int spi_bus_clk; + unsigned int speed_hz; + unsigned int bits_per_word; unsigned int bytes_per_word; unsigned int spi_drctl; @@ -335,12 +333,11 @@ static void mx51_ecspi_trigger(struct spi_imx_data *spi_imx) writel(reg, spi_imx->base + MX51_ECSPI_CTRL); } -static int mx51_ecspi_config(struct spi_device *spi, - struct spi_imx_config *config) +static int mx51_ecspi_config(struct spi_device *spi) { struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); u32 ctrl = MX51_ECSPI_CTRL_ENABLE; - u32 clk = config->speed_hz, delay, reg; + u32 clk = spi_imx->speed_hz, delay, reg; u32 cfg = readl(spi_imx->base + MX51_ECSPI_CONFIG); /* @@ -359,13 +356,13 @@ static int mx51_ecspi_config(struct spi_device *spi, ctrl |= MX51_ECSPI_CTRL_DRCTL(spi_imx->spi_drctl); /* set clock speed */ - ctrl |= mx51_ecspi_clkdiv(spi_imx, config->speed_hz, &clk); + ctrl |= mx51_ecspi_clkdiv(spi_imx, spi_imx->speed_hz, &clk); spi_imx->spi_bus_clk = clk; /* set chip select to use */ ctrl |= MX51_ECSPI_CTRL_CS(spi->chip_select); - ctrl |= (config->bpw - 1) << MX51_ECSPI_CTRL_BL_OFFSET; + ctrl |= (spi_imx->bits_per_word - 1) << MX51_ECSPI_CTRL_BL_OFFSET; cfg |= MX51_ECSPI_CONFIG_SBBCTRL(spi->chip_select); @@ -496,21 +493,21 @@ static void mx31_trigger(struct spi_imx_data *spi_imx) writel(reg, spi_imx->base + MXC_CSPICTRL); } -static int mx31_config(struct spi_device *spi, struct spi_imx_config *config) +static int mx31_config(struct spi_device *spi) { struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER; unsigned int clk; - reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz, &clk) << + reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, spi_imx->speed_hz, &clk) << MX31_CSPICTRL_DR_SHIFT; spi_imx->spi_bus_clk = clk; if (is_imx35_cspi(spi_imx)) { - reg |= (config->bpw - 1) << MX35_CSPICTRL_BL_SHIFT; + reg |= (spi_imx->bits_per_word - 1) << MX35_CSPICTRL_BL_SHIFT; reg |= MX31_CSPICTRL_SSCTL; } else { - reg |= (config->bpw - 1) << MX31_CSPICTRL_BC_SHIFT; + reg |= (spi_imx->bits_per_word - 1) << MX31_CSPICTRL_BC_SHIFT; } if (spi->mode & SPI_CPHA) @@ -592,18 +589,18 @@ static void mx21_trigger(struct spi_imx_data *spi_imx) writel(reg, spi_imx->base + MXC_CSPICTRL); } -static int mx21_config(struct spi_device *spi, struct spi_imx_config *config) +static int mx21_config(struct spi_device *spi) { struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); unsigned int reg = MX21_CSPICTRL_ENABLE | MX21_CSPICTRL_MASTER; unsigned int max = is_imx27_cspi(spi_imx) ? 16 : 18; unsigned int clk; - reg |= spi_imx_clkdiv_1(spi_imx->spi_clk, config->speed_hz, max, &clk) + reg |= spi_imx_clkdiv_1(spi_imx->spi_clk, spi_imx->speed_hz, max, &clk) << MX21_CSPICTRL_DR_SHIFT; spi_imx->spi_bus_clk = clk; - reg |= config->bpw - 1; + reg |= spi_imx->bits_per_word - 1; if (spi->mode & SPI_CPHA) reg |= MX21_CSPICTRL_PHA; @@ -661,17 +658,17 @@ static void mx1_trigger(struct spi_imx_data *spi_imx) writel(reg, spi_imx->base + MXC_CSPICTRL); } -static int mx1_config(struct spi_device *spi, struct spi_imx_config *config) +static int mx1_config(struct spi_device *spi) { struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); unsigned int reg = MX1_CSPICTRL_ENABLE | MX1_CSPICTRL_MASTER; unsigned int clk; - reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz, &clk) << + reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, spi_imx->speed_hz, &clk) << MX1_CSPICTRL_DR_SHIFT; spi_imx->spi_bus_clk = clk; - reg |= config->bpw - 1; + reg |= spi_imx->bits_per_word - 1; if (spi->mode & SPI_CPHA) reg |= MX1_CSPICTRL_PHA; @@ -887,20 +884,19 @@ static int spi_imx_setupxfer(struct spi_device *spi, struct spi_transfer *t) { struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); - struct spi_imx_config config; int ret; if (!t) return 0; - config.bpw = t->bits_per_word; - config.speed_hz = t->speed_hz; + spi_imx->bits_per_word = t->bits_per_word; + spi_imx->speed_hz = t->speed_hz; /* Initialize the functions for transfer */ - if (config.bpw <= 8) { + if (spi_imx->bits_per_word <= 8) { spi_imx->rx = spi_imx_buf_rx_u8; spi_imx->tx = spi_imx_buf_tx_u8; - } else if (config.bpw <= 16) { + } else if (spi_imx->bits_per_word <= 16) { spi_imx->rx = spi_imx_buf_rx_u16; spi_imx->tx = spi_imx_buf_tx_u16; } else { @@ -915,12 +911,12 @@ static int spi_imx_setupxfer(struct spi_device *spi, if (spi_imx->usedma) { ret = spi_imx_dma_configure(spi->master, - spi_imx_bytes_per_word(config.bpw)); + spi_imx_bytes_per_word(spi_imx->bits_per_word)); if (ret) return ret; } - spi_imx->devtype_data->config(spi, &config); + spi_imx->devtype_data->config(spi); return 0; } -- cgit v1.2.3 From d6be7d1db51799fb510458b8ede6e5bef96ab1f0 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 2 Jun 2017 07:38:02 +0200 Subject: spi: imx: drop bogus unnecessary dma config It's unnecessary to call spi_imx_dma_configure() from probe(). It will be called later anyway again when an actual DMA transfer is prepared. Signed-off-by: Sascha Hauer Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 3fa5ccfb45a1..0ec8d816e033 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -965,8 +965,6 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, goto err; } - spi_imx_dma_configure(master, 1); - init_completion(&spi_imx->dma_rx_completion); init_completion(&spi_imx->dma_tx_completion); master->can_dma = spi_imx_can_dma; -- cgit v1.2.3 From 65017ee2cd69bfd9ccdaa1f61b220e9717408106 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 2 Jun 2017 07:38:03 +0200 Subject: spi: imx: remove bytes_per_word from private driver struct We already have bits_per_word in the private driver struct and bytes_per_word can be calculated from it, so remove bits_per_word. Signed-off-by: Sascha Hauer Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 0ec8d816e033..12e5ef7beb0b 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -92,7 +92,6 @@ struct spi_imx_data { unsigned int speed_hz; unsigned int bits_per_word; - unsigned int bytes_per_word; unsigned int spi_drctl; unsigned int count; @@ -215,9 +214,7 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, if (!master->dma_rx) return false; - bpw = transfer->bits_per_word; - - bpw = spi_imx_bytes_per_word(bpw); + bpw = spi_imx_bytes_per_word(transfer->bits_per_word); if (bpw != 1 && bpw != 2 && bpw != 4) return false; @@ -833,15 +830,14 @@ static irqreturn_t spi_imx_isr(int irq, void *dev_id) return IRQ_HANDLED; } -static int spi_imx_dma_configure(struct spi_master *master, - int bytes_per_word) +static int spi_imx_dma_configure(struct spi_master *master) { int ret; enum dma_slave_buswidth buswidth; struct dma_slave_config rx = {}, tx = {}; struct spi_imx_data *spi_imx = spi_master_get_devdata(master); - switch (bytes_per_word) { + switch (spi_imx_bytes_per_word(spi_imx->bits_per_word)) { case 4: buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES; break; @@ -875,8 +871,6 @@ static int spi_imx_dma_configure(struct spi_master *master, return ret; } - spi_imx->bytes_per_word = bytes_per_word; - return 0; } @@ -910,8 +904,7 @@ static int spi_imx_setupxfer(struct spi_device *spi, spi_imx->usedma = 0; if (spi_imx->usedma) { - ret = spi_imx_dma_configure(spi->master, - spi_imx_bytes_per_word(spi_imx->bits_per_word)); + ret = spi_imx_dma_configure(spi->master); if (ret) return ret; } -- cgit v1.2.3 From 2e312f6cdb02a2707870172473b9dee34f620b93 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 2 Jun 2017 07:38:04 +0200 Subject: spi: imx: rename 'bpw' variables 'bpw' is ambiguous and only the context makes sure if bytes_per_word or bits_per_word is meant. Use the full names instead to make reading the code easier. Signed-off-by: Sascha Hauer Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 12e5ef7beb0b..e544f45348cc 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -200,27 +200,27 @@ out: return i; } -static int spi_imx_bytes_per_word(const int bpw) +static int spi_imx_bytes_per_word(const int bits_per_word) { - return DIV_ROUND_UP(bpw, BITS_PER_BYTE); + return DIV_ROUND_UP(bits_per_word, BITS_PER_BYTE); } static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, struct spi_transfer *transfer) { struct spi_imx_data *spi_imx = spi_master_get_devdata(master); - unsigned int bpw, i; + unsigned int bytes_per_word, i; if (!master->dma_rx) return false; - bpw = spi_imx_bytes_per_word(transfer->bits_per_word); + bytes_per_word = spi_imx_bytes_per_word(transfer->bits_per_word); - if (bpw != 1 && bpw != 2 && bpw != 4) + if (bytes_per_word != 1 && bytes_per_word != 2 && bytes_per_word != 4) return false; for (i = spi_imx_get_fifosize(spi_imx) / 2; i > 0; i--) { - if (!(transfer->len % (i * bpw))) + if (!(transfer->len % (i * bytes_per_word))) break; } -- cgit v1.2.3 From 6aba9c65649e5ef137bce7a958c0749f13af88a1 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Tue, 30 May 2017 08:33:30 +0300 Subject: spi: atmel: print version only after successful registration Don't print the version at the beginning of atmel_spi_probe(). This avoids spamming the log whenever a deferred probe runs. Signed-off-by: Baruch Siach Acked-by: Nicolas Ferre Signed-off-by: Mark Brown --- drivers/spi/spi-atmel.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 1eb83c9613d5..4e5e51fe6f73 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -1422,7 +1422,6 @@ static void atmel_get_caps(struct atmel_spi *as) unsigned int version; version = atmel_get_version(as); - dev_info(&as->pdev->dev, "version: 0x%x\n", version); as->caps.is_spi2 = version > 0x121; as->caps.has_wdrbt = version >= 0x210; @@ -1609,8 +1608,9 @@ static int atmel_spi_probe(struct platform_device *pdev) goto out_free_dma; /* go! */ - dev_info(&pdev->dev, "Atmel SPI Controller at 0x%08lx (irq %d)\n", - (unsigned long)regs->start, irq); + dev_info(&pdev->dev, "Atmel SPI Controller version 0x%x at 0x%08lx (irq %d)\n", + atmel_get_version(as), (unsigned long)regs->start, + irq); return 0; -- cgit v1.2.3 From 2c147776dc8b3d67ec42605dcba4deb98f2d0536 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 20 Jun 2017 13:50:55 -0300 Subject: spi: imx: Check for allocation failure earlier In case of spi_alloc_master() failure it is better to return the error immediately, so move the error check right after the allocation. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index e544f45348cc..f9698b7aeb3b 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -1169,15 +1169,15 @@ static int spi_imx_probe(struct platform_device *pdev) } master = spi_alloc_master(&pdev->dev, sizeof(struct spi_imx_data)); + if (!master) + return -ENOMEM; + ret = of_property_read_u32(np, "fsl,spi-rdy-drctl", &spi_drctl); if ((ret < 0) || (spi_drctl >= 0x3)) { /* '11' is reserved */ spi_drctl = 0; } - if (!master) - return -ENOMEM; - platform_set_drvdata(pdev, master); master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); -- cgit v1.2.3 From b85d65dd47e1606299dc054d2162b795df65c94a Mon Sep 17 00:00:00 2001 From: Aravind Thokala Date: Mon, 19 Jun 2017 23:47:48 +0530 Subject: spi/bcm63xx: Fix checkpatch warnings This patch fixes the checkpatch.pl warnings on the driver file. Signed-off-by: Aravind Thokala Reviewed-by: Florian Fainelli Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 247f71b02235..84c7356ce5b4 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -147,7 +147,7 @@ struct bcm63xx_spi { /* Platform data */ const unsigned long *reg_offsets; - unsigned fifo_size; + unsigned int fifo_size; unsigned int msg_type_shift; unsigned int msg_ctl_width; @@ -191,7 +191,7 @@ static inline void bcm_spi_writew(struct bcm63xx_spi *bs, #endif } -static const unsigned bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = { +static const unsigned int bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = { { 20000000, SPI_CLK_20MHZ }, { 12500000, SPI_CLK_12_50MHZ }, { 6250000, SPI_CLK_6_250MHZ }, -- cgit v1.2.3