~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to drivers/usb/musb/omap2430.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno
  • Date: 2011-06-07 12:14:05 UTC
  • mfrom: (43.1.9 sid)
  • Revision ID: james.westby@ubuntu.com-20110607121405-i3h1rd7nrnd2b73h
Tags: 2.6.39-2
[ Ben Hutchings ]
* [x86] Enable BACKLIGHT_APPLE, replacing BACKLIGHT_MBP_NVIDIA
  (Closes: #627492)
* cgroups: Disable memory resource controller by default. Allow it
  to be enabled using kernel parameter 'cgroup_enable=memory'.
* rt2800usb: Enable support for more USB devices including
  Linksys WUSB600N (Closes: #596626) (this change was accidentally
  omitted from 2.6.39-1)
* [x86] Remove Celeron from list of processors supporting PAE. Most
  'Celeron M' models do not.
* Update debconf template translations:
  - Swedish (Martin Bagge) (Closes: #628932)
  - French (David Prévot) (Closes: #628191)
* aufs: Update for 2.6.39 (Closes: #627837)
* Add stable 2.6.39.1, including:
  - ext4: dont set PageUptodate in ext4_end_bio()
  - pata_cmd64x: fix boot crash on parisc (Closes: #622997, #622745)
  - ext3: Fix fs corruption when make_indexed_dir() fails
  - netfilter: nf_ct_sip: validate Content-Length in TCP SIP messages
  - sctp: fix race between sctp_bind_addr_free() and
    sctp_bind_addr_conflict()
  - sctp: fix memory leak of the ASCONF queue when free asoc
  - md/bitmap: fix saving of events_cleared and other state
  - cdc_acm: Fix oops when Droids MuIn LCD is connected
  - cx88: Fix conversion from BKL to fine-grained locks (Closes: #619827)
  - keys: Set cred->user_ns in key_replace_session_keyring (CVE-2011-2184)
  - tmpfs: fix race between truncate and writepage
  - nfs41: Correct offset for LAYOUTCOMMIT
  - xen/mmu: fix a race window causing leave_mm BUG()
  - ext4: fix possible use-after-free in ext4_remove_li_request()
  For the complete list of changes, see:
   http://www.kernel.org/pub/linux/kernel/v2.6/ChangeLog-2.6.39.1
* Bump ABI to 2
* netfilter: Enable IP_SET, IP_SET_BITMAP_IP, IP_SET_BITMAP_IPMAC,
  IP_SET_BITMAP_PORT, IP_SET_HASH_IP, IP_SET_HASH_IPPORT,
  IP_SET_HASH_IPPORTIP, IP_SET_HASH_IPPORTNET, IP_SET_HASH_NET,
  IP_SET_HASH_NETPORT, IP_SET_LIST_SET, NETFILTER_XT_SET as modules
  (Closes: #629401)

[ Aurelien Jarno ]
* [mipsel/loongson-2f] Disable_SCSI_LPFC to workaround GCC ICE.

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
#include <linux/io.h>
34
34
#include <linux/platform_device.h>
35
35
#include <linux/dma-mapping.h>
 
36
#include <linux/pm_runtime.h>
 
37
#include <linux/err.h>
36
38
 
37
39
#include "musb_core.h"
38
40
#include "omap2430.h"
40
42
struct omap2430_glue {
41
43
        struct device           *dev;
42
44
        struct platform_device  *musb;
43
 
        struct clk              *clk;
44
45
};
45
46
#define glue_to_musb(g)         platform_get_drvdata(g->musb)
46
47
 
216
217
        l = musb_readl(musb->mregs, OTG_FORCESTDBY);
217
218
        l |= ENABLEFORCE;       /* enable MSTANDBY */
218
219
        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
220
}
224
221
 
225
222
static inline void omap2430_low_level_init(struct musb *musb)
226
223
{
227
224
        u32 l;
228
225
 
229
 
        l = musb_readl(musb->mregs, OTG_SYSCONFIG);
230
 
        l &= ~ENABLEWAKEUP;     /* disable wakeup */
231
 
        musb_writel(musb->mregs, OTG_SYSCONFIG, l);
232
 
 
233
226
        l = musb_readl(musb->mregs, OTG_FORCESTDBY);
234
227
        l &= ~ENABLEFORCE;      /* disable MSTANDBY */
235
228
        musb_writel(musb->mregs, OTG_FORCESTDBY, l);
251
244
                if (is_otg_enabled(musb)) {
252
245
#ifdef CONFIG_USB_GADGET_MUSB_HDRC
253
246
                        if (musb->gadget_driver) {
 
247
                                pm_runtime_get_sync(musb->controller);
254
248
                                otg_init(musb->xceiv);
255
 
 
256
 
                                if (data->interface_type ==
257
 
                                                MUSB_INTERFACE_UTMI)
258
 
                                        omap2430_musb_set_vbus(musb, 1);
259
 
 
 
249
                                omap2430_musb_set_vbus(musb, 1);
260
250
                        }
261
251
#endif
262
252
                } else {
 
253
                        pm_runtime_get_sync(musb->controller);
263
254
                        otg_init(musb->xceiv);
264
 
                        if (data->interface_type ==
265
 
                                        MUSB_INTERFACE_UTMI)
266
 
                                omap2430_musb_set_vbus(musb, 1);
 
255
                        omap2430_musb_set_vbus(musb, 1);
267
256
                }
268
257
                break;
269
258
 
270
259
        case USB_EVENT_VBUS:
271
260
                DBG(4, "VBUS Connect\n");
272
261
 
 
262
#ifdef CONFIG_USB_GADGET_MUSB_HDRC
 
263
                if (musb->gadget_driver)
 
264
                        pm_runtime_get_sync(musb->controller);
 
265
#endif
273
266
                otg_init(musb->xceiv);
274
267
                break;
275
268
 
276
269
        case USB_EVENT_NONE:
277
270
                DBG(4, "VBUS Disconnect\n");
278
271
 
 
272
#ifdef CONFIG_USB_GADGET_MUSB_HDRC
 
273
                if (is_otg_enabled(musb) || is_peripheral_enabled(musb))
 
274
                        if (musb->gadget_driver)
 
275
#endif
 
276
                        {
 
277
                                pm_runtime_mark_last_busy(musb->controller);
 
278
                                pm_runtime_put_autosuspend(musb->controller);
 
279
                        }
 
280
 
279
281
                if (data->interface_type == MUSB_INTERFACE_UTMI) {
280
282
                        if (musb->xceiv->set_vbus)
281
283
                                otg_set_vbus(musb->xceiv, 0);
307
309
                return -ENODEV;
308
310
        }
309
311
 
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);
 
312
        status = pm_runtime_get_sync(dev);
 
313
        if (status < 0) {
 
314
                dev_err(dev, "pm_runtime_get_sync FAILED");
 
315
                goto err1;
 
316
        }
326
317
 
327
318
        l = musb_readl(musb->mregs, OTG_INTERFSEL);
328
319
 
350
341
        if (status)
351
342
                DBG(1, "notification register failed\n");
352
343
 
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
344
        setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
359
345
 
360
346
        return 0;
 
347
 
 
348
err1:
 
349
        pm_runtime_disable(dev);
 
350
        return status;
 
351
}
 
352
 
 
353
static void omap2430_musb_enable(struct musb *musb)
 
354
{
 
355
        u8              devctl;
 
356
        unsigned long timeout = jiffies + msecs_to_jiffies(1000);
 
357
        struct device *dev = musb->controller;
 
358
        struct musb_hdrc_platform_data *pdata = dev->platform_data;
 
359
        struct omap_musb_board_data *data = pdata->board_data;
 
360
 
 
361
        switch (musb->xceiv->last_event) {
 
362
 
 
363
        case USB_EVENT_ID:
 
364
                otg_init(musb->xceiv);
 
365
                if (data->interface_type == MUSB_INTERFACE_UTMI) {
 
366
                        devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
 
367
                        /* start the session */
 
368
                        devctl |= MUSB_DEVCTL_SESSION;
 
369
                        musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
 
370
                        while (musb_readb(musb->mregs, MUSB_DEVCTL) &
 
371
                                                MUSB_DEVCTL_BDEVICE) {
 
372
                                cpu_relax();
 
373
 
 
374
                                if (time_after(jiffies, timeout)) {
 
375
                                        dev_err(musb->controller,
 
376
                                        "configured as A device timeout");
 
377
                                        break;
 
378
                                }
 
379
                        }
 
380
                }
 
381
                break;
 
382
 
 
383
        case USB_EVENT_VBUS:
 
384
                otg_init(musb->xceiv);
 
385
                break;
 
386
 
 
387
        default:
 
388
                break;
 
389
        }
 
390
}
 
391
 
 
392
static void omap2430_musb_disable(struct musb *musb)
 
393
{
 
394
        if (musb->xceiv->last_event)
 
395
                otg_shutdown(musb->xceiv);
361
396
}
362
397
 
363
398
static int omap2430_musb_exit(struct musb *musb)
378
413
        .try_idle       = omap2430_musb_try_idle,
379
414
 
380
415
        .set_vbus       = omap2430_musb_set_vbus,
 
416
 
 
417
        .enable         = omap2430_musb_enable,
 
418
        .disable        = omap2430_musb_disable,
381
419
};
382
420
 
383
421
static u64 omap2430_dmamask = DMA_BIT_MASK(32);
387
425
        struct musb_hdrc_platform_data  *pdata = pdev->dev.platform_data;
388
426
        struct platform_device          *musb;
389
427
        struct omap2430_glue            *glue;
390
 
        struct clk                      *clk;
391
 
 
392
428
        int                             ret = -ENOMEM;
393
429
 
394
430
        glue = kzalloc(sizeof(*glue), GFP_KERNEL);
403
439
                goto err1;
404
440
        }
405
441
 
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
442
        musb->dev.parent                = &pdev->dev;
420
443
        musb->dev.dma_mask              = &omap2430_dmamask;
421
444
        musb->dev.coherent_dma_mask     = omap2430_dmamask;
422
445
 
423
446
        glue->dev                       = &pdev->dev;
424
447
        glue->musb                      = musb;
425
 
        glue->clk                       = clk;
426
448
 
427
449
        pdata->platform_ops             = &omap2430_ops;
428
450
 
432
454
                        pdev->num_resources);
433
455
        if (ret) {
434
456
                dev_err(&pdev->dev, "failed to add resources\n");
435
 
                goto err4;
 
457
                goto err2;
436
458
        }
437
459
 
438
460
        ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
439
461
        if (ret) {
440
462
                dev_err(&pdev->dev, "failed to add platform_data\n");
441
 
                goto err4;
 
463
                goto err2;
442
464
        }
443
465
 
444
466
        ret = platform_device_add(musb);
445
467
        if (ret) {
446
468
                dev_err(&pdev->dev, "failed to register musb device\n");
447
 
                goto err4;
 
469
                goto err2;
448
470
        }
449
471
 
 
472
        pm_runtime_enable(&pdev->dev);
 
473
 
450
474
        return 0;
451
475
 
452
 
err4:
453
 
        clk_disable(clk);
454
 
 
455
 
err3:
456
 
        clk_put(clk);
457
 
 
458
476
err2:
459
477
        platform_device_put(musb);
460
478
 
471
489
 
472
490
        platform_device_del(glue->musb);
473
491
        platform_device_put(glue->musb);
474
 
        clk_disable(glue->clk);
475
 
        clk_put(glue->clk);
 
492
        pm_runtime_put(&pdev->dev);
 
493
        pm_runtime_disable(&pdev->dev);
476
494
        kfree(glue);
477
495
 
478
496
        return 0;
479
497
}
480
498
 
481
499
#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)
 
500
 
 
501
static int omap2430_runtime_suspend(struct device *dev)
495
502
{
496
503
        struct omap2430_glue            *glue = dev_get_drvdata(dev);
497
504
        struct musb                     *musb = glue_to_musb(glue);
498
505
 
499
506
        omap2430_low_level_exit(musb);
500
507
        otg_set_suspend(musb->xceiv, 1);
501
 
        omap2430_save_context(musb);
502
 
        clk_disable(glue->clk);
503
508
 
504
509
        return 0;
505
510
}
506
511
 
507
 
static int omap2430_resume(struct device *dev)
 
512
static int omap2430_runtime_resume(struct device *dev)
508
513
{
509
514
        struct omap2430_glue            *glue = dev_get_drvdata(dev);
510
515
        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
516
 
519
517
        omap2430_low_level_init(musb);
520
 
        omap2430_restore_context(musb);
521
518
        otg_set_suspend(musb->xceiv, 0);
522
519
 
523
520
        return 0;
524
521
}
525
522
 
526
523
static struct dev_pm_ops omap2430_pm_ops = {
527
 
        .suspend        = omap2430_suspend,
528
 
        .resume         = omap2430_resume,
 
524
        .runtime_suspend = omap2430_runtime_suspend,
 
525
        .runtime_resume = omap2430_runtime_resume,
529
526
};
530
527
 
531
528
#define DEV_PM_OPS      (&omap2430_pm_ops)