usb: musb: omap2430: fix kernel panic on reboot
[linux-2.6.git] / drivers / usb / musb / omap2430.c
1 /*
2  * Copyright (C) 2005-2007 by Texas Instruments
3  * Some code has been taken from tusb6010.c
4  * Copyrights for that are attributable to:
5  * Copyright (C) 2006 Nokia Corporation
6  * Tony Lindgren <tony@atomide.com>
7  *
8  * This file is part of the Inventra Controller Driver for Linux.
9  *
10  * The Inventra Controller Driver for Linux is free software; you
11  * can redistribute it and/or modify it under the terms of the GNU
12  * General Public License version 2 as published by the Free Software
13  * Foundation.
14  *
15  * The Inventra Controller Driver for Linux is distributed in
16  * the hope that it will be useful, but WITHOUT ANY WARRANTY;
17  * without even the implied warranty of MERCHANTABILITY or
18  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
19  * License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with The Inventra Controller Driver for Linux ; if not,
23  * write to the Free Software Foundation, Inc., 59 Temple Place,
24  * Suite 330, Boston, MA  02111-1307  USA
25  *
26  */
27 #include <linux/module.h>
28 #include <linux/kernel.h>
29 #include <linux/sched.h>
30 #include <linux/init.h>
31 #include <linux/list.h>
32 #include <linux/clk.h>
33 #include <linux/io.h>
34 #include <linux/platform_device.h>
35 #include <linux/dma-mapping.h>
36
37 #include "musb_core.h"
38 #include "omap2430.h"
39
40 struct omap2430_glue {
41         struct device           *dev;
42         struct platform_device  *musb;
43         struct clk              *clk;
44 };
45 #define glue_to_musb(g)         platform_get_drvdata(g->musb)
46
47 static struct timer_list musb_idle_timer;
48
49 static void musb_do_idle(unsigned long _musb)
50 {
51         struct musb     *musb = (void *)_musb;
52         unsigned long   flags;
53 #ifdef CONFIG_USB_MUSB_HDRC_HCD
54         u8      power;
55 #endif
56         u8      devctl;
57
58         spin_lock_irqsave(&musb->lock, flags);
59
60         switch (musb->xceiv->state) {
61         case OTG_STATE_A_WAIT_BCON:
62
63                 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
64                 if (devctl & MUSB_DEVCTL_BDEVICE) {
65                         musb->xceiv->state = OTG_STATE_B_IDLE;
66                         MUSB_DEV_MODE(musb);
67                 } else {
68                         musb->xceiv->state = OTG_STATE_A_IDLE;
69                         MUSB_HST_MODE(musb);
70                 }
71                 break;
72 #ifdef CONFIG_USB_MUSB_HDRC_HCD
73         case OTG_STATE_A_SUSPEND:
74                 /* finish RESUME signaling? */
75                 if (musb->port1_status & MUSB_PORT_STAT_RESUME) {
76                         power = musb_readb(musb->mregs, MUSB_POWER);
77                         power &= ~MUSB_POWER_RESUME;
78                         DBG(1, "root port resume stopped, power %02x\n", power);
79                         musb_writeb(musb->mregs, MUSB_POWER, power);
80                         musb->is_active = 1;
81                         musb->port1_status &= ~(USB_PORT_STAT_SUSPEND
82                                                 | MUSB_PORT_STAT_RESUME);
83                         musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16;
84                         usb_hcd_poll_rh_status(musb_to_hcd(musb));
85                         /* NOTE: it might really be A_WAIT_BCON ... */
86                         musb->xceiv->state = OTG_STATE_A_HOST;
87                 }
88                 break;
89 #endif
90 #ifdef CONFIG_USB_MUSB_HDRC_HCD
91         case OTG_STATE_A_HOST:
92                 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
93                 if (devctl &  MUSB_DEVCTL_BDEVICE)
94                         musb->xceiv->state = OTG_STATE_B_IDLE;
95                 else
96                         musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
97 #endif
98         default:
99                 break;
100         }
101         spin_unlock_irqrestore(&musb->lock, flags);
102 }
103
104
105 static void omap2430_musb_try_idle(struct musb *musb, unsigned long timeout)
106 {
107         unsigned long           default_timeout = jiffies + msecs_to_jiffies(3);
108         static unsigned long    last_timer;
109
110         if (timeout == 0)
111                 timeout = default_timeout;
112
113         /* Never idle if active, or when VBUS timeout is not set as host */
114         if (musb->is_active || ((musb->a_wait_bcon == 0)
115                         && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) {
116                 DBG(4, "%s active, deleting timer\n", otg_state_string(musb));
117                 del_timer(&musb_idle_timer);
118                 last_timer = jiffies;
119                 return;
120         }
121
122         if (time_after(last_timer, timeout)) {
123                 if (!timer_pending(&musb_idle_timer))
124                         last_timer = timeout;
125                 else {
126                         DBG(4, "Longer idle timer already pending, ignoring\n");
127                         return;
128                 }
129         }
130         last_timer = timeout;
131
132         DBG(4, "%s inactive, for idle timer for %lu ms\n",
133                 otg_state_string(musb),
134                 (unsigned long)jiffies_to_msecs(timeout - jiffies));
135         mod_timer(&musb_idle_timer, timeout);
136 }
137
138 static void omap2430_musb_set_vbus(struct musb *musb, int is_on)
139 {
140         u8              devctl;
141         unsigned long timeout = jiffies + msecs_to_jiffies(1000);
142         int ret = 1;
143         /* HDRC controls CPEN, but beware current surges during device
144          * connect.  They can trigger transient overcurrent conditions
145          * that must be ignored.
146          */
147
148         devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
149
150         if (is_on) {
151                 if (musb->xceiv->state == OTG_STATE_A_IDLE) {
152                         /* start the session */
153                         devctl |= MUSB_DEVCTL_SESSION;
154                         musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
155                         /*
156                          * Wait for the musb to set as A device to enable the
157                          * VBUS
158                          */
159                         while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) {
160
161                                 cpu_relax();
162
163                                 if (time_after(jiffies, timeout)) {
164                                         dev_err(musb->controller,
165                                         "configured as A device timeout");
166                                         ret = -EINVAL;
167                                         break;
168                                 }
169                         }
170
171                         if (ret && musb->xceiv->set_vbus)
172                                 otg_set_vbus(musb->xceiv, 1);
173                 } else {
174                         musb->is_active = 1;
175                         musb->xceiv->default_a = 1;
176                         musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
177                         devctl |= MUSB_DEVCTL_SESSION;
178                         MUSB_HST_MODE(musb);
179                 }
180         } else {
181                 musb->is_active = 0;
182
183                 /* NOTE:  we're skipping A_WAIT_VFALL -> A_IDLE and
184                  * jumping right to B_IDLE...
185                  */
186
187                 musb->xceiv->default_a = 0;
188                 musb->xceiv->state = OTG_STATE_B_IDLE;
189                 devctl &= ~MUSB_DEVCTL_SESSION;
190
191                 MUSB_DEV_MODE(musb);
192         }
193         musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
194
195         DBG(1, "VBUS %s, devctl %02x "
196                 /* otg %3x conf %08x prcm %08x */ "\n",
197                 otg_state_string(musb),
198                 musb_readb(musb->mregs, MUSB_DEVCTL));
199 }
200
201 static int omap2430_musb_set_mode(struct musb *musb, u8 musb_mode)
202 {
203         u8      devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
204
205         devctl |= MUSB_DEVCTL_SESSION;
206         musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
207
208         return 0;
209 }
210
211 static inline void omap2430_low_level_exit(struct musb *musb)
212 {
213         u32 l;
214
215         /* in any role */
216         l = musb_readl(musb->mregs, OTG_FORCESTDBY);
217         l |= ENABLEFORCE;       /* enable MSTANDBY */
218         musb_writel(musb->mregs, OTG_FORCESTDBY, l);
219
220         l = musb_readl(musb->mregs, OTG_SYSCONFIG);
221         l |= ENABLEWAKEUP;      /* enable wakeup */
222         musb_writel(musb->mregs, OTG_SYSCONFIG, l);
223 }
224
225 static inline void omap2430_low_level_init(struct musb *musb)
226 {
227         u32 l;
228
229         l = musb_readl(musb->mregs, OTG_SYSCONFIG);
230         l &= ~ENABLEWAKEUP;     /* disable wakeup */
231         musb_writel(musb->mregs, OTG_SYSCONFIG, l);
232
233         l = musb_readl(musb->mregs, OTG_FORCESTDBY);
234         l &= ~ENABLEFORCE;      /* disable MSTANDBY */
235         musb_writel(musb->mregs, OTG_FORCESTDBY, l);
236 }
237
238 /* blocking notifier support */
239 static int musb_otg_notifications(struct notifier_block *nb,
240                 unsigned long event, void *unused)
241 {
242         struct musb     *musb = container_of(nb, struct musb, nb);
243         struct device *dev = musb->controller;
244         struct musb_hdrc_platform_data *pdata = dev->platform_data;
245         struct omap_musb_board_data *data = pdata->board_data;
246
247         switch (event) {
248         case USB_EVENT_ID:
249                 DBG(4, "ID GND\n");
250
251                 if (is_otg_enabled(musb)) {
252 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
253                         if (musb->gadget_driver) {
254                                 otg_init(musb->xceiv);
255
256                                 if (data->interface_type ==
257                                                 MUSB_INTERFACE_UTMI)
258                                         omap2430_musb_set_vbus(musb, 1);
259
260                         }
261 #endif
262                 } else {
263                         otg_init(musb->xceiv);
264                         if (data->interface_type ==
265                                         MUSB_INTERFACE_UTMI)
266                                 omap2430_musb_set_vbus(musb, 1);
267                 }
268                 break;
269
270         case USB_EVENT_VBUS:
271                 DBG(4, "VBUS Connect\n");
272
273                 otg_init(musb->xceiv);
274                 break;
275
276         case USB_EVENT_NONE:
277                 DBG(4, "VBUS Disconnect\n");
278
279                 if (data->interface_type == MUSB_INTERFACE_UTMI) {
280                         if (musb->xceiv->set_vbus)
281                                 otg_set_vbus(musb->xceiv, 0);
282                 }
283                 otg_shutdown(musb->xceiv);
284                 break;
285         default:
286                 DBG(4, "ID float\n");
287                 return NOTIFY_DONE;
288         }
289
290         return NOTIFY_OK;
291 }
292
293 static int omap2430_musb_init(struct musb *musb)
294 {
295         u32 l, status = 0;
296         struct device *dev = musb->controller;
297         struct musb_hdrc_platform_data *plat = dev->platform_data;
298         struct omap_musb_board_data *data = plat->board_data;
299
300         /* We require some kind of external transceiver, hooked
301          * up through ULPI.  TWL4030-family PMICs include one,
302          * which needs a driver, drivers aren't always needed.
303          */
304         musb->xceiv = otg_get_transceiver();
305         if (!musb->xceiv) {
306                 pr_err("HS USB OTG: no transceiver configured\n");
307                 return -ENODEV;
308         }
309
310         omap2430_low_level_init(musb);
311
312         l = musb_readl(musb->mregs, OTG_SYSCONFIG);
313         l &= ~ENABLEWAKEUP;     /* disable wakeup */
314         l &= ~NOSTDBY;          /* remove possible nostdby */
315         l |= SMARTSTDBY;        /* enable smart standby */
316         l &= ~AUTOIDLE;         /* disable auto idle */
317         l &= ~NOIDLE;           /* remove possible noidle */
318         l |= SMARTIDLE;         /* enable smart idle */
319         /*
320          * MUSB AUTOIDLE don't work in 3430.
321          * Workaround by Richard Woodruff/TI
322          */
323         if (!cpu_is_omap3430())
324                 l |= AUTOIDLE;          /* enable auto idle */
325         musb_writel(musb->mregs, OTG_SYSCONFIG, l);
326
327         l = musb_readl(musb->mregs, OTG_INTERFSEL);
328
329         if (data->interface_type == MUSB_INTERFACE_UTMI) {
330                 /* OMAP4 uses Internal PHY GS70 which uses UTMI interface */
331                 l &= ~ULPI_12PIN;       /* Disable ULPI */
332                 l |= UTMI_8BIT;         /* Enable UTMI  */
333         } else {
334                 l |= ULPI_12PIN;
335         }
336
337         musb_writel(musb->mregs, OTG_INTERFSEL, l);
338
339         pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, "
340                         "sysstatus 0x%x, intrfsel 0x%x, simenable  0x%x\n",
341                         musb_readl(musb->mregs, OTG_REVISION),
342                         musb_readl(musb->mregs, OTG_SYSCONFIG),
343                         musb_readl(musb->mregs, OTG_SYSSTATUS),
344                         musb_readl(musb->mregs, OTG_INTERFSEL),
345                         musb_readl(musb->mregs, OTG_SIMENABLE));
346
347         musb->nb.notifier_call = musb_otg_notifications;
348         status = otg_register_notifier(musb->xceiv, &musb->nb);
349
350         if (status)
351                 DBG(1, "notification register failed\n");
352
353         /* check whether cable is already connected */
354         if (musb->xceiv->state ==OTG_STATE_B_IDLE)
355                 musb_otg_notifications(&musb->nb, 1,
356                                         musb->xceiv->gadget);
357
358         setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
359
360         return 0;
361 }
362
363 static int omap2430_musb_exit(struct musb *musb)
364 {
365         del_timer_sync(&musb_idle_timer);
366
367         omap2430_low_level_exit(musb);
368         otg_put_transceiver(musb->xceiv);
369
370         return 0;
371 }
372
373 static const struct musb_platform_ops omap2430_ops = {
374         .init           = omap2430_musb_init,
375         .exit           = omap2430_musb_exit,
376
377         .set_mode       = omap2430_musb_set_mode,
378         .try_idle       = omap2430_musb_try_idle,
379
380         .set_vbus       = omap2430_musb_set_vbus,
381 };
382
383 static u64 omap2430_dmamask = DMA_BIT_MASK(32);
384
385 static int __init omap2430_probe(struct platform_device *pdev)
386 {
387         struct musb_hdrc_platform_data  *pdata = pdev->dev.platform_data;
388         struct platform_device          *musb;
389         struct omap2430_glue            *glue;
390         struct clk                      *clk;
391
392         int                             ret = -ENOMEM;
393
394         glue = kzalloc(sizeof(*glue), GFP_KERNEL);
395         if (!glue) {
396                 dev_err(&pdev->dev, "failed to allocate glue context\n");
397                 goto err0;
398         }
399
400         musb = platform_device_alloc("musb-hdrc", -1);
401         if (!musb) {
402                 dev_err(&pdev->dev, "failed to allocate musb device\n");
403                 goto err1;
404         }
405
406         clk = clk_get(&pdev->dev, "ick");
407         if (IS_ERR(clk)) {
408                 dev_err(&pdev->dev, "failed to get clock\n");
409                 ret = PTR_ERR(clk);
410                 goto err2;
411         }
412
413         ret = clk_enable(clk);
414         if (ret) {
415                 dev_err(&pdev->dev, "failed to enable clock\n");
416                 goto err3;
417         }
418
419         musb->dev.parent                = &pdev->dev;
420         musb->dev.dma_mask              = &omap2430_dmamask;
421         musb->dev.coherent_dma_mask     = omap2430_dmamask;
422
423         glue->dev                       = &pdev->dev;
424         glue->musb                      = musb;
425         glue->clk                       = clk;
426
427         pdata->platform_ops             = &omap2430_ops;
428
429         platform_set_drvdata(pdev, glue);
430
431         ret = platform_device_add_resources(musb, pdev->resource,
432                         pdev->num_resources);
433         if (ret) {
434                 dev_err(&pdev->dev, "failed to add resources\n");
435                 goto err4;
436         }
437
438         ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
439         if (ret) {
440                 dev_err(&pdev->dev, "failed to add platform_data\n");
441                 goto err4;
442         }
443
444         ret = platform_device_add(musb);
445         if (ret) {
446                 dev_err(&pdev->dev, "failed to register musb device\n");
447                 goto err4;
448         }
449
450         return 0;
451
452 err4:
453         clk_disable(clk);
454
455 err3:
456         clk_put(clk);
457
458 err2:
459         platform_device_put(musb);
460
461 err1:
462         kfree(glue);
463
464 err0:
465         return ret;
466 }
467
468 static int __exit omap2430_remove(struct platform_device *pdev)
469 {
470         struct omap2430_glue            *glue = platform_get_drvdata(pdev);
471
472         platform_device_del(glue->musb);
473         platform_device_put(glue->musb);
474         clk_disable(glue->clk);
475         clk_put(glue->clk);
476         kfree(glue);
477
478         return 0;
479 }
480
481 #ifdef CONFIG_PM
482 static void omap2430_save_context(struct musb *musb)
483 {
484         musb->context.otg_sysconfig = musb_readl(musb->mregs, OTG_SYSCONFIG);
485         musb->context.otg_forcestandby = musb_readl(musb->mregs, OTG_FORCESTDBY);
486 }
487
488 static void omap2430_restore_context(struct musb *musb)
489 {
490         musb_writel(musb->mregs, OTG_SYSCONFIG, musb->context.otg_sysconfig);
491         musb_writel(musb->mregs, OTG_FORCESTDBY, musb->context.otg_forcestandby);
492 }
493
494 static int omap2430_suspend(struct device *dev)
495 {
496         struct omap2430_glue            *glue = dev_get_drvdata(dev);
497         struct musb                     *musb = glue_to_musb(glue);
498
499         omap2430_low_level_exit(musb);
500         otg_set_suspend(musb->xceiv, 1);
501         omap2430_save_context(musb);
502         clk_disable(glue->clk);
503
504         return 0;
505 }
506
507 static int omap2430_resume(struct device *dev)
508 {
509         struct omap2430_glue            *glue = dev_get_drvdata(dev);
510         struct musb                     *musb = glue_to_musb(glue);
511         int                             ret;
512
513         ret = clk_enable(glue->clk);
514         if (ret) {
515                 dev_err(dev, "faled to enable clock\n");
516                 return ret;
517         }
518
519         omap2430_low_level_init(musb);
520         omap2430_restore_context(musb);
521         otg_set_suspend(musb->xceiv, 0);
522
523         return 0;
524 }
525
526 static struct dev_pm_ops omap2430_pm_ops = {
527         .suspend        = omap2430_suspend,
528         .resume         = omap2430_resume,
529 };
530
531 #define DEV_PM_OPS      (&omap2430_pm_ops)
532 #else
533 #define DEV_PM_OPS      NULL
534 #endif
535
536 static struct platform_driver omap2430_driver = {
537         .remove         = __exit_p(omap2430_remove),
538         .driver         = {
539                 .name   = "musb-omap2430",
540                 .pm     = DEV_PM_OPS,
541         },
542 };
543
544 MODULE_DESCRIPTION("OMAP2PLUS MUSB Glue Layer");
545 MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
546 MODULE_LICENSE("GPL v2");
547
548 static int __init omap2430_init(void)
549 {
550         return platform_driver_probe(&omap2430_driver, omap2430_probe);
551 }
552 subsys_initcall(omap2430_init);
553
554 static void __exit omap2430_exit(void)
555 {
556         platform_driver_unregister(&omap2430_driver);
557 }
558 module_exit(omap2430_exit);