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

Merge remote-tracking branches 'spi/topic/bcm53xx', 'spi/topic/cadence',...

Merge remote-tracking branches 'spi/topic/bcm53xx', 'spi/topic/cadence', 'spi/topic/davinci' and 'spi/topic/dln2' into spi-next
...@@ -525,7 +525,6 @@ static int spi_engine_probe(struct platform_device *pdev) ...@@ -525,7 +525,6 @@ static int spi_engine_probe(struct platform_device *pdev)
if (ret) if (ret)
goto err_ref_clk_disable; goto err_ref_clk_disable;
master->dev.parent = &pdev->dev;
master->dev.of_node = pdev->dev.of_node; master->dev.of_node = pdev->dev.of_node;
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_3WIRE; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_3WIRE;
master->bits_per_word_mask = SPI_BPW_MASK(8); master->bits_per_word_mask = SPI_BPW_MASK(8);
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "spi-bcm53xx.h" #include "spi-bcm53xx.h"
#define BCM53XXSPI_MAX_SPI_BAUD 13500000 /* 216 MHz? */ #define BCM53XXSPI_MAX_SPI_BAUD 13500000 /* 216 MHz? */
#define BCM53XXSPI_FLASH_WINDOW SZ_32M
/* The longest observed required wait was 19 ms */ /* The longest observed required wait was 19 ms */
#define BCM53XXSPI_SPE_TIMEOUT_MS 80 #define BCM53XXSPI_SPE_TIMEOUT_MS 80
...@@ -17,8 +18,10 @@ ...@@ -17,8 +18,10 @@
struct bcm53xxspi { struct bcm53xxspi {
struct bcma_device *core; struct bcma_device *core;
struct spi_master *master; struct spi_master *master;
void __iomem *mmio_base;
size_t read_offset; size_t read_offset;
bool bspi; /* Boot SPI mode with memory mapping */
}; };
static inline u32 bcm53xxspi_read(struct bcm53xxspi *b53spi, u16 offset) static inline u32 bcm53xxspi_read(struct bcm53xxspi *b53spi, u16 offset)
...@@ -32,6 +35,50 @@ static inline void bcm53xxspi_write(struct bcm53xxspi *b53spi, u16 offset, ...@@ -32,6 +35,50 @@ static inline void bcm53xxspi_write(struct bcm53xxspi *b53spi, u16 offset,
bcma_write32(b53spi->core, offset, value); bcma_write32(b53spi->core, offset, value);
} }
static void bcm53xxspi_disable_bspi(struct bcm53xxspi *b53spi)
{
struct device *dev = &b53spi->core->dev;
unsigned long deadline;
u32 tmp;
if (!b53spi->bspi)
return;
tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL);
if (tmp & 0x1)
return;
deadline = jiffies + usecs_to_jiffies(200);
do {
tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_BUSY_STATUS);
if (!(tmp & 0x1)) {
bcm53xxspi_write(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL,
0x1);
ndelay(200);
b53spi->bspi = false;
return;
}
udelay(1);
} while (!time_after_eq(jiffies, deadline));
dev_warn(dev, "Timeout disabling BSPI\n");
}
static void bcm53xxspi_enable_bspi(struct bcm53xxspi *b53spi)
{
u32 tmp;
if (b53spi->bspi)
return;
tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL);
if (!(tmp & 0x1))
return;
bcm53xxspi_write(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL, 0x0);
b53spi->bspi = true;
}
static inline unsigned int bcm53xxspi_calc_timeout(size_t len) static inline unsigned int bcm53xxspi_calc_timeout(size_t len)
{ {
/* Do some magic calculation based on length and buad. Add 10% and 1. */ /* Do some magic calculation based on length and buad. Add 10% and 1. */
...@@ -176,6 +223,8 @@ static int bcm53xxspi_transfer_one(struct spi_master *master, ...@@ -176,6 +223,8 @@ static int bcm53xxspi_transfer_one(struct spi_master *master,
u8 *buf; u8 *buf;
size_t left; size_t left;
bcm53xxspi_disable_bspi(b53spi);
if (t->tx_buf) { if (t->tx_buf) {
buf = (u8 *)t->tx_buf; buf = (u8 *)t->tx_buf;
left = t->len; left = t->len;
...@@ -206,6 +255,22 @@ static int bcm53xxspi_transfer_one(struct spi_master *master, ...@@ -206,6 +255,22 @@ static int bcm53xxspi_transfer_one(struct spi_master *master,
return 0; return 0;
} }
static int bcm53xxspi_flash_read(struct spi_device *spi,
struct spi_flash_read_message *msg)
{
struct bcm53xxspi *b53spi = spi_master_get_devdata(spi->master);
int ret = 0;
if (msg->from + msg->len > BCM53XXSPI_FLASH_WINDOW)
return -EINVAL;
bcm53xxspi_enable_bspi(b53spi);
memcpy_fromio(msg->buf, b53spi->mmio_base + msg->from, msg->len);
msg->retlen = msg->len;
return ret;
}
/************************************************** /**************************************************
* BCMA * BCMA
**************************************************/ **************************************************/
...@@ -222,6 +287,7 @@ MODULE_DEVICE_TABLE(bcma, bcm53xxspi_bcma_tbl); ...@@ -222,6 +287,7 @@ MODULE_DEVICE_TABLE(bcma, bcm53xxspi_bcma_tbl);
static int bcm53xxspi_bcma_probe(struct bcma_device *core) static int bcm53xxspi_bcma_probe(struct bcma_device *core)
{ {
struct device *dev = &core->dev;
struct bcm53xxspi *b53spi; struct bcm53xxspi *b53spi;
struct spi_master *master; struct spi_master *master;
int err; int err;
...@@ -231,7 +297,7 @@ static int bcm53xxspi_bcma_probe(struct bcma_device *core) ...@@ -231,7 +297,7 @@ static int bcm53xxspi_bcma_probe(struct bcma_device *core)
return -ENOTSUPP; return -ENOTSUPP;
} }
master = spi_alloc_master(&core->dev, sizeof(*b53spi)); master = spi_alloc_master(dev, sizeof(*b53spi));
if (!master) if (!master)
return -ENOMEM; return -ENOMEM;
...@@ -239,11 +305,19 @@ static int bcm53xxspi_bcma_probe(struct bcma_device *core) ...@@ -239,11 +305,19 @@ static int bcm53xxspi_bcma_probe(struct bcma_device *core)
b53spi->master = master; b53spi->master = master;
b53spi->core = core; b53spi->core = core;
if (core->addr_s[0])
b53spi->mmio_base = devm_ioremap(dev, core->addr_s[0],
BCM53XXSPI_FLASH_WINDOW);
b53spi->bspi = true;
bcm53xxspi_disable_bspi(b53spi);
master->transfer_one = bcm53xxspi_transfer_one; master->transfer_one = bcm53xxspi_transfer_one;
if (b53spi->mmio_base)
master->spi_flash_read = bcm53xxspi_flash_read;
bcma_set_drvdata(core, b53spi); bcma_set_drvdata(core, b53spi);
err = devm_spi_register_master(&core->dev, master); err = devm_spi_register_master(dev, master);
if (err) { if (err) {
spi_master_put(master); spi_master_put(master);
bcma_set_drvdata(core, NULL); bcma_set_drvdata(core, NULL);
......
This diff is collapsed.
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/dmaengine.h> #include <linux/dmaengine.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/edma.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
...@@ -33,8 +32,6 @@ ...@@ -33,8 +32,6 @@
#include <linux/platform_data/spi-davinci.h> #include <linux/platform_data/spi-davinci.h>
#define SPI_NO_RESOURCE ((resource_size_t)-1)
#define CS_DEFAULT 0xFF #define CS_DEFAULT 0xFF
#define SPIFMT_PHASE_MASK BIT(16) #define SPIFMT_PHASE_MASK BIT(16)
...@@ -130,8 +127,6 @@ struct davinci_spi { ...@@ -130,8 +127,6 @@ struct davinci_spi {
struct dma_chan *dma_rx; struct dma_chan *dma_rx;
struct dma_chan *dma_tx; struct dma_chan *dma_tx;
int dma_rx_chnum;
int dma_tx_chnum;
struct davinci_spi_platform_data pdata; struct davinci_spi_platform_data pdata;
...@@ -797,35 +792,19 @@ static irqreturn_t davinci_spi_irq(s32 irq, void *data) ...@@ -797,35 +792,19 @@ static irqreturn_t davinci_spi_irq(s32 irq, void *data)
static int davinci_spi_request_dma(struct davinci_spi *dspi) static int davinci_spi_request_dma(struct davinci_spi *dspi)
{ {
dma_cap_mask_t mask;
struct device *sdev = dspi->bitbang.master->dev.parent; struct device *sdev = dspi->bitbang.master->dev.parent;
int r;
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
dspi->dma_rx = dma_request_channel(mask, edma_filter_fn, dspi->dma_rx = dma_request_chan(sdev, "rx");
&dspi->dma_rx_chnum); if (IS_ERR(dspi->dma_rx))
if (!dspi->dma_rx) { return PTR_ERR(dspi->dma_rx);
dev_err(sdev, "request RX DMA channel failed\n");
r = -ENODEV;
goto rx_dma_failed;
}
dspi->dma_tx = dma_request_channel(mask, edma_filter_fn, dspi->dma_tx = dma_request_chan(sdev, "tx");
&dspi->dma_tx_chnum); if (IS_ERR(dspi->dma_tx)) {
if (!dspi->dma_tx) { dma_release_channel(dspi->dma_rx);
dev_err(sdev, "request TX DMA channel failed\n"); return PTR_ERR(dspi->dma_tx);
r = -ENODEV;
goto tx_dma_failed;
} }
return 0; return 0;
tx_dma_failed:
dma_release_channel(dspi->dma_rx);
rx_dma_failed:
return r;
} }
#if defined(CONFIG_OF) #if defined(CONFIG_OF)
...@@ -936,8 +915,6 @@ static int davinci_spi_probe(struct platform_device *pdev) ...@@ -936,8 +915,6 @@ static int davinci_spi_probe(struct platform_device *pdev)
struct davinci_spi *dspi; struct davinci_spi *dspi;
struct davinci_spi_platform_data *pdata; struct davinci_spi_platform_data *pdata;
struct resource *r; struct resource *r;
resource_size_t dma_rx_chan = SPI_NO_RESOURCE;
resource_size_t dma_tx_chan = SPI_NO_RESOURCE;
int ret = 0; int ret = 0;
u32 spipc0; u32 spipc0;
...@@ -1044,27 +1021,15 @@ static int davinci_spi_probe(struct platform_device *pdev) ...@@ -1044,27 +1021,15 @@ static int davinci_spi_probe(struct platform_device *pdev)
} }
} }
r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
if (r)
dma_rx_chan = r->start;
r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
if (r)
dma_tx_chan = r->start;
dspi->bitbang.txrx_bufs = davinci_spi_bufs; dspi->bitbang.txrx_bufs = davinci_spi_bufs;
if (dma_rx_chan != SPI_NO_RESOURCE &&
dma_tx_chan != SPI_NO_RESOURCE) { ret = davinci_spi_request_dma(dspi);
dspi->dma_rx_chnum = dma_rx_chan; if (ret == -EPROBE_DEFER) {
dspi->dma_tx_chnum = dma_tx_chan; goto free_clk;
} else if (ret) {
ret = davinci_spi_request_dma(dspi); dev_info(&pdev->dev, "DMA is not supported (%d)\n", ret);
if (ret) dspi->dma_rx = NULL;
goto free_clk; dspi->dma_tx = NULL;
dev_info(&pdev->dev, "DMA: supported\n");
dev_info(&pdev->dev, "DMA: RX channel: %pa, TX channel: %pa, event queue: %d\n",
&dma_rx_chan, &dma_tx_chan,
pdata->dma_event_q);
} }
dspi->get_rx = davinci_spi_rx_buf_u8; dspi->get_rx = davinci_spi_rx_buf_u8;
...@@ -1102,8 +1067,10 @@ static int davinci_spi_probe(struct platform_device *pdev) ...@@ -1102,8 +1067,10 @@ static int davinci_spi_probe(struct platform_device *pdev)
return ret; return ret;
free_dma: free_dma:
dma_release_channel(dspi->dma_rx); if (dspi->dma_rx) {
dma_release_channel(dspi->dma_tx); dma_release_channel(dspi->dma_rx);
dma_release_channel(dspi->dma_tx);
}
free_clk: free_clk:
clk_disable_unprepare(dspi->clk); clk_disable_unprepare(dspi->clk);
free_master: free_master:
...@@ -1134,6 +1101,11 @@ static int davinci_spi_remove(struct platform_device *pdev) ...@@ -1134,6 +1101,11 @@ static int davinci_spi_remove(struct platform_device *pdev)
clk_disable_unprepare(dspi->clk); clk_disable_unprepare(dspi->clk);
spi_master_put(master); spi_master_put(master);
if (dspi->dma_rx) {
dma_release_channel(dspi->dma_rx);
dma_release_channel(dspi->dma_tx);
}
return 0; return 0;
} }
......
...@@ -683,6 +683,7 @@ static int dln2_spi_probe(struct platform_device *pdev) ...@@ -683,6 +683,7 @@ static int dln2_spi_probe(struct platform_device *pdev)
struct spi_master *master; struct spi_master *master;
struct dln2_spi *dln2; struct dln2_spi *dln2;
struct dln2_platform_data *pdata = dev_get_platdata(&pdev->dev); struct dln2_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct device *dev = &pdev->dev;
int ret; int ret;
master = spi_alloc_master(&pdev->dev, sizeof(*dln2)); master = spi_alloc_master(&pdev->dev, sizeof(*dln2));
...@@ -700,6 +701,7 @@ static int dln2_spi_probe(struct platform_device *pdev) ...@@ -700,6 +701,7 @@ static int dln2_spi_probe(struct platform_device *pdev)
} }
dln2->master = master; dln2->master = master;
dln2->master->dev.of_node = dev->of_node;
dln2->pdev = pdev; dln2->pdev = pdev;
dln2->port = pdata->port; dln2->port = pdata->port;
/* cs/mode can never be 0xff, so the first transfer will set them */ /* cs/mode can never be 0xff, so the first transfer will set them */
......
...@@ -1543,7 +1543,6 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) ...@@ -1543,7 +1543,6 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
drv_data->pdev = pdev; drv_data->pdev = pdev;
drv_data->ssp = ssp; drv_data->ssp = ssp;
master->dev.parent = &pdev->dev;
master->dev.of_node = pdev->dev.of_node; master->dev.of_node = pdev->dev.of_node;
/* the spi->mode bits understood by this driver: */ /* the spi->mode bits understood by this driver: */
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
......
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