Commit 5a1b11cb authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'spi/fix/bcm2835', 'spi/fix/bcm2835-code',...

Merge remote-tracking branches 'spi/fix/bcm2835', 'spi/fix/bcm2835-code', 'spi/fix/bitbang', 'spi/fix/fsl-cpm' and 'spi/fix/omap2-mcspi' into spi-linus
...@@ -78,6 +78,7 @@ config SPI_ATMEL ...@@ -78,6 +78,7 @@ config SPI_ATMEL
config SPI_BCM2835 config SPI_BCM2835
tristate "BCM2835 SPI controller" tristate "BCM2835 SPI controller"
depends on ARCH_BCM2835 || COMPILE_TEST depends on ARCH_BCM2835 || COMPILE_TEST
depends on GPIOLIB
help help
This selects a driver for the Broadcom BCM2835 SPI master. This selects a driver for the Broadcom BCM2835 SPI master.
......
...@@ -164,13 +164,12 @@ static int bcm2835_spi_transfer_one_poll(struct spi_master *master, ...@@ -164,13 +164,12 @@ static int bcm2835_spi_transfer_one_poll(struct spi_master *master,
unsigned long xfer_time_us) unsigned long xfer_time_us)
{ {
struct bcm2835_spi *bs = spi_master_get_devdata(master); struct bcm2835_spi *bs = spi_master_get_devdata(master);
unsigned long timeout = jiffies + /* set timeout to 1 second of maximum polling */
max(4 * xfer_time_us * HZ / 1000000, 2uL); unsigned long timeout = jiffies + HZ;
/* enable HW block without interrupts */ /* enable HW block without interrupts */
bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA); bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA);
/* set timeout to 4x the expected time, or 2 jiffies */
/* loop until finished the transfer */ /* loop until finished the transfer */
while (bs->rx_len) { while (bs->rx_len) {
/* read from fifo as much as possible */ /* read from fifo as much as possible */
......
...@@ -180,7 +180,6 @@ int spi_bitbang_setup(struct spi_device *spi) ...@@ -180,7 +180,6 @@ int spi_bitbang_setup(struct spi_device *spi)
{ {
struct spi_bitbang_cs *cs = spi->controller_state; struct spi_bitbang_cs *cs = spi->controller_state;
struct spi_bitbang *bitbang; struct spi_bitbang *bitbang;
int retval;
unsigned long flags; unsigned long flags;
bitbang = spi_master_get_devdata(spi->master); bitbang = spi_master_get_devdata(spi->master);
...@@ -197,9 +196,11 @@ int spi_bitbang_setup(struct spi_device *spi) ...@@ -197,9 +196,11 @@ int spi_bitbang_setup(struct spi_device *spi)
if (!cs->txrx_word) if (!cs->txrx_word)
return -EINVAL; return -EINVAL;
retval = bitbang->setup_transfer(spi, NULL); if (bitbang->setup_transfer) {
int retval = bitbang->setup_transfer(spi, NULL);
if (retval < 0) if (retval < 0)
return retval; return retval;
}
dev_dbg(&spi->dev, "%s, %u nsec/bit\n", __func__, 2 * cs->nsecs); dev_dbg(&spi->dev, "%s, %u nsec/bit\n", __func__, 2 * cs->nsecs);
...@@ -295,9 +296,11 @@ static int spi_bitbang_transfer_one(struct spi_master *master, ...@@ -295,9 +296,11 @@ static int spi_bitbang_transfer_one(struct spi_master *master,
/* init (-1) or override (1) transfer params */ /* init (-1) or override (1) transfer params */
if (do_setup != 0) { if (do_setup != 0) {
if (bitbang->setup_transfer) {
status = bitbang->setup_transfer(spi, t); status = bitbang->setup_transfer(spi, t);
if (status < 0) if (status < 0)
break; break;
}
if (do_setup == -1) if (do_setup == -1)
do_setup = 0; do_setup = 0;
} }
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/platform_device.h>
#include "spi-fsl-cpm.h" #include "spi-fsl-cpm.h"
#include "spi-fsl-lib.h" #include "spi-fsl-lib.h"
...@@ -269,17 +270,6 @@ static unsigned long fsl_spi_cpm_get_pram(struct mpc8xxx_spi *mspi) ...@@ -269,17 +270,6 @@ static unsigned long fsl_spi_cpm_get_pram(struct mpc8xxx_spi *mspi)
if (mspi->flags & SPI_CPM2) { if (mspi->flags & SPI_CPM2) {
pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64); pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64);
out_be16(spi_base, pram_ofs); out_be16(spi_base, pram_ofs);
} else {
struct spi_pram __iomem *pram = spi_base;
u16 rpbase = in_be16(&pram->rpbase);
/* Microcode relocation patch applied? */
if (rpbase) {
pram_ofs = rpbase;
} else {
pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64);
out_be16(spi_base, pram_ofs);
}
} }
iounmap(spi_base); iounmap(spi_base);
...@@ -292,7 +282,6 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi) ...@@ -292,7 +282,6 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi)
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
const u32 *iprop; const u32 *iprop;
int size; int size;
unsigned long pram_ofs;
unsigned long bds_ofs; unsigned long bds_ofs;
if (!(mspi->flags & SPI_CPM_MODE)) if (!(mspi->flags & SPI_CPM_MODE))
...@@ -319,8 +308,21 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi) ...@@ -319,8 +308,21 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi)
} }
} }
pram_ofs = fsl_spi_cpm_get_pram(mspi); if (mspi->flags & SPI_CPM1) {
if (IS_ERR_VALUE(pram_ofs)) { struct resource *res;
res = platform_get_resource(to_platform_device(dev),
IORESOURCE_MEM, 1);
mspi->pram = devm_ioremap_resource(dev, res);
} else {
unsigned long pram_ofs = fsl_spi_cpm_get_pram(mspi);
if (IS_ERR_VALUE(pram_ofs))
mspi->pram = NULL;
else
mspi->pram = cpm_muram_addr(pram_ofs);
}
if (mspi->pram == NULL) {
dev_err(dev, "can't allocate spi parameter ram\n"); dev_err(dev, "can't allocate spi parameter ram\n");
goto err_pram; goto err_pram;
} }
...@@ -346,8 +348,6 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi) ...@@ -346,8 +348,6 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi)
goto err_dummy_rx; goto err_dummy_rx;
} }
mspi->pram = cpm_muram_addr(pram_ofs);
mspi->tx_bd = cpm_muram_addr(bds_ofs); mspi->tx_bd = cpm_muram_addr(bds_ofs);
mspi->rx_bd = cpm_muram_addr(bds_ofs + sizeof(*mspi->tx_bd)); mspi->rx_bd = cpm_muram_addr(bds_ofs + sizeof(*mspi->tx_bd));
...@@ -375,7 +375,8 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi) ...@@ -375,7 +375,8 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi)
err_dummy_tx: err_dummy_tx:
cpm_muram_free(bds_ofs); cpm_muram_free(bds_ofs);
err_bds: err_bds:
cpm_muram_free(pram_ofs); if (!(mspi->flags & SPI_CPM1))
cpm_muram_free(cpm_muram_offset(mspi->pram));
err_pram: err_pram:
fsl_spi_free_dummy_rx(); fsl_spi_free_dummy_rx();
return -ENOMEM; return -ENOMEM;
......
...@@ -1210,6 +1210,7 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, ...@@ -1210,6 +1210,7 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
struct omap2_mcspi *mcspi; struct omap2_mcspi *mcspi;
struct omap2_mcspi_dma *mcspi_dma; struct omap2_mcspi_dma *mcspi_dma;
struct spi_transfer *t; struct spi_transfer *t;
int status;
spi = m->spi; spi = m->spi;
mcspi = spi_master_get_devdata(master); mcspi = spi_master_get_devdata(master);
...@@ -1229,7 +1230,8 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, ...@@ -1229,7 +1230,8 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
tx_buf ? "tx" : "", tx_buf ? "tx" : "",
rx_buf ? "rx" : "", rx_buf ? "rx" : "",
t->bits_per_word); t->bits_per_word);
return -EINVAL; status = -EINVAL;
goto out;
} }
if (m->is_dma_mapped || len < DMA_MIN_BYTES) if (m->is_dma_mapped || len < DMA_MIN_BYTES)
...@@ -1241,7 +1243,8 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, ...@@ -1241,7 +1243,8 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
if (dma_mapping_error(mcspi->dev, t->tx_dma)) { if (dma_mapping_error(mcspi->dev, t->tx_dma)) {
dev_dbg(mcspi->dev, "dma %cX %d bytes error\n", dev_dbg(mcspi->dev, "dma %cX %d bytes error\n",
'T', len); 'T', len);
return -EINVAL; status = -EINVAL;
goto out;
} }
} }
if (mcspi_dma->dma_rx && rx_buf != NULL) { if (mcspi_dma->dma_rx && rx_buf != NULL) {
...@@ -1253,14 +1256,19 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, ...@@ -1253,14 +1256,19 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
if (tx_buf != NULL) if (tx_buf != NULL)
dma_unmap_single(mcspi->dev, t->tx_dma, dma_unmap_single(mcspi->dev, t->tx_dma,
len, DMA_TO_DEVICE); len, DMA_TO_DEVICE);
return -EINVAL; status = -EINVAL;
goto out;
} }
} }
} }
omap2_mcspi_work(mcspi, m); omap2_mcspi_work(mcspi, m);
/* spi_finalize_current_message() changes the status inside the
* spi_message, save the status here. */
status = m->status;
out:
spi_finalize_current_message(master); spi_finalize_current_message(master);
return 0; return status;
} }
static int omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) static int omap2_mcspi_master_setup(struct omap2_mcspi *mcspi)
......
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