spi: rockchip: check return value of dmaengine_prep_slave_sg
[deliverable/linux.git] / drivers / spi / spi-rockchip.c
index 79a8bc4f6cec9e32ec9c78627a2e68fc85ab5e12..aa8528e9840c4ee2cf4346968c1d4c09f9ac973c 100644 (file)
@@ -192,8 +192,6 @@ struct rockchip_spi {
        /* protect state */
        spinlock_t lock;
 
-       struct completion xfer_completion;
-
        u32 use_dma;
        struct sg_table tx_sg;
        struct sg_table rx_sg;
@@ -265,7 +263,10 @@ static inline u32 rx_max(struct rockchip_spi *rs)
 static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
 {
        u32 ser;
-       struct rockchip_spi *rs = spi_master_get_devdata(spi->master);
+       struct spi_master *master = spi->master;
+       struct rockchip_spi *rs = spi_master_get_devdata(master);
+
+       pm_runtime_get_sync(rs->dev);
 
        ser = readl_relaxed(rs->regs + ROCKCHIP_SPI_SER) & SER_MASK;
 
@@ -290,6 +291,8 @@ static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
                ser &= ~(1 << spi->chip_select);
 
        writel_relaxed(ser, rs->regs + ROCKCHIP_SPI_SER);
+
+       pm_runtime_put_sync(rs->dev);
 }
 
 static int rockchip_spi_prepare_message(struct spi_master *master,
@@ -433,7 +436,7 @@ static void rockchip_spi_dma_txcb(void *data)
        spin_unlock_irqrestore(&rs->lock, flags);
 }
 
-static void rockchip_spi_prepare_dma(struct rockchip_spi *rs)
+static int rockchip_spi_prepare_dma(struct rockchip_spi *rs)
 {
        unsigned long flags;
        struct dma_slave_config rxconf, txconf;
@@ -456,6 +459,8 @@ static void rockchip_spi_prepare_dma(struct rockchip_spi *rs)
                                rs->dma_rx.ch,
                                rs->rx_sg.sgl, rs->rx_sg.nents,
                                rs->dma_rx.direction, DMA_PREP_INTERRUPT);
+               if (!rxdesc)
+                       return -EINVAL;
 
                rxdesc->callback = rockchip_spi_dma_rxcb;
                rxdesc->callback_param = rs;
@@ -473,6 +478,11 @@ static void rockchip_spi_prepare_dma(struct rockchip_spi *rs)
                                rs->dma_tx.ch,
                                rs->tx_sg.sgl, rs->tx_sg.nents,
                                rs->dma_tx.direction, DMA_PREP_INTERRUPT);
+               if (!txdesc) {
+                       if (rxdesc)
+                               dmaengine_terminate_sync(rs->dma_rx.ch);
+                       return -EINVAL;
+               }
 
                txdesc->callback = rockchip_spi_dma_txcb;
                txdesc->callback_param = rs;
@@ -494,6 +504,8 @@ static void rockchip_spi_prepare_dma(struct rockchip_spi *rs)
                dmaengine_submit(txdesc);
                dma_async_issue_pending(rs->dma_tx.ch);
        }
+
+       return 0;
 }
 
 static void rockchip_spi_config(struct rockchip_spi *rs)
@@ -503,7 +515,8 @@ static void rockchip_spi_config(struct rockchip_spi *rs)
        int rsd = 0;
 
        u32 cr0 = (CR0_BHT_8BIT << CR0_BHT_OFFSET)
-               | (CR0_SSD_ONE << CR0_SSD_OFFSET);
+               | (CR0_SSD_ONE << CR0_SSD_OFFSET)
+               | (CR0_EM_BIG << CR0_EM_OFFSET);
 
        cr0 |= (rs->n_bytes << CR0_DFS_OFFSET);
        cr0 |= ((rs->mode & 0x3) << CR0_SCPH_OFFSET);
@@ -606,12 +619,12 @@ static int rockchip_spi_transfer_one(
        if (rs->use_dma) {
                if (rs->tmode == CR0_XFM_RO) {
                        /* rx: dma must be prepared first */
-                       rockchip_spi_prepare_dma(rs);
+                       ret = rockchip_spi_prepare_dma(rs);
                        spi_enable_chip(rs, 1);
                } else {
                        /* tx or tr: spi must be enabled first */
                        spi_enable_chip(rs, 1);
-                       rockchip_spi_prepare_dma(rs);
+                       ret = rockchip_spi_prepare_dma(rs);
                }
        } else {
                spi_enable_chip(rs, 1);
@@ -868,6 +881,7 @@ static const struct of_device_id rockchip_spi_dt_match[] = {
        { .compatible = "rockchip,rk3066-spi", },
        { .compatible = "rockchip,rk3188-spi", },
        { .compatible = "rockchip,rk3288-spi", },
+       { .compatible = "rockchip,rk3399-spi", },
        { },
 };
 MODULE_DEVICE_TABLE(of, rockchip_spi_dt_match);
This page took 0.033531 seconds and 5 git commands to generate.