summaryrefslogtreecommitdiff
path: root/drivers/spi/spi-armada-3700.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi-armada-3700.c')
-rw-r--r--drivers/spi/spi-armada-3700.c159
1 files changed, 64 insertions, 95 deletions
diff --git a/drivers/spi/spi-armada-3700.c b/drivers/spi/spi-armada-3700.c
index 7dcb14d303eb..02c1e625742d 100644
--- a/drivers/spi/spi-armada-3700.c
+++ b/drivers/spi/spi-armada-3700.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Marvell Armada-3700 SPI controller driver
*
@@ -5,10 +6,6 @@
*
* Author: Wilson Ding <dingwei@marvell.com>
* Author: Romain Perier <romain.perier@free-electrons.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
*/
#include <linux/clk.h>
@@ -20,8 +17,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_irq.h>
-#include <linux/of_device.h>
+#include <linux/platform_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/spi/spi.h>
@@ -103,7 +99,7 @@
#define A3700_SPI_CLK_CAPT_EDGE BIT(7)
struct a3700_spi {
- struct spi_master *master;
+ struct spi_controller *host;
void __iomem *base;
struct clk *clk;
unsigned int irq;
@@ -177,7 +173,7 @@ static int a3700_spi_pin_mode_set(struct a3700_spi *a3700_spi,
val |= A3700_SPI_ADDR_PIN;
break;
default:
- dev_err(&a3700_spi->master->dev, "wrong pin mode %u", pin_mode);
+ dev_err(&a3700_spi->host->dev, "wrong pin mode %u", pin_mode);
return -EINVAL;
}
@@ -279,11 +275,11 @@ static int a3700_spi_fifo_flush(struct a3700_spi *a3700_spi)
return -ETIMEDOUT;
}
-static int a3700_spi_init(struct a3700_spi *a3700_spi)
+static void a3700_spi_init(struct a3700_spi *a3700_spi)
{
- struct spi_master *master = a3700_spi->master;
+ struct spi_controller *host = a3700_spi->host;
u32 val;
- int i, ret = 0;
+ int i;
/* Reset SPI unit */
val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
@@ -298,14 +294,14 @@ static int a3700_spi_init(struct a3700_spi *a3700_spi)
/* Disable AUTO_CS and deactivate all chip-selects */
a3700_spi_auto_cs_unset(a3700_spi);
- for (i = 0; i < master->num_chipselect; i++)
+ for (i = 0; i < host->num_chipselect; i++)
a3700_spi_deactivate_cs(a3700_spi, i);
/* Enable FIFO mode */
a3700_spi_fifo_mode_set(a3700_spi, true);
/* Set SPI mode */
- a3700_spi_mode_set(a3700_spi, master->mode_bits);
+ a3700_spi_mode_set(a3700_spi, host->mode_bits);
/* Reset counters */
spireg_write(a3700_spi, A3700_SPI_IF_HDR_CNT_REG, 0);
@@ -314,17 +310,15 @@ static int a3700_spi_init(struct a3700_spi *a3700_spi)
/* Mask the interrupts and clear cause bits */
spireg_write(a3700_spi, A3700_SPI_INT_MASK_REG, 0);
spireg_write(a3700_spi, A3700_SPI_INT_STAT_REG, ~0U);
-
- return ret;
}
static irqreturn_t a3700_spi_interrupt(int irq, void *dev_id)
{
- struct spi_master *master = dev_id;
+ struct spi_controller *host = dev_id;
struct a3700_spi *a3700_spi;
u32 cause;
- a3700_spi = spi_master_get_devdata(master);
+ a3700_spi = spi_controller_get_devdata(host);
/* Get interrupt causes */
cause = spireg_read(a3700_spi, A3700_SPI_INT_STAT_REG);
@@ -345,11 +339,11 @@ static irqreturn_t a3700_spi_interrupt(int irq, void *dev_id)
static bool a3700_spi_wait_completion(struct spi_device *spi)
{
struct a3700_spi *a3700_spi;
- unsigned int timeout;
+ unsigned long time_left;
unsigned int ctrl_reg;
unsigned long timeout_jiffies;
- a3700_spi = spi_master_get_devdata(spi->master);
+ a3700_spi = spi_controller_get_devdata(spi->controller);
/* SPI interrupt is edge-triggered, which means an interrupt will
* be generated only when detecting a specific status bit changed
@@ -367,12 +361,12 @@ static bool a3700_spi_wait_completion(struct spi_device *spi)
a3700_spi->wait_mask);
timeout_jiffies = msecs_to_jiffies(A3700_SPI_TIMEOUT);
- timeout = wait_for_completion_timeout(&a3700_spi->done,
- timeout_jiffies);
+ time_left = wait_for_completion_timeout(&a3700_spi->done,
+ timeout_jiffies);
a3700_spi->wait_mask = 0;
- if (timeout)
+ if (time_left)
return true;
/* there might be the case that right after we checked the
@@ -398,7 +392,7 @@ static bool a3700_spi_transfer_wait(struct spi_device *spi,
{
struct a3700_spi *a3700_spi;
- a3700_spi = spi_master_get_devdata(spi->master);
+ a3700_spi = spi_controller_get_devdata(spi->controller);
a3700_spi->wait_mask = bit_mask;
return a3700_spi_wait_completion(spi);
@@ -422,7 +416,7 @@ static void a3700_spi_transfer_setup(struct spi_device *spi,
{
struct a3700_spi *a3700_spi;
- a3700_spi = spi_master_get_devdata(spi->master);
+ a3700_spi = spi_controller_get_devdata(spi->controller);
a3700_spi_clock_set(a3700_spi, xfer->speed_hz);
@@ -439,12 +433,12 @@ static void a3700_spi_transfer_setup(struct spi_device *spi,
static void a3700_spi_set_cs(struct spi_device *spi, bool enable)
{
- struct a3700_spi *a3700_spi = spi_master_get_devdata(spi->master);
+ struct a3700_spi *a3700_spi = spi_controller_get_devdata(spi->controller);
if (!enable)
- a3700_spi_activate_cs(a3700_spi, spi->chip_select);
+ a3700_spi_activate_cs(a3700_spi, spi_get_chipselect(spi, 0));
else
- a3700_spi_deactivate_cs(a3700_spi, spi->chip_select);
+ a3700_spi_deactivate_cs(a3700_spi, spi_get_chipselect(spi, 0));
}
static void a3700_spi_header_set(struct a3700_spi *a3700_spi)
@@ -502,7 +496,7 @@ static int a3700_spi_fifo_write(struct a3700_spi *a3700_spi)
while (!a3700_is_wfifo_full(a3700_spi) && a3700_spi->buf_len) {
val = *(u32 *)a3700_spi->tx_buf;
- spireg_write(a3700_spi, A3700_SPI_DATA_OUT_REG, val);
+ spireg_write(a3700_spi, A3700_SPI_DATA_OUT_REG, cpu_to_le32(val));
a3700_spi->buf_len -= 4;
a3700_spi->tx_buf += 4;
}
@@ -524,7 +518,7 @@ static int a3700_spi_fifo_read(struct a3700_spi *a3700_spi)
while (!a3700_is_rfifo_empty(a3700_spi) && a3700_spi->buf_len) {
val = spireg_read(a3700_spi, A3700_SPI_DATA_IN_REG);
if (a3700_spi->buf_len >= 4) {
-
+ val = le32_to_cpu(val);
memcpy(a3700_spi->rx_buf, &val, 4);
a3700_spi->buf_len -= 4;
@@ -570,10 +564,10 @@ static void a3700_spi_transfer_abort_fifo(struct a3700_spi *a3700_spi)
spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
}
-static int a3700_spi_prepare_message(struct spi_master *master,
+static int a3700_spi_prepare_message(struct spi_controller *host,
struct spi_message *message)
{
- struct a3700_spi *a3700_spi = spi_master_get_devdata(master);
+ struct a3700_spi *a3700_spi = spi_controller_get_devdata(host);
struct spi_device *spi = message->spi;
int ret;
@@ -593,11 +587,11 @@ static int a3700_spi_prepare_message(struct spi_master *master,
return 0;
}
-static int a3700_spi_transfer_one_fifo(struct spi_master *master,
+static int a3700_spi_transfer_one_fifo(struct spi_controller *host,
struct spi_device *spi,
struct spi_transfer *xfer)
{
- struct a3700_spi *a3700_spi = spi_master_get_devdata(master);
+ struct a3700_spi *a3700_spi = spi_controller_get_devdata(host);
int ret = 0, timeout = A3700_SPI_TIMEOUT;
unsigned int nbits = 0, byte_len;
u32 val;
@@ -737,16 +731,16 @@ static int a3700_spi_transfer_one_fifo(struct spi_master *master,
error:
a3700_spi_transfer_abort_fifo(a3700_spi);
out:
- spi_finalize_current_transfer(master);
+ spi_finalize_current_transfer(host);
return ret;
}
-static int a3700_spi_transfer_one_full_duplex(struct spi_master *master,
+static int a3700_spi_transfer_one_full_duplex(struct spi_controller *host,
struct spi_device *spi,
struct spi_transfer *xfer)
{
- struct a3700_spi *a3700_spi = spi_master_get_devdata(master);
+ struct a3700_spi *a3700_spi = spi_controller_get_devdata(host);
u32 val;
/* Disable FIFO mode */
@@ -782,27 +776,27 @@ static int a3700_spi_transfer_one_full_duplex(struct spi_master *master,
}
- spi_finalize_current_transfer(master);
+ spi_finalize_current_transfer(host);
return 0;
}
-static int a3700_spi_transfer_one(struct spi_master *master,
+static int a3700_spi_transfer_one(struct spi_controller *host,
struct spi_device *spi,
struct spi_transfer *xfer)
{
a3700_spi_transfer_setup(spi, xfer);
if (xfer->tx_buf && xfer->rx_buf)
- return a3700_spi_transfer_one_full_duplex(master, spi, xfer);
+ return a3700_spi_transfer_one_full_duplex(host, spi, xfer);
- return a3700_spi_transfer_one_fifo(master, spi, xfer);
+ return a3700_spi_transfer_one_fifo(host, spi, xfer);
}
-static int a3700_spi_unprepare_message(struct spi_master *master,
+static int a3700_spi_unprepare_message(struct spi_controller *host,
struct spi_message *message)
{
- struct a3700_spi *a3700_spi = spi_master_get_devdata(master);
+ struct a3700_spi *a3700_spi = spi_controller_get_devdata(host);
clk_disable(a3700_spi->clk);
@@ -820,15 +814,14 @@ static int a3700_spi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *of_node = dev->of_node;
- struct resource *res;
- struct spi_master *master;
+ struct spi_controller *host;
struct a3700_spi *spi;
u32 num_cs = 0;
int irq, ret = 0;
- master = spi_alloc_master(dev, sizeof(*spi));
- if (!master) {
- dev_err(dev, "master allocation failed\n");
+ host = spi_alloc_host(dev, sizeof(*spi));
+ if (!host) {
+ dev_err(dev, "host allocation failed\n");
ret = -ENOMEM;
goto out;
}
@@ -839,27 +832,25 @@ static int a3700_spi_probe(struct platform_device *pdev)
goto error;
}
- master->bus_num = pdev->id;
- master->dev.of_node = of_node;
- master->mode_bits = SPI_MODE_3;
- master->num_chipselect = num_cs;
- master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(32);
- master->prepare_message = a3700_spi_prepare_message;
- master->transfer_one = a3700_spi_transfer_one;
- master->unprepare_message = a3700_spi_unprepare_message;
- master->set_cs = a3700_spi_set_cs;
- master->mode_bits |= (SPI_RX_DUAL | SPI_TX_DUAL |
+ host->bus_num = pdev->id;
+ host->dev.of_node = of_node;
+ host->mode_bits = SPI_MODE_3;
+ host->num_chipselect = num_cs;
+ host->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(32);
+ host->prepare_message = a3700_spi_prepare_message;
+ host->transfer_one = a3700_spi_transfer_one;
+ host->unprepare_message = a3700_spi_unprepare_message;
+ host->set_cs = a3700_spi_set_cs;
+ host->mode_bits |= (SPI_RX_DUAL | SPI_TX_DUAL |
SPI_RX_QUAD | SPI_TX_QUAD);
- platform_set_drvdata(pdev, master);
+ platform_set_drvdata(pdev, host);
- spi = spi_master_get_devdata(master);
- memset(spi, 0, sizeof(struct a3700_spi));
+ spi = spi_controller_get_devdata(host);
- spi->master = master;
+ spi->host = host;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- spi->base = devm_ioremap_resource(dev, res);
+ spi->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(spi->base)) {
ret = PTR_ERR(spi->base);
goto error;
@@ -867,7 +858,6 @@ static int a3700_spi_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
- dev_err(dev, "could not get irq: %d\n", irq);
ret = -ENXIO;
goto error;
}
@@ -875,67 +865,46 @@ static int a3700_spi_probe(struct platform_device *pdev)
init_completion(&spi->done);
- spi->clk = devm_clk_get(dev, NULL);
+ spi->clk = devm_clk_get_prepared(dev, NULL);
if (IS_ERR(spi->clk)) {
dev_err(dev, "could not find clk: %ld\n", PTR_ERR(spi->clk));
goto error;
}
- ret = clk_prepare(spi->clk);
- if (ret) {
- dev_err(dev, "could not prepare clk: %d\n", ret);
- goto error;
- }
-
- master->max_speed_hz = min_t(unsigned long, A3700_SPI_MAX_SPEED_HZ,
+ host->max_speed_hz = min_t(unsigned long, A3700_SPI_MAX_SPEED_HZ,
clk_get_rate(spi->clk));
- master->min_speed_hz = DIV_ROUND_UP(clk_get_rate(spi->clk),
+ host->min_speed_hz = DIV_ROUND_UP(clk_get_rate(spi->clk),
A3700_SPI_MAX_PRESCALE);
- ret = a3700_spi_init(spi);
- if (ret)
- goto error_clk;
+ a3700_spi_init(spi);
ret = devm_request_irq(dev, spi->irq, a3700_spi_interrupt, 0,
- dev_name(dev), master);
+ dev_name(dev), host);
if (ret) {
dev_err(dev, "could not request IRQ: %d\n", ret);
- goto error_clk;
+ goto error;
}
- ret = devm_spi_register_master(dev, master);
+ ret = devm_spi_register_controller(dev, host);
if (ret) {
- dev_err(dev, "Failed to register master\n");
- goto error_clk;
+ dev_err(dev, "Failed to register host\n");
+ goto error;
}
return 0;
-error_clk:
- clk_disable_unprepare(spi->clk);
error:
- spi_master_put(master);
+ spi_controller_put(host);
out:
return ret;
}
-static int a3700_spi_remove(struct platform_device *pdev)
-{
- struct spi_master *master = platform_get_drvdata(pdev);
- struct a3700_spi *spi = spi_master_get_devdata(master);
-
- clk_unprepare(spi->clk);
-
- return 0;
-}
-
static struct platform_driver a3700_spi_driver = {
.driver = {
.name = DRIVER_NAME,
.of_match_table = of_match_ptr(a3700_spi_dt_ids),
},
.probe = a3700_spi_probe,
- .remove = a3700_spi_remove,
};
module_platform_driver(a3700_spi_driver);