Commit dcc594ae authored by Théo Lebrun's avatar Théo Lebrun Committed by Mark Brown

spi: cadence-qspi: store device data pointer in private struct

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: default avatarThéo Lebrun <theo.lebrun@bootlin.com>
Link: https://msgid.link/r/20240405-cdns-qspi-mbly-v2-4-956679866d6d@bootlin.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 708eafeb
...@@ -102,6 +102,8 @@ struct cqspi_st { ...@@ -102,6 +102,8 @@ struct cqspi_st {
bool apb_ahb_hazard; bool apb_ahb_hazard;
bool is_jh7110; /* Flag for StarFive JH7110 SoC */ bool is_jh7110; /* Flag for StarFive JH7110 SoC */
const struct cqspi_driver_platdata *ddata;
}; };
struct cqspi_driver_platdata { struct cqspi_driver_platdata {
...@@ -334,11 +336,8 @@ static u32 cqspi_get_versal_dma_status(struct cqspi_st *cqspi) ...@@ -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) static irqreturn_t cqspi_irq_handler(int this_irq, void *dev)
{ {
struct cqspi_st *cqspi = dev; struct cqspi_st *cqspi = dev;
const struct cqspi_driver_platdata *ddata = cqspi->ddata;
unsigned int irq_status; 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 */ /* Read interrupt status */
irq_status = readl(cqspi->iobase + CQSPI_REG_IRQSTATUS); irq_status = readl(cqspi->iobase + CQSPI_REG_IRQSTATUS);
...@@ -1358,16 +1357,13 @@ static ssize_t cqspi_read(struct cqspi_flash_pdata *f_pdata, ...@@ -1358,16 +1357,13 @@ static ssize_t cqspi_read(struct cqspi_flash_pdata *f_pdata,
const struct spi_mem_op *op) const struct spi_mem_op *op)
{ {
struct cqspi_st *cqspi = f_pdata->cqspi; struct cqspi_st *cqspi = f_pdata->cqspi;
struct device *dev = &cqspi->pdev->dev; const struct cqspi_driver_platdata *ddata = cqspi->ddata;
const struct cqspi_driver_platdata *ddata;
loff_t from = op->addr.val; loff_t from = op->addr.val;
size_t len = op->data.nbytes; size_t len = op->data.nbytes;
u_char *buf = op->data.buf.in; u_char *buf = op->data.buf.in;
u64 dma_align = (u64)(uintptr_t)buf; u64 dma_align = (u64)(uintptr_t)buf;
int ret; int ret;
ddata = of_device_get_match_data(dev);
ret = cqspi_read_setup(f_pdata, op); ret = cqspi_read_setup(f_pdata, op);
if (ret) if (ret)
return ret; return ret;
...@@ -1822,7 +1818,8 @@ static int cqspi_probe(struct platform_device *pdev) ...@@ -1822,7 +1818,8 @@ static int cqspi_probe(struct platform_device *pdev)
/* write completion is supported by default */ /* write completion is supported by default */
cqspi->wr_completion = true; 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) {
if (ddata->quirks & CQSPI_NEEDS_WR_DELAY) if (ddata->quirks & CQSPI_NEEDS_WR_DELAY)
cqspi->wr_delay = 50 * DIV_ROUND_UP(NSEC_PER_SEC, cqspi->wr_delay = 50 * DIV_ROUND_UP(NSEC_PER_SEC,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment