]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
spi: sh-msiof: Add reset of registers before starting transfer
authorGeert Uytterhoeven <geert+renesas@glider.be>
Tue, 2 Apr 2019 14:40:23 +0000 (16:40 +0200)
committerMark Brown <broonie@kernel.org>
Wed, 3 Apr 2019 04:32:27 +0000 (11:32 +0700)
In accordance with hardware specification Ver 1.0, reset register
transmission / reception setting before transfer.

Signed-off-by: Hiromitsu Yamasaki <hiromitsu.yamasaki.ym@renesas.com>
[geert: Use readl_poll_timeout_atomic()]
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi-sh-msiof.c

index 3243ff258896595b66581cd4cfdbfbdf27a78bdd..d3794499915c17cbd0d8adf054ca63864b89cf48 100644 (file)
@@ -132,6 +132,8 @@ struct sh_msiof_spi_priv {
 #define CTR_TFSE       BIT(14)   /* Transmit Frame Sync Signal Output Enable */
 #define CTR_TXE                BIT(9)    /* Transmit Enable */
 #define CTR_RXE                BIT(8)    /* Receive Enable */
+#define CTR_TXRST      BIT(1)    /* Transmit Reset */
+#define CTR_RXRST      BIT(0)    /* Receive Reset */
 
 /* FCTR */
 #define FCTR_TFWM_MASK GENMASK(31, 29) /* Transmit FIFO Watermark */
@@ -241,6 +243,19 @@ static irqreturn_t sh_msiof_spi_irq(int irq, void *data)
        return IRQ_HANDLED;
 }
 
+static void sh_msiof_spi_reset_regs(struct sh_msiof_spi_priv *p)
+{
+       u32 mask = CTR_TXRST | CTR_RXRST;
+       u32 data;
+
+       data = sh_msiof_read(p, CTR);
+       data |= mask;
+       sh_msiof_write(p, CTR, data);
+
+       readl_poll_timeout_atomic(p->mapbase + CTR, data, !(data & mask), 1,
+                                 100);
+}
+
 static const u32 sh_msiof_spi_div_array[] = {
        SCR_BRDV_DIV_1, SCR_BRDV_DIV_2,  SCR_BRDV_DIV_4,
        SCR_BRDV_DIV_8, SCR_BRDV_DIV_16, SCR_BRDV_DIV_32,
@@ -920,6 +935,9 @@ static int sh_msiof_transfer_one(struct spi_controller *ctlr,
        bool swab;
        int ret;
 
+       /* reset registers */
+       sh_msiof_spi_reset_regs(p);
+
        /* setup clocks (clock already enabled in chipselect()) */
        if (!spi_controller_is_slave(p->ctlr))
                sh_msiof_spi_set_clk_regs(p, clk_get_rate(p->clk), t->speed_hz);