musb resume fix to charge/talk to computer USB port
[kernel-power] / kernel-power-2.6.28 / debian / patches / musb_suspend_and_fixes.diff
1 From a96cab2a7a2afdaf8b895c53f98498d67fa8c563 Mon Sep 17 00:00:00 2001
2 From: David Fries <David@Fries.net>
3 Date: Wed, 5 Sep 2012 19:28:04 -0500
4 Subject: [PATCH 1/4] musb resume fix, don't store context when suspending
5
6 The hardware register context in suspend are in such a state that
7 restoring it later will prevent talking to a computer USB port (or
8 charging).  However leaving the register context as stored previously
9 will allow it to work after a suspend to memory operation.
10 ---
11  drivers/usb/musb/musb_core.c |    9 +++++++--
12  1 file changed, 7 insertions(+), 2 deletions(-)
13
14 diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
15 index cc10f5c..42f8499 100644
16 --- a/drivers/usb/musb/musb_core.c
17 +++ b/drivers/usb/musb/musb_core.c
18 @@ -2665,8 +2665,13 @@ static int musb_suspend(struct platform_device *pdev, pm_message_t message)
19                  */
20         }
21  
22 -       /* save context */
23 -       musb_save_ctx(musb);
24 +       /* save context, actually don't, the hardware register context 'now'
25 +        * is in such a state that restoring it later will prevent talking to
26 +        * a computer USB port (or charging).  However leaving the register
27 +        * context as stored previously will allow it to work.
28 +        *
29 +        * musb_save_ctx(musb);
30 +        */
31  
32         if (musb->set_clock)
33                 musb->set_clock(musb->clock, 0);
34 -- 
35 1.7.10.4
36
37
38 From 85abd671c5dad36dffe6071c4a37619b7396096e Mon Sep 17 00:00:00 2001
39 From: David Fries <David@Fries.net>
40 Date: Mon, 27 Aug 2012 23:25:42 -0500
41 Subject: [PATCH 2/4] twl4030-usb add suggested delay between voltage power on
42
43 ---
44  drivers/usb/otg/twl4030-usb.c |    4 ++++
45  1 file changed, 4 insertions(+)
46
47 diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c
48 index f9ca548..dd44457 100644
49 --- a/drivers/usb/otg/twl4030-usb.c
50 +++ b/drivers/usb/otg/twl4030-usb.c
51 @@ -473,6 +473,10 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on)
52         if (on) {
53                 twl4030_usb3v1_sleep(false);
54                 regulator_enable(twl->usb1v8);
55 +               /* recommened 10 to 20 usec delay to "avoid simultaneous large
56 +                * incrush current" or 450 mA*2*4.5 V = 4.05 W for 2 usec
57 +                */
58 +               udelay(20);
59                 regulator_enable(twl->usb1v5);
60                 pwr &= ~PHY_PWR_PHYPWD;
61                 WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
62 -- 
63 1.7.10.4
64
65
66 From 42440912e1e9c2897835c6e374645612d7a55785 Mon Sep 17 00:00:00 2001
67 From: David Fries <David@Fries.net>
68 Date: Sat, 8 Sep 2012 19:34:29 -0500
69 Subject: [PATCH 3/4] sleep while detecting charger
70
71 Add a 1ms sleep between charger detect reads as it is reading for
72 300ms and most likely already being interrupted in that time.
73 ---
74  drivers/usb/musb/musb_core.c |    1 +
75  1 file changed, 1 insertion(+)
76
77 diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
78 index 42f8499..dee8251 100644
79 --- a/drivers/usb/musb/musb_core.c
80 +++ b/drivers/usb/musb/musb_core.c
81 @@ -289,6 +289,7 @@ static int musb_charger_detect(struct musb *musb)
82                                                         & ISP1704_PWR_CTRL_VDAT_DET);
83                                 if (vdat)
84                                         break;
85 +                               msleep(1);
86                         }
87                         if (vdat)
88                                 vdat = musb_verify_charger(musb->mregs);
89 -- 
90 1.7.10.4
91
92
93 From 11587f1250450ac711706ca68d7161171674fa0a Mon Sep 17 00:00:00 2001
94 From: David Fries <David@Fries.net>
95 Date: Fri, 24 Aug 2012 21:07:28 -0500
96 Subject: [PATCH 4/4] add musb_start/musb_stop to suspend/resume
97
98 ---
99  drivers/usb/musb/musb_core.c   |   35 +++++++++++++++++++++++------------
100  drivers/usb/musb/musb_core.h   |    1 +
101  drivers/usb/musb/musb_gadget.c |    5 +++--
102  3 files changed, 27 insertions(+), 14 deletions(-)
103
104 diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
105 index dee8251..efd1eed 100644
106 --- a/drivers/usb/musb/musb_core.c
107 +++ b/drivers/usb/musb/musb_core.c
108 @@ -2651,8 +2651,6 @@ static int musb_suspend(struct platform_device *pdev, pm_message_t message)
109         unsigned long   flags;
110         struct musb     *musb = dev_to_musb(&pdev->dev);
111  
112 -       if (!musb->clock)
113 -               return 0;
114  
115         spin_lock_irqsave(&musb->lock, flags);
116  
117 @@ -2674,12 +2672,18 @@ static int musb_suspend(struct platform_device *pdev, pm_message_t message)
118          * musb_save_ctx(musb);
119          */
120  
121 -       if (musb->set_clock)
122 -               musb->set_clock(musb->clock, 0);
123 -       else
124 -               clk_disable(musb->clock);
125 +       if (!musb->clock) {
126 +               if (musb->set_clock)
127 +                       musb->set_clock(musb->clock, 0);
128 +               else
129 +                       clk_disable(musb->clock);
130 +       }
131  
132         spin_unlock_irqrestore(&musb->lock, flags);
133 +
134 +       musb_hnp_stop(musb);
135 +       musb_pullup(musb, 0);
136 +       musb_stop(musb);
137         return 0;
138  }
139  
140 @@ -2688,15 +2692,15 @@ static int musb_resume(struct platform_device *pdev)
141         unsigned long   flags;
142         struct musb     *musb = dev_to_musb(&pdev->dev);
143  
144 -       if (!musb->clock)
145 -               return 0;
146  
147         spin_lock_irqsave(&musb->lock, flags);
148  
149 -       if (musb->set_clock)
150 -               musb->set_clock(musb->clock, 1);
151 -       else
152 -               clk_enable(musb->clock);
153 +       if (!musb->clock) {
154 +               if (musb->set_clock)
155 +                       musb->set_clock(musb->clock, 1);
156 +               else
157 +                       clk_enable(musb->clock);
158 +       }
159  
160         /* restore context */
161         musb_restore_ctx(musb);
162 @@ -2706,6 +2710,8 @@ static int musb_resume(struct platform_device *pdev)
163          * not treating that as a whole-system restart (e.g. swsusp)
164          */
165         spin_unlock_irqrestore(&musb->lock, flags);
166 +       if(musb->xceiv && musb->xceiv->gadget)
167 +               musb_start(musb);
168         return 0;
169  }
170  
171 @@ -2767,6 +2773,11 @@ subsys_initcall(musb_init);
172  
173  static void __exit musb_cleanup(void)
174  {
175 +       if(the_musb) {
176 +               musb_hnp_stop(the_musb);
177 +               musb_pullup(the_musb, 0);
178 +               musb_stop(the_musb);
179 +       }
180         platform_driver_unregister(&musb_driver);
181  }
182  module_exit(musb_cleanup);
183 diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
184 index 9ede3ab..7a38d15 100644
185 --- a/drivers/usb/musb/musb_core.h
186 +++ b/drivers/usb/musb/musb_core.h
187 @@ -117,6 +117,7 @@ extern void musb_g_suspend(struct musb *);
188  extern void musb_g_resume(struct musb *);
189  extern void musb_g_wakeup(struct musb *);
190  extern void musb_g_disconnect(struct musb *);
191 +extern void musb_pullup(struct musb *musb, int is_on);
192  
193  #else
194  
195 diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
196 index abd80d3..f19f834 100644
197 --- a/drivers/usb/musb/musb_gadget.c
198 +++ b/drivers/usb/musb/musb_gadget.c
199 @@ -1393,7 +1393,7 @@ musb_gadget_set_self_powered(struct usb_gadget *gadget, int is_selfpowered)
200         return 0;
201  }
202  
203 -static void musb_pullup(struct musb *musb, int is_on)
204 +void musb_pullup(struct musb *musb, int is_on)
205  {
206         u8 power;
207  
208 @@ -1435,7 +1435,8 @@ static void musb_pullup(struct musb *musb, int is_on)
209         /* FIXME if on, HdrcStart; if off, HdrcStop */
210  
211         DBG(3, "gadget %s D+ pullup %s\n",
212 -               musb->gadget_driver->function, is_on ? "on" : "off");
213 +               musb->gadget_driver ? musb->gadget_driver->function : NULL,
214 +               is_on ? "on" : "off");
215         musb_writeb(musb->mregs, MUSB_POWER, power);
216  }
217  
218 -- 
219 1.7.10.4
220