Commit 4f485773 authored by Mark Brown's avatar Mark Brown

spi: s3c64xx: straightforward cleanup

Merge series from Tudor Ambarus <tudor.ambarus@linaro.org>:

Various simple cleanups for the s3c64xx driver.  Tested with gs101-spi.
parents 0da9a7e5 acd6c7b1
...@@ -3,19 +3,21 @@ ...@@ -3,19 +3,21 @@
// Copyright (c) 2009 Samsung Electronics Co., Ltd. // Copyright (c) 2009 Samsung Electronics Co., Ltd.
// Jaswinder Singh <jassi.brar@samsung.com> // Jaswinder Singh <jassi.brar@samsung.com>
#include <linux/init.h> #include <linux/bits.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/dmaengine.h> #include <linux/dmaengine.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_data/spi-s3c64xx.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/of.h> #include <linux/types.h>
#include <linux/platform_data/spi-s3c64xx.h>
#define MAX_SPI_PORTS 16 #define MAX_SPI_PORTS 16
#define S3C64XX_SPI_QUIRK_CS_AUTO (1 << 1) #define S3C64XX_SPI_QUIRK_CS_AUTO (1 << 1)
...@@ -114,8 +116,6 @@ ...@@ -114,8 +116,6 @@
#define S3C64XX_SPI_MAX_TRAILCNT 0x3ff #define S3C64XX_SPI_MAX_TRAILCNT 0x3ff
#define S3C64XX_SPI_TRAILCNT_OFF 19 #define S3C64XX_SPI_TRAILCNT_OFF 19
#define S3C64XX_SPI_TRAILCNT S3C64XX_SPI_MAX_TRAILCNT
#define S3C64XX_SPI_POLLING_SIZE 32 #define S3C64XX_SPI_POLLING_SIZE 32
#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
...@@ -180,7 +180,7 @@ struct s3c64xx_spi_port_config { ...@@ -180,7 +180,7 @@ struct s3c64xx_spi_port_config {
* @cur_speed: Current clock speed * @cur_speed: Current clock speed
* @rx_dma: Local receive DMA data (e.g. chan and direction) * @rx_dma: Local receive DMA data (e.g. chan and direction)
* @tx_dma: Local transmit DMA data (e.g. chan and direction) * @tx_dma: Local transmit DMA data (e.g. chan and direction)
* @port_conf: Local SPI port configuartion data * @port_conf: Local SPI port configuration data
* @port_id: Port identification number * @port_id: Port identification number
*/ */
struct s3c64xx_spi_driver_data { struct s3c64xx_spi_driver_data {
...@@ -279,7 +279,7 @@ static void s3c64xx_spi_dmacb(void *data) ...@@ -279,7 +279,7 @@ static void s3c64xx_spi_dmacb(void *data)
spin_unlock_irqrestore(&sdd->lock, flags); spin_unlock_irqrestore(&sdd->lock, flags);
} }
static int prepare_dma(struct s3c64xx_spi_dma_data *dma, static int s3c64xx_prepare_dma(struct s3c64xx_spi_dma_data *dma,
struct sg_table *sgt) struct sg_table *sgt)
{ {
struct s3c64xx_spi_driver_data *sdd; struct s3c64xx_spi_driver_data *sdd;
...@@ -292,20 +292,20 @@ static int prepare_dma(struct s3c64xx_spi_dma_data *dma, ...@@ -292,20 +292,20 @@ static int prepare_dma(struct s3c64xx_spi_dma_data *dma,
if (dma->direction == DMA_DEV_TO_MEM) { if (dma->direction == DMA_DEV_TO_MEM) {
sdd = container_of((void *)dma, sdd = container_of((void *)dma,
struct s3c64xx_spi_driver_data, rx_dma); struct s3c64xx_spi_driver_data, rx_dma);
config.direction = dma->direction;
config.src_addr = sdd->sfr_start + S3C64XX_SPI_RX_DATA; config.src_addr = sdd->sfr_start + S3C64XX_SPI_RX_DATA;
config.src_addr_width = sdd->cur_bpw / 8; config.src_addr_width = sdd->cur_bpw / 8;
config.src_maxburst = 1; config.src_maxburst = 1;
dmaengine_slave_config(dma->ch, &config);
} else { } else {
sdd = container_of((void *)dma, sdd = container_of((void *)dma,
struct s3c64xx_spi_driver_data, tx_dma); struct s3c64xx_spi_driver_data, tx_dma);
config.direction = dma->direction;
config.dst_addr = sdd->sfr_start + S3C64XX_SPI_TX_DATA; config.dst_addr = sdd->sfr_start + S3C64XX_SPI_TX_DATA;
config.dst_addr_width = sdd->cur_bpw / 8; config.dst_addr_width = sdd->cur_bpw / 8;
config.dst_maxburst = 1; config.dst_maxburst = 1;
dmaengine_slave_config(dma->ch, &config);
} }
config.direction = dma->direction;
ret = dmaengine_slave_config(dma->ch, &config);
if (ret)
return ret;
desc = dmaengine_prep_slave_sg(dma->ch, sgt->sgl, sgt->nents, desc = dmaengine_prep_slave_sg(dma->ch, sgt->sgl, sgt->nents,
dma->direction, DMA_PREP_INTERRUPT); dma->direction, DMA_PREP_INTERRUPT);
...@@ -322,7 +322,7 @@ static int prepare_dma(struct s3c64xx_spi_dma_data *dma, ...@@ -322,7 +322,7 @@ static int prepare_dma(struct s3c64xx_spi_dma_data *dma,
ret = dma_submit_error(dma->cookie); ret = dma_submit_error(dma->cookie);
if (ret) { if (ret) {
dev_err(&sdd->pdev->dev, "DMA submission failed"); dev_err(&sdd->pdev->dev, "DMA submission failed");
return -EIO; return ret;
} }
dma_async_issue_pending(dma->ch); dma_async_issue_pending(dma->ch);
...@@ -408,12 +408,10 @@ static bool s3c64xx_spi_can_dma(struct spi_controller *host, ...@@ -408,12 +408,10 @@ static bool s3c64xx_spi_can_dma(struct spi_controller *host,
{ {
struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host); struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host);
if (sdd->rx_dma.ch && sdd->tx_dma.ch) { if (sdd->rx_dma.ch && sdd->tx_dma.ch)
return xfer->len > FIFO_DEPTH(sdd); return xfer->len > FIFO_DEPTH(sdd);
} else {
return false;
}
return false;
} }
static void s3c64xx_iowrite8_32_rep(volatile void __iomem *addr, static void s3c64xx_iowrite8_32_rep(volatile void __iomem *addr,
...@@ -497,7 +495,7 @@ static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd, ...@@ -497,7 +495,7 @@ static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
chcfg |= S3C64XX_SPI_CH_TXCH_ON; chcfg |= S3C64XX_SPI_CH_TXCH_ON;
if (dma_mode) { if (dma_mode) {
modecfg |= S3C64XX_SPI_MODE_TXDMA_ON; modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
ret = prepare_dma(&sdd->tx_dma, &xfer->tx_sg); ret = s3c64xx_prepare_dma(&sdd->tx_dma, &xfer->tx_sg);
} else { } else {
s3c64xx_iowrite_rep(sdd, xfer); s3c64xx_iowrite_rep(sdd, xfer);
} }
...@@ -516,7 +514,7 @@ static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd, ...@@ -516,7 +514,7 @@ static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
| S3C64XX_SPI_PACKET_CNT_EN, | S3C64XX_SPI_PACKET_CNT_EN,
regs + S3C64XX_SPI_PACKET_CNT); regs + S3C64XX_SPI_PACKET_CNT);
ret = prepare_dma(&sdd->rx_dma, &xfer->rx_sg); ret = s3c64xx_prepare_dma(&sdd->rx_dma, &xfer->rx_sg);
} }
} }
...@@ -566,7 +564,7 @@ static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd, ...@@ -566,7 +564,7 @@ static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd,
/* /*
* If the previous xfer was completed within timeout, then * If the previous xfer was completed within timeout, then
* proceed further else return -EIO. * proceed further else return -ETIMEDOUT.
* DmaTx returns after simply writing data in the FIFO, * DmaTx returns after simply writing data in the FIFO,
* w/o waiting for real transmission on the bus to finish. * w/o waiting for real transmission on the bus to finish.
* DmaRx returns only after Dma read data from FIFO which * DmaRx returns only after Dma read data from FIFO which
...@@ -587,7 +585,7 @@ static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd, ...@@ -587,7 +585,7 @@ static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd,
/* If timed out while checking rx/tx status return error */ /* If timed out while checking rx/tx status return error */
if (!val) if (!val)
return -EIO; return -ETIMEDOUT;
return 0; return 0;
} }
...@@ -617,7 +615,7 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd, ...@@ -617,7 +615,7 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd,
if (use_irq) { if (use_irq) {
val = msecs_to_jiffies(ms); val = msecs_to_jiffies(ms);
if (!wait_for_completion_timeout(&sdd->xfer_completion, val)) if (!wait_for_completion_timeout(&sdd->xfer_completion, val))
return -EIO; return -ETIMEDOUT;
} }
val = msecs_to_loops(ms); val = msecs_to_loops(ms);
...@@ -1131,8 +1129,7 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd) ...@@ -1131,8 +1129,7 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd)
val = readl(regs + S3C64XX_SPI_MODE_CFG); val = readl(regs + S3C64XX_SPI_MODE_CFG);
val &= ~S3C64XX_SPI_MODE_4BURST; val &= ~S3C64XX_SPI_MODE_4BURST;
val &= ~(S3C64XX_SPI_MAX_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF); val |= (S3C64XX_SPI_MAX_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF);
val |= (S3C64XX_SPI_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF);
writel(val, regs + S3C64XX_SPI_MODE_CFG); writel(val, regs + S3C64XX_SPI_MODE_CFG);
s3c64xx_flush_fifo(sdd); s3c64xx_flush_fifo(sdd);
...@@ -1149,14 +1146,14 @@ static struct s3c64xx_spi_info *s3c64xx_spi_parse_dt(struct device *dev) ...@@ -1149,14 +1146,14 @@ static struct s3c64xx_spi_info *s3c64xx_spi_parse_dt(struct device *dev)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
if (of_property_read_u32(dev->of_node, "samsung,spi-src-clk", &temp)) { if (of_property_read_u32(dev->of_node, "samsung,spi-src-clk", &temp)) {
dev_warn(dev, "spi bus clock parent not specified, using clock at index 0 as parent\n"); dev_dbg(dev, "spi bus clock parent not specified, using clock at index 0 as parent\n");
sci->src_clk_nr = 0; sci->src_clk_nr = 0;
} else { } else {
sci->src_clk_nr = temp; sci->src_clk_nr = temp;
} }
if (of_property_read_u32(dev->of_node, "num-cs", &temp)) { if (of_property_read_u32(dev->of_node, "num-cs", &temp)) {
dev_warn(dev, "number of chip select lines not specified, assuming 1 chip select line\n"); dev_dbg(dev, "number of chip select lines not specified, assuming 1 chip select line\n");
sci->num_cs = 1; sci->num_cs = 1;
} else { } else {
sci->num_cs = temp; sci->num_cs = temp;
...@@ -1226,6 +1223,9 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) ...@@ -1226,6 +1223,9 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
"Failed to get alias id\n"); "Failed to get alias id\n");
sdd->port_id = ret; sdd->port_id = ret;
} else { } else {
if (pdev->id < 0)
return dev_err_probe(&pdev->dev, -EINVAL,
"Negative platform ID is not allowed\n");
sdd->port_id = pdev->id; sdd->port_id = pdev->id;
} }
...@@ -1357,8 +1357,9 @@ static int s3c64xx_spi_suspend(struct device *dev) ...@@ -1357,8 +1357,9 @@ static int s3c64xx_spi_suspend(struct device *dev)
{ {
struct spi_controller *host = dev_get_drvdata(dev); struct spi_controller *host = dev_get_drvdata(dev);
struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host); struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host);
int ret;
int ret = spi_controller_suspend(host); ret = spi_controller_suspend(host);
if (ret) if (ret)
return ret; return ret;
...@@ -1563,31 +1564,31 @@ static const struct of_device_id s3c64xx_spi_dt_match[] = { ...@@ -1563,31 +1564,31 @@ static const struct of_device_id s3c64xx_spi_dt_match[] = {
.data = &gs101_spi_port_config, .data = &gs101_spi_port_config,
}, },
{ .compatible = "samsung,s3c2443-spi", { .compatible = "samsung,s3c2443-spi",
.data = (void *)&s3c2443_spi_port_config, .data = &s3c2443_spi_port_config,
}, },
{ .compatible = "samsung,s3c6410-spi", { .compatible = "samsung,s3c6410-spi",
.data = (void *)&s3c6410_spi_port_config, .data = &s3c6410_spi_port_config,
}, },
{ .compatible = "samsung,s5pv210-spi", { .compatible = "samsung,s5pv210-spi",
.data = (void *)&s5pv210_spi_port_config, .data = &s5pv210_spi_port_config,
}, },
{ .compatible = "samsung,exynos4210-spi", { .compatible = "samsung,exynos4210-spi",
.data = (void *)&exynos4_spi_port_config, .data = &exynos4_spi_port_config,
}, },
{ .compatible = "samsung,exynos7-spi", { .compatible = "samsung,exynos7-spi",
.data = (void *)&exynos7_spi_port_config, .data = &exynos7_spi_port_config,
}, },
{ .compatible = "samsung,exynos5433-spi", { .compatible = "samsung,exynos5433-spi",
.data = (void *)&exynos5433_spi_port_config, .data = &exynos5433_spi_port_config,
}, },
{ .compatible = "samsung,exynos850-spi", { .compatible = "samsung,exynos850-spi",
.data = (void *)&exynos850_spi_port_config, .data = &exynos850_spi_port_config,
}, },
{ .compatible = "samsung,exynosautov9-spi", { .compatible = "samsung,exynosautov9-spi",
.data = (void *)&exynosautov9_spi_port_config, .data = &exynosautov9_spi_port_config,
}, },
{ .compatible = "tesla,fsd-spi", { .compatible = "tesla,fsd-spi",
.data = (void *)&fsd_spi_port_config, .data = &fsd_spi_port_config,
}, },
{ }, { },
}; };
......
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