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-sh-hspi.c | |
parent | 15de0599277f3477ddd11766282587f12d214252 (diff) | |
parent | 7cb943615aabbd72624f77f0a84b8c5d627cf846 (diff) | |
download | linux-stable-d3b43e12b2c8c69f79ab76dcdc5956f47c376378.tar.gz linux-stable-d3b43e12b2c8c69f79ab76dcdc5956f47c376378.tar.bz2 linux-stable-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-sh-hspi.c')
-rw-r--r-- | drivers/spi/spi-sh-hspi.c | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c index 796c077ef439..32f7b55fce09 100644 --- a/drivers/spi/spi-sh-hspi.c +++ b/drivers/spi/spi-sh-hspi.c @@ -68,6 +68,16 @@ static u32 hspi_read(struct hspi_priv *hspi, int reg) return ioread32(hspi->addr + reg); } +static void hspi_bit_set(struct hspi_priv *hspi, int reg, u32 mask, u32 set) +{ + u32 val = hspi_read(hspi, reg); + + val &= ~mask; + val |= set & mask; + + hspi_write(hspi, reg, val); +} + /* * transfer function */ @@ -105,6 +115,13 @@ static int hspi_unprepare_transfer(struct spi_master *master) return 0; } +#define hspi_hw_cs_enable(hspi) hspi_hw_cs_ctrl(hspi, 0) +#define hspi_hw_cs_disable(hspi) hspi_hw_cs_ctrl(hspi, 1) +static void hspi_hw_cs_ctrl(struct hspi_priv *hspi, int hi) +{ + hspi_bit_set(hspi, SPSCR, (1 << 6), (hi) << 6); +} + static void hspi_hw_setup(struct hspi_priv *hspi, struct spi_message *msg, struct spi_transfer *t) @@ -155,7 +172,7 @@ static void hspi_hw_setup(struct hspi_priv *hspi, hspi_write(hspi, SPCR, spcr); hspi_write(hspi, SPSR, 0x0); - hspi_write(hspi, SPSCR, 0x1); /* master mode */ + hspi_write(hspi, SPSCR, 0x21); /* master mode / CS control */ } static int hspi_transfer_one_message(struct spi_master *master, @@ -166,12 +183,21 @@ static int hspi_transfer_one_message(struct spi_master *master, u32 tx; u32 rx; int ret, i; + unsigned int cs_change; + const int nsecs = 50; dev_dbg(hspi->dev, "%s\n", __func__); + cs_change = 1; ret = 0; list_for_each_entry(t, &msg->transfers, transfer_list) { - hspi_hw_setup(hspi, msg, t); + + if (cs_change) { + hspi_hw_setup(hspi, msg, t); + hspi_hw_cs_enable(hspi); + ndelay(nsecs); + } + cs_change = t->cs_change; for (i = 0; i < t->len; i++) { @@ -198,9 +224,22 @@ static int hspi_transfer_one_message(struct spi_master *master, } msg->actual_length += t->len; + + if (t->delay_usecs) + udelay(t->delay_usecs); + + if (cs_change) { + ndelay(nsecs); + hspi_hw_cs_disable(hspi); + ndelay(nsecs); + } } msg->status = ret; + if (!cs_change) { + ndelay(nsecs); + hspi_hw_cs_disable(hspi); + } spi_finalize_current_message(master); return ret; @@ -229,7 +268,7 @@ static void hspi_cleanup(struct spi_device *spi) dev_dbg(dev, "%s cleanup\n", spi->modalias); } -static int __devinit hspi_probe(struct platform_device *pdev) +static int hspi_probe(struct platform_device *pdev) { struct resource *res; struct spi_master *master; @@ -300,7 +339,7 @@ static int __devinit hspi_probe(struct platform_device *pdev) return ret; } -static int __devexit hspi_remove(struct platform_device *pdev) +static int hspi_remove(struct platform_device *pdev) { struct hspi_priv *hspi = dev_get_drvdata(&pdev->dev); @@ -314,7 +353,7 @@ static int __devexit hspi_remove(struct platform_device *pdev) static struct platform_driver hspi_driver = { .probe = hspi_probe, - .remove = __devexit_p(hspi_remove), + .remove = hspi_remove, .driver = { .name = "sh-hspi", .owner = THIS_MODULE, |