summaryrefslogtreecommitdiff
path: root/drivers/spi/spi-fsl-lpspi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi-fsl-lpspi.c')
-rw-r--r--drivers/spi/spi-fsl-lpspi.c32
1 files changed, 16 insertions, 16 deletions
diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c
index 29b9676fe43d..5e96913fd946 100644
--- a/drivers/spi/spi-fsl-lpspi.c
+++ b/drivers/spi/spi-fsl-lpspi.c
@@ -3,8 +3,9 @@
// Freescale i.MX7ULP LPSPI driver
//
// Copyright 2016 Freescale Semiconductor, Inc.
-// Copyright 2018 NXP Semiconductors
+// Copyright 2018, 2023, 2025 NXP
+#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/delay.h>
@@ -70,7 +71,7 @@
#define DER_TDDE BIT(0)
#define CFGR1_PCSCFG BIT(27)
#define CFGR1_PINCFG (BIT(24)|BIT(25))
-#define CFGR1_PCSPOL BIT(8)
+#define CFGR1_PCSPOL_MASK GENMASK(11, 8)
#define CFGR1_NOSTALL BIT(3)
#define CFGR1_HOST BIT(0)
#define FSR_TXCOUNT (0xFF)
@@ -82,6 +83,8 @@
#define TCR_RXMSK BIT(19)
#define TCR_TXMSK BIT(18)
+#define SR_CLEAR_MASK GENMASK(13, 8)
+
struct fsl_lpspi_devtype_data {
u8 prescale_max;
};
@@ -330,13 +333,11 @@ static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi)
}
if (config.speed_hz > perclk_rate / 2) {
- dev_err(fsl_lpspi->dev,
- "per-clk should be at least two times of transfer speed");
- return -EINVAL;
+ div = 2;
+ } else {
+ div = DIV_ROUND_UP(perclk_rate, config.speed_hz);
}
- div = DIV_ROUND_UP(perclk_rate, config.speed_hz);
-
for (prescale = 0; prescale <= prescale_max; prescale++) {
scldiv = div / (1 << prescale) - 2;
if (scldiv >= 0 && scldiv < 256) {
@@ -422,7 +423,9 @@ static int fsl_lpspi_config(struct fsl_lpspi_data *fsl_lpspi)
else
temp = CFGR1_PINCFG;
if (fsl_lpspi->config.mode & SPI_CS_HIGH)
- temp |= CFGR1_PCSPOL;
+ temp |= FIELD_PREP(CFGR1_PCSPOL_MASK,
+ BIT(fsl_lpspi->config.chip_select));
+
writel(temp, fsl_lpspi->base + IMX7ULP_CFGR1);
temp = readl(fsl_lpspi->base + IMX7ULP_CR);
@@ -531,14 +534,13 @@ static int fsl_lpspi_reset(struct fsl_lpspi_data *fsl_lpspi)
fsl_lpspi_intctrl(fsl_lpspi, 0);
}
- /* W1C for all flags in SR */
- temp = 0x3F << 8;
- writel(temp, fsl_lpspi->base + IMX7ULP_SR);
-
/* Clear FIFO and disable module */
temp = CR_RRF | CR_RTF;
writel(temp, fsl_lpspi->base + IMX7ULP_CR);
+ /* W1C for all flags in SR */
+ writel(SR_CLEAR_MASK, fsl_lpspi->base + IMX7ULP_SR);
+
return 0;
}
@@ -729,12 +731,10 @@ static int fsl_lpspi_pio_transfer(struct spi_controller *controller,
fsl_lpspi_write_tx_fifo(fsl_lpspi);
ret = fsl_lpspi_wait_for_completion(controller);
- if (ret)
- return ret;
fsl_lpspi_reset(fsl_lpspi);
- return 0;
+ return ret;
}
static int fsl_lpspi_transfer_one(struct spi_controller *controller,
@@ -782,7 +782,7 @@ static irqreturn_t fsl_lpspi_isr(int irq, void *dev_id)
if (temp_SR & SR_MBF ||
readl(fsl_lpspi->base + IMX7ULP_FSR) & FSR_TXCOUNT) {
writel(SR_FCF, fsl_lpspi->base + IMX7ULP_SR);
- fsl_lpspi_intctrl(fsl_lpspi, IER_FCIE);
+ fsl_lpspi_intctrl(fsl_lpspi, IER_FCIE | (temp_IER & IER_TDIE));
return IRQ_HANDLED;
}