diff options
Diffstat (limited to '')
-rw-r--r-- | drivers/mtd/spi-nor/cadence-quadspi.c | 72 |
1 files changed, 30 insertions, 42 deletions
diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c index a92f531ad..d5c6b91fd 100644 --- a/drivers/mtd/spi-nor/cadence-quadspi.c +++ b/drivers/mtd/spi-nor/cadence-quadspi.c @@ -80,9 +80,6 @@ struct cqspi_st { dma_addr_t mmap_phys_base; int current_cs; - int current_page_size; - int current_erase_size; - int current_addr_width; unsigned long master_ref_clk_hz; bool is_decoded_cs; u32 fifo_depth; @@ -734,32 +731,6 @@ static void cqspi_chipselect(struct spi_nor *nor) writel(reg, reg_base + CQSPI_REG_CONFIG); } -static void cqspi_configure_cs_and_sizes(struct spi_nor *nor) -{ - struct cqspi_flash_pdata *f_pdata = nor->priv; - struct cqspi_st *cqspi = f_pdata->cqspi; - void __iomem *iobase = cqspi->iobase; - unsigned int reg; - - /* configure page size and block size. */ - reg = readl(iobase + CQSPI_REG_SIZE); - reg &= ~(CQSPI_REG_SIZE_PAGE_MASK << CQSPI_REG_SIZE_PAGE_LSB); - reg &= ~(CQSPI_REG_SIZE_BLOCK_MASK << CQSPI_REG_SIZE_BLOCK_LSB); - reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK; - reg |= (nor->page_size << CQSPI_REG_SIZE_PAGE_LSB); - reg |= (ilog2(nor->mtd.erasesize) << CQSPI_REG_SIZE_BLOCK_LSB); - reg |= (nor->addr_width - 1); - writel(reg, iobase + CQSPI_REG_SIZE); - - /* configure the chip select */ - cqspi_chipselect(nor); - - /* Store the new configuration of the controller */ - cqspi->current_page_size = nor->page_size; - cqspi->current_erase_size = nor->mtd.erasesize; - cqspi->current_addr_width = nor->addr_width; -} - static unsigned int calculate_ticks_for_ns(const unsigned int ref_clk_hz, const unsigned int ns_val) { @@ -865,18 +836,13 @@ static void cqspi_configure(struct spi_nor *nor) int switch_cs = (cqspi->current_cs != f_pdata->cs); int switch_ck = (cqspi->sclk != sclk); - if ((cqspi->current_page_size != nor->page_size) || - (cqspi->current_erase_size != nor->mtd.erasesize) || - (cqspi->current_addr_width != nor->addr_width)) - switch_cs = 1; - if (switch_cs || switch_ck) cqspi_controller_enable(cqspi, 0); /* Switch chip select. */ if (switch_cs) { cqspi->current_cs = f_pdata->cs; - cqspi_configure_cs_and_sizes(nor); + cqspi_chipselect(nor); } /* Setup baudrate divisor and delays */ @@ -1196,7 +1162,7 @@ static void cqspi_controller_init(struct cqspi_st *cqspi) cqspi_controller_enable(cqspi, 1); } -static void cqspi_request_mmap_dma(struct cqspi_st *cqspi) +static int cqspi_request_mmap_dma(struct cqspi_st *cqspi) { dma_cap_mask_t mask; @@ -1205,10 +1171,16 @@ static void cqspi_request_mmap_dma(struct cqspi_st *cqspi) cqspi->rx_chan = dma_request_chan_by_mask(&mask); if (IS_ERR(cqspi->rx_chan)) { - dev_err(&cqspi->pdev->dev, "No Rx DMA available\n"); + int ret = PTR_ERR(cqspi->rx_chan); + + if (ret != -EPROBE_DEFER) + dev_err(&cqspi->pdev->dev, "No Rx DMA available\n"); cqspi->rx_chan = NULL; + return ret; } init_completion(&cqspi->rx_dma_complete); + + return 0; } static int cqspi_setup_flash(struct cqspi_st *cqspi, struct device_node *np) @@ -1289,8 +1261,11 @@ static int cqspi_setup_flash(struct cqspi_st *cqspi, struct device_node *np) dev_dbg(nor->dev, "using direct mode for %s\n", mtd->name); - if (!cqspi->rx_chan) - cqspi_request_mmap_dma(cqspi); + if (!cqspi->rx_chan) { + ret = cqspi_request_mmap_dma(cqspi); + if (ret == -EPROBE_DEFER) + goto err; + } } } @@ -1437,17 +1412,30 @@ static int cqspi_remove(struct platform_device *pdev) static int cqspi_suspend(struct device *dev) { struct cqspi_st *cqspi = dev_get_drvdata(dev); + struct spi_master *master = dev_get_drvdata(dev); + int ret; + ret = spi_master_suspend(master); cqspi_controller_enable(cqspi, 0); - return 0; + + clk_disable_unprepare(cqspi->clk); + + return ret; } static int cqspi_resume(struct device *dev) { struct cqspi_st *cqspi = dev_get_drvdata(dev); + struct spi_master *master = dev_get_drvdata(dev); - cqspi_controller_enable(cqspi, 1); - return 0; + clk_prepare_enable(cqspi->clk); + cqspi_wait_idle(cqspi); + cqspi_controller_init(cqspi); + + cqspi->current_cs = -1; + cqspi->sclk = 0; + + return spi_master_resume(master); } static const struct dev_pm_ops cqspi__dev_pm_ops = { |