diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/usb/otg/twl4030-usb.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/usb/otg/twl4030-usb.c')
-rw-r--r-- | drivers/usb/otg/twl4030-usb.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index 0bc97698af15..efeb4d1517ff 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c | |||
@@ -124,7 +124,6 @@ | |||
124 | #define PHY_DPLL_CLK (1 << 0) | 124 | #define PHY_DPLL_CLK (1 << 0) |
125 | 125 | ||
126 | /* In module TWL4030_MODULE_PM_MASTER */ | 126 | /* In module TWL4030_MODULE_PM_MASTER */ |
127 | #define PROTECT_KEY 0x0E | ||
128 | #define STS_HW_CONDITIONS 0x0F | 127 | #define STS_HW_CONDITIONS 0x0F |
129 | 128 | ||
130 | /* In module TWL4030_MODULE_PM_RECEIVER */ | 129 | /* In module TWL4030_MODULE_PM_RECEIVER */ |
@@ -161,6 +160,7 @@ struct twl4030_usb { | |||
161 | 160 | ||
162 | int irq; | 161 | int irq; |
163 | u8 linkstat; | 162 | u8 linkstat; |
163 | bool vbus_supplied; | ||
164 | u8 asleep; | 164 | u8 asleep; |
165 | bool irq_enabled; | 165 | bool irq_enabled; |
166 | }; | 166 | }; |
@@ -251,6 +251,8 @@ static enum usb_xceiv_events twl4030_usb_linkstat(struct twl4030_usb *twl) | |||
251 | int status; | 251 | int status; |
252 | int linkstat = USB_EVENT_NONE; | 252 | int linkstat = USB_EVENT_NONE; |
253 | 253 | ||
254 | twl->vbus_supplied = false; | ||
255 | |||
254 | /* | 256 | /* |
255 | * For ID/VBUS sensing, see manual section 15.4.8 ... | 257 | * For ID/VBUS sensing, see manual section 15.4.8 ... |
256 | * except when using only battery backup power, two | 258 | * except when using only battery backup power, two |
@@ -266,6 +268,9 @@ static enum usb_xceiv_events twl4030_usb_linkstat(struct twl4030_usb *twl) | |||
266 | if (status < 0) | 268 | if (status < 0) |
267 | dev_err(twl->dev, "USB link status err %d\n", status); | 269 | dev_err(twl->dev, "USB link status err %d\n", status); |
268 | else if (status & (BIT(7) | BIT(2))) { | 270 | else if (status & (BIT(7) | BIT(2))) { |
271 | if (status & (BIT(7))) | ||
272 | twl->vbus_supplied = true; | ||
273 | |||
269 | if (status & BIT(2)) | 274 | if (status & BIT(2)) |
270 | linkstat = USB_EVENT_ID; | 275 | linkstat = USB_EVENT_ID; |
271 | else | 276 | else |
@@ -276,6 +281,8 @@ static enum usb_xceiv_events twl4030_usb_linkstat(struct twl4030_usb *twl) | |||
276 | dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", | 281 | dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", |
277 | status, status, linkstat); | 282 | status, status, linkstat); |
278 | 283 | ||
284 | twl->otg.last_event = linkstat; | ||
285 | |||
279 | /* REVISIT this assumes host and peripheral controllers | 286 | /* REVISIT this assumes host and peripheral controllers |
280 | * are registered, and that both are active... | 287 | * are registered, and that both are active... |
281 | */ | 288 | */ |
@@ -418,8 +425,13 @@ static void twl4030_phy_resume(struct twl4030_usb *twl) | |||
418 | static int twl4030_usb_ldo_init(struct twl4030_usb *twl) | 425 | static int twl4030_usb_ldo_init(struct twl4030_usb *twl) |
419 | { | 426 | { |
420 | /* Enable writing to power configuration registers */ | 427 | /* Enable writing to power configuration registers */ |
421 | twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0xC0, PROTECT_KEY); | 428 | twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, |
422 | twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0x0C, PROTECT_KEY); | 429 | TWL4030_PM_MASTER_KEY_CFG1, |
430 | TWL4030_PM_MASTER_PROTECT_KEY); | ||
431 | |||
432 | twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, | ||
433 | TWL4030_PM_MASTER_KEY_CFG2, | ||
434 | TWL4030_PM_MASTER_PROTECT_KEY); | ||
423 | 435 | ||
424 | /* Keep VUSB3V1 LDO in sleep state until VBUS/ID change detected*/ | 436 | /* Keep VUSB3V1 LDO in sleep state until VBUS/ID change detected*/ |
425 | /*twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);*/ | 437 | /*twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);*/ |
@@ -455,7 +467,8 @@ static int twl4030_usb_ldo_init(struct twl4030_usb *twl) | |||
455 | twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE); | 467 | twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE); |
456 | 468 | ||
457 | /* disable access to power configuration registers */ | 469 | /* disable access to power configuration registers */ |
458 | twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, PROTECT_KEY); | 470 | twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, |
471 | TWL4030_PM_MASTER_PROTECT_KEY); | ||
459 | 472 | ||
460 | return 0; | 473 | return 0; |
461 | 474 | ||
@@ -477,7 +490,7 @@ static ssize_t twl4030_usb_vbus_show(struct device *dev, | |||
477 | 490 | ||
478 | spin_lock_irqsave(&twl->lock, flags); | 491 | spin_lock_irqsave(&twl->lock, flags); |
479 | ret = sprintf(buf, "%s\n", | 492 | ret = sprintf(buf, "%s\n", |
480 | (twl->linkstat == USB_EVENT_VBUS) ? "on" : "off"); | 493 | twl->vbus_supplied ? "on" : "off"); |
481 | spin_unlock_irqrestore(&twl->lock, flags); | 494 | spin_unlock_irqrestore(&twl->lock, flags); |
482 | 495 | ||
483 | return ret; | 496 | return ret; |
@@ -507,7 +520,7 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) | |||
507 | else | 520 | else |
508 | twl4030_phy_resume(twl); | 521 | twl4030_phy_resume(twl); |
509 | 522 | ||
510 | blocking_notifier_call_chain(&twl->otg.notifier, status, | 523 | atomic_notifier_call_chain(&twl->otg.notifier, status, |
511 | twl->otg.gadget); | 524 | twl->otg.gadget); |
512 | } | 525 | } |
513 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); | 526 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); |
@@ -529,7 +542,7 @@ static void twl4030_usb_phy_init(struct twl4030_usb *twl) | |||
529 | twl->asleep = 0; | 542 | twl->asleep = 0; |
530 | } | 543 | } |
531 | 544 | ||
532 | blocking_notifier_call_chain(&twl->otg.notifier, status, | 545 | atomic_notifier_call_chain(&twl->otg.notifier, status, |
533 | twl->otg.gadget); | 546 | twl->otg.gadget); |
534 | } | 547 | } |
535 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); | 548 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); |
@@ -601,6 +614,7 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) | |||
601 | twl->otg.set_peripheral = twl4030_set_peripheral; | 614 | twl->otg.set_peripheral = twl4030_set_peripheral; |
602 | twl->otg.set_suspend = twl4030_set_suspend; | 615 | twl->otg.set_suspend = twl4030_set_suspend; |
603 | twl->usb_mode = pdata->usb_mode; | 616 | twl->usb_mode = pdata->usb_mode; |
617 | twl->vbus_supplied = false; | ||
604 | twl->asleep = 1; | 618 | twl->asleep = 1; |
605 | 619 | ||
606 | /* init spinlock for workqueue */ | 620 | /* init spinlock for workqueue */ |
@@ -618,7 +632,7 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) | |||
618 | if (device_create_file(&pdev->dev, &dev_attr_vbus)) | 632 | if (device_create_file(&pdev->dev, &dev_attr_vbus)) |
619 | dev_warn(&pdev->dev, "could not create sysfs file\n"); | 633 | dev_warn(&pdev->dev, "could not create sysfs file\n"); |
620 | 634 | ||
621 | BLOCKING_INIT_NOTIFIER_HEAD(&twl->otg.notifier); | 635 | ATOMIC_INIT_NOTIFIER_HEAD(&twl->otg.notifier); |
622 | 636 | ||
623 | /* Our job is to use irqs and status from the power module | 637 | /* Our job is to use irqs and status from the power module |
624 | * to keep the transceiver disabled when nothing's connected. | 638 | * to keep the transceiver disabled when nothing's connected. |
@@ -673,7 +687,8 @@ static int __exit twl4030_usb_remove(struct platform_device *pdev) | |||
673 | /* disable complete OTG block */ | 687 | /* disable complete OTG block */ |
674 | twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); | 688 | twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); |
675 | 689 | ||
676 | twl4030_phy_power(twl, 0); | 690 | if (!twl->asleep) |
691 | twl4030_phy_power(twl, 0); | ||
677 | regulator_put(twl->usb1v5); | 692 | regulator_put(twl->usb1v5); |
678 | regulator_put(twl->usb1v8); | 693 | regulator_put(twl->usb1v8); |
679 | regulator_put(twl->usb3v1); | 694 | regulator_put(twl->usb3v1); |