spi: cadence-qspi: store device data pointer in private struct
authorThéo Lebrun <theo.lebrun@bootlin.com>
Fri, 5 Apr 2024 15:02:14 +0000 (17:02 +0200)
committerMark Brown <broonie@kernel.org>
Mon, 8 Apr 2024 14:18:09 +0000 (15:18 +0100)
Avoid of_device_get_match_data() call on each IRQ and each read
operation. Store pointer in `struct cqspi_st` device instance.

End-to-end performance measurements improve with this patch. On a given
octal flash, reading 235M over UBIFS is ~3.4% faster. During that read,
the average cqspi_exec_mem_op() call goes from 85.4µs to 80.7µs
according to ftrace. The worst case goes from 622.4µs to 615.2µs.

Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
Link: https://msgid.link/r/20240405-cdns-qspi-mbly-v2-4-956679866d6d@bootlin.com
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi-cadence-quadspi.c

index 350b3dab3a05d148198568a780ed9505916687f9..abc1c35929cc65d1e6314e5475ff77f9397aa53b 100644 (file)
@@ -102,6 +102,8 @@ struct cqspi_st {
        bool                    apb_ahb_hazard;
 
        bool                    is_jh7110; /* Flag for StarFive JH7110 SoC */
+
+       const struct cqspi_driver_platdata *ddata;
 };
 
 struct cqspi_driver_platdata {
@@ -334,11 +336,8 @@ static u32 cqspi_get_versal_dma_status(struct cqspi_st *cqspi)
 static irqreturn_t cqspi_irq_handler(int this_irq, void *dev)
 {
        struct cqspi_st *cqspi = dev;
+       const struct cqspi_driver_platdata *ddata = cqspi->ddata;
        unsigned int irq_status;
-       struct device *device = &cqspi->pdev->dev;
-       const struct cqspi_driver_platdata *ddata;
-
-       ddata = of_device_get_match_data(device);
 
        /* Read interrupt status */
        irq_status = readl(cqspi->iobase + CQSPI_REG_IRQSTATUS);
@@ -1358,16 +1357,13 @@ static ssize_t cqspi_read(struct cqspi_flash_pdata *f_pdata,
                          const struct spi_mem_op *op)
 {
        struct cqspi_st *cqspi = f_pdata->cqspi;
-       struct device *dev = &cqspi->pdev->dev;
-       const struct cqspi_driver_platdata *ddata;
+       const struct cqspi_driver_platdata *ddata = cqspi->ddata;
        loff_t from = op->addr.val;
        size_t len = op->data.nbytes;
        u_char *buf = op->data.buf.in;
        u64 dma_align = (u64)(uintptr_t)buf;
        int ret;
 
-       ddata = of_device_get_match_data(dev);
-
        ret = cqspi_read_setup(f_pdata, op);
        if (ret)
                return ret;
@@ -1822,7 +1818,8 @@ static int cqspi_probe(struct platform_device *pdev)
        /* write completion is supported by default */
        cqspi->wr_completion = true;
 
-       ddata  = of_device_get_match_data(dev);
+       ddata = of_device_get_match_data(dev);
+       cqspi->ddata = ddata;
        if (ddata) {
                if (ddata->quirks & CQSPI_NEEDS_WR_DELAY)
                        cqspi->wr_delay = 50 * DIV_ROUND_UP(NSEC_PER_SEC,