All of lore.kernel.org
 help / color / mirror / Atom feed
From: <Tudor.Ambarus@microchip.com>
To: <linux-mtd@lists.infradead.org>,
	<vadivel.muruganx.ramuthevar@linux.intel.com>
Cc: <linux-kernel@vger.kernel.org>, <linux-spi@vger.kernel.org>,
	<broonie@kernel.org>, <vigneshr@ti.com>, <robh+dt@kernel.org>,
	<marex@denx.de>, <devicetree@vger.kernel.org>,
	<tien.fong.chee@intel.com>, <tudor.ambarus@gmail.com>,
	<boris.brezillon@free-electrons.com>, <richard@nod.at>,
	<qi-ming.wu@intel.com>, <simon.k.r.goldschmidt@gmail.com>,
	<dinguyen@kernel.org>, <miquel.raynal@bootlin.com>,
	<cheol.yong.kim@intel.com>, <cyrille.pitchen@atmel.com>,
	<computersforpeace@gmail.com>, <dwmw2@infradead.org>,
	<david.oberhollenzer@sigma-star.at>
Subject: Re: [PATCH v12 2/4] mtd: spi-nor: add spi-mem support in cadence-quadspi controller driver
Date: Thu, 19 Mar 2020 08:09:48 +0000	[thread overview]
Message-ID: <3360641.Vn3sISamPi@192.168.0.120> (raw)
In-Reply-To: <20200310015213.1734-3-vadivel.muruganx.ramuthevar@linux.intel.com>

Hi,

On Tuesday, March 10, 2020 3:52:11 AM EET Ramuthevar, Vadivel MuruganX wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the
> content is safe
> 
> From: Ramuthevar Vadivel Murugan
> <vadivel.muruganx.ramuthevar@linux.intel.com>
> 
> This patch adds a spi-mem framework adaptation over cadence-quadspi driver.

you need to specify on which versions of the controller you tested this.

> 
> Signed-off-by: Ramuthevar Vadivel Murugan
> <vadivel.muruganx.ramuthevar@linux.intel.com> Signed-off-by: Vignesh
> Raghavendra <vigneshr@ti.com>
> ---
>  drivers/mtd/spi-nor/cadence-quadspi.c | 538
> +++++++++++++--------------------- 1 file changed, 209 insertions(+), 329
> deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c
> b/drivers/mtd/spi-nor/cadence-quadspi.c index 494dcab4aaaa..7b52e109036e
> 100644
> --- a/drivers/mtd/spi-nor/cadence-quadspi.c
> +++ b/drivers/mtd/spi-nor/cadence-quadspi.c
> @@ -3,6 +3,8 @@

cut

>  struct cqspi_st {
> @@ -70,23 +66,20 @@ struct cqspi_st {
>         void __iomem            *ahb_base;
>         resource_size_t         ahb_size;
>         struct completion       transfer_complete;
> -       struct mutex            bus_mutex;

are we now supporting just a single flash on the bus? Does 
CQSPI_MAX_CHIPSELECT make sense anymore?

> 
>         struct dma_chan         *rx_chan;
>         struct completion       rx_dma_complete;
>         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;
> +       unsigned long           master_ref_clk_hz;

don't do changes for free, keep it were it was.

>         u32                     fifo_depth;
>         u32                     fifo_width;
>         bool                    rclk_en;
>         u32                     trigger_address;
>         u32                     wr_delay;
> +       bool                    use_dac_mode;
>         struct cqspi_flash_pdata f_pdata[CQSPI_MAX_CHIPSELECT];
>  };

cut

> -static int cqspi_read_setup(struct spi_nor *nor)
> +static int cqspi_read_setup(struct cqspi_flash_pdata *f_pdata,
> +                           const struct spi_mem_op *op)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
>         void __iomem *reg_base = cqspi->iobase;
>         unsigned int dummy_clk = 0;
>         unsigned int reg;
> 
> -       reg = nor->read_opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
> -       reg |= cqspi_calc_rdreg(nor);
> +       reg = op->cmd.opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
> +       reg |= cqspi_calc_rdreg(f_pdata);
> 
>         /* Setup dummy clock cycles */
> -       dummy_clk = nor->read_dummy;
> +       dummy_clk = op->dummy.nbytes * 8;
>         if (dummy_clk > CQSPI_DUMMY_CLKS_MAX)
>                 dummy_clk = CQSPI_DUMMY_CLKS_MAX;
> 
> -       if (dummy_clk / 8) {
> -               reg |= (1 << CQSPI_REG_RD_INSTR_MODE_EN_LSB);
> -               /* Set mode bits high to ensure chip doesn't enter XIP */
> -               writel(0xFF, reg_base + CQSPI_REG_MODE_BIT);
> -
> -               /* Need to subtract the mode byte (8 clocks). */
> -               if (f_pdata->inst_width != CQSPI_INST_TYPE_QUAD)
> -                       dummy_clk -= 8;
> -
> -               if (dummy_clk)
> -                       reg |= (dummy_clk & CQSPI_REG_RD_INSTR_DUMMY_MASK)
> -                              << CQSPI_REG_RD_INSTR_DUMMY_LSB;
> -       }
> +       if (dummy_clk / 8)
> +               reg |= (dummy_clk & CQSPI_REG_RD_INSTR_DUMMY_MASK)
> +                      << CQSPI_REG_RD_INSTR_DUMMY_LSB;

nit: we usually keep the operator on the first line

> 
>         writel(reg, reg_base + CQSPI_REG_RD_INSTR);
> 
>         /* Set address width */
>         reg = readl(reg_base + CQSPI_REG_SIZE);
>         reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
> -       reg |= (nor->addr_width - 1);
> +       reg |= (op->addr.nbytes - 1);
>         writel(reg, reg_base + CQSPI_REG_SIZE);
>         return 0;
>  }
> 
> -static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,
> -                                      loff_t from_addr, const size_t n_rx)
> +static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
> +                                      u8 *rxbuf, loff_t from_addr,
> +                                      const size_t n_rx)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
> +       struct device *dev = &cqspi->pdev->dev;
>         void __iomem *reg_base = cqspi->iobase;
>         void __iomem *ahb_base = cqspi->ahb_base;
>         unsigned int remaining = n_rx;
> @@ -528,13 +508,13 @@ static int cqspi_indirect_read_execute(struct spi_nor
> *nor, u8 *rxbuf,
> 
>         while (remaining > 0) {
>                 if (!wait_for_completion_timeout(&cqspi->transfer_complete,
> -                               msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS)))
> +                                               
> msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS))) ret = -ETIMEDOUT;

nit: unrelated change. You can fix all the checkpatch warnings in the driver 
at the beginning of the series in one dedicated patch, if you care of course, 
but don't do it here.

cut

> -static int cqspi_of_get_pdata(struct platform_device *pdev)
> +static int cqspi_of_get_pdata(struct cqspi_st *cqspi)
>  {
> -       struct device_node *np = pdev->dev.of_node;
> -       struct cqspi_st *cqspi = platform_get_drvdata(pdev);
> -
> -       cqspi->is_decoded_cs = of_property_read_bool(np,
> "cdns,is-decoded-cs"); +       struct device *dev = &cqspi->pdev->dev;

you dropped the reading of this property, but you kept the is_decoded_cs 
member, shouldn't you drop the latter too? I guess this deserves a dedicated 
patch.

cut

> 
> -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;
> 
> @@ -1211,131 +1126,82 @@ 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;

why do you print this just on defer?

> +
> +               return ret;

not initializing completion on errors needs a dedicated patch

>         }
>         init_completion(&cqspi->rx_dma_complete);
> +
> +       return 0;
>  }

cut

> 
>  static int cqspi_probe(struct platform_device *pdev)
>  {
> -       struct device_node *np = pdev->dev.of_node;
> +       const struct cqspi_driver_platdata *ddata;
> +       struct reset_control *rstc, *rstc_ocp;
>         struct device *dev = &pdev->dev;
> +       struct spi_master *master;
> +       struct resource *res_ahb;
>         struct cqspi_st *cqspi;
>         struct resource *res;
> -       struct resource *res_ahb;
> -       struct reset_control *rstc, *rstc_ocp;
> -       const struct cqspi_driver_platdata *ddata;
>         int ret;
>         int irq;
> 
> -       cqspi = devm_kzalloc(dev, sizeof(*cqspi), GFP_KERNEL);
> -       if (!cqspi)
> +       master = spi_alloc_master(&pdev->dev, sizeof(*cqspi));
> +       if (!master) {
> +               dev_err(&pdev->dev, "spi_alloc_master failed\n");
>                 return -ENOMEM;
> +       }

don't forget to free the master on following errors

> +       master->mode_bits = SPI_RX_QUAD | SPI_TX_DUAL | SPI_RX_DUAL;
> +       master->mem_ops = &cqspi_mem_ops;
> +       master->dev.of_node = pdev->dev.of_node;
> +
> +       cqspi = spi_master_get_devdata(master);
> 
> -       mutex_init(&cqspi->bus_mutex);
>         cqspi->pdev = pdev;
> -       platform_set_drvdata(pdev, cqspi);
> 
>         /* Obtain configuration from OF. */
> -       ret = cqspi_of_get_pdata(pdev);
> +       ret = cqspi_of_get_pdata(cqspi);
>         if (ret) {
>                 dev_err(dev, "Cannot get mandatory OF data.\n");
>                 return -ENODEV;
> @@ -1390,13 +1256,13 @@ static int cqspi_probe(struct platform_device *pdev)
> rstc = devm_reset_control_get_optional_exclusive(dev, "qspi"); if
> (IS_ERR(rstc)) {
>                 dev_err(dev, "Cannot get QSPI reset.\n");
> -               return PTR_ERR(rstc);
> +               goto probe_reset_failed;
>         }
> 
>         rstc_ocp = devm_reset_control_get_optional_exclusive(dev,
> "qspi-ocp"); if (IS_ERR(rstc_ocp)) {
>                 dev_err(dev, "Cannot get QSPI OCP reset.\n");
> -               return PTR_ERR(rstc_ocp);
> +               goto probe_reset_failed;

these 2 goto statements need a dedicated patch.

>         }
> 
>         reset_control_assert(rstc);
> @@ -1407,15 +1273,21 @@ static int cqspi_probe(struct platform_device *pdev)
> 
>         cqspi->master_ref_clk_hz = clk_get_rate(cqspi->clk);
>         ddata  = of_device_get_match_data(dev);
> -       if (ddata && (ddata->quirks & CQSPI_NEEDS_WR_DELAY))
> -               cqspi->wr_delay = 5 * DIV_ROUND_UP(NSEC_PER_SEC,
> -                                                 
> cqspi->master_ref_clk_hz); +       if (ddata) {
> +               if (ddata->quirks & CQSPI_NEEDS_WR_DELAY)
> +                       cqspi->wr_delay = 5 * DIV_ROUND_UP(NSEC_PER_SEC,
> +                                               cqspi->master_ref_clk_hz);
> +               if (ddata->hwcaps_mask & CQSPI_SUPPORTS_OCTAL)
> +                       master->mode_bits |= SPI_RX_OCTAL;
> +               if (!(ddata->quirks & CQSPI_DISABLE_DAC_MODE))
> +                       cqspi->use_dac_mode = true;
> +       }
> 
>         ret = devm_request_irq(dev, irq, cqspi_irq_handler, 0,
>                                pdev->name, cqspi);
>         if (ret) {
>                 dev_err(dev, "Cannot request IRQ.\n");
> -               goto probe_irq_failed;
> +               goto probe_reset_failed;
>         }
> 
>         cqspi_wait_idle(cqspi);
> @@ -1423,16 +1295,28 @@ static int cqspi_probe(struct platform_device *pdev)
> cqspi->current_cs = -1;
>         cqspi->sclk = 0;
> 
> -       ret = cqspi_setup_flash(cqspi, np);
> +       ret = cqspi_setup_flash(cqspi);
>         if (ret) {
> -               dev_err(dev, "Cadence QSPI NOR probe failed %d\n", ret);
> +               dev_err(dev, "failed to setup flash parameters %d\n", ret);
>                 goto probe_setup_failed;
>         }
> 
> -       return ret;
> +       if (cqspi->use_dac_mode) {
> +               ret = cqspi_request_mmap_dma(cqspi);

the driver was requesting the mmap for each available flash and now you do it 
once, which is great, but this too has to be made in a dedicated patch.

> +               if (ret == -EPROBE_DEFER)
> +                       goto probe_setup_failed;
> +       }
> +
> +       ret = devm_spi_register_master(dev, master);
> +       if (ret) {
> +               dev_err(&pdev->dev, "failed to register SPI ctlr %d\n",
> ret); +               goto probe_setup_failed;
> +       }
> +
> +       return 0;
>  probe_setup_failed:
>         cqspi_controller_enable(cqspi, 0);
> -probe_irq_failed:
> +probe_reset_failed:
>         clk_disable_unprepare(cqspi->clk);
>  probe_clk_failed:
>         pm_runtime_put_sync(dev);
> @@ -1443,11 +1327,6 @@ static int cqspi_probe(struct platform_device *pdev)
>  static int cqspi_remove(struct platform_device *pdev)
>  {
>         struct cqspi_st *cqspi = platform_get_drvdata(pdev);
> -       int i;
> -
> -       for (i = 0; i < CQSPI_MAX_CHIPSELECT; i++)
> -               if (cqspi->f_pdata[i].registered)
> -                       mtd_device_unregister(&cqspi->f_pdata[i].nor.mtd);
> 
>         cqspi_controller_enable(cqspi, 0);
> 
> @@ -1490,16 +1369,15 @@ static const struct dev_pm_ops cqspi__dev_pm_ops = {
> #endif
> 
>  static const struct cqspi_driver_platdata cdns_qspi = {
> -       .hwcaps_mask = CQSPI_BASE_HWCAPS_MASK,
> +       .quirks = CQSPI_DISABLE_DAC_MODE,

The logic around CQSPI_DISABLE_DAC_MODE needs a dedicated patch.

Cheers,
ta



WARNING: multiple messages have this Message-ID (diff)
From: <Tudor.Ambarus-UWL1GkI3JZL3oGB3hsPCZA@public.gmane.org>
To: <linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org>,
	<vadivel.muruganx.ramuthevar-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Cc: <linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
	<linux-spi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
	<broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	<vigneshr-l0cyMroinI0@public.gmane.org>,
	<robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	<marex-ynQEQJNshbs@public.gmane.org>,
	<devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
	<tien.fong.chee-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
	<tudor.ambarus-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	<boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>,
	<richard-/L3Ra7n9ekc@public.gmane.org>,
	<qi-ming.wu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
	<simon.k.r.goldschmidt-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	<dinguyen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	<miquel.raynal-LDxbnhwyfcJBDgjK7y7TUQ@public.gmane.org>,
	<cheol.yong.kim-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
	<cyrille.pitchen-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>,
	<computersforpeace-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	<dwmw2-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>,
	<david.oberhollenzer-S6VGOU4v5edDinCvNWH78Q@public.gmane.org>
Subject: Re: [PATCH v12 2/4] mtd: spi-nor: add spi-mem support in cadence-quadspi controller driver
Date: Thu, 19 Mar 2020 08:09:48 +0000	[thread overview]
Message-ID: <3360641.Vn3sISamPi@192.168.0.120> (raw)
In-Reply-To: <20200310015213.1734-3-vadivel.muruganx.ramuthevar-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>

Hi,

On Tuesday, March 10, 2020 3:52:11 AM EET Ramuthevar, Vadivel MuruganX wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the
> content is safe
> 
> From: Ramuthevar Vadivel Murugan
> <vadivel.muruganx.ramuthevar-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
> 
> This patch adds a spi-mem framework adaptation over cadence-quadspi driver.

you need to specify on which versions of the controller you tested this.

> 
> Signed-off-by: Ramuthevar Vadivel Murugan
> <vadivel.muruganx.ramuthevar-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> Signed-off-by: Vignesh
> Raghavendra <vigneshr-l0cyMroinI0@public.gmane.org>
> ---
>  drivers/mtd/spi-nor/cadence-quadspi.c | 538
> +++++++++++++--------------------- 1 file changed, 209 insertions(+), 329
> deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c
> b/drivers/mtd/spi-nor/cadence-quadspi.c index 494dcab4aaaa..7b52e109036e
> 100644
> --- a/drivers/mtd/spi-nor/cadence-quadspi.c
> +++ b/drivers/mtd/spi-nor/cadence-quadspi.c
> @@ -3,6 +3,8 @@

cut

>  struct cqspi_st {
> @@ -70,23 +66,20 @@ struct cqspi_st {
>         void __iomem            *ahb_base;
>         resource_size_t         ahb_size;
>         struct completion       transfer_complete;
> -       struct mutex            bus_mutex;

are we now supporting just a single flash on the bus? Does 
CQSPI_MAX_CHIPSELECT make sense anymore?

> 
>         struct dma_chan         *rx_chan;
>         struct completion       rx_dma_complete;
>         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;
> +       unsigned long           master_ref_clk_hz;

don't do changes for free, keep it were it was.

>         u32                     fifo_depth;
>         u32                     fifo_width;
>         bool                    rclk_en;
>         u32                     trigger_address;
>         u32                     wr_delay;
> +       bool                    use_dac_mode;
>         struct cqspi_flash_pdata f_pdata[CQSPI_MAX_CHIPSELECT];
>  };

cut

> -static int cqspi_read_setup(struct spi_nor *nor)
> +static int cqspi_read_setup(struct cqspi_flash_pdata *f_pdata,
> +                           const struct spi_mem_op *op)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
>         void __iomem *reg_base = cqspi->iobase;
>         unsigned int dummy_clk = 0;
>         unsigned int reg;
> 
> -       reg = nor->read_opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
> -       reg |= cqspi_calc_rdreg(nor);
> +       reg = op->cmd.opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
> +       reg |= cqspi_calc_rdreg(f_pdata);
> 
>         /* Setup dummy clock cycles */
> -       dummy_clk = nor->read_dummy;
> +       dummy_clk = op->dummy.nbytes * 8;
>         if (dummy_clk > CQSPI_DUMMY_CLKS_MAX)
>                 dummy_clk = CQSPI_DUMMY_CLKS_MAX;
> 
> -       if (dummy_clk / 8) {
> -               reg |= (1 << CQSPI_REG_RD_INSTR_MODE_EN_LSB);
> -               /* Set mode bits high to ensure chip doesn't enter XIP */
> -               writel(0xFF, reg_base + CQSPI_REG_MODE_BIT);
> -
> -               /* Need to subtract the mode byte (8 clocks). */
> -               if (f_pdata->inst_width != CQSPI_INST_TYPE_QUAD)
> -                       dummy_clk -= 8;
> -
> -               if (dummy_clk)
> -                       reg |= (dummy_clk & CQSPI_REG_RD_INSTR_DUMMY_MASK)
> -                              << CQSPI_REG_RD_INSTR_DUMMY_LSB;
> -       }
> +       if (dummy_clk / 8)
> +               reg |= (dummy_clk & CQSPI_REG_RD_INSTR_DUMMY_MASK)
> +                      << CQSPI_REG_RD_INSTR_DUMMY_LSB;

nit: we usually keep the operator on the first line

> 
>         writel(reg, reg_base + CQSPI_REG_RD_INSTR);
> 
>         /* Set address width */
>         reg = readl(reg_base + CQSPI_REG_SIZE);
>         reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
> -       reg |= (nor->addr_width - 1);
> +       reg |= (op->addr.nbytes - 1);
>         writel(reg, reg_base + CQSPI_REG_SIZE);
>         return 0;
>  }
> 
> -static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,
> -                                      loff_t from_addr, const size_t n_rx)
> +static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
> +                                      u8 *rxbuf, loff_t from_addr,
> +                                      const size_t n_rx)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
> +       struct device *dev = &cqspi->pdev->dev;
>         void __iomem *reg_base = cqspi->iobase;
>         void __iomem *ahb_base = cqspi->ahb_base;
>         unsigned int remaining = n_rx;
> @@ -528,13 +508,13 @@ static int cqspi_indirect_read_execute(struct spi_nor
> *nor, u8 *rxbuf,
> 
>         while (remaining > 0) {
>                 if (!wait_for_completion_timeout(&cqspi->transfer_complete,
> -                               msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS)))
> +                                               
> msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS))) ret = -ETIMEDOUT;

nit: unrelated change. You can fix all the checkpatch warnings in the driver 
at the beginning of the series in one dedicated patch, if you care of course, 
but don't do it here.

cut

> -static int cqspi_of_get_pdata(struct platform_device *pdev)
> +static int cqspi_of_get_pdata(struct cqspi_st *cqspi)
>  {
> -       struct device_node *np = pdev->dev.of_node;
> -       struct cqspi_st *cqspi = platform_get_drvdata(pdev);
> -
> -       cqspi->is_decoded_cs = of_property_read_bool(np,
> "cdns,is-decoded-cs"); +       struct device *dev = &cqspi->pdev->dev;

you dropped the reading of this property, but you kept the is_decoded_cs 
member, shouldn't you drop the latter too? I guess this deserves a dedicated 
patch.

cut

> 
> -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;
> 
> @@ -1211,131 +1126,82 @@ 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;

why do you print this just on defer?

> +
> +               return ret;

not initializing completion on errors needs a dedicated patch

>         }
>         init_completion(&cqspi->rx_dma_complete);
> +
> +       return 0;
>  }

cut

> 
>  static int cqspi_probe(struct platform_device *pdev)
>  {
> -       struct device_node *np = pdev->dev.of_node;
> +       const struct cqspi_driver_platdata *ddata;
> +       struct reset_control *rstc, *rstc_ocp;
>         struct device *dev = &pdev->dev;
> +       struct spi_master *master;
> +       struct resource *res_ahb;
>         struct cqspi_st *cqspi;
>         struct resource *res;
> -       struct resource *res_ahb;
> -       struct reset_control *rstc, *rstc_ocp;
> -       const struct cqspi_driver_platdata *ddata;
>         int ret;
>         int irq;
> 
> -       cqspi = devm_kzalloc(dev, sizeof(*cqspi), GFP_KERNEL);
> -       if (!cqspi)
> +       master = spi_alloc_master(&pdev->dev, sizeof(*cqspi));
> +       if (!master) {
> +               dev_err(&pdev->dev, "spi_alloc_master failed\n");
>                 return -ENOMEM;
> +       }

don't forget to free the master on following errors

> +       master->mode_bits = SPI_RX_QUAD | SPI_TX_DUAL | SPI_RX_DUAL;
> +       master->mem_ops = &cqspi_mem_ops;
> +       master->dev.of_node = pdev->dev.of_node;
> +
> +       cqspi = spi_master_get_devdata(master);
> 
> -       mutex_init(&cqspi->bus_mutex);
>         cqspi->pdev = pdev;
> -       platform_set_drvdata(pdev, cqspi);
> 
>         /* Obtain configuration from OF. */
> -       ret = cqspi_of_get_pdata(pdev);
> +       ret = cqspi_of_get_pdata(cqspi);
>         if (ret) {
>                 dev_err(dev, "Cannot get mandatory OF data.\n");
>                 return -ENODEV;
> @@ -1390,13 +1256,13 @@ static int cqspi_probe(struct platform_device *pdev)
> rstc = devm_reset_control_get_optional_exclusive(dev, "qspi"); if
> (IS_ERR(rstc)) {
>                 dev_err(dev, "Cannot get QSPI reset.\n");
> -               return PTR_ERR(rstc);
> +               goto probe_reset_failed;
>         }
> 
>         rstc_ocp = devm_reset_control_get_optional_exclusive(dev,
> "qspi-ocp"); if (IS_ERR(rstc_ocp)) {
>                 dev_err(dev, "Cannot get QSPI OCP reset.\n");
> -               return PTR_ERR(rstc_ocp);
> +               goto probe_reset_failed;

these 2 goto statements need a dedicated patch.

>         }
> 
>         reset_control_assert(rstc);
> @@ -1407,15 +1273,21 @@ static int cqspi_probe(struct platform_device *pdev)
> 
>         cqspi->master_ref_clk_hz = clk_get_rate(cqspi->clk);
>         ddata  = of_device_get_match_data(dev);
> -       if (ddata && (ddata->quirks & CQSPI_NEEDS_WR_DELAY))
> -               cqspi->wr_delay = 5 * DIV_ROUND_UP(NSEC_PER_SEC,
> -                                                 
> cqspi->master_ref_clk_hz); +       if (ddata) {
> +               if (ddata->quirks & CQSPI_NEEDS_WR_DELAY)
> +                       cqspi->wr_delay = 5 * DIV_ROUND_UP(NSEC_PER_SEC,
> +                                               cqspi->master_ref_clk_hz);
> +               if (ddata->hwcaps_mask & CQSPI_SUPPORTS_OCTAL)
> +                       master->mode_bits |= SPI_RX_OCTAL;
> +               if (!(ddata->quirks & CQSPI_DISABLE_DAC_MODE))
> +                       cqspi->use_dac_mode = true;
> +       }
> 
>         ret = devm_request_irq(dev, irq, cqspi_irq_handler, 0,
>                                pdev->name, cqspi);
>         if (ret) {
>                 dev_err(dev, "Cannot request IRQ.\n");
> -               goto probe_irq_failed;
> +               goto probe_reset_failed;
>         }
> 
>         cqspi_wait_idle(cqspi);
> @@ -1423,16 +1295,28 @@ static int cqspi_probe(struct platform_device *pdev)
> cqspi->current_cs = -1;
>         cqspi->sclk = 0;
> 
> -       ret = cqspi_setup_flash(cqspi, np);
> +       ret = cqspi_setup_flash(cqspi);
>         if (ret) {
> -               dev_err(dev, "Cadence QSPI NOR probe failed %d\n", ret);
> +               dev_err(dev, "failed to setup flash parameters %d\n", ret);
>                 goto probe_setup_failed;
>         }
> 
> -       return ret;
> +       if (cqspi->use_dac_mode) {
> +               ret = cqspi_request_mmap_dma(cqspi);

the driver was requesting the mmap for each available flash and now you do it 
once, which is great, but this too has to be made in a dedicated patch.

> +               if (ret == -EPROBE_DEFER)
> +                       goto probe_setup_failed;
> +       }
> +
> +       ret = devm_spi_register_master(dev, master);
> +       if (ret) {
> +               dev_err(&pdev->dev, "failed to register SPI ctlr %d\n",
> ret); +               goto probe_setup_failed;
> +       }
> +
> +       return 0;
>  probe_setup_failed:
>         cqspi_controller_enable(cqspi, 0);
> -probe_irq_failed:
> +probe_reset_failed:
>         clk_disable_unprepare(cqspi->clk);
>  probe_clk_failed:
>         pm_runtime_put_sync(dev);
> @@ -1443,11 +1327,6 @@ static int cqspi_probe(struct platform_device *pdev)
>  static int cqspi_remove(struct platform_device *pdev)
>  {
>         struct cqspi_st *cqspi = platform_get_drvdata(pdev);
> -       int i;
> -
> -       for (i = 0; i < CQSPI_MAX_CHIPSELECT; i++)
> -               if (cqspi->f_pdata[i].registered)
> -                       mtd_device_unregister(&cqspi->f_pdata[i].nor.mtd);
> 
>         cqspi_controller_enable(cqspi, 0);
> 
> @@ -1490,16 +1369,15 @@ static const struct dev_pm_ops cqspi__dev_pm_ops = {
> #endif
> 
>  static const struct cqspi_driver_platdata cdns_qspi = {
> -       .hwcaps_mask = CQSPI_BASE_HWCAPS_MASK,
> +       .quirks = CQSPI_DISABLE_DAC_MODE,

The logic around CQSPI_DISABLE_DAC_MODE needs a dedicated patch.

Cheers,
ta

WARNING: multiple messages have this Message-ID (diff)
From: <Tudor.Ambarus@microchip.com>
To: <linux-mtd@lists.infradead.org>,
	<vadivel.muruganx.ramuthevar@linux.intel.com>
Cc: marex@denx.de, devicetree@vger.kernel.org,
	tien.fong.chee@intel.com, tudor.ambarus@gmail.com,
	vigneshr@ti.com, boris.brezillon@free-electrons.com,
	computersforpeace@gmail.com, richard@nod.at,
	simon.k.r.goldschmidt@gmail.com, linux-kernel@vger.kernel.org,
	robh+dt@kernel.org, linux-spi@vger.kernel.org,
	dinguyen@kernel.org, broonie@kernel.org,
	miquel.raynal@bootlin.com, cheol.yong.kim@intel.com,
	cyrille.pitchen@atmel.com, qi-ming.wu@intel.com,
	dwmw2@infradead.org, david.oberhollenzer@sigma-star.at
Subject: Re: [PATCH v12 2/4] mtd: spi-nor: add spi-mem support in cadence-quadspi controller driver
Date: Thu, 19 Mar 2020 08:09:48 +0000	[thread overview]
Message-ID: <3360641.Vn3sISamPi@192.168.0.120> (raw)
In-Reply-To: <20200310015213.1734-3-vadivel.muruganx.ramuthevar@linux.intel.com>

Hi,

On Tuesday, March 10, 2020 3:52:11 AM EET Ramuthevar, Vadivel MuruganX wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the
> content is safe
> 
> From: Ramuthevar Vadivel Murugan
> <vadivel.muruganx.ramuthevar@linux.intel.com>
> 
> This patch adds a spi-mem framework adaptation over cadence-quadspi driver.

you need to specify on which versions of the controller you tested this.

> 
> Signed-off-by: Ramuthevar Vadivel Murugan
> <vadivel.muruganx.ramuthevar@linux.intel.com> Signed-off-by: Vignesh
> Raghavendra <vigneshr@ti.com>
> ---
>  drivers/mtd/spi-nor/cadence-quadspi.c | 538
> +++++++++++++--------------------- 1 file changed, 209 insertions(+), 329
> deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c
> b/drivers/mtd/spi-nor/cadence-quadspi.c index 494dcab4aaaa..7b52e109036e
> 100644
> --- a/drivers/mtd/spi-nor/cadence-quadspi.c
> +++ b/drivers/mtd/spi-nor/cadence-quadspi.c
> @@ -3,6 +3,8 @@

cut

>  struct cqspi_st {
> @@ -70,23 +66,20 @@ struct cqspi_st {
>         void __iomem            *ahb_base;
>         resource_size_t         ahb_size;
>         struct completion       transfer_complete;
> -       struct mutex            bus_mutex;

are we now supporting just a single flash on the bus? Does 
CQSPI_MAX_CHIPSELECT make sense anymore?

> 
>         struct dma_chan         *rx_chan;
>         struct completion       rx_dma_complete;
>         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;
> +       unsigned long           master_ref_clk_hz;

don't do changes for free, keep it were it was.

>         u32                     fifo_depth;
>         u32                     fifo_width;
>         bool                    rclk_en;
>         u32                     trigger_address;
>         u32                     wr_delay;
> +       bool                    use_dac_mode;
>         struct cqspi_flash_pdata f_pdata[CQSPI_MAX_CHIPSELECT];
>  };

cut

> -static int cqspi_read_setup(struct spi_nor *nor)
> +static int cqspi_read_setup(struct cqspi_flash_pdata *f_pdata,
> +                           const struct spi_mem_op *op)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
>         void __iomem *reg_base = cqspi->iobase;
>         unsigned int dummy_clk = 0;
>         unsigned int reg;
> 
> -       reg = nor->read_opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
> -       reg |= cqspi_calc_rdreg(nor);
> +       reg = op->cmd.opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
> +       reg |= cqspi_calc_rdreg(f_pdata);
> 
>         /* Setup dummy clock cycles */
> -       dummy_clk = nor->read_dummy;
> +       dummy_clk = op->dummy.nbytes * 8;
>         if (dummy_clk > CQSPI_DUMMY_CLKS_MAX)
>                 dummy_clk = CQSPI_DUMMY_CLKS_MAX;
> 
> -       if (dummy_clk / 8) {
> -               reg |= (1 << CQSPI_REG_RD_INSTR_MODE_EN_LSB);
> -               /* Set mode bits high to ensure chip doesn't enter XIP */
> -               writel(0xFF, reg_base + CQSPI_REG_MODE_BIT);
> -
> -               /* Need to subtract the mode byte (8 clocks). */
> -               if (f_pdata->inst_width != CQSPI_INST_TYPE_QUAD)
> -                       dummy_clk -= 8;
> -
> -               if (dummy_clk)
> -                       reg |= (dummy_clk & CQSPI_REG_RD_INSTR_DUMMY_MASK)
> -                              << CQSPI_REG_RD_INSTR_DUMMY_LSB;
> -       }
> +       if (dummy_clk / 8)
> +               reg |= (dummy_clk & CQSPI_REG_RD_INSTR_DUMMY_MASK)
> +                      << CQSPI_REG_RD_INSTR_DUMMY_LSB;

nit: we usually keep the operator on the first line

> 
>         writel(reg, reg_base + CQSPI_REG_RD_INSTR);
> 
>         /* Set address width */
>         reg = readl(reg_base + CQSPI_REG_SIZE);
>         reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
> -       reg |= (nor->addr_width - 1);
> +       reg |= (op->addr.nbytes - 1);
>         writel(reg, reg_base + CQSPI_REG_SIZE);
>         return 0;
>  }
> 
> -static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,
> -                                      loff_t from_addr, const size_t n_rx)
> +static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
> +                                      u8 *rxbuf, loff_t from_addr,
> +                                      const size_t n_rx)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
> +       struct device *dev = &cqspi->pdev->dev;
>         void __iomem *reg_base = cqspi->iobase;
>         void __iomem *ahb_base = cqspi->ahb_base;
>         unsigned int remaining = n_rx;
> @@ -528,13 +508,13 @@ static int cqspi_indirect_read_execute(struct spi_nor
> *nor, u8 *rxbuf,
> 
>         while (remaining > 0) {
>                 if (!wait_for_completion_timeout(&cqspi->transfer_complete,
> -                               msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS)))
> +                                               
> msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS))) ret = -ETIMEDOUT;

nit: unrelated change. You can fix all the checkpatch warnings in the driver 
at the beginning of the series in one dedicated patch, if you care of course, 
but don't do it here.

cut

> -static int cqspi_of_get_pdata(struct platform_device *pdev)
> +static int cqspi_of_get_pdata(struct cqspi_st *cqspi)
>  {
> -       struct device_node *np = pdev->dev.of_node;
> -       struct cqspi_st *cqspi = platform_get_drvdata(pdev);
> -
> -       cqspi->is_decoded_cs = of_property_read_bool(np,
> "cdns,is-decoded-cs"); +       struct device *dev = &cqspi->pdev->dev;

you dropped the reading of this property, but you kept the is_decoded_cs 
member, shouldn't you drop the latter too? I guess this deserves a dedicated 
patch.

cut

> 
> -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;
> 
> @@ -1211,131 +1126,82 @@ 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;

why do you print this just on defer?

> +
> +               return ret;

not initializing completion on errors needs a dedicated patch

>         }
>         init_completion(&cqspi->rx_dma_complete);
> +
> +       return 0;
>  }

cut

> 
>  static int cqspi_probe(struct platform_device *pdev)
>  {
> -       struct device_node *np = pdev->dev.of_node;
> +       const struct cqspi_driver_platdata *ddata;
> +       struct reset_control *rstc, *rstc_ocp;
>         struct device *dev = &pdev->dev;
> +       struct spi_master *master;
> +       struct resource *res_ahb;
>         struct cqspi_st *cqspi;
>         struct resource *res;
> -       struct resource *res_ahb;
> -       struct reset_control *rstc, *rstc_ocp;
> -       const struct cqspi_driver_platdata *ddata;
>         int ret;
>         int irq;
> 
> -       cqspi = devm_kzalloc(dev, sizeof(*cqspi), GFP_KERNEL);
> -       if (!cqspi)
> +       master = spi_alloc_master(&pdev->dev, sizeof(*cqspi));
> +       if (!master) {
> +               dev_err(&pdev->dev, "spi_alloc_master failed\n");
>                 return -ENOMEM;
> +       }

don't forget to free the master on following errors

> +       master->mode_bits = SPI_RX_QUAD | SPI_TX_DUAL | SPI_RX_DUAL;
> +       master->mem_ops = &cqspi_mem_ops;
> +       master->dev.of_node = pdev->dev.of_node;
> +
> +       cqspi = spi_master_get_devdata(master);
> 
> -       mutex_init(&cqspi->bus_mutex);
>         cqspi->pdev = pdev;
> -       platform_set_drvdata(pdev, cqspi);
> 
>         /* Obtain configuration from OF. */
> -       ret = cqspi_of_get_pdata(pdev);
> +       ret = cqspi_of_get_pdata(cqspi);
>         if (ret) {
>                 dev_err(dev, "Cannot get mandatory OF data.\n");
>                 return -ENODEV;
> @@ -1390,13 +1256,13 @@ static int cqspi_probe(struct platform_device *pdev)
> rstc = devm_reset_control_get_optional_exclusive(dev, "qspi"); if
> (IS_ERR(rstc)) {
>                 dev_err(dev, "Cannot get QSPI reset.\n");
> -               return PTR_ERR(rstc);
> +               goto probe_reset_failed;
>         }
> 
>         rstc_ocp = devm_reset_control_get_optional_exclusive(dev,
> "qspi-ocp"); if (IS_ERR(rstc_ocp)) {
>                 dev_err(dev, "Cannot get QSPI OCP reset.\n");
> -               return PTR_ERR(rstc_ocp);
> +               goto probe_reset_failed;

these 2 goto statements need a dedicated patch.

>         }
> 
>         reset_control_assert(rstc);
> @@ -1407,15 +1273,21 @@ static int cqspi_probe(struct platform_device *pdev)
> 
>         cqspi->master_ref_clk_hz = clk_get_rate(cqspi->clk);
>         ddata  = of_device_get_match_data(dev);
> -       if (ddata && (ddata->quirks & CQSPI_NEEDS_WR_DELAY))
> -               cqspi->wr_delay = 5 * DIV_ROUND_UP(NSEC_PER_SEC,
> -                                                 
> cqspi->master_ref_clk_hz); +       if (ddata) {
> +               if (ddata->quirks & CQSPI_NEEDS_WR_DELAY)
> +                       cqspi->wr_delay = 5 * DIV_ROUND_UP(NSEC_PER_SEC,
> +                                               cqspi->master_ref_clk_hz);
> +               if (ddata->hwcaps_mask & CQSPI_SUPPORTS_OCTAL)
> +                       master->mode_bits |= SPI_RX_OCTAL;
> +               if (!(ddata->quirks & CQSPI_DISABLE_DAC_MODE))
> +                       cqspi->use_dac_mode = true;
> +       }
> 
>         ret = devm_request_irq(dev, irq, cqspi_irq_handler, 0,
>                                pdev->name, cqspi);
>         if (ret) {
>                 dev_err(dev, "Cannot request IRQ.\n");
> -               goto probe_irq_failed;
> +               goto probe_reset_failed;
>         }
> 
>         cqspi_wait_idle(cqspi);
> @@ -1423,16 +1295,28 @@ static int cqspi_probe(struct platform_device *pdev)
> cqspi->current_cs = -1;
>         cqspi->sclk = 0;
> 
> -       ret = cqspi_setup_flash(cqspi, np);
> +       ret = cqspi_setup_flash(cqspi);
>         if (ret) {
> -               dev_err(dev, "Cadence QSPI NOR probe failed %d\n", ret);
> +               dev_err(dev, "failed to setup flash parameters %d\n", ret);
>                 goto probe_setup_failed;
>         }
> 
> -       return ret;
> +       if (cqspi->use_dac_mode) {
> +               ret = cqspi_request_mmap_dma(cqspi);

the driver was requesting the mmap for each available flash and now you do it 
once, which is great, but this too has to be made in a dedicated patch.

> +               if (ret == -EPROBE_DEFER)
> +                       goto probe_setup_failed;
> +       }
> +
> +       ret = devm_spi_register_master(dev, master);
> +       if (ret) {
> +               dev_err(&pdev->dev, "failed to register SPI ctlr %d\n",
> ret); +               goto probe_setup_failed;
> +       }
> +
> +       return 0;
>  probe_setup_failed:
>         cqspi_controller_enable(cqspi, 0);
> -probe_irq_failed:
> +probe_reset_failed:
>         clk_disable_unprepare(cqspi->clk);
>  probe_clk_failed:
>         pm_runtime_put_sync(dev);
> @@ -1443,11 +1327,6 @@ static int cqspi_probe(struct platform_device *pdev)
>  static int cqspi_remove(struct platform_device *pdev)
>  {
>         struct cqspi_st *cqspi = platform_get_drvdata(pdev);
> -       int i;
> -
> -       for (i = 0; i < CQSPI_MAX_CHIPSELECT; i++)
> -               if (cqspi->f_pdata[i].registered)
> -                       mtd_device_unregister(&cqspi->f_pdata[i].nor.mtd);
> 
>         cqspi_controller_enable(cqspi, 0);
> 
> @@ -1490,16 +1369,15 @@ static const struct dev_pm_ops cqspi__dev_pm_ops = {
> #endif
> 
>  static const struct cqspi_driver_platdata cdns_qspi = {
> -       .hwcaps_mask = CQSPI_BASE_HWCAPS_MASK,
> +       .quirks = CQSPI_DISABLE_DAC_MODE,

The logic around CQSPI_DISABLE_DAC_MODE needs a dedicated patch.

Cheers,
ta



______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

  reply	other threads:[~2020-03-19  8:09 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-10  1:52 [PATCH v12 0/4] spi: cadence-quadspi: Add support for the Cadence QSPI controller Ramuthevar,Vadivel MuruganX
2020-03-10  1:52 ` Ramuthevar, Vadivel MuruganX
2020-03-10  1:52 ` Ramuthevar,Vadivel MuruganX
2020-03-10  1:52 ` [PATCH v12 1/4] dt-bindings: spi: Add schema for Cadence QSPI Controller driver Ramuthevar,Vadivel MuruganX
2020-03-10  1:52   ` Ramuthevar, Vadivel MuruganX
2020-03-10  1:52   ` Ramuthevar,Vadivel MuruganX
2020-03-19 18:44   ` Rob Herring
2020-03-19 18:44     ` Rob Herring
2020-03-19 18:44     ` Rob Herring
2020-03-20  2:33     ` Ramuthevar, Vadivel MuruganX
2020-03-20  2:33       ` Ramuthevar, Vadivel MuruganX
2020-03-20  2:33       ` Ramuthevar, Vadivel MuruganX
2020-03-20  6:05   ` Vignesh Raghavendra
2020-03-20  6:05     ` Vignesh Raghavendra
2020-03-20  6:19     ` Ramuthevar, Vadivel MuruganX
2020-03-20  6:19       ` Ramuthevar, Vadivel MuruganX
2020-03-20  6:19       ` Ramuthevar, Vadivel MuruganX
2020-03-10  1:52 ` [PATCH v12 2/4] mtd: spi-nor: add spi-mem support in cadence-quadspi controller driver Ramuthevar,Vadivel MuruganX
2020-03-10  1:52   ` Ramuthevar, Vadivel MuruganX
2020-03-10  1:52   ` Ramuthevar,Vadivel MuruganX
2020-03-19  8:09   ` Tudor.Ambarus [this message]
2020-03-19  8:09     ` Tudor.Ambarus
2020-03-19  8:09     ` Tudor.Ambarus-UWL1GkI3JZL3oGB3hsPCZA
2020-03-19  9:30     ` Vignesh Raghavendra
2020-03-19  9:30       ` Vignesh Raghavendra
2020-03-10  1:52 ` [PATCH v12 3/4] spi: cadence-quadspi: Add support for the Cadence QSPI controller Ramuthevar,Vadivel MuruganX
2020-03-10  1:52   ` Ramuthevar, Vadivel MuruganX
2020-03-10  1:52   ` Ramuthevar,Vadivel MuruganX
2020-03-10  1:52 ` [PATCH v12 4/4] spi: cadence-quadspi: Add qspi support for Intel LGM SoC Ramuthevar,Vadivel MuruganX
2020-03-10  1:52   ` Ramuthevar, Vadivel MuruganX
2020-03-10  1:52   ` Ramuthevar,Vadivel MuruganX

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3360641.Vn3sISamPi@192.168.0.120 \
    --to=tudor.ambarus@microchip.com \
    --cc=boris.brezillon@free-electrons.com \
    --cc=broonie@kernel.org \
    --cc=cheol.yong.kim@intel.com \
    --cc=computersforpeace@gmail.com \
    --cc=cyrille.pitchen@atmel.com \
    --cc=david.oberhollenzer@sigma-star.at \
    --cc=devicetree@vger.kernel.org \
    --cc=dinguyen@kernel.org \
    --cc=dwmw2@infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=linux-spi@vger.kernel.org \
    --cc=marex@denx.de \
    --cc=miquel.raynal@bootlin.com \
    --cc=qi-ming.wu@intel.com \
    --cc=richard@nod.at \
    --cc=robh+dt@kernel.org \
    --cc=simon.k.r.goldschmidt@gmail.com \
    --cc=tien.fong.chee@intel.com \
    --cc=tudor.ambarus@gmail.com \
    --cc=vadivel.muruganx.ramuthevar@linux.intel.com \
    --cc=vigneshr@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.