mirror of
https://github.com/Dasharo/linux.git
synced 2026-03-06 15:25:10 -08:00
Merge remote-tracking branches 'spi/topic/imx', 'spi/topic/lantiq-ssc', 'spi/topic/mpc52xx', 'spi/topic/ppc4xx' and 'spi/topic/pxa2xx' into spi-next
This commit is contained in:
29
Documentation/devicetree/bindings/spi/spi-lantiq-ssc.txt
Normal file
29
Documentation/devicetree/bindings/spi/spi-lantiq-ssc.txt
Normal file
@@ -0,0 +1,29 @@
|
||||
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
|
||||
help
|
||||
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
|
||||
tristate "OpenCores tiny SPI"
|
||||
depends on GPIOLIB || COMPILE_TEST
|
||||
|
||||
@@ -49,6 +49,7 @@ obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o
|
||||
obj-$(CONFIG_SPI_GPIO) += spi-gpio.o
|
||||
obj-$(CONFIG_SPI_IMG_SPFI) += spi-img-spfi.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_LM70_LLP) += spi-lm70llp.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,
|
||||
struct spi_transfer *transfer)
|
||||
{
|
||||
struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
|
||||
unsigned int bpw;
|
||||
unsigned int bpw, i;
|
||||
|
||||
if (!master->dma_rx)
|
||||
return false;
|
||||
@@ -228,11 +228,15 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
|
||||
if (bpw != 1 && bpw != 2 && bpw != 4)
|
||||
return false;
|
||||
|
||||
if (transfer->len < spi_imx->wml * bpw)
|
||||
for (i = spi_imx_get_fifosize(spi_imx) / 2; i > 0; i--) {
|
||||
if (!(transfer->len % (i * bpw)))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
return false;
|
||||
|
||||
if (transfer->len % (spi_imx->wml * bpw))
|
||||
return false;
|
||||
spi_imx->wml = i;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -837,10 +841,6 @@ static int spi_imx_dma_configure(struct spi_master *master,
|
||||
struct dma_slave_config rx = {}, tx = {};
|
||||
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) {
|
||||
case 4:
|
||||
buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
|
||||
983
drivers/spi/spi-lantiq-ssc.c
Normal file
983
drivers/spi/spi-lantiq-ssc.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -437,8 +437,9 @@ static int mpc52xx_spi_probe(struct platform_device *op)
|
||||
ms->gpio_cs_count = of_gpio_count(op->dev.of_node);
|
||||
if (ms->gpio_cs_count > 0) {
|
||||
master->num_chipselect = ms->gpio_cs_count;
|
||||
ms->gpio_cs = kmalloc(ms->gpio_cs_count * sizeof(unsigned int),
|
||||
GFP_KERNEL);
|
||||
ms->gpio_cs = kmalloc_array(ms->gpio_cs_count,
|
||||
sizeof(*ms->gpio_cs),
|
||||
GFP_KERNEL);
|
||||
if (!ms->gpio_cs) {
|
||||
rc = -ENOMEM;
|
||||
goto err_alloc_gpio;
|
||||
@@ -448,8 +449,7 @@ static int mpc52xx_spi_probe(struct platform_device *op)
|
||||
gpio_cs = of_get_gpio(op->dev.of_node, i);
|
||||
if (gpio_cs < 0) {
|
||||
dev_err(&op->dev,
|
||||
"could not parse the gpio field "
|
||||
"in oftree\n");
|
||||
"could not parse the gpio field in oftree\n");
|
||||
rc = -ENODEV;
|
||||
goto err_gpio;
|
||||
}
|
||||
@@ -457,8 +457,8 @@ static int mpc52xx_spi_probe(struct platform_device *op)
|
||||
rc = gpio_request(gpio_cs, dev_name(&op->dev));
|
||||
if (rc) {
|
||||
dev_err(&op->dev,
|
||||
"can't request spi cs gpio #%d "
|
||||
"on gpio line %d\n", i, gpio_cs);
|
||||
"can't request spi cs gpio #%d on gpio line %d\n",
|
||||
i, gpio_cs);
|
||||
goto err_gpio;
|
||||
}
|
||||
|
||||
|
||||
@@ -411,7 +411,7 @@ static int spi_ppc4xx_of_probe(struct platform_device *op)
|
||||
if (num_gpios > 0) {
|
||||
int i;
|
||||
|
||||
hw->gpios = kzalloc(sizeof(int) * num_gpios, GFP_KERNEL);
|
||||
hw->gpios = kcalloc(num_gpios, sizeof(*hw->gpios), GFP_KERNEL);
|
||||
if (!hw->gpios) {
|
||||
ret = -ENOMEM;
|
||||
goto free_master;
|
||||
@@ -428,8 +428,9 @@ static int spi_ppc4xx_of_probe(struct platform_device *op)
|
||||
/* Real CS - set the initial state. */
|
||||
ret = gpio_request(gpio, np->name);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "can't request gpio "
|
||||
"#%d: %d\n", i, ret);
|
||||
dev_err(dev,
|
||||
"can't request gpio #%d: %d\n",
|
||||
i, ret);
|
||||
goto free_gpios;
|
||||
}
|
||||
|
||||
|
||||
@@ -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_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_rx_param = { .src_id = 1 };
|
||||
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)
|
||||
|
||||
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)) {
|
||||
case 0:
|
||||
c->port_id = 3;
|
||||
c->num_chipselect = 1;
|
||||
c->tx_param = &mrfld3_tx_param;
|
||||
c->rx_param = &mrfld3_rx_param;
|
||||
break;
|
||||
case 1:
|
||||
c->port_id = 5;
|
||||
c->num_chipselect = 4;
|
||||
c->tx_param = &mrfld5_tx_param;
|
||||
c->rx_param = &mrfld5_rx_param;
|
||||
break;
|
||||
case 2:
|
||||
c->port_id = 6;
|
||||
c->num_chipselect = 1;
|
||||
c->tx_param = &mrfld6_tx_param;
|
||||
c->rx_param = &mrfld6_rx_param;
|
||||
break;
|
||||
default:
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -203,10 +227,16 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev,
|
||||
ssp = &spi_pdata.ssp;
|
||||
ssp->phys_base = pci_resource_start(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->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);
|
||||
ssp->clk = clk_register_fixed_rate(&dev->dev, buf , NULL, 0,
|
||||
c->max_clk_rate);
|
||||
|
||||
@@ -732,6 +732,20 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
|
||||
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)
|
||||
{
|
||||
struct driver_data *drv_data = dev_id;
|
||||
@@ -771,21 +785,11 @@ static irqreturn_t ssp_int(int irq, void *dev_id)
|
||||
if (!(status & mask))
|
||||
return IRQ_NONE;
|
||||
|
||||
pxa2xx_spi_write(drv_data, SSCR1, sccr1_reg & ~drv_data->int_cr1);
|
||||
pxa2xx_spi_write(drv_data, SSCR1, sccr1_reg);
|
||||
|
||||
if (!drv_data->master->cur_msg) {
|
||||
|
||||
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");
|
||||
|
||||
handle_bad_msg(drv_data);
|
||||
/* Never fail */
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -714,9 +714,10 @@ static int ti_qspi_probe(struct platform_device *pdev)
|
||||
dma_cap_set(DMA_MEMCPY, mask);
|
||||
|
||||
qspi->rx_chan = dma_request_chan_by_mask(&mask);
|
||||
if (!qspi->rx_chan) {
|
||||
if (IS_ERR(qspi->rx_chan)) {
|
||||
dev_err(qspi->dev,
|
||||
"No Rx DMA available, trying mmap mode\n");
|
||||
qspi->rx_chan = NULL;
|
||||
ret = 0;
|
||||
goto no_dma;
|
||||
}
|
||||
|
||||
@@ -90,9 +90,9 @@
|
||||
#define SSSR_RFL_MASK (0xf << 12) /* Receive FIFO Level mask */
|
||||
|
||||
#define SSCR1_TFT (0x000003c0) /* Transmit FIFO Threshold (mask) */
|
||||
#define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..16] */
|
||||
#define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..16] */
|
||||
#define SSCR1_RFT (0x00003c00) /* Receive FIFO Threshold (mask) */
|
||||
#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */
|
||||
#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */
|
||||
|
||||
#define RX_THRESH_CE4100_DFLT 2
|
||||
#define TX_THRESH_CE4100_DFLT 2
|
||||
@@ -106,9 +106,9 @@
|
||||
#define CE4100_SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..4] */
|
||||
|
||||
/* QUARK_X1000 SSCR0 bit definition */
|
||||
#define QUARK_X1000_SSCR0_DSS (0x1F) /* Data Size Select (mask) */
|
||||
#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_DSS (0x1F << 0) /* Data Size Select (mask) */
|
||||
#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_Motorola (0x0 << 5) /* Motorola's Serial Peripheral Interface (SPI) */
|
||||
|
||||
#define RX_THRESH_QUARK_X1000_DFLT 1
|
||||
@@ -121,8 +121,8 @@
|
||||
#define QUARK_X1000_SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..32] */
|
||||
#define QUARK_X1000_SSCR1_RFT (0x1F << 11) /* Receive FIFO Threshold (mask) */
|
||||
#define QUARK_X1000_SSCR1_RxTresh(x) (((x) - 1) << 11) /* level [1..32] */
|
||||
#define QUARK_X1000_SSCR1_STRF (1 << 17) /* Select FIFO or EFWR */
|
||||
#define QUARK_X1000_SSCR1_EFWR (1 << 16) /* Enable FIFO Write/Read */
|
||||
#define QUARK_X1000_SSCR1_STRF (1 << 17) /* Select FIFO or EFWR */
|
||||
#define QUARK_X1000_SSCR1_EFWR (1 << 16) /* Enable FIFO Write/Read */
|
||||
|
||||
/* extra bits in PXA255, PXA26x and PXA27x SSP ports */
|
||||
#define SSCR0_TISSP (1 << 4) /* TI Sync Serial Protocol */
|
||||
|
||||
Reference in New Issue
Block a user