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 @@ | |||
1 | From 72ce69f5fe32170f9662b5c87b0226d6ba19462f Mon Sep 17 00:00:00 2001 | ||
2 | From: Gregory CLEMENT <gregory.clement@free-electrons.com> | ||
3 | Date: Wed, 29 Dec 2010 11:52:53 +0100 | ||
4 | Subject: [PATCH 28/65] spi/omap2_mcspi.c: Force CS to be in inactive state after off-mode transition | ||
5 | |||
6 | When SPI wake up from OFF mode, CS is in the wrong state: force it to the | ||
7 | inactive state. | ||
8 | |||
9 | During the system life, I monitored the CS behavior using a oscilloscope. | ||
10 | I also activated debug in omap2_mcspi, so I saw when driver disable the clocks | ||
11 | and restore context when device is not used.Each time the CS was in the correct | ||
12 | state. It was only when system was put suspend to ram with off-mode activated | ||
13 | that on resume the CS was in wrong state( ie activated). | ||
14 | |||
15 | Changelog: | ||
16 | * Change from v1 to v2: | ||
17 | - Rebase on linus/master (after 2.6.37-rc1) | ||
18 | - Do some clean-up and fix indentation on both patches | ||
19 | - Add more explanations for patch 2 | ||
20 | |||
21 | * Change from v2 to v3: | ||
22 | - Use directly resume function of spi_master instead of using function | ||
23 | - from spi_device as Grant Likely pointed it out. | ||
24 | - Force this transition explicitly for each CS used by a device. | ||
25 | |||
26 | * Change from v3 to v4: | ||
27 | - Patch clean-up according to Kevin Hilman and checkpatch. | ||
28 | - Now force CS to be in inactive state only if it was inactive when it was | ||
29 | suspended. | ||
30 | |||
31 | * Change from v4 to v5: | ||
32 | - Rebase on linus/master (after 2.6.37-rc3) | ||
33 | - Collapse some lines as pointed by Grant Likely | ||
34 | - Fix a spelling | ||
35 | |||
36 | * Change from v5 to v6: | ||
37 | - Rebase on linus/master (after 2.6.37-rc7) | ||
38 | - Use CONFIG_SUSPEND instead of CONFIG_PM | ||
39 | - Didn't use legacy PM methods anymore. Instead, add a struct dev_pm_ops and | ||
40 | add the resume method there. | ||
41 | - Fix multi-line comment style | ||
42 | |||
43 | * Change from v6 to v7: | ||
44 | - Rebase on linus/master (after 2.6.37-rc8) | ||
45 | - Drop an extra line | ||
46 | |||
47 | Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> | ||
48 | Acked-by: David Brownell <dbrownell@users.sourceforge.net> | ||
49 | Reviewed-by: Kevin Hilman <khilman@deeprootsystems.com> | ||
50 | Signed-off-by: Grant Likely <grant.likely@secretlab.ca> | ||
51 | --- | ||
52 | drivers/spi/omap2_mcspi.c | 39 +++++++++++++++++++++++++++++++++++++++ | ||
53 | 1 files changed, 39 insertions(+), 0 deletions(-) | ||
54 | |||
55 | diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c | ||
56 | index 2a651e6..951a160 100644 | ||
57 | --- a/drivers/spi/omap2_mcspi.c | ||
58 | +++ b/drivers/spi/omap2_mcspi.c | ||
59 | @@ -1305,10 +1305,49 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev) | ||
60 | /* work with hotplug and coldplug */ | ||
61 | MODULE_ALIAS("platform:omap2_mcspi"); | ||
62 | |||
63 | +#ifdef CONFIG_SUSPEND | ||
64 | +/* | ||
65 | + * When SPI wake up from off-mode, CS is in activate state. If it was in | ||
66 | + * unactive state when driver was suspend, then force it to unactive state at | ||
67 | + * wake up. | ||
68 | + */ | ||
69 | +static int omap2_mcspi_resume(struct device *dev) | ||
70 | +{ | ||
71 | + struct spi_master *master = dev_get_drvdata(dev); | ||
72 | + struct omap2_mcspi *mcspi = spi_master_get_devdata(master); | ||
73 | + struct omap2_mcspi_cs *cs; | ||
74 | + | ||
75 | + omap2_mcspi_enable_clocks(mcspi); | ||
76 | + list_for_each_entry(cs, &omap2_mcspi_ctx[master->bus_num - 1].cs, | ||
77 | + node) { | ||
78 | + if ((cs->chconf0 & OMAP2_MCSPI_CHCONF_FORCE) == 0) { | ||
79 | + | ||
80 | + /* | ||
81 | + * We need to toggle CS state for OMAP take this | ||
82 | + * change in account. | ||
83 | + */ | ||
84 | + MOD_REG_BIT(cs->chconf0, OMAP2_MCSPI_CHCONF_FORCE, 1); | ||
85 | + __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); | ||
86 | + MOD_REG_BIT(cs->chconf0, OMAP2_MCSPI_CHCONF_FORCE, 0); | ||
87 | + __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); | ||
88 | + } | ||
89 | + } | ||
90 | + omap2_mcspi_disable_clocks(mcspi); | ||
91 | + return 0; | ||
92 | +} | ||
93 | +#else | ||
94 | +#define omap2_mcspi_resume NULL | ||
95 | +#endif | ||
96 | + | ||
97 | +static const struct dev_pm_ops omap2_mcspi_pm_ops = { | ||
98 | + .resume = omap2_mcspi_resume, | ||
99 | +}; | ||
100 | + | ||
101 | static struct platform_driver omap2_mcspi_driver = { | ||
102 | .driver = { | ||
103 | .name = "omap2_mcspi", | ||
104 | .owner = THIS_MODULE, | ||
105 | + .pm = &omap2_mcspi_pm_ops | ||
106 | }, | ||
107 | .remove = __exit_p(omap2_mcspi_remove), | ||
108 | }; | ||
109 | -- | ||
110 | 1.6.6.1 | ||
111 | |||