diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-13 19:15:11 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-13 19:15:11 -0800 |
| commit | d3b43e12b2c8c69f79ab76dcdc5956f47c376378 (patch) | |
| tree | 4fba9e425d7407e5abd5ab50d5ac09398ec5bff6 /drivers/spi/spi-omap2-mcspi.c | |
| parent | 15de0599277f3477ddd11766282587f12d214252 (diff) | |
| parent | 7cb943615aabbd72624f77f0a84b8c5d627cf846 (diff) | |
| download | olio-linux-3.10-d3b43e12b2c8c69f79ab76dcdc5956f47c376378.tar.xz olio-linux-3.10-d3b43e12b2c8c69f79ab76dcdc5956f47c376378.zip | |
Merge tag 'spi-for-linus' of git://git.secretlab.ca/git/linux-2.6
Pull SPI updates from Grant Likely:
"Primarily SPI device driver bug fixes, one removal of an old driver,
and some new tegra support. There is some core code change too, but
all in all pretty small stuff.
The new features to note are:
- Common code for describing GPIO CS lines in the device tree
- Remove the SPI_BUFSIZ limitation on spi_write_the_read()
- core spi ensures bits_per_word is set correctly
- SPARC can now use SPI"
* tag 'spi-for-linus' of git://git.secretlab.ca/git/linux-2.6: (36 commits)
spi/sparc: Allow of_register_spi_devices for sparc
spi: Remove HOTPLUG section attributes
spi: Add support for specifying 3-wire mode via device tree
spi: Fix comparison of different integer types
spi/orion: Add SPI_CHPA and SPI_CPOL support to kirkwood driver.
spi/sh: Add SH Mobile series as dependency to MSIOF controller
spi/sh-msiof: Remove unneeded clock name
spi: Remove SPI_BUFSIZ restriction on spi_write_then_read()
spi/stmp: remove obsolete driver
spi/clps711x: New SPI master driver
spi: omap2-mcspi: remove duplicate inclusion of linux/err.h
spi: omap2-mcspi: Fix the redifine warning
spi/sh-hspi: add CS manual control support
of_spi: add generic binding support to specify cs gpio
spi: omap2-mcspi: remove duplicated include from spi-omap2-mcspi.c
spi/bitbang: (cosmetic) simplify list manipulation
spi/bitbang: avoid needless loop flow manipulations
spi/omap: fix D0/D1 direction confusion
spi: tegra: add spi driver for sflash controller
spi: Dont call master->setup if not populated
...
Diffstat (limited to 'drivers/spi/spi-omap2-mcspi.c')
| -rw-r--r-- | drivers/spi/spi-omap2-mcspi.c | 74 |
1 files changed, 40 insertions, 34 deletions
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 3542fdc664b..b610f522ca4 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -39,7 +39,6 @@ #include <linux/of.h> #include <linux/of_device.h> #include <linux/pinctrl/consumer.h> -#include <linux/err.h> #include <linux/spi/spi.h> @@ -130,6 +129,7 @@ struct omap2_mcspi { struct omap2_mcspi_dma *dma_channels; struct device *dev; struct omap2_mcspi_regs ctx; + unsigned int pin_dir:1; }; struct omap2_mcspi_cs { @@ -323,19 +323,11 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi, struct omap2_mcspi *mcspi; struct omap2_mcspi_dma *mcspi_dma; unsigned int count; - u8 * rx; - const u8 * tx; - void __iomem *chstat_reg; - struct omap2_mcspi_cs *cs = spi->controller_state; mcspi = spi_master_get_devdata(spi->master); mcspi_dma = &mcspi->dma_channels[spi->chip_select]; count = xfer->len; - rx = xfer->rx_buf; - tx = xfer->tx_buf; - chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0; - if (mcspi_dma->dma_tx) { struct dma_async_tx_descriptor *tx; struct scatterlist sg; @@ -359,19 +351,6 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi, dma_async_issue_pending(mcspi_dma->dma_tx); omap2_mcspi_set_dma_req(spi, 0, 1); - wait_for_completion(&mcspi_dma->dma_tx_completion); - dma_unmap_single(mcspi->dev, xfer->tx_dma, count, - DMA_TO_DEVICE); - - /* for TX_ONLY mode, be sure all words have shifted out */ - if (rx == NULL) { - if (mcspi_wait_for_reg_bit(chstat_reg, - OMAP2_MCSPI_CHSTAT_TXS) < 0) - dev_err(&spi->dev, "TXS timed out\n"); - else if (mcspi_wait_for_reg_bit(chstat_reg, - OMAP2_MCSPI_CHSTAT_EOT) < 0) - dev_err(&spi->dev, "EOT timed out\n"); - } } static unsigned @@ -492,6 +471,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) struct dma_slave_config cfg; enum dma_slave_buswidth width; unsigned es; + void __iomem *chstat_reg; mcspi = spi_master_get_devdata(spi->master); mcspi_dma = &mcspi->dma_channels[spi->chip_select]; @@ -526,8 +506,24 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) omap2_mcspi_tx_dma(spi, xfer, cfg); if (rx != NULL) - return omap2_mcspi_rx_dma(spi, xfer, cfg, es); + count = omap2_mcspi_rx_dma(spi, xfer, cfg, es); + + if (tx != NULL) { + chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0; + wait_for_completion(&mcspi_dma->dma_tx_completion); + dma_unmap_single(mcspi->dev, xfer->tx_dma, xfer->len, + DMA_TO_DEVICE); + /* for TX_ONLY mode, be sure all words have shifted out */ + if (rx == NULL) { + if (mcspi_wait_for_reg_bit(chstat_reg, + OMAP2_MCSPI_CHSTAT_TXS) < 0) + dev_err(&spi->dev, "TXS timed out\n"); + else if (mcspi_wait_for_reg_bit(chstat_reg, + OMAP2_MCSPI_CHSTAT_EOT) < 0) + dev_err(&spi->dev, "EOT timed out\n"); + } + } return count; } @@ -765,8 +761,15 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, /* standard 4-wire master mode: SCK, MOSI/out, MISO/in, nCS * REVISIT: this controller could support SPI_3WIRE mode. */ - l &= ~(OMAP2_MCSPI_CHCONF_IS|OMAP2_MCSPI_CHCONF_DPE1); - l |= OMAP2_MCSPI_CHCONF_DPE0; + if (mcspi->pin_dir == MCSPI_PINDIR_D0_IN_D1_OUT) { + l &= ~OMAP2_MCSPI_CHCONF_IS; + l &= ~OMAP2_MCSPI_CHCONF_DPE1; + l |= OMAP2_MCSPI_CHCONF_DPE0; + } else { + l |= OMAP2_MCSPI_CHCONF_IS; + l |= OMAP2_MCSPI_CHCONF_DPE1; + l &= ~OMAP2_MCSPI_CHCONF_DPE0; + } /* wordlength */ l &= ~OMAP2_MCSPI_CHCONF_WL_MASK; @@ -1085,7 +1088,7 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, return 0; } -static int __devinit omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) +static int omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) { struct spi_master *master = mcspi->master; struct omap2_mcspi_regs *ctx = &mcspi->ctx; @@ -1138,7 +1141,7 @@ static const struct of_device_id omap_mcspi_of_match[] = { }; MODULE_DEVICE_TABLE(of, omap_mcspi_of_match); -static int __devinit omap2_mcspi_probe(struct platform_device *pdev) +static int omap2_mcspi_probe(struct platform_device *pdev) { struct spi_master *master; const struct omap2_mcspi_platform_config *pdata; @@ -1167,6 +1170,11 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev) master->cleanup = omap2_mcspi_cleanup; master->dev.of_node = node; + dev_set_drvdata(&pdev->dev, master); + + mcspi = spi_master_get_devdata(master); + mcspi->master = master; + match = of_match_device(omap_mcspi_of_match, &pdev->dev); if (match) { u32 num_cs = 1; /* default number of chipselect */ @@ -1175,19 +1183,17 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev) of_property_read_u32(node, "ti,spi-num-cs", &num_cs); master->num_chipselect = num_cs; master->bus_num = bus_num++; + if (of_get_property(node, "ti,pindir-d0-out-d1-in", NULL)) + mcspi->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN; } else { pdata = pdev->dev.platform_data; master->num_chipselect = pdata->num_cs; if (pdev->id != -1) master->bus_num = pdev->id; + mcspi->pin_dir = pdata->pin_dir; } regs_offset = pdata->regs_offset; - dev_set_drvdata(&pdev->dev, master); - - mcspi = spi_master_get_devdata(master); - mcspi->master = master; - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (r == NULL) { status = -ENODEV; @@ -1272,7 +1278,7 @@ free_master: return status; } -static int __devexit omap2_mcspi_remove(struct platform_device *pdev) +static int omap2_mcspi_remove(struct platform_device *pdev) { struct spi_master *master; struct omap2_mcspi *mcspi; @@ -1341,7 +1347,7 @@ static struct platform_driver omap2_mcspi_driver = { .of_match_table = omap_mcspi_of_match, }, .probe = omap2_mcspi_probe, - .remove = __devexit_p(omap2_mcspi_remove), + .remove = omap2_mcspi_remove, }; module_platform_driver(omap2_mcspi_driver); |