These changes are a raw update to a vanilla kernel 4.1.10, with the
[kvmfornfv.git] / kernel / drivers / spi / spi-bcm2835.c
index 37875cf..a506773 100644 (file)
@@ -257,13 +257,11 @@ static int bcm2835_spi_transfer_one(struct spi_master *master,
        spi_used_hz = cdiv ? (clk_hz / cdiv) : (clk_hz / 65536);
        bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv);
 
-       /* handle all the modes */
+       /* handle all the 3-wire mode */
        if ((spi->mode & SPI_3WIRE) && (tfr->rx_buf))
                cs |= BCM2835_SPI_CS_REN;
-       if (spi->mode & SPI_CPOL)
-               cs |= BCM2835_SPI_CS_CPOL;
-       if (spi->mode & SPI_CPHA)
-               cs |= BCM2835_SPI_CS_CPHA;
+       else
+               cs &= ~BCM2835_SPI_CS_REN;
 
        /* for gpio_cs set dummy CS so that no HW-CS get changed
         * we can not run this in bcm2835_spi_set_cs, as it does
@@ -291,6 +289,25 @@ static int bcm2835_spi_transfer_one(struct spi_master *master,
        return bcm2835_spi_transfer_one_irq(master, spi, tfr, cs);
 }
 
+static int bcm2835_spi_prepare_message(struct spi_master *master,
+                                      struct spi_message *msg)
+{
+       struct spi_device *spi = msg->spi;
+       struct bcm2835_spi *bs = spi_master_get_devdata(master);
+       u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);
+
+       cs &= ~(BCM2835_SPI_CS_CPOL | BCM2835_SPI_CS_CPHA);
+
+       if (spi->mode & SPI_CPOL)
+               cs |= BCM2835_SPI_CS_CPOL;
+       if (spi->mode & SPI_CPHA)
+               cs |= BCM2835_SPI_CS_CPHA;
+
+       bcm2835_wr(bs, BCM2835_SPI_CS, cs);
+
+       return 0;
+}
+
 static void bcm2835_spi_handle_err(struct spi_master *master,
                                   struct spi_message *msg)
 {
@@ -429,6 +446,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
        master->set_cs = bcm2835_spi_set_cs;
        master->transfer_one = bcm2835_spi_transfer_one;
        master->handle_err = bcm2835_spi_handle_err;
+       master->prepare_message = bcm2835_spi_prepare_message;
        master->dev.of_node = pdev->dev.of_node;
 
        bs = spi_master_get_devdata(master);