summaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-mxs.c
Commit message (Collapse)AuthorAgeFilesLines
* tree-wide: use reinit_completion instead of INIT_COMPLETIONWolfram Sang2013-11-151-1/+1
| | | | | | | | | | | | Use this new function to make code more comprehensible, since we are reinitialzing the completion, not initializing. [akpm@linux-foundation.org: linux-next resyncs] Signed-off-by: Wolfram Sang <wsa@the-dreams.de> Acked-by: Linus Walleij <linus.walleij@linaro.org> (personally at LCE13) Cc: Ingo Molnar <mingo@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* Merge remote-tracking branch 'spi/topic/mxs' into spi-nextMark Brown2013-10-251-109/+80
|\
| * spi: spi-mxs: Use u32 instead of uint32_tTrent Piepho2013-10-181-5/+5
| | | | | | | | | | | | | | | | | | | | It's consistent with all the other spi drivers that way. Signed-off-by: Trent Piepho <tpiepho@gmail.com> Cc: Marek Vasut <marex@denx.de> Cc: Fabio Estevam <fabio.estevam@freescale.com> Cc: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Mark Brown <broonie@linaro.org>
| * spi: spi-mxs: Don't set clock for each xferTrent Piepho2013-10-181-1/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | mxs_spi_setup_transfer() would set the SSP SCK rate every time it was called, which is before every transfer. It is uncommon for the SCK rate to change between transfers (or at all of that matter) and this causes many unnecessary reprogrammings of the clock registers. Code changed to only set the rate when it changes. This significantly speeds up short SPI messages, especially messages made up of many transfers, as the calculation of the clock divisors is rather costly. On an iMX287, using spidev with messages that consist of 511 transfers of 4 bytes each at an SCK of 48 MHz, the effective transfer rate more than doubles from about 290 KB/sec to 600 KB/sec! Signed-off-by: Trent Piepho <tpiepho@gmail.com> Cc: Marek Vasut <marex@denx.de> Cc: Fabio Estevam <fabio.estevam@freescale.com> Cc: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Mark Brown <broonie@linaro.org>
| * spi: spi-mxs: Clean up setup_transfer functionTrent Piepho2013-10-181-11/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | It can't be called with a NULL transfer anymore so it can be simplified to not check for that. Fix indention of line-wrapped code to Linux standard. The transfer pointer can be const. It's not necessary to check if the spi_transfer's speed_hz is zero, as the spi core also fills it in from the spi_device. However, the spi core does not check if spi_device's speed is zero so we have to do that still. Signed-off-by: Trent Piepho <tpiepho@gmail.com> Cc: Marek Vasut <marex@denx.de> Cc: Fabio Estevam <fabio.estevam@freescale.com> Cc: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Mark Brown <broonie@linaro.org>
| * spi: spi-mxs: Remove check of spi mode bitsTrent Piepho2013-10-181-3/+0
| | | | | | | | | | | | | | | | | | | | | | | | The spi core already checks for a slave setting mode bits that we didn't list as supported when the master was registered. There is no need to do it again in the master driver. Signed-off-by: Trent Piepho <tpiepho@gmail.com> Cc: Marek Vasut <marex@denx.de> Cc: Fabio Estevam <fabio.estevam@freescale.com> Cc: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Mark Brown <broonie@linaro.org>
| * spi: spi-mxs: Fix race in setup methodTrent Piepho2013-10-181-9/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Despite many warnings in the SPI documentation and code, the spi-mxs driver sets shared chip registers in the ->setup method. This method can be called when transfers are in progress on other slaves controlled by the master. Setting registers or any other shared state will corrupt those transfers. So fix mxs_spi_setup() to not call mxs_spi_setup_transfer(). mxs_spi_setup_transfer() is already called for each transfer when they are actually performed in mxs_spi_transfer_one(), so the call in mxs_spi_setup() isn't necessary to setup anything. Signed-off-by: Trent Piepho <tpiepho@gmail.com> Cc: Marek Vasut <marex@denx.de> Cc: Fabio Estevam <fabio.estevam@freescale.com> Cc: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Mark Brown <broonie@linaro.org>
| * spi: spi-mxs: Remove bogus setting of ssp clk rate fieldTrent Piepho2013-10-181-1/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The ssp struct has a clock rate field, to provide the actual value, in Hz, of the SSP output clock (the rate of SSP_SCK) after mxs_ssp_set_clk_rate() is called. It is set by mxs_ssp_set_clk_rate(), for SSP using drivers (like SPI and MMC) to *read* if they want to know the actual clock rate. The SPI driver isn't supposed to *write* to it. For some reason the spi-mxs driver decides to write to this field on init, and sets it to the value of the SSP input clock (clk_sspN, from the MXS clocking block) in kHz. It shouldn't be setting the value, and certainly shouldn't be setting it with the wrong clock in the wrong units. Signed-off-by: Trent Piepho <tpiepho@gmail.com> Cc: Marek Vasut <marex@denx.de> Cc: Fabio Estevam <fabio.estevam@freescale.com> Cc: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Mark Brown <broonie@linaro.org>
| * spi: spi-mxs: Remove full duplex check, spi core already does itTrent Piepho2013-10-181-6/+0
| | | | | | | | | | | | | | | | | | | | | | | | Because the driver sets the SPI_MASTER_HALF_DUPLEX flag, the spi core will check transfers to insure they are not full duplex. It's not necessary to check that in the spi-mxs driver as well. Signed-off-by: Trent Piepho <tpiepho@gmail.com> Cc: Marek Vasut <marex@denx.de> Cc: Fabio Estevam <fabio.estevam@freescale.com> Cc: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Mark Brown <broonie@linaro.org>
| * spi: spi-mxs: Fix chip select control bits in DMA modeTrent Piepho2013-10-181-23/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In DMA mode the chip select control bits would be ORed into the CTRL0 register without first clearing the bits. This means that after addressing slave 1, the CTRL0 bit to address slave 1 would be still be set when addressing slave 0, resulting in slave 1 continuing to be addressed. The message handling function would pass the CS value to the txrx function, which would re-program the bits on each transfer in the message. The selected CS does not change during a message so this is inefficient. It also means there are two different sets of code for selecting the CS, one for PIO that worked and one for DMA that didn't. Change the code to set the CS bits in the message handling function once. Now the DMA and PIO txrx functions don't need to care about CS at all. Signed-off-by: Trent Piepho <tpiepho@gmail.com> Cc: Marek Vasut <marex@denx.de> Cc: Fabio Estevam <fabio.estevam@freescale.com> Cc: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Mark Brown <broonie@linaro.org>
| * spi: spi-mxs: Fix extra CS pulses and read mode in multi-transfer messagesTrent Piepho2013-10-181-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There are two bits which control the CS line in the CTRL0 register: LOCK_CS and IGNORE_CRC. The latter would be better named DEASSERT_CS in SPI mode. Setting DEASSERT_CS causes CS to be de-asserted at the end of the transfer. It should normally be set only for the final segment of the final transfer. The DMA code explicitly sets it in this case, but because it never clears the bit from the ctrl0 register, it will remain set for all transfers in subsequent messages. This results in a CS pulse between transfers. There is a similar problem with the read mode bit never being cleared in DMA mode. This patch fixes DEASSERT_CS and READ being left on in DMA mode. Signed-off-by: Trent Piepho <tpiepho@gmail.com> Cc: Marek Vasut <marex@denx.de> Cc: Fabio Estevam <fabio.estevam@freescale.com> Cc: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Mark Brown <broonie@linaro.org>
| * spi: spi-mxs: Change flag arguments in txrx functions to bit flagsTrent Piepho2013-10-181-24/+31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There are three flag arguments to the PIO and DMA txrx functions. Two are passed as pointers to integers, even though they are input only and not modified, which makes no sense to do. The third is passed as an integer. The compiler must use an argument register or stack variable for each flag this way. Using bitflags in a single flag argument is more efficient and produces smaller code, since all the flags can fit in a single register. And all the flag arguments get cumbersome, especially when more are added for things like GPIO chipselects. The "first" flag is never used, so can just be deleted. The "last" flag is renamed to DEASSERT_CS, since that's really what it does. The spi_transfer cs_change flag means that CS might be de-asserted on a transfer which is not last and not de-assert on the last transfer, so it is not which transfer is the last we need to know but rather the transfers after which CS should be de-asserted. This also extends the driver to not ignore cs_change when setting the DEASSERT_CS nee "last" flag. Signed-off-by: Trent Piepho <tpiepho@gmail.com> Cc: Marek Vasut <marex@denx.de> Cc: Fabio Estevam <fabio.estevam@freescale.com> Cc: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Mark Brown <broonie@linaro.org>
| * spi: spi-mxs: Always clear INGORE_CRC, to keep CS assertedTrent Piepho2013-10-181-3/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | INGORE_CRC, better named DEASSERT_CS, should be cleared on all tranfers except the last. So instead of only clearing it on the first transfer, we can just always clear it. It will set on the last transfer. This removes the only use of the "first" flag in the transfer functions, so that flag can be then be removed. Signed-off-by: Trent Piepho <tpiepho@gmail.com> Cc: Marek Vasut <marex@denx.de> Cc: Fabio Estevam <fabio.estevam@freescale.com> Cc: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Mark Brown <broonie@linaro.org>
| * spi: spi-mxs: Remove mxs_spi_enable and mxs_spi_disableTrent Piepho2013-10-181-18/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | These functions consist of nothing but one single writel call and are only called once. And the names really aren't accurate or clear, since they don't enable or disble SPI. Rather they set the bit that controls the state of CS at the end of transfer. It easier to follow the code to just set this bit with a writel() along with all the other bits being set in the same function. Signed-off-by: Trent Piepho <tpiepho@gmail.com> Cc: Marek Vasut <marex@denx.de> Cc: Fabio Estevam <fabio.estevam@freescale.com> Cc: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Mark Brown <broonie@linaro.org>
| * spi: spi-mxs: Always set LOCK_CSTrent Piepho2013-10-181-6/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There are two bits which control the CS line in the CTRL0 register: LOCK_CS and IGNORE_CRC. The latter would be better named DEASSERT_CS in SPI mode. LOCK_CS keeps CS asserted though the entire transfer. This should always be set. The DMA code will always set it, explicitly on the first segment of the first transfer, and then implicitly on all the rest by never clearing the bit from the value read from the ctrl0 register. The PIO code will explicitly set it for the first transfer, leave it set for intermediate transfers, and then clear it for the final transfer. It should not clear it. The only reason to not set LOCK_CS would be to attempt an altered protocol where CS pulses between each word. Though don't get your hopes up if you want to do this, as the hardware doesn't appear to do this in any sane manner. It appears to be related to the hardware FIFO fill level. The code can be simplified by just setting LOCK_CS once and then not needing to deal with it at all in the PIO and DMA transfer functions. Signed-off-by: Trent Piepho <tpiepho@gmail.com> Cc: Marek Vasut <marex@denx.de> Cc: Fabio Estevam <fabio.estevam@freescale.com> Cc: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Mark Brown <broonie@linaro.org>
* | spi: mxs: use devm_spi_register_master()Jingoo Han2013-09-261-3/+1
|/ | | | | | | | Use devm_spi_register_master() to make cleanup paths simpler, and remove a duplicate put. Signed-off-by: Jingoo Han <jg1.han@samsung.com> Signed-off-by: Mark Brown <broonie@linaro.org>
* spi: spi-mxs: Remove unused bits_per_word variableAxel Lin2013-08-061-5/+0
| | | | | | | | | The bits_per_word variable is not used after commit 24778be20f8 "spi: convert drivers to use bits_per_word_mask". Signed-off-by: Axel Lin <axel.lin@ingics.com> Acked-by: Marek Vasut <marex@denx.de> Signed-off-by: Mark Brown <broonie@linaro.org>
* spi: spi-mxs: Remove unneeded check for platform_get_resource()Fabio Estevam2013-07-221-1/+1
| | | | | | | | | As devm_ioremap_resource() is used on probe, there is no need to explicitly check the return value from platform_get_resource(), as this is something that devm_ioremap_resource() takes care by itself. Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com> Signed-off-by: Mark Brown <broonie@linaro.org>
* spi: spi-mxs: Check the return value from stmp_reset_block()Fabio Estevam2013-07-151-1/+3
| | | | | | | | | stmp_reset_block() may fail, so let's check its return value and propagate it in the case of error. Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com> Acked-by: Marek Vasut <marex@denx.de> Signed-off-by: Mark Brown <broonie@linaro.org>
* spi: spi-mxs: Check the return value from clk_prepare_enable()Fabio Estevam2013-07-151-3/+7
| | | | | | | | | | | | clk_prepare_enable() may fail, so let's check its return value and propagate it in the case of error. While at it, rename 'out_free_dma' to 'out_disable_clk' so that it can properly describe its purpose. Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com> Acked-by: Marek Vasut <marex@denx.de> Signed-off-by: Mark Brown <broonie@linaro.org>
* spi: spi-mxs: Fix the error path sequenceFabio Estevam2013-07-151-5/+2
| | | | | | | | | | | | On mxs_spi_probe() the dma channels are requested prior to enabling the SSP clock, so in the error path we should disable the SSP clock first and release the DMA channels later. Same logic applies in mxs_spi_remove(). Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com> Acked-by: Marek Vasut <marex@denx.de> Signed-off-by: Mark Brown <broonie@linaro.org>
* Merge remote-tracking branch 'spi/topic/mxs' into spi-nextMark Brown2013-06-261-6/+0
|\
| * spi: spi-mxs: Let device core handle pinctrlFabio Estevam2013-05-131-6/+0
| | | | | | | | | | | | | | | | | | | | Since commit ab78029 (drivers/pinctrl: grab default handles from device core), we can rely on device core for handling pinctrl. So remove devm_pinctrl_get_select_default() from the driver. Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
* | spi: convert drivers to use bits_per_word_maskStephen Warren2013-05-291-6/+1
|/ | | | | | | | | | Fill in the recently added spi_master.bits_per_word_mask field in as many drivers as possible. Make related cleanups, such as removing any redundant error-checking, or empty setup callbacks. Signed-off-by: Stephen Warren <swarren@wwwdotorg.org> Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
* Merge tag 'dt-for-linus-2' of ↵Linus Torvalds2013-05-071-51/+9
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc Pull ARM SoC device tree updates (part 2) from Arnd Bergmann: "These are mostly new device tree bindings for existing drivers, as well as changes to the device tree source files to add support for those devices, and a couple of new boards, most notably Samsung's Exynos5 based Chromebook. The changes depend on earlier platform specific updates and touch the usual platforms: omap, exynos, tegra, mxs, mvebu and davinci." * tag 'dt-for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (169 commits) ARM: exynos: dts: cros5250: add EC device ARM: dts: Add sbs-battery for exynos5250-snow ARM: dts: Add i2c-arbitrator bus for exynos5250-snow ARM: dts: add mshc controller node for Exynos4x12 SoCs ARM: dts: Add chip-id controller node on Exynos4/5 SoC ARM: EXYNOS: Create virtual I/O mapping for Chip-ID controller using device tree ARM: davinci: da850-evm: add SPI flash support ARM: davinci: da850: override SPI DT node device name ARM: davinci: da850: add SPI1 DT node spi/davinci: add DT binding documentation spi/davinci: no wildcards in DT compatible property ARM: dts: mvebu: Convert mvebu device tree files to 64 bits ARM: dts: mvebu: introduce internal-regs node ARM: dts: mvebu: Convert all the mvebu files to use the range property ARM: dts: mvebu: move all peripherals inside soc ARM: dts: mvebu: fix cpus section indentation ARM: davinci: da850: add EHRPWM & ECAP DT node ARM/dts: OMAP3: fix pinctrl-single configuration ARM: dts: Add OMAP3430 SDP NOR flash memory binding ARM: dts: Add NOR flash bindings for OMAP2420 H4 ...
| * spi: mxs-spi: move to use generic DMA helperShawn Guo2013-04-041-51/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | With the generic DMA device tree helper supported by mxs-dma driver, client devices only need to call dma_request_slave_channel() for requesting a DMA channel from dmaengine. Since mxs is a DT only platform now, along with the changes, the non-DT case handling in probe function also gets removed. Signed-off-by: Shawn Guo <shawn.guo@linaro.org> Acked-by: Grant Likely <grant.likely@secretlab.ca> Reviewed-by: Arnd Bergmann <arnd@arndb.de>
* | mxs/spi: fix error return code in mxs_spi_probe()Wei Yongjun2013-04-031-0/+1
|/ | | | | | | | Fix to return a negative error code from the error handling case instead of 0, as returned elsewhere in this function. Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
* Merge tag 'driver-core-3.9-rc1' of ↵Linus Torvalds2013-02-211-3/+3
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core Pull driver core patches from Greg Kroah-Hartman: "Here is the big driver core merge for 3.9-rc1 There are two major series here, both of which touch lots of drivers all over the kernel, and will cause you some merge conflicts: - add a new function called devm_ioremap_resource() to properly be able to check return values. - remove CONFIG_EXPERIMENTAL Other than those patches, there's not much here, some minor fixes and updates" Fix up trivial conflicts * tag 'driver-core-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (221 commits) base: memory: fix soft/hard_offline_page permissions drivercore: Fix ordering between deferred_probe and exiting initcalls backlight: fix class_find_device() arguments TTY: mark tty_get_device call with the proper const values driver-core: constify data for class_find_device() firmware: Ignore abort check when no user-helper is used firmware: Reduce ifdef CONFIG_FW_LOADER_USER_HELPER firmware: Make user-mode helper optional firmware: Refactoring for splitting user-mode helper code Driver core: treat unregistered bus_types as having no devices watchdog: Convert to devm_ioremap_resource() thermal: Convert to devm_ioremap_resource() spi: Convert to devm_ioremap_resource() power: Convert to devm_ioremap_resource() mtd: Convert to devm_ioremap_resource() mmc: Convert to devm_ioremap_resource() mfd: Convert to devm_ioremap_resource() media: Convert to devm_ioremap_resource() iommu: Convert to devm_ioremap_resource() drm: Convert to devm_ioremap_resource() ...
| * spi: Convert to devm_ioremap_resource()Thierry Reding2013-01-251-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | Convert all uses of devm_request_and_ioremap() to the newly introduced devm_ioremap_resource() which provides more consistent error handling. devm_ioremap_resource() provides its own error messages so all explicit error messages can be removed from the failure code paths. Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de> Cc: Grant Likely <grant.likely@secretlab.ca> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* | mxs/spi: clear XFER_COUNT in ctrl0 field in DMA descriptorJuha Lumme2013-02-051-1/+4
|/ | | | | | | | | | | | | | | On MX23 the XFER_COUNT part in ctrl0 field in DMA descriptor was improperly OR'd during the construction of DMA descriptor chain, instead of being freshly set. Because of that too many bytes were being expected from SPI during the last DMA cycle. This caused a timeout (SSP_TIMEOUT) to happen in the processing of the last DMA descriptor, and thus reads and writes were failing. This is a fix for the problem, by clearing XFER_COUNT bytes in ctrl0 before setting the new XFER_COUNT for DMA descriptor. Signed-off-by: Juha Lumme <juha.lumme@gmail.com> Acked-by: Marek Vasut <marex@denx.de> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
* spi: Remove HOTPLUG section attributesGrant Likely2012-12-071-3/+3
| | | | | | | | | | | | | | CONFIG_HOTPLUG is going away as an option. As result the __dev* markings will be going away. Remove use of __devinit, __devexit_p, __devinitdata, __devinitconst, and __devexit. Bill Pemberton has done most of the legwork on this series. I've used his script to purge the attributes from the drivers/gpio tree. Reported-by: Bill Pemberton <wfp5p@virginia.edu> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
* spi: mxs: Terminate DMA in case of DMA timeoutMarek Vasut2012-10-171-0/+1
| | | | | | | | | In case the SPI DMA times out, the DMA might still be in some kind of inconsistent state. Issue dmaengine_terminate_all() on the particular channel to kill off all operations before continuing. Signed-off-by: Marek Vasut <marex@denx.de> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
* spi: mxs: Assign message status after transfer finishedMarek Vasut2012-10-171-1/+1
| | | | | | | | | In the current code implementing the MXS SPI driver, every transferred message had assigned status = 0, which is not correct. Properly assign status returned from the I/O functions. Signed-off-by: Marek Vasut <marex@denx.de> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
* spi/mxs: Make the SPI block clock speed configurable via DTMarek Vasut2012-09-061-6/+15
| | | | | | | | Add "clock-frequency" property, which allows configuring the SPI block's base speed. Signed-off-by: Marek Vasut <marex@denx.de> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
* mxs/spi: Rework the mxs_ssp_timeout to be more readableMarek Vasut2012-09-061-11/+9
| | | | | | | | | | | | Rework the mxs_ssp_timeout() function to make it a bit more readable and hopefully less error prone. Also, have only one successful exit from the function and one failing exit instead of two. Finally, discard the udelay() from this function altogether, as this tightloop is quick enough it's pointless. Signed-off-by: Marek Vasut <marex@denx.de> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
* mxs/spi: Decrement the DMA/PIO borderMarek Vasut2012-09-061-1/+1
| | | | | | | | | | | | | This driver checks the length of transfer to be made and based on this information, either chooses to transfer data via DMA or PIO. Decrement this border further to gain better performace eg. during SPI flash writes. Empiric measurement shows that this gives extra 3kB/s write speed with a M25P80 flash clocked at 40MHz. Signed-off-by: Marek Vasut <marex@denx.de> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
* mxs/spi: Increment the transfer length only if transfer succeededMarek Vasut2012-09-061-1/+1
| | | | | | | | | The transfer function incremented (struct spi_message)->actual_length unconditionally, even if the transfer failed. Rectify this by incrementing this only if transfer succeeded. Signed-off-by: Marek Vasut <marex@denx.de> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
* mxs/spi: Fix issues when doing long continuous transferMarek Vasut2012-09-061-53/+88
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When doing long continuous transfer, eg. from SPI flash via /dev/mtd, the driver dies. This is caused by a bug in the DMA chaining. Rework the DMA transfer code so that this issue does not happen any longer. This involves proper allocation of correct amount of sg-list members. Also, this means proper creation of DMA descriptors. There is actually an important catch to this, the data transfer descriptors must be interleaved with PIO register write descriptor, otherwise the transfer stalls. This can be done in one descriptor, but due to the limitation of the DMA API, it's not possible. It turns out that in order for the SPI DMA to properly support continuous transfers longer than 65280 bytes, there are some very important parts that were left out from the documentation about about the PIO transfer that is used. Firstly, the XFER_SIZE register is not written with the whole length of a transfer, but is written by each and every chained descriptor with the length of the descriptors data buffer. Next, unlike the demo code supplied by FSL, which only writes one PIO word per descriptor, this does not apply if the descriptors are chained, since the XFER_SIZE register must be written. Therefore, it is essential to use four PIO words, CTRL0, CMD0, CMD1, XFER_SIZE. CMD0 and CMD1 are written with zero, since they don't apply. The DMA programs the PIO words in an incrementing order, so four PIO words. Finally, unlike the demo code supplied by FSL, the SSP_CTRL0_IGNORE_CRC must not be set during the whole transfer, but it must be set only on the last descriptor in the chain. Lastly, this code lends code from drivers/mtd/nand/omap2.c, which solves trouble when the buffer supplied to the DMA transfer was vmalloc()'d. So with this patch, it's safe to use /dev/mtdblockX interface again. Signed-off-by: Marek Vasut <marex@denx.de> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
* spi/mxs: Fix device remove functionGuenter Roeck2012-08-271-4/+1
| | | | | | | | | | | | | | | | | | | The call sequence spi_alloc_master/spi_register_master/spi_unregister_master is complete; it reduces the device reference count to zero, which results in device memory being freed. The remove function accesses the freed memory after the call to spi_unregister_master(), _and_ it calls spi_master_put on the freed memory. Acquire a reference to the SPI master device and release it after cleanup is complete (with the existing spi_master_put) to solve the problem. Also, the device subsystem ensures that the remove function is only called once, and resets device driver data to NULL. Remove the unnecessaary calls to platform_set_drvdata(). Signed-off-by: Guenter Roeck <linux@roeck-us.net> Reviewed-by: Marek Vasut <marex@denx.de> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
* mxs/spi: Fix misuse of init_completionMarek Vasut2012-08-271-1/+3
| | | | | | | | | | | | | | | | | | | | | | | The init_completion() call does reinit not only the variable carrying the flag that the completion finished, but also initialized the waitqueue associated with the completion. On the contrary, the INIT_COMPLETION() call only reinits the flag. In case there was anything still stuck in the waitqueue, subsequent call to init_completion() would be able to create possible race condition. This patch uses the proper function and moves init_completion() into .probe() call of the driver, to be issued only once. Note that such scenario is impossible, since two threads can never enter the mxs_spi_txrx_dma(), since whole this section is protected by mutex in SPI core. This by no means allows this issue to exit though. Signed-off-by: Marek Vasut <marex@denx.de> Cc: Chris Ball <cjb@laptop.org> Cc: Shawn Guo <shawn.guo@linaro.org> Cc: Mark Brown <broonie@opensource.wolfsonmicro.com> Cc: Fabio Estevam <fabio.estevam@freescale.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
* mxs/spi: Restart the block after unsuccessful transferMarek Vasut2012-08-271-1/+3
| | | | | | | | | | | | Restart the SSP block in case the SSP transfer failed in any way. The block hung in some cases otherwise. Signed-off-by: Marek Vasut <marex@denx.de> Cc: Chris Ball <cjb@laptop.org> Cc: Shawn Guo <shawn.guo@linaro.org> Cc: Mark Brown <broonie@opensource.wolfsonmicro.com> Cc: Fabio Estevam <fabio.estevam@freescale.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
* spi/mxs: Add DMA support into SPI driverMarek Vasut2012-08-171-15/+216
| | | | | | | Signed-off-by: Marek Vasut <marex@denx.de> Acked-by: Chris Ball <cjb@laptop.org> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
* mmc: spi: Pull out common DMA parts from MXS MMCMarek Vasut2012-08-171-1/+0
| | | | | | | | | These parts will be used by the MXS SPI driver too. Signed-off-by: Marek Vasut <marex@denx.de> Acked-by: Chris Ball <cjb@laptop.org> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
* spi/mxs: Add SPI driver for mx233/mx28Marek Vasut2012-08-171-0/+431
This is slightly reworked version of the SPI driver. Support for DT has been added and it's been converted to queued API. Based on previous attempt by: Fabio Estevam <fabio.estevam@freescale.com> Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com> Signed-off-by: Marek Vasut <marex@denx.de> Acked-by: Chris Ball <cjb@laptop.org> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>