diff options
Diffstat (limited to 'extras/recipes-kernel/linux/linux-omap/linus/0028-spi-omap2_mcspi.c-Force-CS-to-be-in-inactive-state-a.patch')
-rw-r--r-- | extras/recipes-kernel/linux/linux-omap/linus/0028-spi-omap2_mcspi.c-Force-CS-to-be-in-inactive-state-a.patch | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/extras/recipes-kernel/linux/linux-omap/linus/0028-spi-omap2_mcspi.c-Force-CS-to-be-in-inactive-state-a.patch b/extras/recipes-kernel/linux/linux-omap/linus/0028-spi-omap2_mcspi.c-Force-CS-to-be-in-inactive-state-a.patch new file mode 100644 index 00000000..4c3acd7c --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/linus/0028-spi-omap2_mcspi.c-Force-CS-to-be-in-inactive-state-a.patch @@ -0,0 +1,111 @@ +From 72ce69f5fe32170f9662b5c87b0226d6ba19462f Mon Sep 17 00:00:00 2001 +From: Gregory CLEMENT <gregory.clement@free-electrons.com> +Date: Wed, 29 Dec 2010 11:52:53 +0100 +Subject: [PATCH 28/65] spi/omap2_mcspi.c: Force CS to be in inactive state after off-mode transition + +When SPI wake up from OFF mode, CS is in the wrong state: force it to the +inactive state. + +During the system life, I monitored the CS behavior using a oscilloscope. +I also activated debug in omap2_mcspi, so I saw when driver disable the clocks +and restore context when device is not used.Each time the CS was in the correct +state. It was only when system was put suspend to ram with off-mode activated +that on resume the CS was in wrong state( ie activated). + +Changelog: +* Change from v1 to v2: + - Rebase on linus/master (after 2.6.37-rc1) + - Do some clean-up and fix indentation on both patches + - Add more explanations for patch 2 + +* Change from v2 to v3: + - Use directly resume function of spi_master instead of using function + - from spi_device as Grant Likely pointed it out. + - Force this transition explicitly for each CS used by a device. + +* Change from v3 to v4: + - Patch clean-up according to Kevin Hilman and checkpatch. + - Now force CS to be in inactive state only if it was inactive when it was + suspended. + +* Change from v4 to v5: + - Rebase on linus/master (after 2.6.37-rc3) + - Collapse some lines as pointed by Grant Likely + - Fix a spelling + +* Change from v5 to v6: + - Rebase on linus/master (after 2.6.37-rc7) + - Use CONFIG_SUSPEND instead of CONFIG_PM + - Didn't use legacy PM methods anymore. Instead, add a struct dev_pm_ops and + add the resume method there. + - Fix multi-line comment style + +* Change from v6 to v7: + - Rebase on linus/master (after 2.6.37-rc8) + - Drop an extra line + +Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> +Acked-by: David Brownell <dbrownell@users.sourceforge.net> +Reviewed-by: Kevin Hilman <khilman@deeprootsystems.com> +Signed-off-by: Grant Likely <grant.likely@secretlab.ca> +--- + drivers/spi/omap2_mcspi.c | 39 +++++++++++++++++++++++++++++++++++++++ + 1 files changed, 39 insertions(+), 0 deletions(-) + +diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c +index 2a651e6..951a160 100644 +--- a/drivers/spi/omap2_mcspi.c ++++ b/drivers/spi/omap2_mcspi.c +@@ -1305,10 +1305,49 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev) + /* work with hotplug and coldplug */ + MODULE_ALIAS("platform:omap2_mcspi"); + ++#ifdef CONFIG_SUSPEND ++/* ++ * When SPI wake up from off-mode, CS is in activate state. If it was in ++ * unactive state when driver was suspend, then force it to unactive state at ++ * wake up. ++ */ ++static int omap2_mcspi_resume(struct device *dev) ++{ ++ struct spi_master *master = dev_get_drvdata(dev); ++ struct omap2_mcspi *mcspi = spi_master_get_devdata(master); ++ struct omap2_mcspi_cs *cs; ++ ++ omap2_mcspi_enable_clocks(mcspi); ++ list_for_each_entry(cs, &omap2_mcspi_ctx[master->bus_num - 1].cs, ++ node) { ++ if ((cs->chconf0 & OMAP2_MCSPI_CHCONF_FORCE) == 0) { ++ ++ /* ++ * We need to toggle CS state for OMAP take this ++ * change in account. ++ */ ++ MOD_REG_BIT(cs->chconf0, OMAP2_MCSPI_CHCONF_FORCE, 1); ++ __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); ++ MOD_REG_BIT(cs->chconf0, OMAP2_MCSPI_CHCONF_FORCE, 0); ++ __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); ++ } ++ } ++ omap2_mcspi_disable_clocks(mcspi); ++ return 0; ++} ++#else ++#define omap2_mcspi_resume NULL ++#endif ++ ++static const struct dev_pm_ops omap2_mcspi_pm_ops = { ++ .resume = omap2_mcspi_resume, ++}; ++ + static struct platform_driver omap2_mcspi_driver = { + .driver = { + .name = "omap2_mcspi", + .owner = THIS_MODULE, ++ .pm = &omap2_mcspi_pm_ops + }, + .remove = __exit_p(omap2_mcspi_remove), + }; +-- +1.6.6.1 + |