aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/phy/phy-twl4030-usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/phy/phy-twl4030-usb.c')
-rw-r--r--drivers/phy/phy-twl4030-usb.c125
1 files changed, 46 insertions, 79 deletions
diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c
index 9cd33a4bcfb1..7b04befd5271 100644
--- a/drivers/phy/phy-twl4030-usb.c
+++ b/drivers/phy/phy-twl4030-usb.c
@@ -28,7 +28,6 @@
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/interrupt.h> 29#include <linux/interrupt.h>
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/spinlock.h>
32#include <linux/workqueue.h> 31#include <linux/workqueue.h>
33#include <linux/io.h> 32#include <linux/io.h>
34#include <linux/delay.h> 33#include <linux/delay.h>
@@ -155,7 +154,7 @@ struct twl4030_usb {
155 struct regulator *usb3v1; 154 struct regulator *usb3v1;
156 155
157 /* for vbus reporting with irqs disabled */ 156 /* for vbus reporting with irqs disabled */
158 spinlock_t lock; 157 struct mutex lock;
159 158
160 /* pin configuration */ 159 /* pin configuration */
161 enum twl4030_usb_mode usb_mode; 160 enum twl4030_usb_mode usb_mode;
@@ -163,8 +162,6 @@ struct twl4030_usb {
163 int irq; 162 int irq;
164 enum omap_musb_vbus_id_status linkstat; 163 enum omap_musb_vbus_id_status linkstat;
165 bool vbus_supplied; 164 bool vbus_supplied;
166 u8 asleep;
167 bool irq_enabled;
168 165
169 struct delayed_work id_workaround_work; 166 struct delayed_work id_workaround_work;
170}; 167};
@@ -384,55 +381,18 @@ static void __twl4030_phy_power(struct twl4030_usb *twl, int on)
384 WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0); 381 WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
385} 382}
386 383
387static void twl4030_phy_power(struct twl4030_usb *twl, int on)
388{
389 int ret;
390
391 if (on) {
392 ret = regulator_enable(twl->usb3v1);
393 if (ret)
394 dev_err(twl->dev, "Failed to enable usb3v1\n");
395
396 ret = regulator_enable(twl->usb1v8);
397 if (ret)
398 dev_err(twl->dev, "Failed to enable usb1v8\n");
399
400 /*
401 * Disabling usb3v1 regulator (= writing 0 to VUSB3V1_DEV_GRP
402 * in twl4030) resets the VUSB_DEDICATED2 register. This reset
403 * enables VUSB3V1_SLEEP bit that remaps usb3v1 ACTIVE state to
404 * SLEEP. We work around this by clearing the bit after usv3v1
405 * is re-activated. This ensures that VUSB3V1 is really active.
406 */
407 twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);
408
409 ret = regulator_enable(twl->usb1v5);
410 if (ret)
411 dev_err(twl->dev, "Failed to enable usb1v5\n");
412
413 __twl4030_phy_power(twl, 1);
414 twl4030_usb_write(twl, PHY_CLK_CTRL,
415 twl4030_usb_read(twl, PHY_CLK_CTRL) |
416 (PHY_CLK_CTRL_CLOCKGATING_EN |
417 PHY_CLK_CTRL_CLK32K_EN));
418 } else {
419 __twl4030_phy_power(twl, 0);
420 regulator_disable(twl->usb1v5);
421 regulator_disable(twl->usb1v8);
422 regulator_disable(twl->usb3v1);
423 }
424}
425
426static int twl4030_usb_runtime_suspend(struct device *dev) 384static int twl4030_usb_runtime_suspend(struct device *dev)
427{ 385{
428 struct twl4030_usb *twl = dev_get_drvdata(dev); 386 struct twl4030_usb *twl = dev_get_drvdata(dev);
429 387
430 dev_dbg(twl->dev, "%s\n", __func__); 388 dev_dbg(twl->dev, "%s\n", __func__);
431 if (twl->asleep) 389 if (pm_runtime_suspended(dev))
432 return 0; 390 return 0;
433 391
434 twl4030_phy_power(twl, 0); 392 __twl4030_phy_power(twl, 0);
435 twl->asleep = 1; 393 regulator_disable(twl->usb1v5);
394 regulator_disable(twl->usb1v8);
395 regulator_disable(twl->usb3v1);
436 396
437 return 0; 397 return 0;
438} 398}
@@ -440,13 +400,38 @@ static int twl4030_usb_runtime_suspend(struct device *dev)
440static int twl4030_usb_runtime_resume(struct device *dev) 400static int twl4030_usb_runtime_resume(struct device *dev)
441{ 401{
442 struct twl4030_usb *twl = dev_get_drvdata(dev); 402 struct twl4030_usb *twl = dev_get_drvdata(dev);
403 int res;
443 404
444 dev_dbg(twl->dev, "%s\n", __func__); 405 dev_dbg(twl->dev, "%s\n", __func__);
445 if (!twl->asleep) 406 if (pm_runtime_active(dev))
446 return 0; 407 return 0;
447 408
448 twl4030_phy_power(twl, 1); 409 res = regulator_enable(twl->usb3v1);
449 twl->asleep = 0; 410 if (res)
411 dev_err(twl->dev, "Failed to enable usb3v1\n");
412
413 res = regulator_enable(twl->usb1v8);
414 if (res)
415 dev_err(twl->dev, "Failed to enable usb1v8\n");
416
417 /*
418 * Disabling usb3v1 regulator (= writing 0 to VUSB3V1_DEV_GRP
419 * in twl4030) resets the VUSB_DEDICATED2 register. This reset
420 * enables VUSB3V1_SLEEP bit that remaps usb3v1 ACTIVE state to
421 * SLEEP. We work around this by clearing the bit after usv3v1
422 * is re-activated. This ensures that VUSB3V1 is really active.
423 */
424 twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);
425
426 res = regulator_enable(twl->usb1v5);
427 if (res)
428 dev_err(twl->dev, "Failed to enable usb1v5\n");
429
430 __twl4030_phy_power(twl, 1);
431 twl4030_usb_write(twl, PHY_CLK_CTRL,
432 twl4030_usb_read(twl, PHY_CLK_CTRL) |
433 (PHY_CLK_CTRL_CLOCKGATING_EN |
434 PHY_CLK_CTRL_CLK32K_EN));
450 435
451 return 0; 436 return 0;
452} 437}
@@ -472,16 +457,8 @@ static int twl4030_phy_power_on(struct phy *phy)
472 twl4030_usb_set_mode(twl, twl->usb_mode); 457 twl4030_usb_set_mode(twl, twl->usb_mode);
473 if (twl->usb_mode == T2_USB_MODE_ULPI) 458 if (twl->usb_mode == T2_USB_MODE_ULPI)
474 twl4030_i2c_access(twl, 0); 459 twl4030_i2c_access(twl, 0);
460 schedule_delayed_work(&twl->id_workaround_work, 0);
475 461
476 /*
477 * XXX When VBUS gets driven after musb goes to A mode,
478 * ID_PRES related interrupts no longer arrive, why?
479 * Register itself is updated fine though, so we must poll.
480 */
481 if (twl->linkstat == OMAP_MUSB_ID_GROUND) {
482 cancel_delayed_work(&twl->id_workaround_work);
483 schedule_delayed_work(&twl->id_workaround_work, HZ);
484 }
485 return 0; 462 return 0;
486} 463}
487 464
@@ -538,13 +515,12 @@ static ssize_t twl4030_usb_vbus_show(struct device *dev,
538 struct device_attribute *attr, char *buf) 515 struct device_attribute *attr, char *buf)
539{ 516{
540 struct twl4030_usb *twl = dev_get_drvdata(dev); 517 struct twl4030_usb *twl = dev_get_drvdata(dev);
541 unsigned long flags;
542 int ret = -EINVAL; 518 int ret = -EINVAL;
543 519
544 spin_lock_irqsave(&twl->lock, flags); 520 mutex_lock(&twl->lock);
545 ret = sprintf(buf, "%s\n", 521 ret = sprintf(buf, "%s\n",
546 twl->vbus_supplied ? "on" : "off"); 522 twl->vbus_supplied ? "on" : "off");
547 spin_unlock_irqrestore(&twl->lock, flags); 523 mutex_unlock(&twl->lock);
548 524
549 return ret; 525 return ret;
550} 526}
@@ -558,12 +534,12 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
558 534
559 status = twl4030_usb_linkstat(twl); 535 status = twl4030_usb_linkstat(twl);
560 536
561 spin_lock_irq(&twl->lock); 537 mutex_lock(&twl->lock);
562 if (status >= 0 && status != twl->linkstat) { 538 if (status >= 0 && status != twl->linkstat) {
563 twl->linkstat = status; 539 twl->linkstat = status;
564 status_changed = true; 540 status_changed = true;
565 } 541 }
566 spin_unlock_irq(&twl->lock); 542 mutex_unlock(&twl->lock);
567 543
568 if (status_changed) { 544 if (status_changed) {
569 /* FIXME add a set_power() method so that B-devices can 545 /* FIXME add a set_power() method so that B-devices can
@@ -579,10 +555,10 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
579 */ 555 */
580 if ((status == OMAP_MUSB_VBUS_VALID) || 556 if ((status == OMAP_MUSB_VBUS_VALID) ||
581 (status == OMAP_MUSB_ID_GROUND)) { 557 (status == OMAP_MUSB_ID_GROUND)) {
582 if (twl->asleep) 558 if (pm_runtime_suspended(twl->dev))
583 pm_runtime_get_sync(twl->dev); 559 pm_runtime_get_sync(twl->dev);
584 } else { 560 } else {
585 if (!twl->asleep) { 561 if (pm_runtime_active(twl->dev)) {
586 pm_runtime_mark_last_busy(twl->dev); 562 pm_runtime_mark_last_busy(twl->dev);
587 pm_runtime_put_autosuspend(twl->dev); 563 pm_runtime_put_autosuspend(twl->dev);
588 } 564 }
@@ -591,7 +567,7 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
591 } 567 }
592 568
593 /* don't schedule during sleep - irq works right then */ 569 /* don't schedule during sleep - irq works right then */
594 if (status == OMAP_MUSB_ID_GROUND && !twl->asleep) { 570 if (status == OMAP_MUSB_ID_GROUND && pm_runtime_active(twl->dev)) {
595 cancel_delayed_work(&twl->id_workaround_work); 571 cancel_delayed_work(&twl->id_workaround_work);
596 schedule_delayed_work(&twl->id_workaround_work, HZ); 572 schedule_delayed_work(&twl->id_workaround_work, HZ);
597 } 573 }
@@ -613,16 +589,9 @@ static void twl4030_id_workaround_work(struct work_struct *work)
613static int twl4030_phy_init(struct phy *phy) 589static int twl4030_phy_init(struct phy *phy)
614{ 590{
615 struct twl4030_usb *twl = phy_get_drvdata(phy); 591 struct twl4030_usb *twl = phy_get_drvdata(phy);
616 enum omap_musb_vbus_id_status status;
617 592
618 pm_runtime_get_sync(twl->dev); 593 pm_runtime_get_sync(twl->dev);
619 status = twl4030_usb_linkstat(twl); 594 schedule_delayed_work(&twl->id_workaround_work, 0);
620 twl->linkstat = status;
621
622 if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID)
623 omap_musb_mailbox(twl->linkstat);
624
625 sysfs_notify(&twl->dev->kobj, NULL, "vbus");
626 pm_runtime_mark_last_busy(twl->dev); 595 pm_runtime_mark_last_busy(twl->dev);
627 pm_runtime_put_autosuspend(twl->dev); 596 pm_runtime_put_autosuspend(twl->dev);
628 597
@@ -699,7 +668,7 @@ static int twl4030_usb_probe(struct platform_device *pdev)
699 twl->dev = &pdev->dev; 668 twl->dev = &pdev->dev;
700 twl->irq = platform_get_irq(pdev, 0); 669 twl->irq = platform_get_irq(pdev, 0);
701 twl->vbus_supplied = false; 670 twl->vbus_supplied = false;
702 twl->asleep = 1; 671 twl->linkstat = -EINVAL;
703 twl->linkstat = OMAP_MUSB_UNKNOWN; 672 twl->linkstat = OMAP_MUSB_UNKNOWN;
704 673
705 twl->phy.dev = twl->dev; 674 twl->phy.dev = twl->dev;
@@ -724,8 +693,8 @@ static int twl4030_usb_probe(struct platform_device *pdev)
724 if (IS_ERR(phy_provider)) 693 if (IS_ERR(phy_provider))
725 return PTR_ERR(phy_provider); 694 return PTR_ERR(phy_provider);
726 695
727 /* init spinlock for workqueue */ 696 /* init mutex for workqueue */
728 spin_lock_init(&twl->lock); 697 mutex_init(&twl->lock);
729 698
730 INIT_DELAYED_WORK(&twl->id_workaround_work, twl4030_id_workaround_work); 699 INIT_DELAYED_WORK(&twl->id_workaround_work, twl4030_id_workaround_work);
731 700
@@ -755,7 +724,6 @@ static int twl4030_usb_probe(struct platform_device *pdev)
755 * set_host() and/or set_peripheral() ... OTG_capable boards 724 * set_host() and/or set_peripheral() ... OTG_capable boards
756 * need both handles, otherwise just one suffices. 725 * need both handles, otherwise just one suffices.
757 */ 726 */
758 twl->irq_enabled = true;
759 status = devm_request_threaded_irq(twl->dev, twl->irq, NULL, 727 status = devm_request_threaded_irq(twl->dev, twl->irq, NULL,
760 twl4030_usb_irq, IRQF_TRIGGER_FALLING | 728 twl4030_usb_irq, IRQF_TRIGGER_FALLING |
761 IRQF_TRIGGER_RISING | IRQF_ONESHOT, "twl4030_usb", twl); 729 IRQF_TRIGGER_RISING | IRQF_ONESHOT, "twl4030_usb", twl);
@@ -817,7 +785,6 @@ static struct platform_driver twl4030_usb_driver = {
817 .driver = { 785 .driver = {
818 .name = "twl4030_usb", 786 .name = "twl4030_usb",
819 .pm = &twl4030_usb_pm_ops, 787 .pm = &twl4030_usb_pm_ops,
820 .owner = THIS_MODULE,
821 .of_match_table = of_match_ptr(twl4030_usb_id_table), 788 .of_match_table = of_match_ptr(twl4030_usb_id_table),
822 }, 789 },
823}; 790};