Commit 2016d52a authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'spi/topic/imx', 'spi/topic/lantiq-ssc',...

Merge remote-tracking branches 'spi/topic/imx', 'spi/topic/lantiq-ssc', 'spi/topic/mpc52xx', 'spi/topic/ppc4xx' and 'spi/topic/pxa2xx' into spi-next
Lantiq Synchronous Serial Controller (SSC) SPI master driver
Required properties:
- compatible: "lantiq,ase-spi", "lantiq,falcon-spi", "lantiq,xrx100-spi"
- #address-cells: see spi-bus.txt
- #size-cells: see spi-bus.txt
- reg: address and length of the spi master registers
- interrupts: should contain the "spi_rx", "spi_tx" and "spi_err" interrupt.
Optional properties:
- clocks: spi clock phandle
- num-cs: see spi-bus.txt, set to 8 if unset
- base-cs: the number of the first chip select, set to 1 if unset.
Example:
spi: spi@E100800 {
compatible = "lantiq,xrx200-spi", "lantiq,xrx100-spi";
reg = <0xE100800 0x100>;
interrupt-parent = <&icu0>;
interrupts = <22 23 24>;
interrupt-names = "spi_rx", "spi_tx", "spi_err";
#address-cells = <1>;
#size-cells = <1>;
num-cs = <6>;
base-cs = <1>;
};
...@@ -417,6 +417,14 @@ config SPI_NUC900 ...@@ -417,6 +417,14 @@ config SPI_NUC900
help help
SPI driver for Nuvoton NUC900 series ARM SoCs SPI driver for Nuvoton NUC900 series ARM SoCs
config SPI_LANTIQ_SSC
tristate "Lantiq SSC SPI controller"
depends on LANTIQ || COMPILE_TEST
help
This driver supports the Lantiq SSC SPI controller in master
mode. This controller is found on Intel (former Lantiq) SoCs like
the Danube, Falcon, xRX200, xRX300.
config SPI_OC_TINY config SPI_OC_TINY
tristate "OpenCores tiny SPI" tristate "OpenCores tiny SPI"
depends on GPIOLIB || COMPILE_TEST depends on GPIOLIB || COMPILE_TEST
......
...@@ -49,6 +49,7 @@ obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o ...@@ -49,6 +49,7 @@ obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o
obj-$(CONFIG_SPI_GPIO) += spi-gpio.o obj-$(CONFIG_SPI_GPIO) += spi-gpio.o
obj-$(CONFIG_SPI_IMG_SPFI) += spi-img-spfi.o obj-$(CONFIG_SPI_IMG_SPFI) += spi-img-spfi.o
obj-$(CONFIG_SPI_IMX) += spi-imx.o obj-$(CONFIG_SPI_IMX) += spi-imx.o
obj-$(CONFIG_SPI_LANTIQ_SSC) += spi-lantiq-ssc.o
obj-$(CONFIG_SPI_JCORE) += spi-jcore.o obj-$(CONFIG_SPI_JCORE) += spi-jcore.o
obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o
obj-$(CONFIG_SPI_LP8841_RTC) += spi-lp8841-rtc.o obj-$(CONFIG_SPI_LP8841_RTC) += spi-lp8841-rtc.o
......
...@@ -211,7 +211,7 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, ...@@ -211,7 +211,7 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
struct spi_transfer *transfer) struct spi_transfer *transfer)
{ {
struct spi_imx_data *spi_imx = spi_master_get_devdata(master); struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
unsigned int bpw; unsigned int bpw, i;
if (!master->dma_rx) if (!master->dma_rx)
return false; return false;
...@@ -228,12 +228,16 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, ...@@ -228,12 +228,16 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
if (bpw != 1 && bpw != 2 && bpw != 4) if (bpw != 1 && bpw != 2 && bpw != 4)
return false; return false;
if (transfer->len < spi_imx->wml * bpw) for (i = spi_imx_get_fifosize(spi_imx) / 2; i > 0; i--) {
return false; if (!(transfer->len % (i * bpw)))
break;
}
if (transfer->len % (spi_imx->wml * bpw)) if (i == 0)
return false; return false;
spi_imx->wml = i;
return true; return true;
} }
...@@ -837,10 +841,6 @@ static int spi_imx_dma_configure(struct spi_master *master, ...@@ -837,10 +841,6 @@ static int spi_imx_dma_configure(struct spi_master *master,
struct dma_slave_config rx = {}, tx = {}; struct dma_slave_config rx = {}, tx = {};
struct spi_imx_data *spi_imx = spi_master_get_devdata(master); struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
if (bytes_per_word == spi_imx->bytes_per_word)
/* Same as last time */
return 0;
switch (bytes_per_word) { switch (bytes_per_word) {
case 4: case 4:
buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES; buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
......
This diff is collapsed.
...@@ -437,7 +437,8 @@ static int mpc52xx_spi_probe(struct platform_device *op) ...@@ -437,7 +437,8 @@ static int mpc52xx_spi_probe(struct platform_device *op)
ms->gpio_cs_count = of_gpio_count(op->dev.of_node); ms->gpio_cs_count = of_gpio_count(op->dev.of_node);
if (ms->gpio_cs_count > 0) { if (ms->gpio_cs_count > 0) {
master->num_chipselect = ms->gpio_cs_count; master->num_chipselect = ms->gpio_cs_count;
ms->gpio_cs = kmalloc(ms->gpio_cs_count * sizeof(unsigned int), ms->gpio_cs = kmalloc_array(ms->gpio_cs_count,
sizeof(*ms->gpio_cs),
GFP_KERNEL); GFP_KERNEL);
if (!ms->gpio_cs) { if (!ms->gpio_cs) {
rc = -ENOMEM; rc = -ENOMEM;
...@@ -448,8 +449,7 @@ static int mpc52xx_spi_probe(struct platform_device *op) ...@@ -448,8 +449,7 @@ static int mpc52xx_spi_probe(struct platform_device *op)
gpio_cs = of_get_gpio(op->dev.of_node, i); gpio_cs = of_get_gpio(op->dev.of_node, i);
if (gpio_cs < 0) { if (gpio_cs < 0) {
dev_err(&op->dev, dev_err(&op->dev,
"could not parse the gpio field " "could not parse the gpio field in oftree\n");
"in oftree\n");
rc = -ENODEV; rc = -ENODEV;
goto err_gpio; goto err_gpio;
} }
...@@ -457,8 +457,8 @@ static int mpc52xx_spi_probe(struct platform_device *op) ...@@ -457,8 +457,8 @@ static int mpc52xx_spi_probe(struct platform_device *op)
rc = gpio_request(gpio_cs, dev_name(&op->dev)); rc = gpio_request(gpio_cs, dev_name(&op->dev));
if (rc) { if (rc) {
dev_err(&op->dev, dev_err(&op->dev,
"can't request spi cs gpio #%d " "can't request spi cs gpio #%d on gpio line %d\n",
"on gpio line %d\n", i, gpio_cs); i, gpio_cs);
goto err_gpio; goto err_gpio;
} }
......
...@@ -411,7 +411,7 @@ static int spi_ppc4xx_of_probe(struct platform_device *op) ...@@ -411,7 +411,7 @@ static int spi_ppc4xx_of_probe(struct platform_device *op)
if (num_gpios > 0) { if (num_gpios > 0) {
int i; int i;
hw->gpios = kzalloc(sizeof(int) * num_gpios, GFP_KERNEL); hw->gpios = kcalloc(num_gpios, sizeof(*hw->gpios), GFP_KERNEL);
if (!hw->gpios) { if (!hw->gpios) {
ret = -ENOMEM; ret = -ENOMEM;
goto free_master; goto free_master;
...@@ -428,8 +428,9 @@ static int spi_ppc4xx_of_probe(struct platform_device *op) ...@@ -428,8 +428,9 @@ static int spi_ppc4xx_of_probe(struct platform_device *op)
/* Real CS - set the initial state. */ /* Real CS - set the initial state. */
ret = gpio_request(gpio, np->name); ret = gpio_request(gpio, np->name);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "can't request gpio " dev_err(dev,
"#%d: %d\n", i, ret); "can't request gpio #%d: %d\n",
i, ret);
goto free_gpios; goto free_gpios;
} }
......
...@@ -41,6 +41,13 @@ struct pxa_spi_info { ...@@ -41,6 +41,13 @@ struct pxa_spi_info {
static struct dw_dma_slave byt_tx_param = { .dst_id = 0 }; static struct dw_dma_slave byt_tx_param = { .dst_id = 0 };
static struct dw_dma_slave byt_rx_param = { .src_id = 1 }; static struct dw_dma_slave byt_rx_param = { .src_id = 1 };
static struct dw_dma_slave mrfld3_tx_param = { .dst_id = 15 };
static struct dw_dma_slave mrfld3_rx_param = { .src_id = 14 };
static struct dw_dma_slave mrfld5_tx_param = { .dst_id = 13 };
static struct dw_dma_slave mrfld5_rx_param = { .src_id = 12 };
static struct dw_dma_slave mrfld6_tx_param = { .dst_id = 11 };
static struct dw_dma_slave mrfld6_rx_param = { .src_id = 10 };
static struct dw_dma_slave bsw0_tx_param = { .dst_id = 0 }; static struct dw_dma_slave bsw0_tx_param = { .dst_id = 0 };
static struct dw_dma_slave bsw0_rx_param = { .src_id = 1 }; static struct dw_dma_slave bsw0_rx_param = { .src_id = 1 };
static struct dw_dma_slave bsw1_tx_param = { .dst_id = 6 }; static struct dw_dma_slave bsw1_tx_param = { .dst_id = 6 };
...@@ -93,22 +100,39 @@ static int lpss_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c) ...@@ -93,22 +100,39 @@ static int lpss_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c)
static int mrfld_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c) static int mrfld_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c)
{ {
struct pci_dev *dma_dev = pci_get_slot(dev->bus, PCI_DEVFN(21, 0));
struct dw_dma_slave *tx, *rx;
switch (PCI_FUNC(dev->devfn)) { switch (PCI_FUNC(dev->devfn)) {
case 0: case 0:
c->port_id = 3; c->port_id = 3;
c->num_chipselect = 1; c->num_chipselect = 1;
c->tx_param = &mrfld3_tx_param;
c->rx_param = &mrfld3_rx_param;
break; break;
case 1: case 1:
c->port_id = 5; c->port_id = 5;
c->num_chipselect = 4; c->num_chipselect = 4;
c->tx_param = &mrfld5_tx_param;
c->rx_param = &mrfld5_rx_param;
break; break;
case 2: case 2:
c->port_id = 6; c->port_id = 6;
c->num_chipselect = 1; c->num_chipselect = 1;
c->tx_param = &mrfld6_tx_param;
c->rx_param = &mrfld6_rx_param;
break; break;
default: default:
return -ENODEV; return -ENODEV;
} }
tx = c->tx_param;
tx->dma_dev = &dma_dev->dev;
rx = c->rx_param;
rx->dma_dev = &dma_dev->dev;
c->dma_filter = lpss_dma_filter;
return 0; return 0;
} }
...@@ -203,10 +227,16 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, ...@@ -203,10 +227,16 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev,
ssp = &spi_pdata.ssp; ssp = &spi_pdata.ssp;
ssp->phys_base = pci_resource_start(dev, 0); ssp->phys_base = pci_resource_start(dev, 0);
ssp->mmio_base = pcim_iomap_table(dev)[0]; ssp->mmio_base = pcim_iomap_table(dev)[0];
ssp->irq = dev->irq;
ssp->port_id = (c->port_id >= 0) ? c->port_id : dev->devfn; ssp->port_id = (c->port_id >= 0) ? c->port_id : dev->devfn;
ssp->type = c->type; ssp->type = c->type;
pci_set_master(dev);
ret = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_ALL_TYPES);
if (ret < 0)
return ret;
ssp->irq = pci_irq_vector(dev, 0);
snprintf(buf, sizeof(buf), "pxa2xx-spi.%d", ssp->port_id); snprintf(buf, sizeof(buf), "pxa2xx-spi.%d", ssp->port_id);
ssp->clk = clk_register_fixed_rate(&dev->dev, buf , NULL, 0, ssp->clk = clk_register_fixed_rate(&dev->dev, buf , NULL, 0,
c->max_clk_rate); c->max_clk_rate);
......
...@@ -732,6 +732,20 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data) ...@@ -732,6 +732,20 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static void handle_bad_msg(struct driver_data *drv_data)
{
pxa2xx_spi_write(drv_data, SSCR0,
pxa2xx_spi_read(drv_data, SSCR0) & ~SSCR0_SSE);
pxa2xx_spi_write(drv_data, SSCR1,
pxa2xx_spi_read(drv_data, SSCR1) & ~drv_data->int_cr1);
if (!pxa25x_ssp_comp(drv_data))
pxa2xx_spi_write(drv_data, SSTO, 0);
write_SSSR_CS(drv_data, drv_data->clear_sr);
dev_err(&drv_data->pdev->dev,
"bad message state in interrupt handler\n");
}
static irqreturn_t ssp_int(int irq, void *dev_id) static irqreturn_t ssp_int(int irq, void *dev_id)
{ {
struct driver_data *drv_data = dev_id; struct driver_data *drv_data = dev_id;
...@@ -771,21 +785,11 @@ static irqreturn_t ssp_int(int irq, void *dev_id) ...@@ -771,21 +785,11 @@ static irqreturn_t ssp_int(int irq, void *dev_id)
if (!(status & mask)) if (!(status & mask))
return IRQ_NONE; return IRQ_NONE;
if (!drv_data->master->cur_msg) { pxa2xx_spi_write(drv_data, SSCR1, sccr1_reg & ~drv_data->int_cr1);
pxa2xx_spi_write(drv_data, SSCR1, sccr1_reg);
pxa2xx_spi_write(drv_data, SSCR0,
pxa2xx_spi_read(drv_data, SSCR0)
& ~SSCR0_SSE);
pxa2xx_spi_write(drv_data, SSCR1,
pxa2xx_spi_read(drv_data, SSCR1)
& ~drv_data->int_cr1);
if (!pxa25x_ssp_comp(drv_data))
pxa2xx_spi_write(drv_data, SSTO, 0);
write_SSSR_CS(drv_data, drv_data->clear_sr);
dev_err(&drv_data->pdev->dev,
"bad message state in interrupt handler\n");
if (!drv_data->master->cur_msg) {
handle_bad_msg(drv_data);
/* Never fail */ /* Never fail */
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -714,9 +714,10 @@ static int ti_qspi_probe(struct platform_device *pdev) ...@@ -714,9 +714,10 @@ static int ti_qspi_probe(struct platform_device *pdev)
dma_cap_set(DMA_MEMCPY, mask); dma_cap_set(DMA_MEMCPY, mask);
qspi->rx_chan = dma_request_chan_by_mask(&mask); qspi->rx_chan = dma_request_chan_by_mask(&mask);
if (!qspi->rx_chan) { if (IS_ERR(qspi->rx_chan)) {
dev_err(qspi->dev, dev_err(qspi->dev,
"No Rx DMA available, trying mmap mode\n"); "No Rx DMA available, trying mmap mode\n");
qspi->rx_chan = NULL;
ret = 0; ret = 0;
goto no_dma; goto no_dma;
} }
......
...@@ -106,7 +106,7 @@ ...@@ -106,7 +106,7 @@
#define CE4100_SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..4] */ #define CE4100_SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..4] */
/* QUARK_X1000 SSCR0 bit definition */ /* QUARK_X1000 SSCR0 bit definition */
#define QUARK_X1000_SSCR0_DSS (0x1F) /* Data Size Select (mask) */ #define QUARK_X1000_SSCR0_DSS (0x1F << 0) /* Data Size Select (mask) */
#define QUARK_X1000_SSCR0_DataSize(x) ((x) - 1) /* Data Size Select [4..32] */ #define QUARK_X1000_SSCR0_DataSize(x) ((x) - 1) /* Data Size Select [4..32] */
#define QUARK_X1000_SSCR0_FRF (0x3 << 5) /* FRame Format (mask) */ #define QUARK_X1000_SSCR0_FRF (0x3 << 5) /* FRame Format (mask) */
#define QUARK_X1000_SSCR0_Motorola (0x0 << 5) /* Motorola's Serial Peripheral Interface (SPI) */ #define QUARK_X1000_SSCR0_Motorola (0x0 << 5) /* Motorola's Serial Peripheral Interface (SPI) */
......
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