summaryrefslogtreecommitdiffstats
path: root/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd
diff options
context:
space:
mode:
Diffstat (limited to 'extras/recipes-kernel/linux/linux-omap-2.6.39/mfd')
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0001-mfd-Fix-omap-usbhs-crash-when-rmmoding-ehci-or-ohci.patch67
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0002-mfd-Fix-omap_usbhs_alloc_children-error-handling.patch50
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0003-mfd-Add-omap-usbhs-runtime-PM-support.patch245
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0004-arm-omap-usb-ehci-and-ohci-hwmod-structures-for-omap.patch406
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0005-arm-omap-usb-register-hwmods-of-usbhs.patch160
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0006-arm-omap-usb-device-name-change-for-the-clk-names-of.patch123
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0007-mfd-global-Suspend-and-resume-support-of-ehci-and-oh.patch165
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0008-MFD-TWL4030-Correct-the-warning-print-during-script-.patch36
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0009-MFD-TWL4030-Modifying-the-macro-name-Main_Ref-to-all.patch61
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0010-MFD-TWL4030-power-scripts-for-OMAP3-boards.patch705
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0011-MFD-TWL4030-TWL-version-checking.patch164
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0012-MFD-TWL4030-workaround-changes-for-Erratum-27.patch341
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0013-MFD-TWL4030-optimizing-resource-configuration.patch184
13 files changed, 2707 insertions, 0 deletions
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0001-mfd-Fix-omap-usbhs-crash-when-rmmoding-ehci-or-ohci.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0001-mfd-Fix-omap-usbhs-crash-when-rmmoding-ehci-or-ohci.patch
new file mode 100644
index 00000000..c9f1e6a9
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0001-mfd-Fix-omap-usbhs-crash-when-rmmoding-ehci-or-ohci.patch
@@ -0,0 +1,67 @@
1From 46be90d202c36db19e27c2991cbff401c6c3ee81 Mon Sep 17 00:00:00 2001
2From: Keshava Munegowda <Keshava_mgowda@ti.com>
3Date: Mon, 16 May 2011 14:24:58 +0530
4Subject: [PATCH 01/13] mfd: Fix omap usbhs crash when rmmoding ehci or ohci
5
6The disabling of clocks and freeing GPIO are changed
7to fix the occurrence of the crash of rmmod of ehci and ohci
8drivers. The GPIOs should be freed after the spin locks are
9unlocked.
10
11Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
12Acked-by: Felipe Balbi <balbi@ti.com>
13Cc: stable@kernel.org
14Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
15---
16 drivers/mfd/omap-usb-host.c | 27 +++++++++++++++++++--------
17 1 files changed, 19 insertions(+), 8 deletions(-)
18
19diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
20index 3ab9ffa..55c5d47 100644
21--- a/drivers/mfd/omap-usb-host.c
22+++ b/drivers/mfd/omap-usb-host.c
23@@ -994,22 +994,33 @@ static void usbhs_disable(struct device *dev)
24 dev_dbg(dev, "operation timed out\n");
25 }
26
27- if (pdata->ehci_data->phy_reset) {
28- if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
29- gpio_free(pdata->ehci_data->reset_gpio_port[0]);
30-
31- if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
32- gpio_free(pdata->ehci_data->reset_gpio_port[1]);
33+ if (is_omap_usbhs_rev2(omap)) {
34+ if (is_ehci_tll_mode(pdata->port_mode[0]))
35+ clk_enable(omap->usbtll_p1_fck);
36+ if (is_ehci_tll_mode(pdata->port_mode[1]))
37+ clk_enable(omap->usbtll_p2_fck);
38+ clk_disable(omap->utmi_p2_fck);
39+ clk_disable(omap->utmi_p1_fck);
40 }
41
42- clk_disable(omap->utmi_p2_fck);
43- clk_disable(omap->utmi_p1_fck);
44 clk_disable(omap->usbtll_ick);
45 clk_disable(omap->usbtll_fck);
46 clk_disable(omap->usbhost_fs_fck);
47 clk_disable(omap->usbhost_hs_fck);
48 clk_disable(omap->usbhost_ick);
49
50+ /* The gpio_free migh sleep; so unlock the spinlock */
51+ spin_unlock_irqrestore(&omap->lock, flags);
52+
53+ if (pdata->ehci_data->phy_reset) {
54+ if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
55+ gpio_free(pdata->ehci_data->reset_gpio_port[0]);
56+
57+ if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
58+ gpio_free(pdata->ehci_data->reset_gpio_port[1]);
59+ }
60+ return;
61+
62 end_disble:
63 spin_unlock_irqrestore(&omap->lock, flags);
64 }
65--
661.6.6.1
67
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0002-mfd-Fix-omap_usbhs_alloc_children-error-handling.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0002-mfd-Fix-omap_usbhs_alloc_children-error-handling.patch
new file mode 100644
index 00000000..380dd82a
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0002-mfd-Fix-omap_usbhs_alloc_children-error-handling.patch
@@ -0,0 +1,50 @@
1From 89a903aca8fda3dcf1a6f9a424247e772afdd44e Mon Sep 17 00:00:00 2001
2From: Axel Lin <axel.lin@gmail.com>
3Date: Sat, 14 May 2011 14:15:36 +0800
4Subject: [PATCH 02/13] mfd: Fix omap_usbhs_alloc_children error handling
5
61. Return proper error if omap_usbhs_alloc_child fails
72. In the case of goto err_ehci, we should call platform_device_unregister(ehci)
8 instead of platform_device_put(ehci) because we have already added the
9 platform device to device hierarchy.
10
11Signed-off-by: Axel Lin <axel.lin@gmail.com>
12Signed-off-by: Axel Lin <axel.lin@gmail.com>
13Tested-by: Keshava Munegowda <keshava_mgowda@ti.com>
14Acked-by: Felipe Balbi <balbi@ti.com>
15Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
16---
17 drivers/mfd/omap-usb-host.c | 4 +++-
18 1 files changed, 3 insertions(+), 1 deletions(-)
19
20diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
21index 55c5d47..1717144 100644
22--- a/drivers/mfd/omap-usb-host.c
23+++ b/drivers/mfd/omap-usb-host.c
24@@ -281,6 +281,7 @@ static int omap_usbhs_alloc_children(struct platform_device *pdev)
25
26 if (!ehci) {
27 dev_err(dev, "omap_usbhs_alloc_child failed\n");
28+ ret = -ENOMEM;
29 goto err_end;
30 }
31
32@@ -304,13 +305,14 @@ static int omap_usbhs_alloc_children(struct platform_device *pdev)
33 sizeof(*ohci_data), dev);
34 if (!ohci) {
35 dev_err(dev, "omap_usbhs_alloc_child failed\n");
36+ ret = -ENOMEM;
37 goto err_ehci;
38 }
39
40 return 0;
41
42 err_ehci:
43- platform_device_put(ehci);
44+ platform_device_unregister(ehci);
45
46 err_end:
47 return ret;
48--
491.6.6.1
50
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0003-mfd-Add-omap-usbhs-runtime-PM-support.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0003-mfd-Add-omap-usbhs-runtime-PM-support.patch
new file mode 100644
index 00000000..b47deb2c
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0003-mfd-Add-omap-usbhs-runtime-PM-support.patch
@@ -0,0 +1,245 @@
1From edc881f9c4897fab11542cd5c36a33b288f702be Mon Sep 17 00:00:00 2001
2From: Keshava Munegowda <Keshava_mgowda@ti.com>
3Date: Sun, 22 May 2011 22:51:26 +0200
4Subject: [PATCH 03/13] mfd: Add omap-usbhs runtime PM support
5
6The usbhs core driver does not enable/disable the interface and
7functional clocks; These clocks are handled by hwmod and runtime pm,
8hence insted of the clock enable/disable, the runtime pm APIS are
9used. however,the port clocks and tll clocks are handled
10by the usbhs core.
11
12Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
13Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
14---
15 drivers/mfd/omap-usb-host.c | 131 +++----------------------------------------
16 1 files changed, 9 insertions(+), 122 deletions(-)
17
18diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
19index 1717144..8552195 100644
20--- a/drivers/mfd/omap-usb-host.c
21+++ b/drivers/mfd/omap-usb-host.c
22@@ -26,6 +26,7 @@
23 #include <linux/spinlock.h>
24 #include <linux/gpio.h>
25 #include <plat/usb.h>
26+#include <linux/pm_runtime.h>
27
28 #define USBHS_DRIVER_NAME "usbhs-omap"
29 #define OMAP_EHCI_DEVICE "ehci-omap"
30@@ -146,9 +147,6 @@
31
32
33 struct usbhs_hcd_omap {
34- struct clk *usbhost_ick;
35- struct clk *usbhost_hs_fck;
36- struct clk *usbhost_fs_fck;
37 struct clk *xclk60mhsp1_ck;
38 struct clk *xclk60mhsp2_ck;
39 struct clk *utmi_p1_fck;
40@@ -158,8 +156,6 @@ struct usbhs_hcd_omap {
41 struct clk *usbhost_p2_fck;
42 struct clk *usbtll_p2_fck;
43 struct clk *init_60m_fclk;
44- struct clk *usbtll_fck;
45- struct clk *usbtll_ick;
46
47 void __iomem *uhh_base;
48 void __iomem *tll_base;
49@@ -353,46 +349,13 @@ static int __devinit usbhs_omap_probe(struct platform_device *pdev)
50 omap->platdata.ehci_data = pdata->ehci_data;
51 omap->platdata.ohci_data = pdata->ohci_data;
52
53- omap->usbhost_ick = clk_get(dev, "usbhost_ick");
54- if (IS_ERR(omap->usbhost_ick)) {
55- ret = PTR_ERR(omap->usbhost_ick);
56- dev_err(dev, "usbhost_ick failed error:%d\n", ret);
57- goto err_end;
58- }
59-
60- omap->usbhost_hs_fck = clk_get(dev, "hs_fck");
61- if (IS_ERR(omap->usbhost_hs_fck)) {
62- ret = PTR_ERR(omap->usbhost_hs_fck);
63- dev_err(dev, "usbhost_hs_fck failed error:%d\n", ret);
64- goto err_usbhost_ick;
65- }
66-
67- omap->usbhost_fs_fck = clk_get(dev, "fs_fck");
68- if (IS_ERR(omap->usbhost_fs_fck)) {
69- ret = PTR_ERR(omap->usbhost_fs_fck);
70- dev_err(dev, "usbhost_fs_fck failed error:%d\n", ret);
71- goto err_usbhost_hs_fck;
72- }
73-
74- omap->usbtll_fck = clk_get(dev, "usbtll_fck");
75- if (IS_ERR(omap->usbtll_fck)) {
76- ret = PTR_ERR(omap->usbtll_fck);
77- dev_err(dev, "usbtll_fck failed error:%d\n", ret);
78- goto err_usbhost_fs_fck;
79- }
80-
81- omap->usbtll_ick = clk_get(dev, "usbtll_ick");
82- if (IS_ERR(omap->usbtll_ick)) {
83- ret = PTR_ERR(omap->usbtll_ick);
84- dev_err(dev, "usbtll_ick failed error:%d\n", ret);
85- goto err_usbtll_fck;
86- }
87+ pm_runtime_enable(&pdev->dev);
88
89 omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk");
90 if (IS_ERR(omap->utmi_p1_fck)) {
91 ret = PTR_ERR(omap->utmi_p1_fck);
92 dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret);
93- goto err_usbtll_ick;
94+ goto err_end;
95 }
96
97 omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
98@@ -522,22 +485,8 @@ err_xclk60mhsp1_ck:
99 err_utmi_p1_fck:
100 clk_put(omap->utmi_p1_fck);
101
102-err_usbtll_ick:
103- clk_put(omap->usbtll_ick);
104-
105-err_usbtll_fck:
106- clk_put(omap->usbtll_fck);
107-
108-err_usbhost_fs_fck:
109- clk_put(omap->usbhost_fs_fck);
110-
111-err_usbhost_hs_fck:
112- clk_put(omap->usbhost_hs_fck);
113-
114-err_usbhost_ick:
115- clk_put(omap->usbhost_ick);
116-
117 err_end:
118+ pm_runtime_disable(&pdev->dev);
119 kfree(omap);
120
121 end_probe:
122@@ -571,11 +520,7 @@ static int __devexit usbhs_omap_remove(struct platform_device *pdev)
123 clk_put(omap->utmi_p2_fck);
124 clk_put(omap->xclk60mhsp1_ck);
125 clk_put(omap->utmi_p1_fck);
126- clk_put(omap->usbtll_ick);
127- clk_put(omap->usbtll_fck);
128- clk_put(omap->usbhost_fs_fck);
129- clk_put(omap->usbhost_hs_fck);
130- clk_put(omap->usbhost_ick);
131+ pm_runtime_disable(&pdev->dev);
132 kfree(omap);
133
134 return 0;
135@@ -695,7 +640,6 @@ static int usbhs_enable(struct device *dev)
136 struct usbhs_omap_platform_data *pdata = &omap->platdata;
137 unsigned long flags = 0;
138 int ret = 0;
139- unsigned long timeout;
140 unsigned reg;
141
142 dev_dbg(dev, "starting TI HSUSB Controller\n");
143@@ -708,11 +652,7 @@ static int usbhs_enable(struct device *dev)
144 if (omap->count > 0)
145 goto end_count;
146
147- clk_enable(omap->usbhost_ick);
148- clk_enable(omap->usbhost_hs_fck);
149- clk_enable(omap->usbhost_fs_fck);
150- clk_enable(omap->usbtll_fck);
151- clk_enable(omap->usbtll_ick);
152+ pm_runtime_get_sync(dev);
153
154 if (pdata->ehci_data->phy_reset) {
155 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) {
156@@ -736,50 +676,6 @@ static int usbhs_enable(struct device *dev)
157 omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
158 dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
159
160- /* perform TLL soft reset, and wait until reset is complete */
161- usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG,
162- OMAP_USBTLL_SYSCONFIG_SOFTRESET);
163-
164- /* Wait for TLL reset to complete */
165- timeout = jiffies + msecs_to_jiffies(1000);
166- while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS)
167- & OMAP_USBTLL_SYSSTATUS_RESETDONE)) {
168- cpu_relax();
169-
170- if (time_after(jiffies, timeout)) {
171- dev_dbg(dev, "operation timed out\n");
172- ret = -EINVAL;
173- goto err_tll;
174- }
175- }
176-
177- dev_dbg(dev, "TLL RESET DONE\n");
178-
179- /* (1<<3) = no idle mode only for initial debugging */
180- usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG,
181- OMAP_USBTLL_SYSCONFIG_ENAWAKEUP |
182- OMAP_USBTLL_SYSCONFIG_SIDLEMODE |
183- OMAP_USBTLL_SYSCONFIG_AUTOIDLE);
184-
185- /* Put UHH in NoIdle/NoStandby mode */
186- reg = usbhs_read(omap->uhh_base, OMAP_UHH_SYSCONFIG);
187- if (is_omap_usbhs_rev1(omap)) {
188- reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP
189- | OMAP_UHH_SYSCONFIG_SIDLEMODE
190- | OMAP_UHH_SYSCONFIG_CACTIVITY
191- | OMAP_UHH_SYSCONFIG_MIDLEMODE);
192- reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE;
193-
194-
195- } else if (is_omap_usbhs_rev2(omap)) {
196- reg &= ~OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR;
197- reg |= OMAP4_UHH_SYSCONFIG_NOIDLE;
198- reg &= ~OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR;
199- reg |= OMAP4_UHH_SYSCONFIG_NOSTDBY;
200- }
201-
202- usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg);
203-
204 reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG);
205 /* setup ULPI bypass and burst configurations */
206 reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN
207@@ -919,6 +815,8 @@ end_count:
208 return 0;
209
210 err_tll:
211+ pm_runtime_put_sync(dev);
212+ spin_unlock_irqrestore(&omap->lock, flags);
213 if (pdata->ehci_data->phy_reset) {
214 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
215 gpio_free(pdata->ehci_data->reset_gpio_port[0]);
216@@ -926,13 +824,6 @@ err_tll:
217 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
218 gpio_free(pdata->ehci_data->reset_gpio_port[1]);
219 }
220-
221- clk_disable(omap->usbtll_ick);
222- clk_disable(omap->usbtll_fck);
223- clk_disable(omap->usbhost_fs_fck);
224- clk_disable(omap->usbhost_hs_fck);
225- clk_disable(omap->usbhost_ick);
226- spin_unlock_irqrestore(&omap->lock, flags);
227 return ret;
228 }
229
230@@ -1005,11 +896,7 @@ static void usbhs_disable(struct device *dev)
231 clk_disable(omap->utmi_p1_fck);
232 }
233
234- clk_disable(omap->usbtll_ick);
235- clk_disable(omap->usbtll_fck);
236- clk_disable(omap->usbhost_fs_fck);
237- clk_disable(omap->usbhost_hs_fck);
238- clk_disable(omap->usbhost_ick);
239+ pm_runtime_put_sync(dev);
240
241 /* The gpio_free migh sleep; so unlock the spinlock */
242 spin_unlock_irqrestore(&omap->lock, flags);
243--
2441.6.6.1
245
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0004-arm-omap-usb-ehci-and-ohci-hwmod-structures-for-omap.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0004-arm-omap-usb-ehci-and-ohci-hwmod-structures-for-omap.patch
new file mode 100644
index 00000000..3d4d8a2d
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0004-arm-omap-usb-ehci-and-ohci-hwmod-structures-for-omap.patch
@@ -0,0 +1,406 @@
1From 339b167f6f76707a2d6ae3a7c0b921b8278564af Mon Sep 17 00:00:00 2001
2From: Keshava Munegowda <Keshava_mgowda@ti.com>
3Date: Wed, 1 Jun 2011 11:02:49 -0700
4Subject: [PATCH 04/13] arm: omap: usb: ehci and ohci hwmod structures for omap3 and omap4
5
6Following 2 hwmod strcuture are added:
7UHH hwmod of usbhs with uhh base address and
8EHCI , OHCI irq and base addresses.
9TLL hwmod of usbhs with the TLL base address and irq.
10
11Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
12---
13 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 184 ++++++++++++++++++++++++++++
14 arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 153 +++++++++++++++++++++++
15 2 files changed, 337 insertions(+), 0 deletions(-)
16
17diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
18index 909a84d..fe9a176 100644
19--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
20+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
21@@ -84,6 +84,8 @@ static struct omap_hwmod omap3xxx_mcbsp4_hwmod;
22 static struct omap_hwmod omap3xxx_mcbsp5_hwmod;
23 static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod;
24 static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod;
25+static struct omap_hwmod omap34xx_usb_host_hs_hwmod;
26+static struct omap_hwmod omap34xx_usb_tll_hs_hwmod;
27
28 /* L3 -> L4_CORE interface */
29 static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = {
30@@ -3574,6 +3576,185 @@ static struct omap_hwmod omap3xxx_mmc3_hwmod = {
31 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
32 };
33
34+/*
35+ * 'usb_host_hs' class
36+ * high-speed multi-port usb host controller
37+ */
38+static struct omap_hwmod_ocp_if omap34xx_usb_host_hs__l3_main_2 = {
39+ .master = &omap34xx_usb_host_hs_hwmod,
40+ .slave = &omap3xxx_l3_main_hwmod,
41+ .clk = "core_l3_ick",
42+ .user = OCP_USER_MPU,
43+};
44+
45+static struct omap_hwmod_class_sysconfig omap34xx_usb_host_hs_sysc = {
46+ .rev_offs = 0x0000,
47+ .sysc_offs = 0x0010,
48+ .syss_offs = 0x0014,
49+ .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE),
50+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
51+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
52+ .sysc_fields = &omap_hwmod_sysc_type1,
53+};
54+
55+static struct omap_hwmod_class omap34xx_usb_host_hs_hwmod_class = {
56+ .name = "usbhs_uhh",
57+ .sysc = &omap34xx_usb_host_hs_sysc,
58+};
59+
60+static struct omap_hwmod_ocp_if *omap34xx_usb_host_hs_masters[] = {
61+ &omap34xx_usb_host_hs__l3_main_2,
62+};
63+
64+static struct omap_hwmod_irq_info omap34xx_usb_host_hs_irqs[] = {
65+ { .name = "ohci-irq", .irq = 76 },
66+ { .name = "ehci-irq", .irq = 77 },
67+};
68+
69+static struct omap_hwmod_addr_space omap34xx_usb_host_hs_addrs[] = {
70+ {
71+ .name = "uhh",
72+ .pa_start = 0x48064000,
73+ .pa_end = 0x480643ff,
74+ .flags = ADDR_TYPE_RT
75+ },
76+ {
77+ .name = "ohci",
78+ .pa_start = 0x48064400,
79+ .pa_end = 0x480647FF,
80+ .flags = ADDR_MAP_ON_INIT
81+ },
82+ {
83+ .name = "ehci",
84+ .pa_start = 0x48064800,
85+ .pa_end = 0x48064CFF,
86+ .flags = ADDR_MAP_ON_INIT
87+ }
88+};
89+
90+static struct omap_hwmod_ocp_if omap34xx_l4_cfg__usb_host_hs = {
91+ .master = &omap3xxx_l4_core_hwmod,
92+ .slave = &omap34xx_usb_host_hs_hwmod,
93+ .clk = "l4_ick",
94+ .addr = omap34xx_usb_host_hs_addrs,
95+ .addr_cnt = ARRAY_SIZE(omap34xx_usb_host_hs_addrs),
96+ .user = OCP_USER_MPU | OCP_USER_SDMA,
97+};
98+
99+static struct omap_hwmod_ocp_if omap34xx_f128m_cfg__usb_host_hs = {
100+ .clk = "usbhost_120m_fck",
101+ .user = OCP_USER_MPU,
102+ .flags = OCPIF_SWSUP_IDLE,
103+};
104+
105+static struct omap_hwmod_ocp_if omap34xx_f48m_cfg__usb_host_hs = {
106+ .clk = "usbhost_48m_fck",
107+ .user = OCP_USER_MPU,
108+ .flags = OCPIF_SWSUP_IDLE,
109+};
110+
111+static struct omap_hwmod_ocp_if *omap34xx_usb_host_hs_slaves[] = {
112+ &omap34xx_l4_cfg__usb_host_hs,
113+ &omap34xx_f128m_cfg__usb_host_hs,
114+ &omap34xx_f48m_cfg__usb_host_hs,
115+};
116+
117+static struct omap_hwmod omap34xx_usb_host_hs_hwmod = {
118+ .name = "usbhs_uhh",
119+ .class = &omap34xx_usb_host_hs_hwmod_class,
120+ .mpu_irqs = omap34xx_usb_host_hs_irqs,
121+ .mpu_irqs_cnt = ARRAY_SIZE(omap34xx_usb_host_hs_irqs),
122+ .main_clk = "usbhost_ick",
123+ .prcm = {
124+ .omap2 = {
125+ .module_offs = OMAP3430ES2_USBHOST_MOD,
126+ .prcm_reg_id = 1,
127+ .module_bit = 0,
128+ .idlest_reg_id = 1,
129+ .idlest_idle_bit = 1,
130+ .idlest_stdby_bit = 0,
131+ },
132+ },
133+ .slaves = omap34xx_usb_host_hs_slaves,
134+ .slaves_cnt = ARRAY_SIZE(omap34xx_usb_host_hs_slaves),
135+ .masters = omap34xx_usb_host_hs_masters,
136+ .masters_cnt = ARRAY_SIZE(omap34xx_usb_host_hs_masters),
137+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
138+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
139+};
140+
141+/*
142+ * 'usb_tll_hs' class
143+ * usb_tll_hs module is the adapter on the usb_host_hs ports
144+ */
145+static struct omap_hwmod_class_sysconfig omap34xx_usb_tll_hs_sysc = {
146+ .rev_offs = 0x0000,
147+ .sysc_offs = 0x0010,
148+ .syss_offs = 0x0014,
149+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE),
150+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
151+ .sysc_fields = &omap_hwmod_sysc_type1,
152+};
153+
154+static struct omap_hwmod_class omap34xx_usb_tll_hs_hwmod_class = {
155+ .name = "usbhs_tll",
156+ .sysc = &omap34xx_usb_tll_hs_sysc,
157+};
158+
159+static struct omap_hwmod_irq_info omap34xx_usb_tll_hs_irqs[] = {
160+ { .name = "tll-irq", .irq = 78 },
161+};
162+
163+static struct omap_hwmod_addr_space omap34xx_usb_tll_hs_addrs[] = {
164+ {
165+ .name = "tll",
166+ .pa_start = 0x48062000,
167+ .pa_end = 0x48062fff,
168+ .flags = ADDR_TYPE_RT
169+ },
170+};
171+
172+static struct omap_hwmod_ocp_if omap34xx_f_cfg__usb_tll_hs = {
173+ .clk = "usbtll_fck",
174+ .user = OCP_USER_MPU,
175+ .flags = OCPIF_SWSUP_IDLE,
176+};
177+
178+static struct omap_hwmod_ocp_if omap34xx_l4_cfg__usb_tll_hs = {
179+ .master = &omap3xxx_l4_core_hwmod,
180+ .slave = &omap34xx_usb_tll_hs_hwmod,
181+ .clk = "l4_ick",
182+ .addr = omap34xx_usb_tll_hs_addrs,
183+ .addr_cnt = ARRAY_SIZE(omap34xx_usb_tll_hs_addrs),
184+ .user = OCP_USER_MPU | OCP_USER_SDMA,
185+};
186+
187+static struct omap_hwmod_ocp_if *omap34xx_usb_tll_hs_slaves[] = {
188+ &omap34xx_l4_cfg__usb_tll_hs,
189+ &omap34xx_f_cfg__usb_tll_hs,
190+};
191+
192+static struct omap_hwmod omap34xx_usb_tll_hs_hwmod = {
193+ .name = "usbhs_tll",
194+ .class = &omap34xx_usb_tll_hs_hwmod_class,
195+ .mpu_irqs = omap34xx_usb_tll_hs_irqs,
196+ .mpu_irqs_cnt = ARRAY_SIZE(omap34xx_usb_tll_hs_irqs),
197+ .main_clk = "usbtll_ick",
198+ .prcm = {
199+ .omap2 = {
200+ .module_offs = CORE_MOD,
201+ .prcm_reg_id = 3,
202+ .module_bit = 2,
203+ .idlest_reg_id = 3,
204+ .idlest_idle_bit = 2,
205+ },
206+ },
207+ .slaves = omap34xx_usb_tll_hs_slaves,
208+ .slaves_cnt = ARRAY_SIZE(omap34xx_usb_tll_hs_slaves),
209+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
210+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
211+};
212+
213 static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
214 &omap3xxx_l3_main_hwmod,
215 &omap3xxx_l4_core_hwmod,
216@@ -3656,6 +3837,9 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
217 /* usbotg for am35x */
218 &am35xx_usbhsotg_hwmod,
219
220+ &omap34xx_usb_host_hs_hwmod,
221+ &omap34xx_usb_tll_hs_hwmod,
222+
223 NULL,
224 };
225
226diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
227index abc548a..d7112b0 100644
228--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
229+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
230@@ -66,6 +66,8 @@ static struct omap_hwmod omap44xx_mmc2_hwmod;
231 static struct omap_hwmod omap44xx_mpu_hwmod;
232 static struct omap_hwmod omap44xx_mpu_private_hwmod;
233 static struct omap_hwmod omap44xx_usb_otg_hs_hwmod;
234+static struct omap_hwmod omap44xx_usb_host_hs_hwmod;
235+static struct omap_hwmod omap44xx_usb_tll_hs_hwmod;
236
237 /*
238 * Interconnects omap_hwmod structures
239@@ -5027,6 +5029,155 @@ static struct omap_hwmod omap44xx_wd_timer3_hwmod = {
240 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
241 };
242
243+/*
244+ * 'usb_host_hs' class
245+ * high-speed multi-port usb host controller
246+ */
247+static struct omap_hwmod_ocp_if omap44xx_usb_host_hs__l3_main_2 = {
248+ .master = &omap44xx_usb_host_hs_hwmod,
249+ .slave = &omap44xx_l3_main_2_hwmod,
250+ .clk = "l3_div_ck",
251+ .user = OCP_USER_MPU | OCP_USER_SDMA,
252+};
253+
254+static struct omap_hwmod_class_sysconfig omap44xx_usb_host_hs_sysc = {
255+ .rev_offs = 0x0000,
256+ .sysc_offs = 0x0010,
257+ .syss_offs = 0x0014,
258+ .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE),
259+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
260+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
261+ .sysc_fields = &omap_hwmod_sysc_type2,
262+};
263+
264+static struct omap_hwmod_class omap44xx_usb_host_hs_hwmod_class = {
265+ .name = "usbhs_uhh",
266+ .sysc = &omap44xx_usb_host_hs_sysc,
267+};
268+
269+static struct omap_hwmod_ocp_if *omap44xx_usb_host_hs_masters[] = {
270+ &omap44xx_usb_host_hs__l3_main_2,
271+};
272+
273+static struct omap_hwmod_irq_info omap44xx_usb_host_hs_irqs[] = {
274+ { .name = "ohci-irq", .irq = 76 + OMAP44XX_IRQ_GIC_START },
275+ { .name = "ehci-irq", .irq = 77 + OMAP44XX_IRQ_GIC_START },
276+};
277+
278+static struct omap_hwmod_addr_space omap44xx_usb_host_hs_addrs[] = {
279+ {
280+ .name = "uhh",
281+ .pa_start = 0x4a064000,
282+ .pa_end = 0x4a0647ff,
283+ .flags = ADDR_TYPE_RT
284+ },
285+ {
286+ .name = "ohci",
287+ .pa_start = 0x4A064800,
288+ .pa_end = 0x4A064BFF,
289+ .flags = ADDR_MAP_ON_INIT
290+ },
291+ {
292+ .name = "ehci",
293+ .pa_start = 0x4A064C00,
294+ .pa_end = 0x4A064FFF,
295+ .flags = ADDR_MAP_ON_INIT
296+ }
297+};
298+
299+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_host_hs = {
300+ .master = &omap44xx_l4_cfg_hwmod,
301+ .slave = &omap44xx_usb_host_hs_hwmod,
302+ .clk = "l4_div_ck",
303+ .addr = omap44xx_usb_host_hs_addrs,
304+ .addr_cnt = ARRAY_SIZE(omap44xx_usb_host_hs_addrs),
305+ .user = OCP_USER_MPU | OCP_USER_SDMA,
306+};
307+
308+static struct omap_hwmod_ocp_if *omap44xx_usb_host_hs_slaves[] = {
309+ &omap44xx_l4_cfg__usb_host_hs,
310+};
311+
312+static struct omap_hwmod omap44xx_usb_host_hs_hwmod = {
313+ .name = "usbhs_uhh",
314+ .class = &omap44xx_usb_host_hs_hwmod_class,
315+ .mpu_irqs = omap44xx_usb_host_hs_irqs,
316+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_usb_host_hs_irqs),
317+ .main_clk = "usb_host_hs_fck",
318+ .prcm = {
319+ .omap4 = {
320+ .clkctrl_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
321+ },
322+ },
323+ .slaves = omap44xx_usb_host_hs_slaves,
324+ .slaves_cnt = ARRAY_SIZE(omap44xx_usb_host_hs_slaves),
325+ .masters = omap44xx_usb_host_hs_masters,
326+ .masters_cnt = ARRAY_SIZE(omap44xx_usb_host_hs_masters),
327+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
328+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
329+};
330+
331+/*
332+ * 'usb_tll_hs' class
333+ * usb_tll_hs module is the adapter on the usb_host_hs ports
334+ */
335+static struct omap_hwmod_class_sysconfig omap44xx_usb_tll_hs_sysc = {
336+ .rev_offs = 0x0000,
337+ .sysc_offs = 0x0010,
338+ .syss_offs = 0x0014,
339+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE),
340+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
341+ .sysc_fields = &omap_hwmod_sysc_type1,
342+};
343+
344+static struct omap_hwmod_class omap44xx_usb_tll_hs_hwmod_class = {
345+ .name = "usbhs_tll",
346+ .sysc = &omap44xx_usb_tll_hs_sysc,
347+};
348+
349+static struct omap_hwmod_irq_info omap44xx_usb_tll_hs_irqs[] = {
350+ { .name = "tll-irq", .irq = 78 + OMAP44XX_IRQ_GIC_START },
351+};
352+
353+static struct omap_hwmod_addr_space omap44xx_usb_tll_hs_addrs[] = {
354+ {
355+ .name = "tll",
356+ .pa_start = 0x4a062000,
357+ .pa_end = 0x4a063fff,
358+ .flags = ADDR_TYPE_RT
359+ },
360+};
361+
362+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_tll_hs = {
363+ .master = &omap44xx_l4_cfg_hwmod,
364+ .slave = &omap44xx_usb_tll_hs_hwmod,
365+ .clk = "l4_div_ck",
366+ .addr = omap44xx_usb_tll_hs_addrs,
367+ .addr_cnt = ARRAY_SIZE(omap44xx_usb_tll_hs_addrs),
368+ .user = OCP_USER_MPU | OCP_USER_SDMA,
369+};
370+
371+static struct omap_hwmod_ocp_if *omap44xx_usb_tll_hs_slaves[] = {
372+ &omap44xx_l4_cfg__usb_tll_hs,
373+};
374+
375+static struct omap_hwmod omap44xx_usb_tll_hs_hwmod = {
376+ .name = "usbhs_tll",
377+ .class = &omap44xx_usb_tll_hs_hwmod_class,
378+ .mpu_irqs = omap44xx_usb_tll_hs_irqs,
379+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_usb_tll_hs_irqs),
380+ .main_clk = "usb_tll_hs_ick",
381+ .prcm = {
382+ .omap4 = {
383+ .clkctrl_reg = OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
384+ },
385+ },
386+ .slaves = omap44xx_usb_tll_hs_slaves,
387+ .slaves_cnt = ARRAY_SIZE(omap44xx_usb_tll_hs_slaves),
388+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
389+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
390+};
391+
392 static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
393
394 /* dmm class */
395@@ -5173,6 +5324,8 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
396 &omap44xx_wd_timer2_hwmod,
397 &omap44xx_wd_timer3_hwmod,
398
399+ &omap44xx_usb_host_hs_hwmod,
400+ &omap44xx_usb_tll_hs_hwmod,
401 NULL,
402 };
403
404--
4051.6.6.1
406
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0005-arm-omap-usb-register-hwmods-of-usbhs.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0005-arm-omap-usb-register-hwmods-of-usbhs.patch
new file mode 100644
index 00000000..8e9a4ba4
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0005-arm-omap-usb-register-hwmods-of-usbhs.patch
@@ -0,0 +1,160 @@
1From 70f5e1a0e6639710503a9ffb9008ddcd2bb3f06e Mon Sep 17 00:00:00 2001
2From: Keshava Munegowda <Keshava_mgowda@ti.com>
3Date: Wed, 1 Jun 2011 11:02:54 -0700
4Subject: [PATCH 05/13] arm: omap: usb: register hwmods of usbhs
5
6The hwmod structure of uhh and tll are retrived
7and registered with omap device
8
9Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
10---
11 arch/arm/mach-omap2/usb-host.c | 99 ++++++++++++++--------------------------
12 1 files changed, 35 insertions(+), 64 deletions(-)
13
14diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c
15index 89ae298..9d762c4 100644
16--- a/arch/arm/mach-omap2/usb-host.c
17+++ b/arch/arm/mach-omap2/usb-host.c
18@@ -28,51 +28,28 @@
19 #include <mach/hardware.h>
20 #include <mach/irqs.h>
21 #include <plat/usb.h>
22+#include <plat/omap_device.h>
23
24 #include "mux.h"
25
26 #ifdef CONFIG_MFD_OMAP_USB_HOST
27
28-#define OMAP_USBHS_DEVICE "usbhs-omap"
29-
30-static struct resource usbhs_resources[] = {
31- {
32- .name = "uhh",
33- .flags = IORESOURCE_MEM,
34- },
35- {
36- .name = "tll",
37- .flags = IORESOURCE_MEM,
38- },
39- {
40- .name = "ehci",
41- .flags = IORESOURCE_MEM,
42- },
43- {
44- .name = "ehci-irq",
45- .flags = IORESOURCE_IRQ,
46- },
47- {
48- .name = "ohci",
49- .flags = IORESOURCE_MEM,
50- },
51- {
52- .name = "ohci-irq",
53- .flags = IORESOURCE_IRQ,
54- }
55-};
56-
57-static struct platform_device usbhs_device = {
58- .name = OMAP_USBHS_DEVICE,
59- .id = 0,
60- .num_resources = ARRAY_SIZE(usbhs_resources),
61- .resource = usbhs_resources,
62-};
63+#define OMAP_USBHS_DEVICE "usbhs_omap"
64+#define USBHS_UHH_HWMODNAME "usbhs_uhh"
65+#define USBHS_TLL_HWMODNAME "usbhs_tll"
66
67 static struct usbhs_omap_platform_data usbhs_data;
68 static struct ehci_hcd_omap_platform_data ehci_data;
69 static struct ohci_hcd_omap_platform_data ohci_data;
70
71+static struct omap_device_pm_latency omap_uhhtll_latency[] = {
72+ {
73+ .deactivate_func = omap_device_idle_hwmods,
74+ .activate_func = omap_device_enable_hwmods,
75+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
76+ },
77+};
78+
79 /* MUX settings for EHCI pins */
80 /*
81 * setup_ehci_io_mux - initialize IO pad mux for USBHOST
82@@ -508,7 +485,10 @@ static void setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode)
83
84 void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
85 {
86- int i;
87+ struct omap_hwmod *oh[2];
88+ struct omap_device *od;
89+ int bus_id = -1;
90+ int i;
91
92 for (i = 0; i < OMAP3_HS_USB_PORTS; i++) {
93 usbhs_data.port_mode[i] = pdata->port_mode[i];
94@@ -523,44 +503,35 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
95 usbhs_data.ohci_data = &ohci_data;
96
97 if (cpu_is_omap34xx()) {
98- usbhs_resources[0].start = OMAP34XX_UHH_CONFIG_BASE;
99- usbhs_resources[0].end = OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1;
100- usbhs_resources[1].start = OMAP34XX_USBTLL_BASE;
101- usbhs_resources[1].end = OMAP34XX_USBTLL_BASE + SZ_4K - 1;
102- usbhs_resources[2].start = OMAP34XX_EHCI_BASE;
103- usbhs_resources[2].end = OMAP34XX_EHCI_BASE + SZ_1K - 1;
104- usbhs_resources[3].start = INT_34XX_EHCI_IRQ;
105- usbhs_resources[4].start = OMAP34XX_OHCI_BASE;
106- usbhs_resources[4].end = OMAP34XX_OHCI_BASE + SZ_1K - 1;
107- usbhs_resources[5].start = INT_34XX_OHCI_IRQ;
108 setup_ehci_io_mux(pdata->port_mode);
109 setup_ohci_io_mux(pdata->port_mode);
110 } else if (cpu_is_omap44xx()) {
111- usbhs_resources[0].start = OMAP44XX_UHH_CONFIG_BASE;
112- usbhs_resources[0].end = OMAP44XX_UHH_CONFIG_BASE + SZ_1K - 1;
113- usbhs_resources[1].start = OMAP44XX_USBTLL_BASE;
114- usbhs_resources[1].end = OMAP44XX_USBTLL_BASE + SZ_4K - 1;
115- usbhs_resources[2].start = OMAP44XX_HSUSB_EHCI_BASE;
116- usbhs_resources[2].end = OMAP44XX_HSUSB_EHCI_BASE + SZ_1K - 1;
117- usbhs_resources[3].start = OMAP44XX_IRQ_EHCI;
118- usbhs_resources[4].start = OMAP44XX_HSUSB_OHCI_BASE;
119- usbhs_resources[4].end = OMAP44XX_HSUSB_OHCI_BASE + SZ_1K - 1;
120- usbhs_resources[5].start = OMAP44XX_IRQ_OHCI;
121 setup_4430ehci_io_mux(pdata->port_mode);
122 setup_4430ohci_io_mux(pdata->port_mode);
123 }
124
125- if (platform_device_add_data(&usbhs_device,
126- &usbhs_data, sizeof(usbhs_data)) < 0) {
127- printk(KERN_ERR "USBHS platform_device_add_data failed\n");
128- goto init_end;
129+ oh[0] = omap_hwmod_lookup(USBHS_UHH_HWMODNAME);
130+ if (!oh[0]) {
131+ pr_err("Could not look up %s\n", USBHS_UHH_HWMODNAME);
132+ return;
133 }
134
135- if (platform_device_register(&usbhs_device) < 0)
136- printk(KERN_ERR "USBHS platform_device_register failed\n");
137+ oh[1] = omap_hwmod_lookup(USBHS_TLL_HWMODNAME);
138+ if (!oh[1]) {
139+ pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME);
140+ return;
141+ }
142
143-init_end:
144- return;
145+ od = omap_device_build_ss(OMAP_USBHS_DEVICE, bus_id, oh, 2,
146+ (void *)&usbhs_data, sizeof(usbhs_data),
147+ omap_uhhtll_latency,
148+ ARRAY_SIZE(omap_uhhtll_latency), false);
149+
150+ if (IS_ERR(od)) {
151+ pr_err("Could not build hwmod devices %s, %s\n",
152+ USBHS_UHH_HWMODNAME, USBHS_TLL_HWMODNAME);
153+ return;
154+ }
155 }
156
157 #else
158--
1591.6.6.1
160
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0006-arm-omap-usb-device-name-change-for-the-clk-names-of.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0006-arm-omap-usb-device-name-change-for-the-clk-names-of.patch
new file mode 100644
index 00000000..c0ac58bf
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0006-arm-omap-usb-device-name-change-for-the-clk-names-of.patch
@@ -0,0 +1,123 @@
1From 64bc651bb56435e4cd86d2ebfa4f301abdbac6e5 Mon Sep 17 00:00:00 2001
2From: Keshava Munegowda <Keshava_mgowda@ti.com>
3Date: Wed, 1 Jun 2011 11:02:58 -0700
4Subject: [PATCH 06/13] arm: omap: usb: device name change for the clk names of usbhs
5
6device name usbhs clocks are changed from
7usbhs-omap.0 to usbhs_omap; this is because
8in the hwmod registration the device name is set
9as usbhs_omap
10
11Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
12---
13 arch/arm/mach-omap2/clock3xxx_data.c | 28 ++++++++++++++--------------
14 arch/arm/mach-omap2/clock44xx_data.c | 10 +++++-----
15 drivers/mfd/omap-usb-host.c | 2 +-
16 3 files changed, 20 insertions(+), 20 deletions(-)
17
18diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
19index 75b119b..fabe482 100644
20--- a/arch/arm/mach-omap2/clock3xxx_data.c
21+++ b/arch/arm/mach-omap2/clock3xxx_data.c
22@@ -3285,7 +3285,7 @@ static struct omap_clk omap3xxx_clks[] = {
23 CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
24 CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
25 CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
26- CLK("usbhs-omap.0", "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
27+ CLK("usbhs_omap", "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
28 CLK("omap-mcbsp.1", "prcm_fck", &core_96m_fck, CK_3XXX),
29 CLK("omap-mcbsp.5", "prcm_fck", &core_96m_fck, CK_3XXX),
30 CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX),
31@@ -3321,7 +3321,7 @@ static struct omap_clk omap3xxx_clks[] = {
32 CLK(NULL, "pka_ick", &pka_ick, CK_34XX | CK_36XX),
33 CLK(NULL, "core_l4_ick", &core_l4_ick, CK_3XXX),
34 CLK(NULL, "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
35- CLK("usbhs-omap.0", "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
36+ CLK("usbhs_omap", "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
37 CLK("omap_hsmmc.2", "ick", &mmchs3_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
38 CLK(NULL, "icr_ick", &icr_ick, CK_34XX | CK_36XX),
39 CLK("omap-aes", "ick", &aes2_ick, CK_34XX | CK_36XX),
40@@ -3367,20 +3367,20 @@ static struct omap_clk omap3xxx_clks[] = {
41 CLK(NULL, "cam_ick", &cam_ick, CK_34XX | CK_36XX),
42 CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_34XX | CK_36XX),
43 CLK(NULL, "usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
44- CLK("usbhs-omap.0", "hs_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
45+ CLK("usbhs_omap", "hs_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
46 CLK(NULL, "usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
47- CLK("usbhs-omap.0", "fs_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
48+ CLK("usbhs_omap", "fs_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
49 CLK(NULL, "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
50- CLK("usbhs-omap.0", "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
51- CLK("usbhs-omap.0", "utmi_p1_gfclk", &dummy_ck, CK_3XXX),
52- CLK("usbhs-omap.0", "utmi_p2_gfclk", &dummy_ck, CK_3XXX),
53- CLK("usbhs-omap.0", "xclk60mhsp1_ck", &dummy_ck, CK_3XXX),
54- CLK("usbhs-omap.0", "xclk60mhsp2_ck", &dummy_ck, CK_3XXX),
55- CLK("usbhs-omap.0", "usb_host_hs_utmi_p1_clk", &dummy_ck, CK_3XXX),
56- CLK("usbhs-omap.0", "usb_host_hs_utmi_p2_clk", &dummy_ck, CK_3XXX),
57- CLK("usbhs-omap.0", "usb_tll_hs_usb_ch0_clk", &dummy_ck, CK_3XXX),
58- CLK("usbhs-omap.0", "usb_tll_hs_usb_ch1_clk", &dummy_ck, CK_3XXX),
59- CLK("usbhs-omap.0", "init_60m_fclk", &dummy_ck, CK_3XXX),
60+ CLK("usbhs_omap", "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
61+ CLK("usbhs_omap", "utmi_p1_gfclk", &dummy_ck, CK_3XXX),
62+ CLK("usbhs_omap", "utmi_p2_gfclk", &dummy_ck, CK_3XXX),
63+ CLK("usbhs_omap", "xclk60mhsp1_ck", &dummy_ck, CK_3XXX),
64+ CLK("usbhs_omap", "xclk60mhsp2_ck", &dummy_ck, CK_3XXX),
65+ CLK("usbhs_omap", "usb_host_hs_utmi_p1_clk", &dummy_ck, CK_3XXX),
66+ CLK("usbhs_omap", "usb_host_hs_utmi_p2_clk", &dummy_ck, CK_3XXX),
67+ CLK("usbhs_omap", "usb_tll_hs_usb_ch0_clk", &dummy_ck, CK_3XXX),
68+ CLK("usbhs_omap", "usb_tll_hs_usb_ch1_clk", &dummy_ck, CK_3XXX),
69+ CLK("usbhs_omap", "init_60m_fclk", &dummy_ck, CK_3XXX),
70 CLK(NULL, "usim_fck", &usim_fck, CK_3430ES2PLUS | CK_36XX),
71 CLK(NULL, "gpt1_fck", &gpt1_fck, CK_3XXX),
72 CLK(NULL, "wkup_32k_fck", &wkup_32k_fck, CK_3XXX),
73diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
74index 8c96567..34e91eb 100644
75--- a/arch/arm/mach-omap2/clock44xx_data.c
76+++ b/arch/arm/mach-omap2/clock44xx_data.c
77@@ -3205,7 +3205,7 @@ static struct omap_clk omap44xx_clks[] = {
78 CLK(NULL, "uart3_fck", &uart3_fck, CK_443X),
79 CLK(NULL, "uart4_fck", &uart4_fck, CK_443X),
80 CLK(NULL, "usb_host_fs_fck", &usb_host_fs_fck, CK_443X),
81- CLK("usbhs-omap.0", "fs_fck", &usb_host_fs_fck, CK_443X),
82+ CLK("usbhs_omap", "fs_fck", &usb_host_fs_fck, CK_443X),
83 CLK(NULL, "utmi_p1_gfclk", &utmi_p1_gfclk, CK_443X),
84 CLK(NULL, "usb_host_hs_utmi_p1_clk", &usb_host_hs_utmi_p1_clk, CK_443X),
85 CLK(NULL, "utmi_p2_gfclk", &utmi_p2_gfclk, CK_443X),
86@@ -3217,8 +3217,8 @@ static struct omap_clk omap44xx_clks[] = {
87 CLK(NULL, "usb_host_hs_hsic480m_p2_clk", &usb_host_hs_hsic480m_p2_clk, CK_443X),
88 CLK(NULL, "usb_host_hs_func48mclk", &usb_host_hs_func48mclk, CK_443X),
89 CLK(NULL, "usb_host_hs_fck", &usb_host_hs_fck, CK_443X),
90- CLK("usbhs-omap.0", "hs_fck", &usb_host_hs_fck, CK_443X),
91- CLK("usbhs-omap.0", "usbhost_ick", &dummy_ck, CK_443X),
92+ CLK("usbhs_omap", "hs_fck", &usb_host_hs_fck, CK_443X),
93+ CLK("usbhs_omap", "usbhost_ick", &dummy_ck, CK_443X),
94 CLK(NULL, "otg_60m_gfclk", &otg_60m_gfclk, CK_443X),
95 CLK(NULL, "usb_otg_hs_xclk", &usb_otg_hs_xclk, CK_443X),
96 CLK("musb-omap2430", "ick", &usb_otg_hs_ick, CK_443X),
97@@ -3227,8 +3227,8 @@ static struct omap_clk omap44xx_clks[] = {
98 CLK(NULL, "usb_tll_hs_usb_ch0_clk", &usb_tll_hs_usb_ch0_clk, CK_443X),
99 CLK(NULL, "usb_tll_hs_usb_ch1_clk", &usb_tll_hs_usb_ch1_clk, CK_443X),
100 CLK(NULL, "usb_tll_hs_ick", &usb_tll_hs_ick, CK_443X),
101- CLK("usbhs-omap.0", "usbtll_ick", &usb_tll_hs_ick, CK_443X),
102- CLK("usbhs-omap.0", "usbtll_fck", &dummy_ck, CK_443X),
103+ CLK("usbhs_omap", "usbtll_ick", &usb_tll_hs_ick, CK_443X),
104+ CLK("usbhs_omap", "usbtll_fck", &dummy_ck, CK_443X),
105 CLK(NULL, "usim_ck", &usim_ck, CK_443X),
106 CLK(NULL, "usim_fclk", &usim_fclk, CK_443X),
107 CLK(NULL, "usim_fck", &usim_fck, CK_443X),
108diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
109index 8552195..43de12a 100644
110--- a/drivers/mfd/omap-usb-host.c
111+++ b/drivers/mfd/omap-usb-host.c
112@@ -28,7 +28,7 @@
113 #include <plat/usb.h>
114 #include <linux/pm_runtime.h>
115
116-#define USBHS_DRIVER_NAME "usbhs-omap"
117+#define USBHS_DRIVER_NAME "usbhs_omap"
118 #define OMAP_EHCI_DEVICE "ehci-omap"
119 #define OMAP_OHCI_DEVICE "ohci-omap3"
120
121--
1221.6.6.1
123
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0007-mfd-global-Suspend-and-resume-support-of-ehci-and-oh.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0007-mfd-global-Suspend-and-resume-support-of-ehci-and-oh.patch
new file mode 100644
index 00000000..94d5f591
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0007-mfd-global-Suspend-and-resume-support-of-ehci-and-oh.patch
@@ -0,0 +1,165 @@
1From bf583f2924fd9b2f0356cbd0bbfd58c48d98ef15 Mon Sep 17 00:00:00 2001
2From: Keshava Munegowda <Keshava_mgowda@ti.com>
3Date: Wed, 1 Jun 2011 11:03:03 -0700
4Subject: [PATCH 07/13] mfd: global Suspend and resume support of ehci and ohci
5
6The global suspend and resume functions for usbhs core driver
7are implemented.These routine are called when the global suspend
8and resume occurs. Before calling these functions, the
9bus suspend and resume of ehci and ohci drivers are called
10from runtime pm.
11
12Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
13---
14 drivers/mfd/omap-usb-host.c | 103 +++++++++++++++++++++++++++++++++++++++++++
15 1 files changed, 103 insertions(+), 0 deletions(-)
16
17diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
18index 43de12a..32d19e2 100644
19--- a/drivers/mfd/omap-usb-host.c
20+++ b/drivers/mfd/omap-usb-host.c
21@@ -146,6 +146,10 @@
22 #define is_ehci_hsic_mode(x) (x == OMAP_EHCI_PORT_MODE_HSIC)
23
24
25+/* USBHS state bits */
26+#define OMAP_USBHS_INIT 0
27+#define OMAP_USBHS_SUSPEND 4
28+
29 struct usbhs_hcd_omap {
30 struct clk *xclk60mhsp1_ck;
31 struct clk *xclk60mhsp2_ck;
32@@ -165,6 +169,7 @@ struct usbhs_hcd_omap {
33 u32 usbhs_rev;
34 spinlock_t lock;
35 int count;
36+ unsigned long state;
37 };
38 /*-------------------------------------------------------------------------*/
39
40@@ -809,6 +814,8 @@ static int usbhs_enable(struct device *dev)
41 (pdata->ehci_data->reset_gpio_port[1], 1);
42 }
43
44+ set_bit(OMAP_USBHS_INIT, &omap->state);
45+
46 end_count:
47 omap->count++;
48 spin_unlock_irqrestore(&omap->lock, flags);
49@@ -897,6 +904,7 @@ static void usbhs_disable(struct device *dev)
50 }
51
52 pm_runtime_put_sync(dev);
53+ clear_bit(OMAP_USBHS_INIT, &omap->state);
54
55 /* The gpio_free migh sleep; so unlock the spinlock */
56 spin_unlock_irqrestore(&omap->lock, flags);
57@@ -926,10 +934,105 @@ void omap_usbhs_disable(struct device *dev)
58 }
59 EXPORT_SYMBOL_GPL(omap_usbhs_disable);
60
61+#ifdef CONFIG_PM
62+
63+static int usbhs_resume(struct device *dev)
64+{
65+ struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
66+ struct usbhs_omap_platform_data *pdata = &omap->platdata;
67+ unsigned long flags = 0;
68+
69+ dev_dbg(dev, "Resuming TI HSUSB Controller\n");
70+
71+ if (!pdata) {
72+ dev_dbg(dev, "missing platform_data\n");
73+ return -ENODEV;
74+ }
75+
76+ spin_lock_irqsave(&omap->lock, flags);
77+
78+ if (!test_bit(OMAP_USBHS_INIT, &omap->state) ||
79+ !test_bit(OMAP_USBHS_SUSPEND, &omap->state))
80+ goto end_resume;
81+
82+ pm_runtime_get_sync(dev);
83+
84+ if (is_omap_usbhs_rev2(omap)) {
85+ if (is_ehci_tll_mode(pdata->port_mode[0])) {
86+ clk_enable(omap->usbhost_p1_fck);
87+ clk_enable(omap->usbtll_p1_fck);
88+ }
89+ if (is_ehci_tll_mode(pdata->port_mode[1])) {
90+ clk_enable(omap->usbhost_p2_fck);
91+ clk_enable(omap->usbtll_p2_fck);
92+ }
93+ clk_enable(omap->utmi_p1_fck);
94+ clk_enable(omap->utmi_p2_fck);
95+ }
96+ clear_bit(OMAP_USBHS_SUSPEND, &omap->state);
97+
98+end_resume:
99+ spin_unlock_irqrestore(&omap->lock, flags);
100+ return 0;
101+}
102+
103+
104+static int usbhs_suspend(struct device *dev)
105+{
106+ struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
107+ struct usbhs_omap_platform_data *pdata = &omap->platdata;
108+ unsigned long flags = 0;
109+
110+ dev_dbg(dev, "Suspending TI HSUSB Controller\n");
111+
112+ if (!pdata) {
113+ dev_dbg(dev, "missing platform_data\n");
114+ return -ENODEV;
115+ }
116+
117+ spin_lock_irqsave(&omap->lock, flags);
118+
119+ if (!test_bit(OMAP_USBHS_INIT, &omap->state) ||
120+ test_bit(OMAP_USBHS_SUSPEND, &omap->state))
121+ goto end_suspend;
122+
123+ if (is_omap_usbhs_rev2(omap)) {
124+ if (is_ehci_tll_mode(pdata->port_mode[0])) {
125+ clk_disable(omap->usbhost_p1_fck);
126+ clk_disable(omap->usbtll_p1_fck);
127+ }
128+ if (is_ehci_tll_mode(pdata->port_mode[1])) {
129+ clk_disable(omap->usbhost_p2_fck);
130+ clk_disable(omap->usbtll_p2_fck);
131+ }
132+ clk_disable(omap->utmi_p2_fck);
133+ clk_disable(omap->utmi_p1_fck);
134+ }
135+
136+ set_bit(OMAP_USBHS_SUSPEND, &omap->state);
137+ pm_runtime_put_sync(dev);
138+
139+end_suspend:
140+ spin_unlock_irqrestore(&omap->lock, flags);
141+ return 0;
142+}
143+
144+
145+static const struct dev_pm_ops usbhsomap_dev_pm_ops = {
146+ .suspend = usbhs_suspend,
147+ .resume = usbhs_resume,
148+};
149+
150+#define USBHS_OMAP_DEV_PM_OPS (&usbhsomap_dev_pm_ops)
151+#else
152+#define USBHS_OMAP_DEV_PM_OPS NULL
153+#endif
154+
155 static struct platform_driver usbhs_omap_driver = {
156 .driver = {
157 .name = (char *)usbhs_driver_name,
158 .owner = THIS_MODULE,
159+ .pm = USBHS_OMAP_DEV_PM_OPS,
160 },
161 .remove = __exit_p(usbhs_omap_remove),
162 };
163--
1641.6.6.1
165
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0008-MFD-TWL4030-Correct-the-warning-print-during-script-.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0008-MFD-TWL4030-Correct-the-warning-print-during-script-.patch
new file mode 100644
index 00000000..e3de4672
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0008-MFD-TWL4030-Correct-the-warning-print-during-script-.patch
@@ -0,0 +1,36 @@
1From 1f2e639755b920398d6592775e0e31f7fb1ca955 Mon Sep 17 00:00:00 2001
2From: Lesly A M <leslyam@ti.com>
3Date: Wed, 1 Jun 2011 14:56:38 -0700
4Subject: [PATCH 08/13] MFD: TWL4030: Correct the warning print during script loading
5
6Correcting the if condition check for printing the warning,
7if wakeup script is not updated before updating the sleep script.
8
9Since the flag 'order' is set to '1' while updating the wakeup script for P1P2,
10the condition checking for printing the warning should be if(!order)
11(ie: print the warning if wakeup script is not updated before updating the sleep script)
12
13Signed-off-by: Lesly A M <leslyam@ti.com>
14Cc: Nishanth Menon <nm@ti.com>
15Cc: David Derrick <dderrick@ti.com>
16Cc: Samuel Ortiz <sameo@linux.intel.com>
17---
18 drivers/mfd/twl4030-power.c | 2 +-
19 1 files changed, 1 insertions(+), 1 deletions(-)
20
21diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
22index 2c0d4d1..8373d79 100644
23--- a/drivers/mfd/twl4030-power.c
24+++ b/drivers/mfd/twl4030-power.c
25@@ -448,7 +448,7 @@ static int __init load_twl4030_script(struct twl4030_script *tscript,
26 goto out;
27 }
28 if (tscript->flags & TWL4030_SLEEP_SCRIPT) {
29- if (order)
30+ if (!order)
31 pr_warning("TWL4030: Bad order of scripts (sleep "\
32 "script before wakeup) Leads to boot"\
33 "failure on some boards\n");
34--
351.6.6.1
36
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0009-MFD-TWL4030-Modifying-the-macro-name-Main_Ref-to-all.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0009-MFD-TWL4030-Modifying-the-macro-name-Main_Ref-to-all.patch
new file mode 100644
index 00000000..6be454aa
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0009-MFD-TWL4030-Modifying-the-macro-name-Main_Ref-to-all.patch
@@ -0,0 +1,61 @@
1From ea9acebfe2d3ca8fb3969eaf327665632142b85d Mon Sep 17 00:00:00 2001
2From: Lesly A M <leslyam@ti.com>
3Date: Wed, 1 Jun 2011 14:56:45 -0700
4Subject: [PATCH 09/13] MFD: TWL4030: Modifying the macro name Main_Ref to all caps
5
6Modifying the macro name Main_Ref to all caps(MAIN_REF).
7
8Suggested by Nishanth Menon <nm@ti.com>
9
10Signed-off-by: Lesly A M <leslyam@ti.com>
11Cc: Nishanth Menon <nm@ti.com>
12Cc: David Derrick <dderrick@ti.com>
13Cc: Samuel Ortiz <sameo@linux.intel.com>
14---
15 arch/arm/mach-omap2/board-rx51-peripherals.c | 2 +-
16 drivers/mfd/twl4030-power.c | 2 +-
17 include/linux/i2c/twl.h | 2 +-
18 3 files changed, 3 insertions(+), 3 deletions(-)
19
20diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
21index bbcb677..01ee0a1 100644
22--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
23+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
24@@ -730,7 +730,7 @@ static struct twl4030_resconfig twl4030_rconfig[] __initdata = {
25 { .resource = RES_RESET, .devgroup = -1,
26 .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
27 },
28- { .resource = RES_Main_Ref, .devgroup = -1,
29+ { .resource = RES_MAIN_REF, .devgroup = -1,
30 .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
31 },
32 { 0, 0},
33diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
34index 8373d79..8162e43 100644
35--- a/drivers/mfd/twl4030-power.c
36+++ b/drivers/mfd/twl4030-power.c
37@@ -120,7 +120,7 @@ static u8 res_config_addrs[] = {
38 [RES_HFCLKOUT] = 0x8b,
39 [RES_32KCLKOUT] = 0x8e,
40 [RES_RESET] = 0x91,
41- [RES_Main_Ref] = 0x94,
42+ [RES_MAIN_REF] = 0x94,
43 };
44
45 static int __init twl4030_write_script_byte(u8 address, u8 byte)
46diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
47index cbbf3b3..aee3a22 100644
48--- a/include/linux/i2c/twl.h
49+++ b/include/linux/i2c/twl.h
50@@ -502,7 +502,7 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot)
51 #define RES_32KCLKOUT 26
52 #define RES_RESET 27
53 /* Power Reference */
54-#define RES_Main_Ref 28
55+#define RES_MAIN_REF 28
56
57 #define TOTAL_RESOURCES 28
58 /*
59--
601.6.6.1
61
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0010-MFD-TWL4030-power-scripts-for-OMAP3-boards.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0010-MFD-TWL4030-power-scripts-for-OMAP3-boards.patch
new file mode 100644
index 00000000..84e1ae7e
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0010-MFD-TWL4030-power-scripts-for-OMAP3-boards.patch
@@ -0,0 +1,705 @@
1From 0b29e1f61b85dd2d04f035088b70dc287d15b9f0 Mon Sep 17 00:00:00 2001
2From: Lesly A M <leslyam@ti.com>
3Date: Wed, 1 Jun 2011 14:56:49 -0700
4Subject: [PATCH 10/13] MFD: TWL4030: power scripts for OMAP3 boards
5
6Power bus message sequence for TWL4030 to enter sleep/wakeup/warm_reset.
7
8TWL4030 power scripts which can be used by different OMAP3 boards
9with the power companion chip (TWL4030 series).
10
11The twl4030 generic script can be used by any board file to update
12the power data in twl4030_platform_data.
13
14Since the TWL4030 power script has dependency with APIs in twl4030-power.c
15removing the __init for these APIs.
16
17For more information please see:
18 http://omapedia.org/wiki/TWL4030_power_scripts
19
20Signed-off-by: Lesly A M <leslyam@ti.com>
21Cc: Nishanth Menon <nm@ti.com>
22Cc: David Derrick <dderrick@ti.com>
23Cc: Samuel Ortiz <sameo@linux.intel.com>
24---
25 arch/arm/configs/omap2plus_defconfig | 1 +
26 arch/arm/mach-omap2/devices.c | 15 ++
27 drivers/mfd/Kconfig | 11 +
28 drivers/mfd/Makefile | 1 +
29 drivers/mfd/twl4030-power.c | 31 ++--
30 drivers/mfd/twl4030-script-omap.c | 373 ++++++++++++++++++++++++++++++++++
31 include/linux/i2c/twl.h | 41 ++++-
32 7 files changed, 454 insertions(+), 19 deletions(-)
33 create mode 100644 drivers/mfd/twl4030-script-omap.c
34
35diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
36index 076db52..d9b9858 100644
37--- a/arch/arm/configs/omap2plus_defconfig
38+++ b/arch/arm/configs/omap2plus_defconfig
39@@ -184,6 +184,7 @@ CONFIG_TWL4030_WATCHDOG=y
40 CONFIG_MENELAUS=y
41 CONFIG_TWL4030_CORE=y
42 CONFIG_TWL4030_POWER=y
43+CONFIG_TWL4030_SCRIPT=m
44 CONFIG_REGULATOR=y
45 CONFIG_REGULATOR_TWL4030=y
46 CONFIG_REGULATOR_TPS65023=y
47diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
48index 7b85585..7653329 100644
49--- a/arch/arm/mach-omap2/devices.c
50+++ b/arch/arm/mach-omap2/devices.c
51@@ -329,6 +329,20 @@ static void omap_init_audio(void)
52 static inline void omap_init_audio(void) {}
53 #endif
54
55+#ifdef CONFIG_ARCH_OMAP3
56+static struct platform_device omap_twl4030_script = {
57+ .name = "twl4030_script",
58+ .id = -1,
59+};
60+
61+static void omap_init_twl4030_script(void)
62+{
63+ platform_device_register(&omap_twl4030_script);
64+}
65+#else
66+static inline void omap_init_twl4030_script(void) {}
67+#endif
68+
69 #if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
70
71 #include <plat/mcspi.h>
72@@ -691,6 +705,7 @@ static int __init omap2_init_devices(void)
73 omap_init_sham();
74 omap_init_aes();
75 omap_init_vout();
76+ omap_init_twl4030_script();
77
78 return 0;
79 }
80diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
81index fe2370a..ea25d93 100644
82--- a/drivers/mfd/Kconfig
83+++ b/drivers/mfd/Kconfig
84@@ -204,6 +204,17 @@ config TWL4030_POWER
85 and load scripts controlling which resources are switched off/on
86 or reset when a sleep, wakeup or warm reset event occurs.
87
88+config TWL4030_SCRIPT
89+ tristate "Support TWL4030 script for OMAP3 boards"
90+ depends on TWL4030_CORE && TWL4030_POWER
91+ help
92+ Say yes here if you want to use the twl4030 power scripts
93+ for OMAP3 boards. Power bus message sequence for
94+ TWL4030 to enter sleep/wakeup/warm_reset.
95+
96+ TWL4030 power scripts which can be used by different
97+ OMAP3 boards with the power companion chip (TWL4030 series).
98+
99 config TWL4030_CODEC
100 bool
101 depends on TWL4030_CORE
102diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
103index 419caa9..53ada21 100644
104--- a/drivers/mfd/Makefile
105+++ b/drivers/mfd/Makefile
106@@ -42,6 +42,7 @@ obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o
107 obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o
108 obj-$(CONFIG_TWL4030_CODEC) += twl4030-codec.o
109 obj-$(CONFIG_TWL6030_PWM) += twl6030-pwm.o
110+obj-$(CONFIG_TWL4030_SCRIPT) += twl4030-script-omap.o
111
112 obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o
113
114diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
115index 8162e43..91d5bc8 100644
116--- a/drivers/mfd/twl4030-power.c
117+++ b/drivers/mfd/twl4030-power.c
118@@ -123,7 +123,7 @@ static u8 res_config_addrs[] = {
119 [RES_MAIN_REF] = 0x94,
120 };
121
122-static int __init twl4030_write_script_byte(u8 address, u8 byte)
123+static int twl4030_write_script_byte(u8 address, u8 byte)
124 {
125 int err;
126
127@@ -137,7 +137,7 @@ out:
128 return err;
129 }
130
131-static int __init twl4030_write_script_ins(u8 address, u16 pmb_message,
132+static int twl4030_write_script_ins(u8 address, u16 pmb_message,
133 u8 delay, u8 next)
134 {
135 int err;
136@@ -157,7 +157,7 @@ out:
137 return err;
138 }
139
140-static int __init twl4030_write_script(u8 address, struct twl4030_ins *script,
141+static int twl4030_write_script(u8 address, struct twl4030_ins *script,
142 int len)
143 {
144 int err;
145@@ -182,7 +182,7 @@ static int __init twl4030_write_script(u8 address, struct twl4030_ins *script,
146 return err;
147 }
148
149-static int __init twl4030_config_wakeup3_sequence(u8 address)
150+static int twl4030_config_wakeup3_sequence(u8 address)
151 {
152 int err;
153 u8 data;
154@@ -207,7 +207,7 @@ out:
155 return err;
156 }
157
158-static int __init twl4030_config_wakeup12_sequence(u8 address)
159+static int twl4030_config_wakeup12_sequence(u8 address)
160 {
161 int err = 0;
162 u8 data;
163@@ -261,7 +261,7 @@ out:
164 return err;
165 }
166
167-static int __init twl4030_config_sleep_sequence(u8 address)
168+static int twl4030_config_sleep_sequence(u8 address)
169 {
170 int err;
171
172@@ -275,7 +275,7 @@ static int __init twl4030_config_sleep_sequence(u8 address)
173 return err;
174 }
175
176-static int __init twl4030_config_warmreset_sequence(u8 address)
177+static int twl4030_config_warmreset_sequence(u8 address)
178 {
179 int err;
180 u8 rd_data;
181@@ -323,7 +323,7 @@ out:
182 return err;
183 }
184
185-static int __init twl4030_configure_resource(struct twl4030_resconfig *rconfig)
186+static int twl4030_configure_resource(struct twl4030_resconfig *rconfig)
187 {
188 int rconfig_addr;
189 int err;
190@@ -415,7 +415,7 @@ static int __init twl4030_configure_resource(struct twl4030_resconfig *rconfig)
191 return 0;
192 }
193
194-static int __init load_twl4030_script(struct twl4030_script *tscript,
195+static int load_twl4030_script(struct twl4030_script *tscript,
196 u8 address)
197 {
198 int err;
199@@ -510,8 +510,9 @@ int twl4030_remove_script(u8 flags)
200
201 return err;
202 }
203+EXPORT_SYMBOL_GPL(twl4030_remove_script);
204
205-void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
206+int twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
207 {
208 int err = 0;
209 int i;
210@@ -529,7 +530,6 @@ void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
211 TWL4030_PM_MASTER_PROTECT_KEY);
212 if (err)
213 goto unlock;
214-
215 for (i = 0; i < twl4030_scripts->num; i++) {
216 err = load_twl4030_script(twl4030_scripts->scripts[i], address);
217 if (err)
218@@ -552,18 +552,19 @@ void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
219 TWL4030_PM_MASTER_PROTECT_KEY);
220 if (err)
221 pr_err("TWL4030 Unable to relock registers\n");
222- return;
223+ return err;
224
225 unlock:
226 if (err)
227 pr_err("TWL4030 Unable to unlock registers\n");
228- return;
229+ return err;
230 load:
231 if (err)
232 pr_err("TWL4030 failed to load scripts\n");
233- return;
234+ return err;
235 resource:
236 if (err)
237 pr_err("TWL4030 failed to configure resource\n");
238- return;
239+ return err;
240 }
241+EXPORT_SYMBOL_GPL(twl4030_power_init);
242diff --git a/drivers/mfd/twl4030-script-omap.c b/drivers/mfd/twl4030-script-omap.c
243new file mode 100644
244index 0000000..867a442
245--- /dev/null
246+++ b/drivers/mfd/twl4030-script-omap.c
247@@ -0,0 +1,373 @@
248+/*
249+ * OMAP power script for PMIC TWL4030
250+ *
251+ * Author: Lesly A M <leslyam@ti.com>
252+ *
253+ * Copyright (C) 2010 Texas Instruments, Inc.
254+ * Lesly A M <leslyam@ti.com>
255+ *
256+ * This program is free software; you can redistribute it and/or modify
257+ * it under the terms of the GNU General Public License version 2 as
258+ * published by the Free Software Foundation.
259+ */
260+
261+#include <linux/kernel.h>
262+#include <linux/module.h>
263+#include <linux/platform_device.h>
264+
265+#include <linux/i2c/twl.h>
266+
267+/*
268+ * power management signal connections for OMAP3430 with TWL5030
269+ *
270+ * TWL5030 OMAP3430
271+ * ______________________ _____________________
272+ * | | | |
273+ * | (P1) NSLEEP1|<----------|SYS_OFFMODE |
274+ * | NRESWARM|<----------|NWARMRESET |
275+ * | (P2) NSLEEP2|---| | |
276+ * | | === | |
277+ * | | - | |
278+ * | | | |
279+ * | VDD1 |---------->| VDD1 |
280+ * | VDD2 |---------->| VDD2 |
281+ * | VIO |---------->| VDDS |
282+ * ________ | VAUX1 | | |
283+ * | | | ... | | |
284+ * | ENABLE|<--------|CLKEN CLKREQ|<----------|SYS_CLKREQ |
285+ * | CLKOUT|-------->|HFCLKIN (P3) HFCLKOUT|---------->|XTALIN |
286+ * |________| |______________________| |_____________________|
287+ *
288+ *
289+ * Signal descriptions:
290+ *
291+ * SYS_OFFMODE - OMAP drives this signal low only when the OMAP is in the
292+ * OFF idle mode. It is driven high when a wake up event is detected.
293+ * This signal should control the P1 device group in the PMIC.
294+ *
295+ * SYS_CLKREQ - OMAP should drive this signal low when the OMAP goes into
296+ * any idle mode. This signal should control the P3 device group
297+ * in the PMIC. It is used to notify PMIC when XTALIN is no longer needed.
298+ *
299+ * NSLEEP1(P1) - When this signal goes low the P1 sleep sequence is executed
300+ * in the PMIC turning off certain resources. When this signal goes high
301+ * the P1 active sequence is executed turning back on certain resources.
302+ *
303+ * NSLEEP2(P2) - This signal controls the P2 device group of the PMIC.
304+ * It is not used in this setup and should be tied to ground.
305+ * This can be used for connecting a different processor or MODEM chip.
306+ *
307+ * CLKREQ(P3) - When this signal goes low the P3 sleep sequence is executed
308+ * in the PMIC turning off HFCLKOUT. When this signal goes high
309+ * the P3 active sequence is executed turning back on HFCLKOUT and other
310+ * resources.
311+ *
312+ * CLKEN - Enable signal for oscillator. Should only go low when OMAP is
313+ * in the OFF idle mode due to long oscillator startup times.
314+ *
315+ * HFCLKIN - Oscillator output clock into PMIC.
316+ *
317+ * HFCLKOUT - System clock output from PMIC to OMAP.
318+ *
319+ * XTALIN - OMAP system clock input(HFCLKOUT).
320+ */
321+
322+/*
323+ * Recommended sleep and active sequences for TWL5030 when connected to OMAP3
324+ *
325+ * WARNING: If the board is using NSLEEP2(P2), should modify this script and
326+ * setuptime values accordingly.
327+ *
328+ * Chip Retention/Off (using i2c for scaling voltage):
329+ * When OMAP de-assert the SYS_CLKREQ signal, only HFCLKOUT is affected
330+ * since it is the only resource assigned to P3 only.
331+ *
332+ * Sysoff (using sys_off signal):
333+ * When OMAP de-assert the SYS_OFFMODE signal A2S(active to sleep sequence)
334+ * on the PMIC is executed. This will put resources of TYPE2=1 and TYPE2=2
335+ * into sleep. At this point only resources assigned to P1 only will be
336+ * affected (VDD1, VDD2 & VPLL1).
337+ *
338+ * Next the OMAP will lower SYS_CLKREQ which will allow the A2S sequence
339+ * in PMIC to execute again. This will put resources of TYPE2=1 and TYPE2=2
340+ * into sleep but will affect resources that are assigned to P3(HFCLKOUT)
341+ * only or assigned to P1 and P3.
342+ *
343+ * On wakeup event OMAP goes active and pulls the SYS_CLKREQ high,
344+ * which will execute the P3 S2A sequence on the PMIC. This will turn on
345+ * resources assigned to P3 or assigned to P1 and P3 and of TYPE2=2.
346+ *
347+ * Next the OMAP will wait the PRM_VOLTOFFSET time and then de-assert
348+ * the SYS_OFFMODE pin allowing the PMIC to execute the P1 S2A active
349+ * sequence. This will turn on resources assigned to P1 or assigned to
350+ * P1 and P3 and of TYPE2=1.
351+ *
352+ * Timing diagram for OMAP wakeup from OFFMODE using sys_off signal
353+ * _____________________________________________________________
354+ * OMAP active __/
355+ * |<--------------------PRM_CLKSETP-------------------->|
356+ * ______________________________________________________
357+ * SYS_CLKREQ _________/
358+ * ___________________________________________________
359+ * CLKEN ____________/
360+ *
361+ * HFCLKIN _______________________________________________/////////////////
362+ *
363+ * HFCLKOUT __________________________________________________//////////////
364+ * |<---PRM_VOLTOFFSET-->|
365+ * ________________________________
366+ * SYS_OFFMODE _______________________________/
367+ * |<--------PRM_VOLTSETUP2------->|
368+ * ___________
369+ * VPLL1 ____________________________________________________/
370+ * __
371+ * VDD1 _____________________________________________________________/
372+ * __
373+ * VDD2 _____________________________________________________________/
374+ *
375+ * Other resources which are not handled by this script should be
376+ * controlled by the respective drivers using them (VAUX1, VAUX2, VAUX3,
377+ * VAUX4, VMMC1, VMMC2, VPLL2, VSIM, VDAC, VUSB1V5, VUSB1V8 & VUSB3V1).
378+ *
379+ * More info:
380+ * http://omapedia.org/wiki/TWL4030_power_scripts
381+ */
382+
383+/**
384+ * DOC: Sleep to active sequence for P1/P2
385+ *
386+ * Sequence to control the TWL4030 Power resources,
387+ * when the system wakeup from sleep.
388+ * Executed upon P1_P2 transition for wakeup
389+ * (sys_offmode signal de-asserted on OMAP).
390+ */
391+static struct twl4030_ins wakeup_p12_seq[] __initdata = {
392+ /*
393+ * Broadcast message to put resources to active
394+ *
395+ * Since we are not using TYPE, resources which have TYPE2 configured
396+ * as 1 will be targeted (VPLL1, VDD1, VDD2, REGEN, NRES_PWRON, SYSEN).
397+ */
398+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1,
399+ RES_STATE_ACTIVE), 2},
400+};
401+
402+static struct twl4030_script wakeup_p12_script __initdata = {
403+ .script = wakeup_p12_seq,
404+ .size = ARRAY_SIZE(wakeup_p12_seq),
405+ .flags = TWL4030_WAKEUP12_SCRIPT,
406+};
407+
408+/**
409+ * DOC: Sleep to active sequence for P3
410+ *
411+ * Sequence to control the TWL4030 Power resources,
412+ * when the system wakeup from sleep.
413+ * Executed upon P3 transition for wakeup
414+ * (clkreq signal asserted on OMAP).
415+ */
416+static struct twl4030_ins wakeup_p3_seq[] __initdata = {
417+ /*
418+ * Broadcast message to put resources to active
419+ *
420+ * Since we are not using TYPE, resources which have TYPE2 configured
421+ * as 2 will be targeted
422+ * (VINTANA1, VINTANA2, VINTDIG, VIO, CLKEN, HFCLKOUT).
423+ */
424+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
425+ RES_STATE_ACTIVE), 2},
426+};
427+
428+static struct twl4030_script wakeup_p3_script __initdata = {
429+ .script = wakeup_p3_seq,
430+ .size = ARRAY_SIZE(wakeup_p3_seq),
431+ .flags = TWL4030_WAKEUP3_SCRIPT,
432+};
433+
434+/**
435+ * DOC: Active to sleep sequence for P1/P2/P3
436+ *
437+ * Sequence to control the TWL4030 Power resources,
438+ * when the system goes into sleep.
439+ * Executed upon P1_P2/P3 transition for sleep.
440+ * (sys_offmode signal asserted/clkreq de-asserted on OMAP).
441+ */
442+static struct twl4030_ins sleep_on_seq[] __initdata = {
443+ /* Broadcast message to put res to sleep (TYPE2 = 1, 2) */
444+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1,
445+ RES_STATE_SLEEP), 2},
446+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
447+ RES_STATE_SLEEP), 2},
448+};
449+
450+static struct twl4030_script sleep_on_script __initdata = {
451+ .script = sleep_on_seq,
452+ .size = ARRAY_SIZE(sleep_on_seq),
453+ .flags = TWL4030_SLEEP_SCRIPT,
454+};
455+
456+/**
457+ * DOC: Warm reset sequence
458+ *
459+ * Sequence to reset the TWL4030 Power resources,
460+ * when the system gets warm reset.
461+ * Executed upon warm reset signal.
462+ *
463+ * First the device is put in reset, then the system clock is requested to
464+ * the external oscillator, and default ON power reference and power providers
465+ * are enabled. Next some additional resources which are software controlled
466+ * are enabled. Finally sequence is ended by the release of TWL5030 reset.
467+ */
468+static struct twl4030_ins wrst_seq[] __initdata = {
469+ /*
470+ * As a workaround for OMAP Erratum (ID: i537 - OMAP HS devices are
471+ * not recovering from warm reset while in OFF mode)
472+ * NRESPWRON is toggled to force a power on reset condition to OMAP
473+ */
474+ /* Trun OFF NRES_PWRON */
475+ {MSG_SINGULAR(DEV_GRP_NULL, RES_NRES_PWRON, RES_STATE_OFF), 2},
476+ /* Reset twl4030 */
477+ {MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_OFF), 2},
478+ /* Reset MAIN_REF */
479+ {MSG_SINGULAR(DEV_GRP_NULL, RES_MAIN_REF, RES_STATE_WRST), 2},
480+ /* Reset All type2_group2 */
481+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
482+ RES_STATE_WRST), 2},
483+ /* Reset VUSB_3v1 */
484+ {MSG_SINGULAR(DEV_GRP_NULL, RES_VUSB_3V1, RES_STATE_WRST), 2},
485+ /* Reset All type2_group1 */
486+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1,
487+ RES_STATE_WRST), 2},
488+ /* Reset the Reset & Contorl_signals */
489+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_RC, RES_TYPE_ALL, RES_TYPE2_R0,
490+ RES_STATE_WRST), 2},
491+ /* Re-enable twl4030 */
492+ {MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_ACTIVE), 2},
493+ /* Trun ON NRES_PWRON */
494+ {MSG_SINGULAR(DEV_GRP_NULL, RES_NRES_PWRON, RES_STATE_ACTIVE), 2},
495+};
496+
497+static struct twl4030_script wrst_script __initdata = {
498+ .script = wrst_seq,
499+ .size = ARRAY_SIZE(wrst_seq),
500+ .flags = TWL4030_WRST_SCRIPT,
501+};
502+
503+/* TWL4030 script for sleep, wakeup & warm_reset */
504+static struct twl4030_script *twl4030_scripts[] __initdata = {
505+ &wakeup_p12_script,
506+ &wakeup_p3_script,
507+ &sleep_on_script,
508+ &wrst_script,
509+};
510+
511+/**
512+ * DOC: TWL4030 resource configuration
513+ *
514+ * Resource which are attached to P1 device group alone
515+ * will go to sleep state, when sys_off signal from OMAP is de-asserted.
516+ * (VPLL1, VDD1, VDD2)
517+ *
518+ * None of the resources are attached to P2 device group alone.
519+ * (WARNING: If MODEM or connectivity chip is connected to NSLEEP2 PIN on
520+ * TWL4030, should modify the resource configuration accordingly).
521+ *
522+ * Resource which are attached to P3 device group alone
523+ * will go to sleep state, when clk_req signal from OMAP is de-asserted.
524+ * (HFCLKOUT)
525+ *
526+ * Resource which are attached to more than one device group
527+ * will go to sleep state, when corresponding signals are de-asserted.
528+ * (VINTANA1, VINTANA2, VINTDIG, VIO, REGEN, NRESPWRON, CLKEN, SYSEN)
529+ *
530+ * REGEN is an output of the device which can be connected to slave power ICs
531+ * or external LDOs that power on before voltage for the IO interface (VIO).
532+ *
533+ * SYSEN is a bidirectional signal of the device that controls slave power ICs.
534+ * In master mode, the device sets SYSEN high to enable the slave power ICs.
535+ * In slave mode, when one of the power ICs drives the SYSEN signal low,
536+ * all devices of the platform stay in the wait-on state.
537+ *
538+ * Resource which are attached to none of the device group by default
539+ * will be in sleep state. These resource should be controlled by
540+ * the respective drivers using them.
541+ * Resource which are controlled by drivers are not modified here.
542+ * (VAUX1, VAUX2, VAUX3, VAUX4, VMMC1, VMMC2, VPLL2, VSIM, VDAC,
543+ * VUSB1V5, VUSB1V8, VUSB3V1)
544+ *
545+ * Resource using reset values.
546+ * (32KCLKOUT, TRITON_RESET, MAINREF)
547+ */
548+static struct twl4030_resconfig twl4030_rconfig[] __initdata = {
549+ { .resource = RES_VPLL1, .devgroup = DEV_GRP_P1, .type = 3,
550+ .type2 = 1, .remap_sleep = RES_STATE_OFF },
551+ { .resource = RES_VINTANA1, .devgroup = DEV_GRP_ALL, .type = 1,
552+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
553+ { .resource = RES_VINTANA2, .devgroup = DEV_GRP_ALL, .type = 0,
554+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
555+ { .resource = RES_VINTDIG, .devgroup = DEV_GRP_ALL, .type = 1,
556+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
557+ { .resource = RES_VIO, .devgroup = DEV_GRP_ALL, .type = 2,
558+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
559+ { .resource = RES_VDD1, .devgroup = DEV_GRP_P1,
560+ .type = 4, .type2 = 1, .remap_sleep = RES_STATE_OFF },
561+ { .resource = RES_VDD2, .devgroup = DEV_GRP_P1,
562+ .type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF },
563+ { .resource = RES_REGEN, .devgroup = DEV_GRP_ALL, .type = 2,
564+ .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
565+ { .resource = RES_NRES_PWRON, .devgroup = DEV_GRP_ALL, .type = 0,
566+ .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
567+ { .resource = RES_CLKEN, .devgroup = DEV_GRP_ALL, .type = 3,
568+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
569+ { .resource = RES_SYSEN, .devgroup = DEV_GRP_ALL, .type = 6,
570+ .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
571+ { .resource = RES_HFCLKOUT, .devgroup = DEV_GRP_P3,
572+ .type = 0, .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
573+ { 0, 0},
574+};
575+
576+struct twl4030_power_data twl4030_generic_script __initdata = {
577+ .scripts = twl4030_scripts,
578+ .num = ARRAY_SIZE(twl4030_scripts),
579+ .resource_config = twl4030_rconfig,
580+};
581+
582+static int __init twl4030_script_probe(struct platform_device *pdev)
583+{
584+ return twl4030_power_init(&twl4030_generic_script);
585+}
586+
587+static int twl4030_script_remove(struct platform_device *pdev)
588+{
589+ return twl4030_remove_script(TWL4030_SLEEP_SCRIPT |
590+ TWL4030_WAKEUP12_SCRIPT | TWL4030_WAKEUP3_SCRIPT |
591+ TWL4030_WRST_SCRIPT);
592+}
593+
594+static struct platform_driver twl4030_script_driver = {
595+ .remove = twl4030_script_remove,
596+ .driver = {
597+ .name = "twl4030_script",
598+ .owner = THIS_MODULE,
599+ },
600+};
601+
602+static int __init twl4030_script_init(void)
603+{
604+ /* Register the TWL4030 script driver */
605+ return platform_driver_probe(&twl4030_script_driver,
606+ twl4030_script_probe);
607+}
608+
609+static void __exit twl4030_script_cleanup(void)
610+{
611+ /* Unregister TWL4030 script driver */
612+ platform_driver_unregister(&twl4030_script_driver);
613+}
614+
615+module_init(twl4030_script_init);
616+module_exit(twl4030_script_cleanup);
617+
618+MODULE_DESCRIPTION("OMAP TWL4030 script driver");
619+MODULE_LICENSE("GPL");
620+MODULE_AUTHOR("Texas Instruments Inc");
621diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
622index aee3a22..f343974 100644
623--- a/include/linux/i2c/twl.h
624+++ b/include/linux/i2c/twl.h
625@@ -205,6 +205,12 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot)
626 return -EIO;
627 }
628 #endif
629+
630+#ifdef CONFIG_TWL4030_POWER
631+extern struct twl4030_power_data twl4030_generic_script;
632+#else
633+#define twl4030_generic_script NULL;
634+#endif
635 /*----------------------------------------------------------------------*/
636
637 /*
638@@ -437,9 +443,23 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot)
639
640 /* Power bus message definitions */
641
642-/* The TWL4030/5030 splits its power-management resources (the various
643- * regulators, clock and reset lines) into 3 processor groups - P1, P2 and
644- * P3. These groups can then be configured to transition between sleep, wait-on
645+/*
646+ * The TWL4030/5030 splits its power-management resources (the various
647+ * regulators, clock and reset lines) into 3 processor groups - P1, P2 and P3.
648+ *
649+ * Resources attached to device group P1 is managed depending on the state of
650+ * NSLEEP1 pin of TWL4030, which is connected to sys_off signal from OMAP
651+ *
652+ * Resources attached to device group P2 is managed depending on the state of
653+ * NSLEEP2 pin of TWL4030, which is can be connected to a modem or
654+ * connectivity chip
655+ *
656+ * Resources attached to device group P3 is managed depending on the state of
657+ * CLKREQ pin of TWL4030, which is connected to clk request signal from OMAP
658+ *
659+ * If required these resources can be attached to combination of P1/P2/P3.
660+ *
661+ * These groups can then be configured to transition between sleep, wait-on
662 * and active states by sending messages to the power bus. See Section 5.4.2
663 * Power Resources of TWL4030 TRM
664 */
665@@ -449,7 +469,17 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot)
666 #define DEV_GRP_P1 0x1 /* P1: all OMAP devices */
667 #define DEV_GRP_P2 0x2 /* P2: all Modem devices */
668 #define DEV_GRP_P3 0x4 /* P3: all peripheral devices */
669+#define DEV_GRP_ALL 0x7 /* P1/P2/P3: all devices */
670
671+/*
672+ * The 27 power resources in TWL4030 is again divided into
673+ * analog resources:
674+ * Power Providers - LDO regulators, dc-to-dc regulators
675+ * Power Reference - analog reference
676+ *
677+ * and digital resources:
678+ * Reset & Clock - reset and clock signals.
679+ */
680 /* Resource groups */
681 #define RES_GRP_RES 0x0 /* Reserved */
682 #define RES_GRP_PP 0x1 /* Power providers */
683@@ -461,7 +491,10 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot)
684 #define RES_GRP_ALL 0x7 /* All resource groups */
685
686 #define RES_TYPE2_R0 0x0
687+#define RES_TYPE2_R1 0x1
688+#define RES_TYPE2_R2 0x2
689
690+#define RES_TYPE_R0 0x0
691 #define RES_TYPE_ALL 0x7
692
693 /* Resource states */
694@@ -636,7 +669,7 @@ struct twl4030_power_data {
695 #define TWL4030_RESCONFIG_UNDEF ((u8)-1)
696 };
697
698-extern void twl4030_power_init(struct twl4030_power_data *triton2_scripts);
699+extern int twl4030_power_init(struct twl4030_power_data *triton2_scripts);
700 extern int twl4030_remove_script(u8 flags);
701
702 struct twl4030_codec_audio_data {
703--
7041.6.6.1
705
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0011-MFD-TWL4030-TWL-version-checking.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0011-MFD-TWL4030-TWL-version-checking.patch
new file mode 100644
index 00000000..6de2193d
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0011-MFD-TWL4030-TWL-version-checking.patch
@@ -0,0 +1,164 @@
1From 3ceb224732230934aba7d082f3e2ca96c14a9ca0 Mon Sep 17 00:00:00 2001
2From: Lesly A M <leslyam@ti.com>
3Date: Wed, 1 Jun 2011 14:56:56 -0700
4Subject: [PATCH 11/13] MFD: TWL4030: TWL version checking
5
6Added API to get the TWL5030 Si version from the IDCODE register.
7It is used for enabling the workaround for TWL erratum 27.
8
9Signed-off-by: Lesly A M <leslyam@ti.com>
10Cc: Nishanth Menon <nm@ti.com>
11Cc: David Derrick <dderrick@ti.com>
12Cc: Samuel Ortiz <sameo@linux.intel.com>
13---
14 drivers/mfd/twl-core.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++
15 include/linux/i2c/twl.h | 17 ++++++++++++-
16 2 files changed, 78 insertions(+), 1 deletions(-)
17
18diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
19index 9096d7d..a60601d 100644
20--- a/drivers/mfd/twl-core.c
21+++ b/drivers/mfd/twl-core.c
22@@ -251,6 +251,9 @@
23 /* is driver active, bound to a chip? */
24 static bool inuse;
25
26+/* TWL IDCODE Register value */
27+static u32 twl_idcode;
28+
29 static unsigned int twl_id;
30 unsigned int twl_rev(void)
31 {
32@@ -509,6 +512,58 @@ EXPORT_SYMBOL(twl_i2c_read_u8);
33
34 /*----------------------------------------------------------------------*/
35
36+/**
37+ * twl_read_idcode_register - API to read the IDCODE register.
38+ *
39+ * Unlocks the IDCODE register and read the 32 bit value.
40+ */
41+static int twl_read_idcode_register(void)
42+{
43+ int err;
44+
45+ err = twl_i2c_write_u8(TWL4030_MODULE_INTBR, TWL_EEPROM_R_UNLOCK,
46+ REG_UNLOCK_TEST_REG);
47+ if (err) {
48+ pr_err("TWL4030 Unable to unlock IDCODE registers -%d\n", err);
49+ goto fail;
50+ }
51+
52+ err = twl_i2c_read(TWL4030_MODULE_INTBR, (u8 *)(&twl_idcode),
53+ REG_IDCODE_7_0, 4);
54+ if (err) {
55+ pr_err("TWL4030: unable to read IDCODE -%d\n", err);
56+ goto fail;
57+ }
58+
59+ err = twl_i2c_write_u8(TWL4030_MODULE_INTBR, 0x0, REG_UNLOCK_TEST_REG);
60+ if (err)
61+ pr_err("TWL4030 Unable to relock IDCODE registers -%d\n", err);
62+fail:
63+ return err;
64+}
65+
66+/**
67+ * twl_get_type - API to get TWL Si type.
68+ *
69+ * Api to get the TWL Si type from IDCODE value.
70+ */
71+int twl_get_type(void)
72+{
73+ return TWL_SIL_TYPE(twl_idcode);
74+}
75+EXPORT_SYMBOL_GPL(twl_get_type);
76+
77+/**
78+ * twl_get_version - API to get TWL Si version.
79+ *
80+ * Api to get the TWL Si version from IDCODE value.
81+ */
82+int twl_get_version(void)
83+{
84+ return TWL_SIL_REV(twl_idcode);
85+}
86+EXPORT_SYMBOL_GPL(twl_get_version);
87+
88 static struct device *
89 add_numbered_child(unsigned chip, const char *name, int num,
90 void *pdata, unsigned pdata_len,
91@@ -1071,6 +1126,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
92 unsigned i;
93 struct twl4030_platform_data *pdata = client->dev.platform_data;
94 u8 temp;
95+ int ret = 0;
96
97 if (!pdata) {
98 dev_dbg(&client->dev, "no platform data?\n");
99@@ -1117,6 +1173,12 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
100 /* setup clock framework */
101 clocks_init(&client->dev, pdata->clock);
102
103+ /* read TWL IDCODE Register */
104+ if (twl_id == TWL4030_CLASS_ID) {
105+ ret = twl_read_idcode_register();
106+ WARN(ret < 0, "Error: reading twl_idcode register value\n");
107+ }
108+
109 /* load power event scripts */
110 if (twl_has_power() && pdata->power)
111 twl4030_power_init(pdata->power);
112diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
113index f343974..23ec058 100644
114--- a/include/linux/i2c/twl.h
115+++ b/include/linux/i2c/twl.h
116@@ -151,7 +151,12 @@
117 #define MMC_PU (0x1 << 3)
118 #define MMC_PD (0x1 << 2)
119
120-
121+#define TWL_SIL_TYPE(rev) ((rev) & 0x00FFFFFF)
122+#define TWL_SIL_REV(rev) ((rev) >> 24)
123+#define TWL_SIL_5030 0x09002F
124+#define TWL5030_REV_1_0 0x00
125+#define TWL5030_REV_1_1 0x10
126+#define TWL5030_REV_1_2 0x30
127
128 #define TWL4030_CLASS_ID 0x4030
129 #define TWL6030_CLASS_ID 0x6030
130@@ -181,6 +186,9 @@ int twl_i2c_read_u8(u8 mod_no, u8 *val, u8 reg);
131 int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes);
132 int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes);
133
134+int twl_get_type(void);
135+int twl_get_version(void);
136+
137 int twl6030_interrupt_unmask(u8 bit_mask, u8 offset);
138 int twl6030_interrupt_mask(u8 bit_mask, u8 offset);
139
140@@ -286,7 +294,12 @@ extern struct twl4030_power_data twl4030_generic_script;
141 *(Use TWL_4030_MODULE_INTBR)
142 */
143
144+#define REG_IDCODE_7_0 0x00
145+#define REG_IDCODE_15_8 0x01
146+#define REG_IDCODE_16_23 0x02
147+#define REG_IDCODE_31_24 0x03
148 #define REG_GPPUPDCTR1 0x0F
149+#define REG_UNLOCK_TEST_REG 0x12
150
151 /*I2C1 and I2C4(SR) SDA/SCL pull-up control bits */
152
153@@ -295,6 +308,8 @@ extern struct twl4030_power_data twl4030_generic_script;
154 #define SR_I2C_SCL_CTRL_PU BIT(4)
155 #define SR_I2C_SDA_CTRL_PU BIT(6)
156
157+#define TWL_EEPROM_R_UNLOCK 0x49
158+
159 /*----------------------------------------------------------------------*/
160
161 /*
162--
1631.6.6.1
164
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0012-MFD-TWL4030-workaround-changes-for-Erratum-27.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0012-MFD-TWL4030-workaround-changes-for-Erratum-27.patch
new file mode 100644
index 00000000..6fe9dbfb
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0012-MFD-TWL4030-workaround-changes-for-Erratum-27.patch
@@ -0,0 +1,341 @@
1From 0bec9f7b20e7c61e0bab93195ec39cf94f1f8e25 Mon Sep 17 00:00:00 2001
2From: Lesly A M <leslyam@ti.com>
3Date: Wed, 1 Jun 2011 14:57:01 -0700
4Subject: [PATCH 12/13] MFD: TWL4030: workaround changes for Erratum 27
5
6Workaround for TWL5030 Silicon Errata 27 & 28:
7 27 - VDD1, VDD2, may have glitches when their output value is updated.
8 28 - VDD1 and / or VDD2 DCDC clock may stop working when internal clock
9 is switched from internal to external.
10
11Erratum 27:
12 If the DCDC regulators is running on their internal oscillator,
13 negative glitches may occur on VDD1, VDD2 output when voltage is changed.
14 The OMAP device may reboot if the VDD1 or VDD2 go below the
15 core minimum operating voltage.
16
17 WORKAROUND
18 Set up the TWL5030 DC-DC power supplies to use the HFCLKIN instead of
19 the internal oscillator.
20
21Erratum 28:
22 VDD1/VDD2 clock system may hang during switching the clock source from
23 internal oscillator to external. VDD1/VDD2 output voltages may collapse
24 if clock stops.
25
26 WORKAROUND
27 If HFCLK is disabled in OFFMODE, modify the sleep/wakeup sequence and
28 setuptimes to make sure the switching will happen only when HFCLKIN is stable.
29 Also use the TWL5030 watchdog to safeguard the first switching from
30 internal oscillator to HFCLKIN during the TWL5030 init.
31
32 IMPACT
33 power sequence is changed.
34 sleep/wakeup time values will be changed.
35
36The workaround changes are called from twl4030_power_init(), since we have to
37make some i2c_read calls to check the TWL4030 version & the i2c will not be
38initialized in the early stage.
39
40This workaround is required for TWL5030 Silicon version less than ES1.2
41The power script & setup time changes are recommended by TI HW team.
42
43For more information please see:
44 http://omapedia.org/wiki/TWL4030_power_scripts
45
46Changes taken from TWL4030 Erratum 27 workaround patch by Nishanth Menon.
47
48Signed-off-by: Lesly A M <leslyam@ti.com>
49Cc: Nishanth Menon <nm@ti.com>
50Cc: David Derrick <dderrick@ti.com>
51Cc: Samuel Ortiz <sameo@linux.intel.com>
52---
53 drivers/mfd/twl4030-power.c | 79 +++++++++++++++++++
54 drivers/mfd/twl4030-script-omap.c | 150 +++++++++++++++++++++++++++++++++++++
55 include/linux/i2c/twl.h | 1 +
56 3 files changed, 230 insertions(+), 0 deletions(-)
57
58diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
59index 91d5bc8..8af3fe3 100644
60--- a/drivers/mfd/twl4030-power.c
61+++ b/drivers/mfd/twl4030-power.c
62@@ -63,6 +63,14 @@ static u8 twl4030_start_script_address = 0x2b;
63 #define R_MEMORY_ADDRESS PHY_TO_OFF_PM_MASTER(0x59)
64 #define R_MEMORY_DATA PHY_TO_OFF_PM_MASTER(0x5a)
65
66+#define R_VDD1_OSC 0x5C
67+#define R_VDD2_OSC 0x6A
68+#define R_VIO_OSC 0x52
69+#define EXT_FS_CLK_EN BIT(6)
70+
71+#define R_WDT_CFG 0x03
72+#define WDT_WRK_TIMEOUT 0x03
73+
74 /* resource configuration registers
75 <RESOURCE>_DEV_GRP at address 'n+0'
76 <RESOURCE>_TYPE at address 'n+1'
77@@ -512,6 +520,67 @@ int twl4030_remove_script(u8 flags)
78 }
79 EXPORT_SYMBOL_GPL(twl4030_remove_script);
80
81+/**
82+ * twl_dcdc_use_hfclk - API to use HFCLK for TWL DCDCs
83+ *
84+ * TWL DCDCs switching to HFCLK instead of using internal RC oscillator.
85+ */
86+static int twl_dcdc_use_hfclk(void)
87+{
88+ u8 val;
89+ u8 smps_osc_reg[] = {R_VDD1_OSC, R_VDD2_OSC, R_VIO_OSC};
90+ int i;
91+ int err;
92+
93+ for (i = 0; i < sizeof(smps_osc_reg); i++) {
94+ err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &val,
95+ smps_osc_reg[i]);
96+ val |= EXT_FS_CLK_EN;
97+ err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, val,
98+ smps_osc_reg[i]);
99+ }
100+ return err;
101+}
102+
103+/**
104+ * twl_erratum27_workaround - Workaround for TWL5030 Silicon Erratum 27
105+ * 27 - VDD1, VDD2, may have glitches when their output value is updated.
106+ * 28 - VDD1 and / or VDD2 DCDC clock may stop working when internal clock is
107+ * switched from internal to external.
108+ *
109+ * Workaround requires the TWL DCDCs to use HFCLK instead of
110+ * internal oscillator. Also enable TWL watchdog before switching the osc
111+ * to recover if the VDD1/VDD2 stop working.
112+ */
113+static void twl_erratum27_workaround(void)
114+{
115+ u8 wdt_counter_val = 0;
116+ int err;
117+
118+ /* Setup the twl wdt to take care of borderline failure case */
119+ err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &wdt_counter_val,
120+ R_WDT_CFG);
121+ err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, WDT_WRK_TIMEOUT,
122+ R_WDT_CFG);
123+
124+ /* TWL DCDC switching to HFCLK */
125+ err |= twl_dcdc_use_hfclk();
126+
127+ /* restore the original value */
128+ err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, wdt_counter_val,
129+ R_WDT_CFG);
130+ if (err)
131+ pr_warning("TWL4030: workaround setup failed!\n");
132+}
133+
134+static bool is_twl5030_erratum27wa_required(void)
135+{
136+ if (twl_get_type() == TWL_SIL_5030)
137+ return (twl_get_version() < TWL5030_REV_1_2);
138+
139+ return 0;
140+}
141+
142 int twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
143 {
144 int err = 0;
145@@ -530,6 +599,16 @@ int twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
146 TWL4030_PM_MASTER_PROTECT_KEY);
147 if (err)
148 goto unlock;
149+
150+ /* Applying TWL5030 Erratum 27 WA based on Si revision &
151+ * flag updated from board file*/
152+ if (is_twl5030_erratum27wa_required()) {
153+ pr_info("TWL5030: Enabling workaround for Si Erratum 27\n");
154+ twl_erratum27_workaround();
155+ if (twl4030_scripts->twl5030_erratum27wa_script)
156+ twl4030_scripts->twl5030_erratum27wa_script();
157+ }
158+
159 for (i = 0; i < twl4030_scripts->num; i++) {
160 err = load_twl4030_script(twl4030_scripts->scripts[i], address);
161 if (err)
162diff --git a/drivers/mfd/twl4030-script-omap.c b/drivers/mfd/twl4030-script-omap.c
163index 867a442..ff93fd2 100644
164--- a/drivers/mfd/twl4030-script-omap.c
165+++ b/drivers/mfd/twl4030-script-omap.c
166@@ -326,10 +326,160 @@ static struct twl4030_resconfig twl4030_rconfig[] __initdata = {
167 { 0, 0},
168 };
169
170+/*
171+ * Sleep and active sequences with changes for TWL5030 Erratum 27 workaround
172+ *
173+ * Sysoff (using sys_off signal):
174+ * When SYS_CLKREQ goes low during retention no resources will be affected
175+ * since no resources are assigned to P3 only.
176+ *
177+ * Since all resources are assigned to P1 and P3 then all resources
178+ * will be affected on the falling edge of P3 (SYS_CLKREQ).
179+ * When OMAP lower the SYS_CLKREQ signal PMIC will execute the
180+ * A2S sequence in which HFCLKOUT is dissabled first and
181+ * after 488.32 usec(PRM_VOLTOFFSET) resources assigned to P1 and P3
182+ * and of TYPE2=1 are put to sleep
183+ * (VDD1, VDD2, VPLL1, REGEN, NRESPWRON & SYSEN).
184+ * Again after a 61.04 usec resources assigned to P1 and P3
185+ * and of TYPE2=2 are put to sleep
186+ * (VINTANA1, VINTANA2, VINTDIG, VIO & CLKEN).
187+ *
188+ * On wakeup event OMAP goes active and pulls the SYS_CLKREQ high,
189+ * and will execute the S2A sequence which is same for P1_P2 & P3.
190+ * This will turn on all resources of TYPE2=2 to go to the active state.
191+ * Three dummy broadcast messages are added to get a delay of ~10 ms
192+ * before enabling the HFCLKOUT resource. And after a 30.52 usec
193+ * all resources of TYPE2=1 are put to the active state.
194+ *
195+ * This 10ms delay can be reduced if the oscillator is having less
196+ * stabilization time. A should be taken care if it needs more time
197+ * for stabilization.
198+ *
199+ */
200+
201+/**
202+ * DOC: Sleep to Active sequence for P1/P2/P3
203+ *
204+ * The wakeup sequence is adjusted to do the VDD1/VDD2 voltage ramp-up
205+ * only after HFCLKIN is stabilized and the HFCLKOUT is enabled.
206+ */
207+static struct twl4030_ins wakeup_seq_erratum27[] __initdata = {
208+ /*
209+ * Broadcast message to put res(TYPE2 = 2) to active.
210+ * Wait for ~10 mS (ramp-up time for OSC on the board)
211+ * after HFCLKIN is enabled
212+ */
213+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
214+ RES_STATE_ACTIVE), 55},
215+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
216+ RES_STATE_ACTIVE), 55},
217+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
218+ RES_STATE_ACTIVE), 54},
219+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
220+ RES_STATE_ACTIVE), 1},
221+ /* Singular message to enable HCLKOUT after HFCLKIN is stabilized */
222+ {MSG_SINGULAR(DEV_GRP_NULL, RES_HFCLKOUT, RES_STATE_ACTIVE), 1},
223+ /*
224+ * Broadcast message to put res(TYPE2 = 1) to active.
225+ * VDD1/VDD2 ramp-up after HFCLKIN is stable and HFCLKOUT is enabled.
226+ */
227+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1,
228+ RES_STATE_ACTIVE), 2},
229+};
230+
231+static struct twl4030_script wakeup_script_erratum27 __initdata = {
232+ .script = wakeup_seq_erratum27,
233+ .size = ARRAY_SIZE(wakeup_seq_erratum27),
234+ .flags = TWL4030_WAKEUP12_SCRIPT | TWL4030_WAKEUP3_SCRIPT,
235+};
236+
237+/**
238+ * DOC: Active to Sleep sequence for P1/P2/P3
239+ *
240+ * The sleep sequence is adjusted to do the switching of VDD1/VDD2/VIO OSC from
241+ * HFCLKIN to internal oscillator when the HFCLKIN is stable.
242+ */
243+static struct twl4030_ins sleep_on_seq_erratum27[] __initdata = {
244+ /*
245+ * Singular message to disable HCLKOUT.
246+ * Wait for ~488.32 uS to do the switching of VDD1/VDD2/VIO OSC from
247+ * HFCLKIN to internal oscillator before disabling HFCLKIN.
248+ */
249+ {MSG_SINGULAR(DEV_GRP_NULL, RES_HFCLKOUT, RES_STATE_SLEEP), 20},
250+ /* Broadcast message to put res(TYPE2 = 1) to sleep */
251+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1,
252+ RES_STATE_SLEEP), 2},
253+ /* Broadcast message to put res(TYPE2 = 2) to sleep, disable HFCLKIN */
254+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
255+ RES_STATE_SLEEP), 2},
256+};
257+
258+static struct twl4030_script sleep_on_script_erratum27 __initdata = {
259+ .script = sleep_on_seq_erratum27,
260+ .size = ARRAY_SIZE(sleep_on_seq_erratum27),
261+ .flags = TWL4030_SLEEP_SCRIPT,
262+};
263+
264+/* TWL4030 script for sleep, wakeup & warm_reset */
265+static struct twl4030_script *twl4030_scripts_erratum27[] __initdata = {
266+ &wakeup_script_erratum27,
267+ &sleep_on_script_erratum27,
268+ &wrst_script,
269+};
270+
271+/**
272+ * DOC: TWL4030 resource configuration
273+ *
274+ * VDD1/VDD2/VPLL are assigned to P1 and P3, to have better control
275+ * during OFFMODE. HFCLKOUT is assigned to P1 and P3 (*p2) to turn off
276+ * only during OFFMODE.
277+ * (*P2 is included if the platform uses it for modem/some other processor)
278+ */
279+static struct twl4030_resconfig twl4030_rconfig_erratum27[] __initdata = {
280+ { .resource = RES_VPLL1, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
281+ .type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF },
282+ { .resource = RES_VINTANA1, .devgroup = DEV_GRP_ALL, .type = 1,
283+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
284+ { .resource = RES_VINTANA2, .devgroup = DEV_GRP_ALL, .type = 0,
285+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
286+ { .resource = RES_VINTDIG, .devgroup = DEV_GRP_ALL, .type = 1,
287+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
288+ { .resource = RES_VIO, .devgroup = DEV_GRP_ALL, .type = 2,
289+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
290+ { .resource = RES_VDD1, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
291+ .type = 4, .type2 = 1, .remap_sleep = RES_STATE_OFF },
292+ { .resource = RES_VDD2, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
293+ .type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF },
294+ { .resource = RES_REGEN, .devgroup = DEV_GRP_ALL, .type = 2,
295+ .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
296+ { .resource = RES_NRES_PWRON, .devgroup = DEV_GRP_ALL, .type = 0,
297+ .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
298+ { .resource = RES_CLKEN, .devgroup = DEV_GRP_ALL, .type = 3,
299+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
300+ { .resource = RES_SYSEN, .devgroup = DEV_GRP_ALL, .type = 6,
301+ .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
302+ { .resource = RES_HFCLKOUT, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
303+ .type = 0, .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
304+ { 0, 0},
305+};
306+
307+/**
308+ * twl5030_script_erratum27() - API to modify TWL4030 script
309+ *
310+ * Updating the TWL4030 script & resource configuration
311+ */
312+static void __init twl5030_script_erratum27(void)
313+{
314+ twl4030_generic_script.scripts = twl4030_scripts_erratum27;
315+ twl4030_generic_script.num = ARRAY_SIZE(twl4030_scripts_erratum27);
316+ twl4030_generic_script.resource_config = twl4030_rconfig_erratum27;
317+}
318+
319 struct twl4030_power_data twl4030_generic_script __initdata = {
320 .scripts = twl4030_scripts,
321 .num = ARRAY_SIZE(twl4030_scripts),
322 .resource_config = twl4030_rconfig,
323+ .twl5030_erratum27wa_script = twl5030_script_erratum27,
324 };
325
326 static int __init twl4030_script_probe(struct platform_device *pdev)
327diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
328index 23ec058..10cb6e2 100644
329--- a/include/linux/i2c/twl.h
330+++ b/include/linux/i2c/twl.h
331@@ -681,6 +681,7 @@ struct twl4030_power_data {
332 struct twl4030_script **scripts;
333 unsigned num;
334 struct twl4030_resconfig *resource_config;
335+ void (*twl5030_erratum27wa_script)(void);
336 #define TWL4030_RESCONFIG_UNDEF ((u8)-1)
337 };
338
339--
3401.6.6.1
341
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0013-MFD-TWL4030-optimizing-resource-configuration.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0013-MFD-TWL4030-optimizing-resource-configuration.patch
new file mode 100644
index 00000000..8904f8de
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0013-MFD-TWL4030-optimizing-resource-configuration.patch
@@ -0,0 +1,184 @@
1From bf171753a162d07753208c6bcfae8ca1e5c94af3 Mon Sep 17 00:00:00 2001
2From: Lesly A M <leslyam@ti.com>
3Date: Wed, 1 Jun 2011 14:57:05 -0700
4Subject: [PATCH 13/13] MFD: TWL4030: optimizing resource configuration
5
6Skip the i2c register writes in twl4030_configure_resource() if the new value
7is same as the old value, for devgrp/type/remap regs.
8
9Suggested by David Derrick <dderrick@ti.com>
10
11Signed-off-by: Lesly A M <leslyam@ti.com>
12Cc: Nishanth Menon <nm@ti.com>
13Cc: David Derrick <dderrick@ti.com>
14Cc: Samuel Ortiz <sameo@linux.intel.com>
15---
16 drivers/mfd/twl4030-power.c | 126 ++++++++++++++++++++++++------------------
17 1 files changed, 72 insertions(+), 54 deletions(-)
18
19diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
20index 8af3fe3..d82632f 100644
21--- a/drivers/mfd/twl4030-power.c
22+++ b/drivers/mfd/twl4030-power.c
23@@ -335,9 +335,9 @@ static int twl4030_configure_resource(struct twl4030_resconfig *rconfig)
24 {
25 int rconfig_addr;
26 int err;
27- u8 type;
28- u8 grp;
29- u8 remap;
30+ u8 type, type_value;
31+ u8 grp, grp_value;
32+ u8 remap, remap_value;
33
34 if (rconfig->resource > TOTAL_RESOURCES) {
35 pr_err("TWL4030 Resource %d does not exist\n",
36@@ -348,76 +348,94 @@ static int twl4030_configure_resource(struct twl4030_resconfig *rconfig)
37 rconfig_addr = res_config_addrs[rconfig->resource];
38
39 /* Set resource group */
40- err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &grp,
41+ if (rconfig->devgroup != TWL4030_RESCONFIG_UNDEF) {
42+ err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &grp,
43 rconfig_addr + DEV_GRP_OFFSET);
44- if (err) {
45- pr_err("TWL4030 Resource %d group could not be read\n",
46- rconfig->resource);
47- return err;
48- }
49+ if (err) {
50+ pr_err("TWL4030 Resource %d group could not be read\n",
51+ rconfig->resource);
52+ return err;
53+ }
54
55- if (rconfig->devgroup != TWL4030_RESCONFIG_UNDEF) {
56- grp &= ~DEV_GRP_MASK;
57- grp |= rconfig->devgroup << DEV_GRP_SHIFT;
58- err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
59+ grp_value = (grp & DEV_GRP_MASK) >> DEV_GRP_SHIFT;
60+
61+ if (rconfig->devgroup != grp_value) {
62+ grp &= ~DEV_GRP_MASK;
63+ grp |= rconfig->devgroup << DEV_GRP_SHIFT;
64+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
65 grp, rconfig_addr + DEV_GRP_OFFSET);
66- if (err < 0) {
67- pr_err("TWL4030 failed to program devgroup\n");
68- return err;
69+ if (err < 0) {
70+ pr_err("TWL4030 failed to program devgroup\n");
71+ return err;
72+ }
73 }
74 }
75
76 /* Set resource types */
77- err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &type,
78+ if ((rconfig->type != TWL4030_RESCONFIG_UNDEF) ||
79+ (rconfig->type2 != TWL4030_RESCONFIG_UNDEF)) {
80+
81+ err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &type,
82 rconfig_addr + TYPE_OFFSET);
83- if (err < 0) {
84- pr_err("TWL4030 Resource %d type could not be read\n",
85- rconfig->resource);
86- return err;
87- }
88+ if (err < 0) {
89+ pr_err("TWL4030 Resource %d type could not be read\n",
90+ rconfig->resource);
91+ return err;
92+ }
93
94- if (rconfig->type != TWL4030_RESCONFIG_UNDEF) {
95- type &= ~TYPE_MASK;
96- type |= rconfig->type << TYPE_SHIFT;
97- }
98+ type_value = type;
99
100- if (rconfig->type2 != TWL4030_RESCONFIG_UNDEF) {
101- type &= ~TYPE2_MASK;
102- type |= rconfig->type2 << TYPE2_SHIFT;
103- }
104+ if (rconfig->type != TWL4030_RESCONFIG_UNDEF) {
105+ type &= ~TYPE_MASK;
106+ type |= rconfig->type << TYPE_SHIFT;
107+ }
108
109- err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
110+ if (rconfig->type2 != TWL4030_RESCONFIG_UNDEF) {
111+ type &= ~TYPE2_MASK;
112+ type |= rconfig->type2 << TYPE2_SHIFT;
113+ }
114+
115+ if (type != type_value) {
116+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
117 type, rconfig_addr + TYPE_OFFSET);
118- if (err < 0) {
119- pr_err("TWL4030 failed to program resource type\n");
120- return err;
121+ if (err < 0) {
122+ pr_err("TWL4030 failed to program resource type\n");
123+ return err;
124+ }
125+ }
126 }
127
128 /* Set remap states */
129- err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &remap,
130+ if ((rconfig->remap_off != TWL4030_RESCONFIG_UNDEF) ||
131+ (rconfig->remap_sleep != TWL4030_RESCONFIG_UNDEF)) {
132+ err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &remap,
133 rconfig_addr + REMAP_OFFSET);
134- if (err < 0) {
135- pr_err("TWL4030 Resource %d remap could not be read\n",
136- rconfig->resource);
137- return err;
138- }
139+ if (err < 0) {
140+ pr_err("TWL4030 Resource %d remap could not be read\n",
141+ rconfig->resource);
142+ return err;
143+ }
144
145- if (rconfig->remap_off != TWL4030_RESCONFIG_UNDEF) {
146- remap &= ~OFF_STATE_MASK;
147- remap |= rconfig->remap_off << OFF_STATE_SHIFT;
148- }
149+ remap_value = remap;
150
151- if (rconfig->remap_sleep != TWL4030_RESCONFIG_UNDEF) {
152- remap &= ~SLEEP_STATE_MASK;
153- remap |= rconfig->remap_sleep << SLEEP_STATE_SHIFT;
154- }
155+ if (rconfig->remap_off != TWL4030_RESCONFIG_UNDEF) {
156+ remap &= ~OFF_STATE_MASK;
157+ remap |= rconfig->remap_off << OFF_STATE_SHIFT;
158+ }
159
160- err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
161- remap,
162- rconfig_addr + REMAP_OFFSET);
163- if (err < 0) {
164- pr_err("TWL4030 failed to program remap\n");
165- return err;
166+ if (rconfig->remap_sleep != TWL4030_RESCONFIG_UNDEF) {
167+ remap &= ~SLEEP_STATE_MASK;
168+ remap |= rconfig->remap_sleep << SLEEP_STATE_SHIFT;
169+ }
170+
171+ if (remap != remap_value) {
172+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
173+ remap, rconfig_addr + REMAP_OFFSET);
174+ if (err < 0) {
175+ pr_err("TWL4030 failed to program remap\n");
176+ return err;
177+ }
178+ }
179 }
180
181 return 0;
182--
1831.6.6.1
184