From 25c56c88a4627e7fdbfa12a4c20c75e2ccb366d1 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 18 Jul 2017 16:43:31 -0500 Subject: spi: Convert to using %pOF instead of full_name Now that we have a custom printf format specifier, convert users of full_name to use %pOF instead. This is preparation to remove storing of the full path string for each node. Signed-off-by: Rob Herring Reviewed-by: Geert Uytterhoeven Signed-off-by: Mark Brown --- drivers/spi/spi-orion.c | 4 ++-- drivers/spi/spi.c | 27 +++++++++++---------------- 2 files changed, 13 insertions(+), 18 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index 28fc9f161b9d..4b6dd73b80da 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c @@ -669,8 +669,8 @@ static int orion_spi_probe(struct platform_device *pdev) status = of_property_read_u32(np, "reg", &cs); if (status) { dev_err(&pdev->dev, - "%s has no valid 'reg' property (%d)\n", - np->full_name, status); + "%pOF has no valid 'reg' property (%d)\n", + np, status); status = 0; continue; } diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 4fcbb0aa71d3..0725c78b0de6 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1583,8 +1583,8 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi, if (spi_controller_is_slave(ctlr)) { if (strcmp(nc->name, "slave")) { - dev_err(&ctlr->dev, "%s is not called 'slave'\n", - nc->full_name); + dev_err(&ctlr->dev, "%pOF is not called 'slave'\n", + nc); return -EINVAL; } return 0; @@ -1593,8 +1593,8 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi, /* Device address */ rc = of_property_read_u32(nc, "reg", &value); if (rc) { - dev_err(&ctlr->dev, "%s has no valid 'reg' property (%d)\n", - nc->full_name, rc); + dev_err(&ctlr->dev, "%pOF has no valid 'reg' property (%d)\n", + nc, rc); return rc; } spi->chip_select = value; @@ -1603,8 +1603,7 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi, rc = of_property_read_u32(nc, "spi-max-frequency", &value); if (rc) { dev_err(&ctlr->dev, - "%s has no valid 'spi-max-frequency' property (%d)\n", - nc->full_name, rc); + "%pOF has no valid 'spi-max-frequency' property (%d)\n", nc, rc); return rc; } spi->max_speed_hz = value; @@ -1621,8 +1620,7 @@ of_register_spi_device(struct spi_controller *ctlr, struct device_node *nc) /* Alloc an spi_device */ spi = spi_alloc_device(ctlr); if (!spi) { - dev_err(&ctlr->dev, "spi_device alloc error for %s\n", - nc->full_name); + dev_err(&ctlr->dev, "spi_device alloc error for %pOF\n", nc); rc = -ENOMEM; goto err_out; } @@ -1631,8 +1629,7 @@ of_register_spi_device(struct spi_controller *ctlr, struct device_node *nc) rc = of_modalias_node(nc, spi->modalias, sizeof(spi->modalias)); if (rc < 0) { - dev_err(&ctlr->dev, "cannot find modalias for %s\n", - nc->full_name); + dev_err(&ctlr->dev, "cannot find modalias for %pOF\n", nc); goto err_out; } @@ -1647,8 +1644,7 @@ of_register_spi_device(struct spi_controller *ctlr, struct device_node *nc) /* Register the new device */ rc = spi_add_device(spi); if (rc) { - dev_err(&ctlr->dev, "spi_device register error %s\n", - nc->full_name); + dev_err(&ctlr->dev, "spi_device register error %pOF\n", nc); goto err_of_node_put; } @@ -1682,8 +1678,7 @@ static void of_register_spi_devices(struct spi_controller *ctlr) spi = of_register_spi_device(ctlr, nc); if (IS_ERR(spi)) { dev_warn(&ctlr->dev, - "Failed to create SPI device for %s\n", - nc->full_name); + "Failed to create SPI device for %pOF\n", nc); of_node_clear_flag(nc, OF_POPULATED); } } @@ -3311,8 +3306,8 @@ static int of_spi_notify(struct notifier_block *nb, unsigned long action, put_device(&ctlr->dev); if (IS_ERR(spi)) { - pr_err("%s: failed to create for '%s'\n", - __func__, rd->dn->full_name); + pr_err("%s: failed to create for '%pOF'\n", + __func__, rd->dn); of_node_clear_flag(rd->dn, OF_POPULATED); return notifier_from_errno(PTR_ERR(spi)); } -- cgit From 48767fd8982d39d90a9e83b1461dc5feedf73e29 Mon Sep 17 00:00:00 2001 From: Naga Sureshkumar Relli Date: Tue, 8 Aug 2017 10:59:33 +0200 Subject: spi: cadence: change sequence of calling runtime_enable call pm_runtime_enable after set_active other wise it will enable clock always. Signed-off-by: Naga Sureshkumar Relli Signed-off-by: Michal Simek Signed-off-by: Mark Brown --- drivers/spi/spi-cadence.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c index f0b5c7b91f37..5e02f9b91688 100644 --- a/drivers/spi/spi-cadence.c +++ b/drivers/spi/spi-cadence.c @@ -576,10 +576,10 @@ static int cdns_spi_probe(struct platform_device *pdev) goto clk_dis_apb; } - pm_runtime_enable(&pdev->dev); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT); pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); ret = of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs); if (ret < 0) -- cgit From 802740890c4200c9266aee3139c5bd8e9b154e8f Mon Sep 17 00:00:00 2001 From: Shubhrajyoti Datta Date: Tue, 8 Aug 2017 11:00:03 +0200 Subject: spi: cadence: Add support for context loss Context could be lost across the suspend and resume. Reinit the driver to tide over. Signed-off-by: Shubhrajyoti Datta Signed-off-by: Michal Simek Signed-off-by: Mark Brown --- drivers/spi/spi-cadence.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c index 5e02f9b91688..5c9516ae4942 100644 --- a/drivers/spi/spi-cadence.c +++ b/drivers/spi/spi-cadence.c @@ -704,7 +704,9 @@ static int __maybe_unused cdns_spi_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct spi_master *master = platform_get_drvdata(pdev); + struct cdns_spi *xspi = spi_master_get_devdata(master); + cdns_spi_init_hw(xspi); return spi_master_resume(master); } -- cgit From 1232978a0dff2d361c3d43cd74e46200c9933466 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 9 Aug 2017 08:51:25 +1200 Subject: spi: spi-ep93xx: remove io wrappers The io wrappers just add obfuscation to the driver. Remove them. Signed-off-by: H Hartley Sweeten Signed-off-by: Chris Packham Signed-off-by: Mark Brown --- drivers/spi/spi-ep93xx.c | 72 +++++++++++++++++------------------------------- 1 file changed, 25 insertions(+), 47 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index b5d766064b7b..49c42a6c2be1 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c @@ -72,7 +72,7 @@ * struct ep93xx_spi - EP93xx SPI controller structure * @pdev: pointer to platform device * @clk: clock for the controller - * @regs_base: pointer to ioremap()'d registers + * @mmio: pointer to ioremap()'d registers * @sspdr_phys: physical address of the SSPDR register * @wait: wait here until given transfer is completed * @current_msg: message that is currently processed (or %NULL if none) @@ -92,7 +92,7 @@ struct ep93xx_spi { const struct platform_device *pdev; struct clk *clk; - void __iomem *regs_base; + void __iomem *mmio; unsigned long sspdr_phys; struct completion wait; struct spi_message *current_msg; @@ -111,28 +111,6 @@ struct ep93xx_spi { /* converts bits per word to CR0.DSS value */ #define bits_per_word_to_dss(bpw) ((bpw) - 1) -static void ep93xx_spi_write_u8(const struct ep93xx_spi *espi, - u16 reg, u8 value) -{ - writeb(value, espi->regs_base + reg); -} - -static u8 ep93xx_spi_read_u8(const struct ep93xx_spi *spi, u16 reg) -{ - return readb(spi->regs_base + reg); -} - -static void ep93xx_spi_write_u16(const struct ep93xx_spi *espi, - u16 reg, u16 value) -{ - writew(value, espi->regs_base + reg); -} - -static u16 ep93xx_spi_read_u16(const struct ep93xx_spi *spi, u16 reg) -{ - return readw(spi->regs_base + reg); -} - static int ep93xx_spi_enable(const struct ep93xx_spi *espi) { u8 regval; @@ -142,9 +120,9 @@ static int ep93xx_spi_enable(const struct ep93xx_spi *espi) if (err) return err; - regval = ep93xx_spi_read_u8(espi, SSPCR1); + regval = readb(espi->mmio + SSPCR1); regval |= SSPCR1_SSE; - ep93xx_spi_write_u8(espi, SSPCR1, regval); + writeb(regval, espi->mmio + SSPCR1); return 0; } @@ -153,9 +131,9 @@ static void ep93xx_spi_disable(const struct ep93xx_spi *espi) { u8 regval; - regval = ep93xx_spi_read_u8(espi, SSPCR1); + regval = readb(espi->mmio + SSPCR1); regval &= ~SSPCR1_SSE; - ep93xx_spi_write_u8(espi, SSPCR1, regval); + writeb(regval, espi->mmio + SSPCR1); clk_disable(espi->clk); } @@ -164,18 +142,18 @@ static void ep93xx_spi_enable_interrupts(const struct ep93xx_spi *espi) { u8 regval; - regval = ep93xx_spi_read_u8(espi, SSPCR1); + regval = readb(espi->mmio + SSPCR1); regval |= (SSPCR1_RORIE | SSPCR1_TIE | SSPCR1_RIE); - ep93xx_spi_write_u8(espi, SSPCR1, regval); + writeb(regval, espi->mmio + SSPCR1); } static void ep93xx_spi_disable_interrupts(const struct ep93xx_spi *espi) { u8 regval; - regval = ep93xx_spi_read_u8(espi, SSPCR1); + regval = readb(espi->mmio + SSPCR1); regval &= ~(SSPCR1_RORIE | SSPCR1_TIE | SSPCR1_RIE); - ep93xx_spi_write_u8(espi, SSPCR1, regval); + writeb(regval, espi->mmio + SSPCR1); } /** @@ -252,8 +230,8 @@ static int ep93xx_spi_chip_setup(const struct ep93xx_spi *espi, spi->mode, div_cpsr, div_scr, dss); dev_dbg(&espi->pdev->dev, "setup: cr0 %#x\n", cr0); - ep93xx_spi_write_u8(espi, SSPCPSR, div_cpsr); - ep93xx_spi_write_u16(espi, SSPCR0, cr0); + writeb(div_cpsr, espi->mmio + SSPCPSR); + writew(cr0, espi->mmio + SSPCR0); return 0; } @@ -265,14 +243,14 @@ static void ep93xx_do_write(struct ep93xx_spi *espi, struct spi_transfer *t) if (t->tx_buf) tx_val = ((u16 *)t->tx_buf)[espi->tx]; - ep93xx_spi_write_u16(espi, SSPDR, tx_val); + writew(tx_val, espi->mmio + SSPDR); espi->tx += sizeof(tx_val); } else { u8 tx_val = 0; if (t->tx_buf) tx_val = ((u8 *)t->tx_buf)[espi->tx]; - ep93xx_spi_write_u8(espi, SSPDR, tx_val); + writeb(tx_val, espi->mmio + SSPDR); espi->tx += sizeof(tx_val); } } @@ -282,14 +260,14 @@ static void ep93xx_do_read(struct ep93xx_spi *espi, struct spi_transfer *t) if (t->bits_per_word > 8) { u16 rx_val; - rx_val = ep93xx_spi_read_u16(espi, SSPDR); + rx_val = readw(espi->mmio + SSPDR); if (t->rx_buf) ((u16 *)t->rx_buf)[espi->rx] = rx_val; espi->rx += sizeof(rx_val); } else { u8 rx_val; - rx_val = ep93xx_spi_read_u8(espi, SSPDR); + rx_val = readb(espi->mmio + SSPDR); if (t->rx_buf) ((u8 *)t->rx_buf)[espi->rx] = rx_val; espi->rx += sizeof(rx_val); @@ -313,7 +291,7 @@ static int ep93xx_spi_read_write(struct ep93xx_spi *espi) struct spi_transfer *t = msg->state; /* read as long as RX FIFO has frames in it */ - while ((ep93xx_spi_read_u8(espi, SSPSR) & SSPSR_RNE)) { + while ((readb(espi->mmio + SSPSR) & SSPSR_RNE)) { ep93xx_do_read(espi, t); espi->fifo_level--; } @@ -615,14 +593,14 @@ static void ep93xx_spi_process_message(struct ep93xx_spi *espi, * Just to be sure: flush any data from RX FIFO. */ timeout = jiffies + msecs_to_jiffies(SPI_TIMEOUT); - while (ep93xx_spi_read_u16(espi, SSPSR) & SSPSR_RNE) { + while (readw(espi->mmio + SSPSR) & SSPSR_RNE) { if (time_after(jiffies, timeout)) { dev_warn(&espi->pdev->dev, "timeout while flushing RX FIFO\n"); msg->status = -ETIMEDOUT; return; } - ep93xx_spi_read_u16(espi, SSPDR); + readw(espi->mmio + SSPDR); } /* @@ -671,7 +649,7 @@ static int ep93xx_spi_transfer_one_message(struct spi_master *master, static irqreturn_t ep93xx_spi_interrupt(int irq, void *dev_id) { struct ep93xx_spi *espi = dev_id; - u8 irq_status = ep93xx_spi_read_u8(espi, SSPIIR); + u8 irq_status = readb(espi->mmio + SSPIIR); /* * If we got ROR (receive overrun) interrupt we know that something is @@ -679,7 +657,7 @@ static irqreturn_t ep93xx_spi_interrupt(int irq, void *dev_id) */ if (unlikely(irq_status & SSPIIR_RORIS)) { /* clear the overrun interrupt */ - ep93xx_spi_write_u8(espi, SSPICR, 0); + writeb(0, espi->mmio + SSPICR); dev_warn(&espi->pdev->dev, "receive overrun, aborting the message\n"); espi->current_msg->status = -EIO; @@ -862,9 +840,9 @@ static int ep93xx_spi_probe(struct platform_device *pdev) espi->sspdr_phys = res->start + SSPDR; - espi->regs_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(espi->regs_base)) { - error = PTR_ERR(espi->regs_base); + espi->mmio = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(espi->mmio)) { + error = PTR_ERR(espi->mmio); goto fail_release_master; } @@ -879,7 +857,7 @@ static int ep93xx_spi_probe(struct platform_device *pdev) dev_warn(&pdev->dev, "DMA setup failed. Falling back to PIO\n"); /* make sure that the hardware is disabled */ - ep93xx_spi_write_u8(espi, SSPCR1, 0); + writeb(0, espi->mmio + SSPCR1); error = devm_spi_register_master(&pdev->dev, master); if (error) { -- cgit From 8447e4781f033f56cb18c2ec0301ea5d207877fc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 9 Aug 2017 08:51:26 +1200 Subject: spi: spi-ep93xx: use 32-bit read/write for all registers All the EP93xx SSP registers are 32-bit. Since most of the upper bits are unused, this driver tries to be tricky and uses 8 or 16-bit I/O to access the registers. This really just adds a bit of confusion. Simplify the I/O by using 32-bit read/write's for all of the registers. Signed-off-by: H Hartley Sweeten [chris: use u32 instead of unsigned int] Signed-off-by: Chris Packham Reviewed-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/spi-ep93xx.c | 83 ++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 45 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index 49c42a6c2be1..0bd792020471 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c @@ -113,47 +113,47 @@ struct ep93xx_spi { static int ep93xx_spi_enable(const struct ep93xx_spi *espi) { - u8 regval; + u32 val; int err; err = clk_enable(espi->clk); if (err) return err; - regval = readb(espi->mmio + SSPCR1); - regval |= SSPCR1_SSE; - writeb(regval, espi->mmio + SSPCR1); + val = readl(espi->mmio + SSPCR1); + val |= SSPCR1_SSE; + writel(val, espi->mmio + SSPCR1); return 0; } static void ep93xx_spi_disable(const struct ep93xx_spi *espi) { - u8 regval; + u32 val; - regval = readb(espi->mmio + SSPCR1); - regval &= ~SSPCR1_SSE; - writeb(regval, espi->mmio + SSPCR1); + val = readl(espi->mmio + SSPCR1); + val &= ~SSPCR1_SSE; + writel(val, espi->mmio + SSPCR1); clk_disable(espi->clk); } static void ep93xx_spi_enable_interrupts(const struct ep93xx_spi *espi) { - u8 regval; + u32 val; - regval = readb(espi->mmio + SSPCR1); - regval |= (SSPCR1_RORIE | SSPCR1_TIE | SSPCR1_RIE); - writeb(regval, espi->mmio + SSPCR1); + val = readl(espi->mmio + SSPCR1); + val |= (SSPCR1_RORIE | SSPCR1_TIE | SSPCR1_RIE); + writel(val, espi->mmio + SSPCR1); } static void ep93xx_spi_disable_interrupts(const struct ep93xx_spi *espi) { - u8 regval; + u32 val; - regval = readb(espi->mmio + SSPCR1); - regval &= ~(SSPCR1_RORIE | SSPCR1_TIE | SSPCR1_RIE); - writeb(regval, espi->mmio + SSPCR1); + val = readl(espi->mmio + SSPCR1); + val &= ~(SSPCR1_RORIE | SSPCR1_TIE | SSPCR1_RIE); + writel(val, espi->mmio + SSPCR1); } /** @@ -230,47 +230,41 @@ static int ep93xx_spi_chip_setup(const struct ep93xx_spi *espi, spi->mode, div_cpsr, div_scr, dss); dev_dbg(&espi->pdev->dev, "setup: cr0 %#x\n", cr0); - writeb(div_cpsr, espi->mmio + SSPCPSR); - writew(cr0, espi->mmio + SSPCR0); + writel(div_cpsr, espi->mmio + SSPCPSR); + writel(cr0, espi->mmio + SSPCR0); return 0; } static void ep93xx_do_write(struct ep93xx_spi *espi, struct spi_transfer *t) { - if (t->bits_per_word > 8) { - u16 tx_val = 0; + u32 val = 0; + if (t->bits_per_word > 8) { if (t->tx_buf) - tx_val = ((u16 *)t->tx_buf)[espi->tx]; - writew(tx_val, espi->mmio + SSPDR); - espi->tx += sizeof(tx_val); + val = ((u16 *)t->tx_buf)[espi->tx]; + espi->tx += 2; } else { - u8 tx_val = 0; - if (t->tx_buf) - tx_val = ((u8 *)t->tx_buf)[espi->tx]; - writeb(tx_val, espi->mmio + SSPDR); - espi->tx += sizeof(tx_val); + val = ((u8 *)t->tx_buf)[espi->tx]; + espi->tx += 1; } + writel(val, espi->mmio + SSPDR); } static void ep93xx_do_read(struct ep93xx_spi *espi, struct spi_transfer *t) { - if (t->bits_per_word > 8) { - u16 rx_val; + u32 val; - rx_val = readw(espi->mmio + SSPDR); + val = readl(espi->mmio + SSPDR); + if (t->bits_per_word > 8) { if (t->rx_buf) - ((u16 *)t->rx_buf)[espi->rx] = rx_val; - espi->rx += sizeof(rx_val); + ((u16 *)t->rx_buf)[espi->rx] = val; + espi->rx += 2; } else { - u8 rx_val; - - rx_val = readb(espi->mmio + SSPDR); if (t->rx_buf) - ((u8 *)t->rx_buf)[espi->rx] = rx_val; - espi->rx += sizeof(rx_val); + ((u8 *)t->rx_buf)[espi->rx] = val; + espi->rx += 1; } } @@ -291,7 +285,7 @@ static int ep93xx_spi_read_write(struct ep93xx_spi *espi) struct spi_transfer *t = msg->state; /* read as long as RX FIFO has frames in it */ - while ((readb(espi->mmio + SSPSR) & SSPSR_RNE)) { + while ((readl(espi->mmio + SSPSR) & SSPSR_RNE)) { ep93xx_do_read(espi, t); espi->fifo_level--; } @@ -593,14 +587,14 @@ static void ep93xx_spi_process_message(struct ep93xx_spi *espi, * Just to be sure: flush any data from RX FIFO. */ timeout = jiffies + msecs_to_jiffies(SPI_TIMEOUT); - while (readw(espi->mmio + SSPSR) & SSPSR_RNE) { + while (readl(espi->mmio + SSPSR) & SSPSR_RNE) { if (time_after(jiffies, timeout)) { dev_warn(&espi->pdev->dev, "timeout while flushing RX FIFO\n"); msg->status = -ETIMEDOUT; return; } - readw(espi->mmio + SSPDR); + readl(espi->mmio + SSPDR); } /* @@ -649,15 +643,14 @@ static int ep93xx_spi_transfer_one_message(struct spi_master *master, static irqreturn_t ep93xx_spi_interrupt(int irq, void *dev_id) { struct ep93xx_spi *espi = dev_id; - u8 irq_status = readb(espi->mmio + SSPIIR); /* * If we got ROR (receive overrun) interrupt we know that something is * wrong. Just abort the message. */ - if (unlikely(irq_status & SSPIIR_RORIS)) { + if (readl(espi->mmio + SSPIIR) & SSPIIR_RORIS) { /* clear the overrun interrupt */ - writeb(0, espi->mmio + SSPICR); + writel(0, espi->mmio + SSPICR); dev_warn(&espi->pdev->dev, "receive overrun, aborting the message\n"); espi->current_msg->status = -EIO; @@ -857,7 +850,7 @@ static int ep93xx_spi_probe(struct platform_device *pdev) dev_warn(&pdev->dev, "DMA setup failed. Falling back to PIO\n"); /* make sure that the hardware is disabled */ - writeb(0, espi->mmio + SSPCR1); + writel(0, espi->mmio + SSPCR1); error = devm_spi_register_master(&pdev->dev, master); if (error) { -- cgit From 16779622be1c8959d6a665e2b6886bb33885fcb1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 9 Aug 2017 08:51:27 +1200 Subject: spi: spi-ep93xx: add spi master prepare_transfer_hardware() This driver currently enables the hardware at the start of every message and disabled it when the message is complete. Make it a bit smarter by adding the prepare_transfer_hardware() and unprepare_transfer_hardware() callbacks so that the core can enable/disable the hardware based on spi message queue. Signed-off-by: H Hartley Sweeten [chris: use u32 instead of unsigned int] Signed-off-by: Chris Packham Reviewed-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/spi-ep93xx.c | 72 ++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 39 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index 0bd792020471..ce6ec164f2f2 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c @@ -111,33 +111,6 @@ struct ep93xx_spi { /* converts bits per word to CR0.DSS value */ #define bits_per_word_to_dss(bpw) ((bpw) - 1) -static int ep93xx_spi_enable(const struct ep93xx_spi *espi) -{ - u32 val; - int err; - - err = clk_enable(espi->clk); - if (err) - return err; - - val = readl(espi->mmio + SSPCR1); - val |= SSPCR1_SSE; - writel(val, espi->mmio + SSPCR1); - - return 0; -} - -static void ep93xx_spi_disable(const struct ep93xx_spi *espi) -{ - u32 val; - - val = readl(espi->mmio + SSPCR1); - val &= ~SSPCR1_SSE; - writel(val, espi->mmio + SSPCR1); - - clk_disable(espi->clk); -} - static void ep93xx_spi_enable_interrupts(const struct ep93xx_spi *espi) { u32 val; @@ -571,17 +544,6 @@ static void ep93xx_spi_process_message(struct ep93xx_spi *espi, { unsigned long timeout; struct spi_transfer *t; - int err; - - /* - * Enable the SPI controller and its clock. - */ - err = ep93xx_spi_enable(espi); - if (err) { - dev_err(&espi->pdev->dev, "failed to enable SPI controller\n"); - msg->status = err; - return; - } /* * Just to be sure: flush any data from RX FIFO. @@ -619,7 +581,6 @@ static void ep93xx_spi_process_message(struct ep93xx_spi *espi, * deselect the device and disable the SPI controller. */ ep93xx_spi_cs_control(msg->spi, false); - ep93xx_spi_disable(espi); } static int ep93xx_spi_transfer_one_message(struct spi_master *master, @@ -679,6 +640,37 @@ static irqreturn_t ep93xx_spi_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } +static int ep93xx_spi_prepare_hardware(struct spi_master *master) +{ + struct ep93xx_spi *espi = spi_master_get_devdata(master); + u32 val; + int ret; + + ret = clk_enable(espi->clk); + if (ret) + return ret; + + val = readl(espi->mmio + SSPCR1); + val |= SSPCR1_SSE; + writel(val, espi->mmio + SSPCR1); + + return 0; +} + +static int ep93xx_spi_unprepare_hardware(struct spi_master *master) +{ + struct ep93xx_spi *espi = spi_master_get_devdata(master); + u32 val; + + val = readl(espi->mmio + SSPCR1); + val &= ~SSPCR1_SSE; + writel(val, espi->mmio + SSPCR1); + + clk_disable(espi->clk); + + return 0; +} + static bool ep93xx_spi_dma_filter(struct dma_chan *chan, void *filter_param) { if (ep93xx_dma_chan_is_m2p(chan)) @@ -780,6 +772,8 @@ static int ep93xx_spi_probe(struct platform_device *pdev) if (!master) return -ENOMEM; + master->prepare_transfer_hardware = ep93xx_spi_prepare_hardware; + master->unprepare_transfer_hardware = ep93xx_spi_unprepare_hardware; master->transfer_one_message = ep93xx_spi_transfer_one_message; master->bus_num = pdev->id; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; -- cgit From ac8d06df9a1f40a9feb759dd7ef5664328ae7694 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 9 Aug 2017 08:51:28 +1200 Subject: spi: spi-ep93xx: absorb the interrupt enable/disable helpers These are each only called once. Just absorb them into the callers. Signed-off-by: H Hartley Sweeten [chris: use u32 instead of unsigned int] Signed-off-by: Chris Packham Reviewed-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/spi-ep93xx.c | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index ce6ec164f2f2..041842e0d028 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c @@ -111,24 +111,6 @@ struct ep93xx_spi { /* converts bits per word to CR0.DSS value */ #define bits_per_word_to_dss(bpw) ((bpw) - 1) -static void ep93xx_spi_enable_interrupts(const struct ep93xx_spi *espi) -{ - u32 val; - - val = readl(espi->mmio + SSPCR1); - val |= (SSPCR1_RORIE | SSPCR1_TIE | SSPCR1_RIE); - writel(val, espi->mmio + SSPCR1); -} - -static void ep93xx_spi_disable_interrupts(const struct ep93xx_spi *espi) -{ - u32 val; - - val = readl(espi->mmio + SSPCR1); - val &= ~(SSPCR1_RORIE | SSPCR1_TIE | SSPCR1_RIE); - writel(val, espi->mmio + SSPCR1); -} - /** * ep93xx_spi_calc_divisors() - calculates SPI clock divisors * @espi: ep93xx SPI controller struct @@ -282,7 +264,12 @@ static void ep93xx_spi_pio_transfer(struct ep93xx_spi *espi) * FIFO, enable interrupts, and wait for the transfer to complete. */ if (ep93xx_spi_read_write(espi)) { - ep93xx_spi_enable_interrupts(espi); + u32 val; + + val = readl(espi->mmio + SSPCR1); + val |= (SSPCR1_RORIE | SSPCR1_TIE | SSPCR1_RIE); + writel(val, espi->mmio + SSPCR1); + wait_for_completion(&espi->wait); } } @@ -604,6 +591,7 @@ static int ep93xx_spi_transfer_one_message(struct spi_master *master, static irqreturn_t ep93xx_spi_interrupt(int irq, void *dev_id) { struct ep93xx_spi *espi = dev_id; + u32 val; /* * If we got ROR (receive overrun) interrupt we know that something is @@ -635,8 +623,12 @@ static irqreturn_t ep93xx_spi_interrupt(int irq, void *dev_id) * any case we disable interrupts and notify the worker to handle * any post-processing of the message. */ - ep93xx_spi_disable_interrupts(espi); + val = readl(espi->mmio + SSPCR1); + val &= ~(SSPCR1_RORIE | SSPCR1_TIE | SSPCR1_RIE); + writel(val, espi->mmio + SSPCR1); + complete(&espi->wait); + return IRQ_HANDLED; } -- cgit From 48738831018003c80f1131e77a25b8e832bec6f1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 9 Aug 2017 08:51:29 +1200 Subject: spi: spi-ep93xx: pass the spi_master pointer around Change the parameters for some of the functions so that the spi_master pointer is passed around instead of the private data ep93xx_spi pointer. This allows removing the 'pdev' member of the private data and will help with some later cleanup. Signed-off-by: H Hartley Sweeten Reviewed-by: Andy Shevchenko Signed-off-by: Chris Packham Signed-off-by: Mark Brown --- drivers/spi/spi-ep93xx.c | 90 ++++++++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 41 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index 041842e0d028..2d80e36f5015 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c @@ -70,7 +70,6 @@ /** * struct ep93xx_spi - EP93xx SPI controller structure - * @pdev: pointer to platform device * @clk: clock for the controller * @mmio: pointer to ioremap()'d registers * @sspdr_phys: physical address of the SSPDR register @@ -90,7 +89,6 @@ * the client */ struct ep93xx_spi { - const struct platform_device *pdev; struct clk *clk; void __iomem *mmio; unsigned long sspdr_phys; @@ -113,15 +111,15 @@ struct ep93xx_spi { /** * ep93xx_spi_calc_divisors() - calculates SPI clock divisors - * @espi: ep93xx SPI controller struct + * @master: SPI master * @rate: desired SPI output clock rate * @div_cpsr: pointer to return the cpsr (pre-scaler) divider * @div_scr: pointer to return the scr divider */ -static int ep93xx_spi_calc_divisors(const struct ep93xx_spi *espi, +static int ep93xx_spi_calc_divisors(struct spi_master *master, u32 rate, u8 *div_cpsr, u8 *div_scr) { - struct spi_master *master = platform_get_drvdata(espi->pdev); + struct ep93xx_spi *espi = spi_master_get_devdata(master); unsigned long spi_clk_rate = clk_get_rate(espi->clk); int cpsr, scr; @@ -162,17 +160,18 @@ static void ep93xx_spi_cs_control(struct spi_device *spi, bool enable) gpio_set_value(spi->cs_gpio, !enable); } -static int ep93xx_spi_chip_setup(const struct ep93xx_spi *espi, +static int ep93xx_spi_chip_setup(struct spi_master *master, struct spi_device *spi, struct spi_transfer *xfer) { + struct ep93xx_spi *espi = spi_master_get_devdata(master); u8 dss = bits_per_word_to_dss(xfer->bits_per_word); u8 div_cpsr = 0; u8 div_scr = 0; u16 cr0; int err; - err = ep93xx_spi_calc_divisors(espi, xfer->speed_hz, + err = ep93xx_spi_calc_divisors(master, xfer->speed_hz, &div_cpsr, &div_scr); if (err) return err; @@ -181,9 +180,9 @@ static int ep93xx_spi_chip_setup(const struct ep93xx_spi *espi, cr0 |= (spi->mode & (SPI_CPHA | SPI_CPOL)) << SSPCR0_MODE_SHIFT; cr0 |= dss; - dev_dbg(&espi->pdev->dev, "setup: mode %d, cpsr %d, scr %d, dss %d\n", + dev_dbg(&master->dev, "setup: mode %d, cpsr %d, scr %d, dss %d\n", spi->mode, div_cpsr, div_scr, dss); - dev_dbg(&espi->pdev->dev, "setup: cr0 %#x\n", cr0); + dev_dbg(&master->dev, "setup: cr0 %#x\n", cr0); writel(div_cpsr, espi->mmio + SSPCPSR); writel(cr0, espi->mmio + SSPCR0); @@ -234,8 +233,9 @@ static void ep93xx_do_read(struct ep93xx_spi *espi, struct spi_transfer *t) * When this function is finished, RX FIFO should be empty and TX FIFO should be * full. */ -static int ep93xx_spi_read_write(struct ep93xx_spi *espi) +static int ep93xx_spi_read_write(struct spi_master *master) { + struct ep93xx_spi *espi = spi_master_get_devdata(master); struct spi_message *msg = espi->current_msg; struct spi_transfer *t = msg->state; @@ -257,13 +257,15 @@ static int ep93xx_spi_read_write(struct ep93xx_spi *espi) return -EINPROGRESS; } -static void ep93xx_spi_pio_transfer(struct ep93xx_spi *espi) +static void ep93xx_spi_pio_transfer(struct spi_master *master) { + struct ep93xx_spi *espi = spi_master_get_devdata(master); + /* * Now everything is set up for the current transfer. We prime the TX * FIFO, enable interrupts, and wait for the transfer to complete. */ - if (ep93xx_spi_read_write(espi)) { + if (ep93xx_spi_read_write(master)) { u32 val; val = readl(espi->mmio + SSPCR1); @@ -276,7 +278,7 @@ static void ep93xx_spi_pio_transfer(struct ep93xx_spi *espi) /** * ep93xx_spi_dma_prepare() - prepares a DMA transfer - * @espi: ep93xx SPI controller struct + * @master: SPI master * @dir: DMA transfer direction * * Function configures the DMA, maps the buffer and prepares the DMA @@ -284,8 +286,10 @@ static void ep93xx_spi_pio_transfer(struct ep93xx_spi *espi) * in case of failure. */ static struct dma_async_tx_descriptor * -ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_transfer_direction dir) +ep93xx_spi_dma_prepare(struct spi_master *master, + enum dma_transfer_direction dir) { + struct ep93xx_spi *espi = spi_master_get_devdata(master); struct spi_transfer *t = espi->current_msg->state; struct dma_async_tx_descriptor *txd; enum dma_slave_buswidth buswidth; @@ -361,7 +365,7 @@ ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_transfer_direction dir) } if (WARN_ON(len)) { - dev_warn(&espi->pdev->dev, "len = %zu expected 0!\n", len); + dev_warn(&master->dev, "len = %zu expected 0!\n", len); return ERR_PTR(-EINVAL); } @@ -379,15 +383,16 @@ ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_transfer_direction dir) /** * ep93xx_spi_dma_finish() - finishes with a DMA transfer - * @espi: ep93xx SPI controller struct + * @master: SPI master * @dir: DMA transfer direction * * Function finishes with the DMA transfer. After this, the DMA buffer is * unmapped. */ -static void ep93xx_spi_dma_finish(struct ep93xx_spi *espi, +static void ep93xx_spi_dma_finish(struct spi_master *master, enum dma_transfer_direction dir) { + struct ep93xx_spi *espi = spi_master_get_devdata(master); struct dma_chan *chan; struct sg_table *sgt; @@ -407,22 +412,23 @@ static void ep93xx_spi_dma_callback(void *callback_param) complete(callback_param); } -static void ep93xx_spi_dma_transfer(struct ep93xx_spi *espi) +static void ep93xx_spi_dma_transfer(struct spi_master *master) { + struct ep93xx_spi *espi = spi_master_get_devdata(master); struct spi_message *msg = espi->current_msg; struct dma_async_tx_descriptor *rxd, *txd; - rxd = ep93xx_spi_dma_prepare(espi, DMA_DEV_TO_MEM); + rxd = ep93xx_spi_dma_prepare(master, DMA_DEV_TO_MEM); if (IS_ERR(rxd)) { - dev_err(&espi->pdev->dev, "DMA RX failed: %ld\n", PTR_ERR(rxd)); + dev_err(&master->dev, "DMA RX failed: %ld\n", PTR_ERR(rxd)); msg->status = PTR_ERR(rxd); return; } - txd = ep93xx_spi_dma_prepare(espi, DMA_MEM_TO_DEV); + txd = ep93xx_spi_dma_prepare(master, DMA_MEM_TO_DEV); if (IS_ERR(txd)) { - ep93xx_spi_dma_finish(espi, DMA_DEV_TO_MEM); - dev_err(&espi->pdev->dev, "DMA TX failed: %ld\n", PTR_ERR(txd)); + ep93xx_spi_dma_finish(master, DMA_DEV_TO_MEM); + dev_err(&master->dev, "DMA TX failed: %ld\n", PTR_ERR(txd)); msg->status = PTR_ERR(txd); return; } @@ -440,13 +446,13 @@ static void ep93xx_spi_dma_transfer(struct ep93xx_spi *espi) wait_for_completion(&espi->wait); - ep93xx_spi_dma_finish(espi, DMA_MEM_TO_DEV); - ep93xx_spi_dma_finish(espi, DMA_DEV_TO_MEM); + ep93xx_spi_dma_finish(master, DMA_MEM_TO_DEV); + ep93xx_spi_dma_finish(master, DMA_DEV_TO_MEM); } /** * ep93xx_spi_process_transfer() - processes one SPI transfer - * @espi: ep93xx SPI controller struct + * @master: SPI master * @msg: current message * @t: transfer to process * @@ -454,17 +460,18 @@ static void ep93xx_spi_dma_transfer(struct ep93xx_spi *espi) * transfer is complete (may sleep) and updates @msg->status based on whether * transfer was successfully processed or not. */ -static void ep93xx_spi_process_transfer(struct ep93xx_spi *espi, +static void ep93xx_spi_process_transfer(struct spi_master *master, struct spi_message *msg, struct spi_transfer *t) { + struct ep93xx_spi *espi = spi_master_get_devdata(master); int err; msg->state = t; - err = ep93xx_spi_chip_setup(espi, msg->spi, t); + err = ep93xx_spi_chip_setup(master, msg->spi, t); if (err) { - dev_err(&espi->pdev->dev, + dev_err(&master->dev, "failed to setup chip for transfer\n"); msg->status = err; return; @@ -479,9 +486,9 @@ static void ep93xx_spi_process_transfer(struct ep93xx_spi *espi, * So in these cases we will be using PIO and don't bother for DMA. */ if (espi->dma_rx && t->len > SPI_FIFO_SIZE) - ep93xx_spi_dma_transfer(espi); + ep93xx_spi_dma_transfer(master); else - ep93xx_spi_pio_transfer(espi); + ep93xx_spi_pio_transfer(master); /* * In case of error during transmit, we bail out from processing @@ -516,7 +523,7 @@ static void ep93xx_spi_process_transfer(struct ep93xx_spi *espi, /* * ep93xx_spi_process_message() - process one SPI message - * @espi: ep93xx SPI controller struct + * @master: SPI master * @msg: message to process * * This function processes a single SPI message. We go through all transfers in @@ -526,9 +533,10 @@ static void ep93xx_spi_process_transfer(struct ep93xx_spi *espi, * @msg->status contains %0 in case of success or negative error code in case of * failure. */ -static void ep93xx_spi_process_message(struct ep93xx_spi *espi, +static void ep93xx_spi_process_message(struct spi_master *master, struct spi_message *msg) { + struct ep93xx_spi *espi = spi_master_get_devdata(master); unsigned long timeout; struct spi_transfer *t; @@ -538,7 +546,7 @@ static void ep93xx_spi_process_message(struct ep93xx_spi *espi, timeout = jiffies + msecs_to_jiffies(SPI_TIMEOUT); while (readl(espi->mmio + SSPSR) & SSPSR_RNE) { if (time_after(jiffies, timeout)) { - dev_warn(&espi->pdev->dev, + dev_warn(&master->dev, "timeout while flushing RX FIFO\n"); msg->status = -ETIMEDOUT; return; @@ -558,7 +566,7 @@ static void ep93xx_spi_process_message(struct ep93xx_spi *espi, ep93xx_spi_cs_control(msg->spi, true); list_for_each_entry(t, &msg->transfers, transfer_list) { - ep93xx_spi_process_transfer(espi, msg, t); + ep93xx_spi_process_transfer(master, msg, t); if (msg->status) break; } @@ -580,7 +588,7 @@ static int ep93xx_spi_transfer_one_message(struct spi_master *master, msg->actual_length = 0; espi->current_msg = msg; - ep93xx_spi_process_message(espi, msg); + ep93xx_spi_process_message(master, msg); espi->current_msg = NULL; spi_finalize_current_message(master); @@ -590,7 +598,8 @@ static int ep93xx_spi_transfer_one_message(struct spi_master *master, static irqreturn_t ep93xx_spi_interrupt(int irq, void *dev_id) { - struct ep93xx_spi *espi = dev_id; + struct spi_master *master = dev_id; + struct ep93xx_spi *espi = spi_master_get_devdata(master); u32 val; /* @@ -600,7 +609,7 @@ static irqreturn_t ep93xx_spi_interrupt(int irq, void *dev_id) if (readl(espi->mmio + SSPIIR) & SSPIIR_RORIS) { /* clear the overrun interrupt */ writel(0, espi->mmio + SSPICR); - dev_warn(&espi->pdev->dev, + dev_warn(&master->dev, "receive overrun, aborting the message\n"); espi->current_msg->status = -EIO; } else { @@ -608,7 +617,7 @@ static irqreturn_t ep93xx_spi_interrupt(int irq, void *dev_id) * Interrupt is either RX (RIS) or TX (TIS). For both cases we * simply execute next data transfer. */ - if (ep93xx_spi_read_write(espi)) { + if (ep93xx_spi_read_write(master)) { /* * In normal case, there still is some processing left * for current transfer. Let's wait for the next @@ -815,7 +824,6 @@ static int ep93xx_spi_probe(struct platform_device *pdev) */ master->max_speed_hz = clk_get_rate(espi->clk) / 2; master->min_speed_hz = clk_get_rate(espi->clk) / (254 * 256); - espi->pdev = pdev; espi->sspdr_phys = res->start + SSPDR; @@ -826,7 +834,7 @@ static int ep93xx_spi_probe(struct platform_device *pdev) } error = devm_request_irq(&pdev->dev, irq, ep93xx_spi_interrupt, - 0, "ep93xx-spi", espi); + 0, "ep93xx-spi", master); if (error) { dev_err(&pdev->dev, "failed to request irq\n"); goto fail_release_master; -- cgit From c7a909cf25c6e1198f5a261d2af0503985871e1a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 9 Aug 2017 08:51:30 +1200 Subject: spi: spi-ep93xx: remove private data 'current_msg' The currently in-flight message can be found from the spi master. Use that instead and remove the private data pointer. Signed-off-by: H Hartley Sweeten Reviewed-by: Andy Shevchenko Signed-off-by: Chris Packham Signed-off-by: Mark Brown --- drivers/spi/spi-ep93xx.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index 2d80e36f5015..cf7d8175bf79 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c @@ -74,7 +74,6 @@ * @mmio: pointer to ioremap()'d registers * @sspdr_phys: physical address of the SSPDR register * @wait: wait here until given transfer is completed - * @current_msg: message that is currently processed (or %NULL if none) * @tx: current byte in transfer to transmit * @rx: current byte in transfer to receive * @fifo_level: how full is FIFO (%0..%SPI_FIFO_SIZE - %1). Receiving one @@ -93,7 +92,6 @@ struct ep93xx_spi { void __iomem *mmio; unsigned long sspdr_phys; struct completion wait; - struct spi_message *current_msg; size_t tx; size_t rx; size_t fifo_level; @@ -236,8 +234,7 @@ static void ep93xx_do_read(struct ep93xx_spi *espi, struct spi_transfer *t) static int ep93xx_spi_read_write(struct spi_master *master) { struct ep93xx_spi *espi = spi_master_get_devdata(master); - struct spi_message *msg = espi->current_msg; - struct spi_transfer *t = msg->state; + struct spi_transfer *t = master->cur_msg->state; /* read as long as RX FIFO has frames in it */ while ((readl(espi->mmio + SSPSR) & SSPSR_RNE)) { @@ -290,7 +287,7 @@ ep93xx_spi_dma_prepare(struct spi_master *master, enum dma_transfer_direction dir) { struct ep93xx_spi *espi = spi_master_get_devdata(master); - struct spi_transfer *t = espi->current_msg->state; + struct spi_transfer *t = master->cur_msg->state; struct dma_async_tx_descriptor *txd; enum dma_slave_buswidth buswidth; struct dma_slave_config conf; @@ -415,13 +412,12 @@ static void ep93xx_spi_dma_callback(void *callback_param) static void ep93xx_spi_dma_transfer(struct spi_master *master) { struct ep93xx_spi *espi = spi_master_get_devdata(master); - struct spi_message *msg = espi->current_msg; struct dma_async_tx_descriptor *rxd, *txd; rxd = ep93xx_spi_dma_prepare(master, DMA_DEV_TO_MEM); if (IS_ERR(rxd)) { dev_err(&master->dev, "DMA RX failed: %ld\n", PTR_ERR(rxd)); - msg->status = PTR_ERR(rxd); + master->cur_msg->status = PTR_ERR(rxd); return; } @@ -429,7 +425,7 @@ static void ep93xx_spi_dma_transfer(struct spi_master *master) if (IS_ERR(txd)) { ep93xx_spi_dma_finish(master, DMA_DEV_TO_MEM); dev_err(&master->dev, "DMA TX failed: %ld\n", PTR_ERR(txd)); - msg->status = PTR_ERR(txd); + master->cur_msg->status = PTR_ERR(txd); return; } @@ -587,9 +583,7 @@ static int ep93xx_spi_transfer_one_message(struct spi_master *master, msg->status = 0; msg->actual_length = 0; - espi->current_msg = msg; ep93xx_spi_process_message(master, msg); - espi->current_msg = NULL; spi_finalize_current_message(master); @@ -611,7 +605,7 @@ static irqreturn_t ep93xx_spi_interrupt(int irq, void *dev_id) writel(0, espi->mmio + SSPICR); dev_warn(&master->dev, "receive overrun, aborting the message\n"); - espi->current_msg->status = -EIO; + master->cur_msg->status = -EIO; } else { /* * Interrupt is either RX (RIS) or TX (TIS). For both cases we -- cgit From d9a017713d909697f528a3f6569d5deb7477cea1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 9 Aug 2017 08:51:31 +1200 Subject: spi: spi-ep93xx: use the default master transfer queueing mechanism Update this driver to the default implementation of transfer_one_message(). Signed-off-by: H Hartley Sweeten Reviewed-by: Andy Shevchenko Signed-off-by: Chris Packham Signed-off-by: Mark Brown --- drivers/spi/spi-ep93xx.c | 322 ++++++++++++++++------------------------------- 1 file changed, 108 insertions(+), 214 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index cf7d8175bf79..e5cc07357746 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c @@ -73,7 +73,6 @@ * @clk: clock for the controller * @mmio: pointer to ioremap()'d registers * @sspdr_phys: physical address of the SSPDR register - * @wait: wait here until given transfer is completed * @tx: current byte in transfer to transmit * @rx: current byte in transfer to receive * @fifo_level: how full is FIFO (%0..%SPI_FIFO_SIZE - %1). Receiving one @@ -91,7 +90,6 @@ struct ep93xx_spi { struct clk *clk; void __iomem *mmio; unsigned long sspdr_phys; - struct completion wait; size_t tx; size_t rx; size_t fifo_level; @@ -123,8 +121,7 @@ static int ep93xx_spi_calc_divisors(struct spi_master *master, /* * Make sure that max value is between values supported by the - * controller. Note that minimum value is already checked in - * ep93xx_spi_transfer_one_message(). + * controller. */ rate = clamp(rate, master->min_speed_hz, master->max_speed_hz); @@ -149,15 +146,6 @@ static int ep93xx_spi_calc_divisors(struct spi_master *master, return -EINVAL; } -static void ep93xx_spi_cs_control(struct spi_device *spi, bool enable) -{ - if (spi->mode & SPI_CS_HIGH) - enable = !enable; - - if (gpio_is_valid(spi->cs_gpio)) - gpio_set_value(spi->cs_gpio, !enable); -} - static int ep93xx_spi_chip_setup(struct spi_master *master, struct spi_device *spi, struct spi_transfer *xfer) @@ -188,34 +176,38 @@ static int ep93xx_spi_chip_setup(struct spi_master *master, return 0; } -static void ep93xx_do_write(struct ep93xx_spi *espi, struct spi_transfer *t) +static void ep93xx_do_write(struct spi_master *master) { + struct ep93xx_spi *espi = spi_master_get_devdata(master); + struct spi_transfer *xfer = master->cur_msg->state; u32 val = 0; - if (t->bits_per_word > 8) { - if (t->tx_buf) - val = ((u16 *)t->tx_buf)[espi->tx]; + if (xfer->bits_per_word > 8) { + if (xfer->tx_buf) + val = ((u16 *)xfer->tx_buf)[espi->tx]; espi->tx += 2; } else { - if (t->tx_buf) - val = ((u8 *)t->tx_buf)[espi->tx]; + if (xfer->tx_buf) + val = ((u8 *)xfer->tx_buf)[espi->tx]; espi->tx += 1; } writel(val, espi->mmio + SSPDR); } -static void ep93xx_do_read(struct ep93xx_spi *espi, struct spi_transfer *t) +static void ep93xx_do_read(struct spi_master *master) { + struct ep93xx_spi *espi = spi_master_get_devdata(master); + struct spi_transfer *xfer = master->cur_msg->state; u32 val; val = readl(espi->mmio + SSPDR); - if (t->bits_per_word > 8) { - if (t->rx_buf) - ((u16 *)t->rx_buf)[espi->rx] = val; + if (xfer->bits_per_word > 8) { + if (xfer->rx_buf) + ((u16 *)xfer->rx_buf)[espi->rx] = val; espi->rx += 2; } else { - if (t->rx_buf) - ((u8 *)t->rx_buf)[espi->rx] = val; + if (xfer->rx_buf) + ((u8 *)xfer->rx_buf)[espi->rx] = val; espi->rx += 1; } } @@ -234,45 +226,26 @@ static void ep93xx_do_read(struct ep93xx_spi *espi, struct spi_transfer *t) static int ep93xx_spi_read_write(struct spi_master *master) { struct ep93xx_spi *espi = spi_master_get_devdata(master); - struct spi_transfer *t = master->cur_msg->state; + struct spi_transfer *xfer = master->cur_msg->state; /* read as long as RX FIFO has frames in it */ while ((readl(espi->mmio + SSPSR) & SSPSR_RNE)) { - ep93xx_do_read(espi, t); + ep93xx_do_read(master); espi->fifo_level--; } /* write as long as TX FIFO has room */ - while (espi->fifo_level < SPI_FIFO_SIZE && espi->tx < t->len) { - ep93xx_do_write(espi, t); + while (espi->fifo_level < SPI_FIFO_SIZE && espi->tx < xfer->len) { + ep93xx_do_write(master); espi->fifo_level++; } - if (espi->rx == t->len) + if (espi->rx == xfer->len) return 0; return -EINPROGRESS; } -static void ep93xx_spi_pio_transfer(struct spi_master *master) -{ - struct ep93xx_spi *espi = spi_master_get_devdata(master); - - /* - * Now everything is set up for the current transfer. We prime the TX - * FIFO, enable interrupts, and wait for the transfer to complete. - */ - if (ep93xx_spi_read_write(master)) { - u32 val; - - val = readl(espi->mmio + SSPCR1); - val |= (SSPCR1_RORIE | SSPCR1_TIE | SSPCR1_RIE); - writel(val, espi->mmio + SSPCR1); - - wait_for_completion(&espi->wait); - } -} - /** * ep93xx_spi_dma_prepare() - prepares a DMA transfer * @master: SPI master @@ -287,7 +260,7 @@ ep93xx_spi_dma_prepare(struct spi_master *master, enum dma_transfer_direction dir) { struct ep93xx_spi *espi = spi_master_get_devdata(master); - struct spi_transfer *t = master->cur_msg->state; + struct spi_transfer *xfer = master->cur_msg->state; struct dma_async_tx_descriptor *txd; enum dma_slave_buswidth buswidth; struct dma_slave_config conf; @@ -295,10 +268,10 @@ ep93xx_spi_dma_prepare(struct spi_master *master, struct sg_table *sgt; struct dma_chan *chan; const void *buf, *pbuf; - size_t len = t->len; + size_t len = xfer->len; int i, ret, nents; - if (t->bits_per_word > 8) + if (xfer->bits_per_word > 8) buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES; else buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE; @@ -308,14 +281,14 @@ ep93xx_spi_dma_prepare(struct spi_master *master, if (dir == DMA_DEV_TO_MEM) { chan = espi->dma_rx; - buf = t->rx_buf; + buf = xfer->rx_buf; sgt = &espi->rx_sgt; conf.src_addr = espi->sspdr_phys; conf.src_addr_width = buswidth; } else { chan = espi->dma_tx; - buf = t->tx_buf; + buf = xfer->tx_buf; sgt = &espi->tx_sgt; conf.dst_addr = espi->sspdr_phys; @@ -406,10 +379,15 @@ static void ep93xx_spi_dma_finish(struct spi_master *master, static void ep93xx_spi_dma_callback(void *callback_param) { - complete(callback_param); + struct spi_master *master = callback_param; + + ep93xx_spi_dma_finish(master, DMA_MEM_TO_DEV); + ep93xx_spi_dma_finish(master, DMA_DEV_TO_MEM); + + spi_finalize_current_transfer(master); } -static void ep93xx_spi_dma_transfer(struct spi_master *master) +static int ep93xx_spi_dma_transfer(struct spi_master *master) { struct ep93xx_spi *espi = spi_master_get_devdata(master); struct dma_async_tx_descriptor *rxd, *txd; @@ -417,177 +395,29 @@ static void ep93xx_spi_dma_transfer(struct spi_master *master) rxd = ep93xx_spi_dma_prepare(master, DMA_DEV_TO_MEM); if (IS_ERR(rxd)) { dev_err(&master->dev, "DMA RX failed: %ld\n", PTR_ERR(rxd)); - master->cur_msg->status = PTR_ERR(rxd); - return; + return PTR_ERR(rxd); } txd = ep93xx_spi_dma_prepare(master, DMA_MEM_TO_DEV); if (IS_ERR(txd)) { ep93xx_spi_dma_finish(master, DMA_DEV_TO_MEM); dev_err(&master->dev, "DMA TX failed: %ld\n", PTR_ERR(txd)); - master->cur_msg->status = PTR_ERR(txd); - return; + return PTR_ERR(txd); } /* We are ready when RX is done */ rxd->callback = ep93xx_spi_dma_callback; - rxd->callback_param = &espi->wait; + rxd->callback_param = master; - /* Now submit both descriptors and wait while they finish */ + /* Now submit both descriptors and start DMA */ dmaengine_submit(rxd); dmaengine_submit(txd); dma_async_issue_pending(espi->dma_rx); dma_async_issue_pending(espi->dma_tx); - wait_for_completion(&espi->wait); - - ep93xx_spi_dma_finish(master, DMA_MEM_TO_DEV); - ep93xx_spi_dma_finish(master, DMA_DEV_TO_MEM); -} - -/** - * ep93xx_spi_process_transfer() - processes one SPI transfer - * @master: SPI master - * @msg: current message - * @t: transfer to process - * - * This function processes one SPI transfer given in @t. Function waits until - * transfer is complete (may sleep) and updates @msg->status based on whether - * transfer was successfully processed or not. - */ -static void ep93xx_spi_process_transfer(struct spi_master *master, - struct spi_message *msg, - struct spi_transfer *t) -{ - struct ep93xx_spi *espi = spi_master_get_devdata(master); - int err; - - msg->state = t; - - err = ep93xx_spi_chip_setup(master, msg->spi, t); - if (err) { - dev_err(&master->dev, - "failed to setup chip for transfer\n"); - msg->status = err; - return; - } - - espi->rx = 0; - espi->tx = 0; - - /* - * There is no point of setting up DMA for the transfers which will - * fit into the FIFO and can be transferred with a single interrupt. - * So in these cases we will be using PIO and don't bother for DMA. - */ - if (espi->dma_rx && t->len > SPI_FIFO_SIZE) - ep93xx_spi_dma_transfer(master); - else - ep93xx_spi_pio_transfer(master); - - /* - * In case of error during transmit, we bail out from processing - * the message. - */ - if (msg->status) - return; - - msg->actual_length += t->len; - - /* - * After this transfer is finished, perform any possible - * post-transfer actions requested by the protocol driver. - */ - if (t->delay_usecs) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(usecs_to_jiffies(t->delay_usecs)); - } - if (t->cs_change) { - if (!list_is_last(&t->transfer_list, &msg->transfers)) { - /* - * In case protocol driver is asking us to drop the - * chipselect briefly, we let the scheduler to handle - * any "delay" here. - */ - ep93xx_spi_cs_control(msg->spi, false); - cond_resched(); - ep93xx_spi_cs_control(msg->spi, true); - } - } -} - -/* - * ep93xx_spi_process_message() - process one SPI message - * @master: SPI master - * @msg: message to process - * - * This function processes a single SPI message. We go through all transfers in - * the message and pass them to ep93xx_spi_process_transfer(). Chipselect is - * asserted during the whole message (unless per transfer cs_change is set). - * - * @msg->status contains %0 in case of success or negative error code in case of - * failure. - */ -static void ep93xx_spi_process_message(struct spi_master *master, - struct spi_message *msg) -{ - struct ep93xx_spi *espi = spi_master_get_devdata(master); - unsigned long timeout; - struct spi_transfer *t; - - /* - * Just to be sure: flush any data from RX FIFO. - */ - timeout = jiffies + msecs_to_jiffies(SPI_TIMEOUT); - while (readl(espi->mmio + SSPSR) & SSPSR_RNE) { - if (time_after(jiffies, timeout)) { - dev_warn(&master->dev, - "timeout while flushing RX FIFO\n"); - msg->status = -ETIMEDOUT; - return; - } - readl(espi->mmio + SSPDR); - } - - /* - * We explicitly handle FIFO level. This way we don't have to check TX - * FIFO status using %SSPSR_TNF bit which may cause RX FIFO overruns. - */ - espi->fifo_level = 0; - - /* - * Assert the chipselect. - */ - ep93xx_spi_cs_control(msg->spi, true); - - list_for_each_entry(t, &msg->transfers, transfer_list) { - ep93xx_spi_process_transfer(master, msg, t); - if (msg->status) - break; - } - - /* - * Now the whole message is transferred (or failed for some reason). We - * deselect the device and disable the SPI controller. - */ - ep93xx_spi_cs_control(msg->spi, false); -} - -static int ep93xx_spi_transfer_one_message(struct spi_master *master, - struct spi_message *msg) -{ - struct ep93xx_spi *espi = spi_master_get_devdata(master); - - msg->state = NULL; - msg->status = 0; - msg->actual_length = 0; - - ep93xx_spi_process_message(master, msg); - - spi_finalize_current_message(master); - - return 0; + /* signal that we need to wait for completion */ + return 1; } static irqreturn_t ep93xx_spi_interrupt(int irq, void *dev_id) @@ -630,11 +460,76 @@ static irqreturn_t ep93xx_spi_interrupt(int irq, void *dev_id) val &= ~(SSPCR1_RORIE | SSPCR1_TIE | SSPCR1_RIE); writel(val, espi->mmio + SSPCR1); - complete(&espi->wait); + spi_finalize_current_transfer(master); return IRQ_HANDLED; } +static int ep93xx_spi_transfer_one(struct spi_master *master, + struct spi_device *spi, + struct spi_transfer *xfer) +{ + struct ep93xx_spi *espi = spi_master_get_devdata(master); + u32 val; + int ret; + + ret = ep93xx_spi_chip_setup(master, spi, xfer); + if (ret) { + dev_err(&master->dev, "failed to setup chip for transfer\n"); + return ret; + } + + master->cur_msg->state = xfer; + espi->rx = 0; + espi->tx = 0; + + /* + * There is no point of setting up DMA for the transfers which will + * fit into the FIFO and can be transferred with a single interrupt. + * So in these cases we will be using PIO and don't bother for DMA. + */ + if (espi->dma_rx && xfer->len > SPI_FIFO_SIZE) + return ep93xx_spi_dma_transfer(master); + + /* Using PIO so prime the TX FIFO and enable interrupts */ + ep93xx_spi_read_write(master); + + val = readl(espi->mmio + SSPCR1); + val |= (SSPCR1_RORIE | SSPCR1_TIE | SSPCR1_RIE); + writel(val, espi->mmio + SSPCR1); + + /* signal that we need to wait for completion */ + return 1; +} + +static int ep93xx_spi_prepare_message(struct spi_master *master, + struct spi_message *msg) +{ + struct ep93xx_spi *espi = spi_master_get_devdata(master); + unsigned long timeout; + + /* + * Just to be sure: flush any data from RX FIFO. + */ + timeout = jiffies + msecs_to_jiffies(SPI_TIMEOUT); + while (readl(espi->mmio + SSPSR) & SSPSR_RNE) { + if (time_after(jiffies, timeout)) { + dev_warn(&master->dev, + "timeout while flushing RX FIFO\n"); + return -ETIMEDOUT; + } + readl(espi->mmio + SSPDR); + } + + /* + * We explicitly handle FIFO level. This way we don't have to check TX + * FIFO status using %SSPSR_TNF bit which may cause RX FIFO overruns. + */ + espi->fifo_level = 0; + + return 0; +} + static int ep93xx_spi_prepare_hardware(struct spi_master *master) { struct ep93xx_spi *espi = spi_master_get_devdata(master); @@ -769,7 +664,8 @@ static int ep93xx_spi_probe(struct platform_device *pdev) master->prepare_transfer_hardware = ep93xx_spi_prepare_hardware; master->unprepare_transfer_hardware = ep93xx_spi_unprepare_hardware; - master->transfer_one_message = ep93xx_spi_transfer_one_message; + master->prepare_message = ep93xx_spi_prepare_message; + master->transfer_one = ep93xx_spi_transfer_one; master->bus_num = pdev->id; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); @@ -810,8 +706,6 @@ static int ep93xx_spi_probe(struct platform_device *pdev) goto fail_release_master; } - init_completion(&espi->wait); - /* * Calculate maximum and minimum supported clock rates * for the controller. -- cgit From 1a41aa1376df9e24d0c760df1a6f59765316c457 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sun, 20 Aug 2017 00:18:10 +0200 Subject: spi: spi-falcon: drop check of boot select Do not check which flash type the SoC was booted from before using this driver. Assume that the device tree is correct and use this driver when it was added to device tree. This also removes a build dependency to the SoC code. All device trees I am aware of only have one correct flash device entry in it. The device tree is anyway bundled with the kernel in all systems using device tree I know of. The boot mode can be specified with some pin straps and will select the flash type the rom code will boot from. One SPI, NOR or NAND flash chip can be connect to the EBU and used to load the first stage boot loader from. Signed-off-by: Hauke Mehrtens Cc: Mark Brown Cc: linux-spi@vger.kernel.org Signed-off-by: Mark Brown --- drivers/spi/spi-falcon.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-falcon.c b/drivers/spi/spi-falcon.c index 286b2c81fc6b..f8638e82e5db 100644 --- a/drivers/spi/spi-falcon.c +++ b/drivers/spi/spi-falcon.c @@ -395,11 +395,6 @@ static int falcon_sflash_probe(struct platform_device *pdev) struct spi_master *master; int ret; - if (ltq_boot_select() != BS_SPI) { - dev_err(&pdev->dev, "invalid bootstrap options\n"); - return -ENODEV; - } - master = spi_alloc_master(&pdev->dev, sizeof(*priv)); if (!master) return -ENOMEM; -- cgit