aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/phy
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2014-10-06 08:01:11 -0400
committerTakashi Iwai <tiwai@suse.de>2014-10-06 08:01:11 -0400
commit8df22a4d6f5b81c9c1703579d4907b57002689ed (patch)
tree064e9662d427a82076e1151fcd9aa78a1066f9f4 /drivers/phy
parent0cae90a96c15f2fd3bd139ba5505755c9c9ef2eb (diff)
parenta5448c88b812390a3622e76d774e10c0da1fb970 (diff)
Merge tag 'asoc-v3.18' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: Updates for v3.18 - More componentisation work from Lars-Peter, this time mainly cleaning up the suspend and bias level transition callbacks. - Real system support for the Intel drivers and a bunch of fixes and enhancements for the associated CODEC drivers, this is going to need a lot quirks over time due to the lack of any firmware description of the boards. - Jack detect support for simple card from Dylan Reid. - A bunch of small fixes and enhancements for the Freescale drivers. - New drivers for Analog Devices SSM4567, Cirrus Logic CS35L32, Everest Semiconductor ES8328 and Freescale cards using the ASRC in newer i.MX processors.
Diffstat (limited to 'drivers/phy')
-rw-r--r--drivers/phy/Kconfig4
-rw-r--r--drivers/phy/phy-exynos5-usbdrd.c1
-rw-r--r--drivers/phy/phy-miphy365x.c1
-rw-r--r--drivers/phy/phy-twl4030-usb.c121
4 files changed, 78 insertions, 49 deletions
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 0dd742719154..f833aa271a2e 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -41,9 +41,9 @@ config PHY_MVEBU_SATA
41config PHY_MIPHY365X 41config PHY_MIPHY365X
42 tristate "STMicroelectronics MIPHY365X PHY driver for STiH41x series" 42 tristate "STMicroelectronics MIPHY365X PHY driver for STiH41x series"
43 depends on ARCH_STI 43 depends on ARCH_STI
44 depends on GENERIC_PHY
45 depends on HAS_IOMEM 44 depends on HAS_IOMEM
46 depends on OF 45 depends on OF
46 select GENERIC_PHY
47 help 47 help
48 Enable this to support the miphy transceiver (for SATA/PCIE) 48 Enable this to support the miphy transceiver (for SATA/PCIE)
49 that is part of STMicroelectronics STiH41x SoC series. 49 that is part of STMicroelectronics STiH41x SoC series.
@@ -214,12 +214,14 @@ config PHY_QCOM_IPQ806X_SATA
214config PHY_ST_SPEAR1310_MIPHY 214config PHY_ST_SPEAR1310_MIPHY
215 tristate "ST SPEAR1310-MIPHY driver" 215 tristate "ST SPEAR1310-MIPHY driver"
216 select GENERIC_PHY 216 select GENERIC_PHY
217 depends on MACH_SPEAR1310 || COMPILE_TEST
217 help 218 help
218 Support for ST SPEAr1310 MIPHY which can be used for PCIe and SATA. 219 Support for ST SPEAr1310 MIPHY which can be used for PCIe and SATA.
219 220
220config PHY_ST_SPEAR1340_MIPHY 221config PHY_ST_SPEAR1340_MIPHY
221 tristate "ST SPEAR1340-MIPHY driver" 222 tristate "ST SPEAR1340-MIPHY driver"
222 select GENERIC_PHY 223 select GENERIC_PHY
224 depends on MACH_SPEAR1340 || COMPILE_TEST
223 help 225 help
224 Support for ST SPEAr1340 MIPHY which can be used for PCIe and SATA. 226 Support for ST SPEAr1340 MIPHY which can be used for PCIe and SATA.
225 227
diff --git a/drivers/phy/phy-exynos5-usbdrd.c b/drivers/phy/phy-exynos5-usbdrd.c
index b05302b09c9f..392101c8d6b0 100644
--- a/drivers/phy/phy-exynos5-usbdrd.c
+++ b/drivers/phy/phy-exynos5-usbdrd.c
@@ -542,6 +542,7 @@ static const struct of_device_id exynos5_usbdrd_phy_of_match[] = {
542 }, 542 },
543 { }, 543 { },
544}; 544};
545MODULE_DEVICE_TABLE(of, exynos5_usbdrd_phy_of_match);
545 546
546static int exynos5_usbdrd_phy_probe(struct platform_device *pdev) 547static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
547{ 548{
diff --git a/drivers/phy/phy-miphy365x.c b/drivers/phy/phy-miphy365x.c
index e111baf187ce..e0fb7a1e5a5a 100644
--- a/drivers/phy/phy-miphy365x.c
+++ b/drivers/phy/phy-miphy365x.c
@@ -163,6 +163,7 @@ enum miphy_sata_gen {
163}; 163};
164 164
165static u8 rx_tx_spd[] = { 165static u8 rx_tx_spd[] = {
166 0, /* GEN0 doesn't exist. */
166 TX_SPDSEL_GEN1_VAL | RX_SPDSEL_GEN1_VAL, 167 TX_SPDSEL_GEN1_VAL | RX_SPDSEL_GEN1_VAL,
167 TX_SPDSEL_GEN2_VAL | RX_SPDSEL_GEN2_VAL, 168 TX_SPDSEL_GEN2_VAL | RX_SPDSEL_GEN2_VAL,
168 TX_SPDSEL_GEN3_VAL | RX_SPDSEL_GEN3_VAL 169 TX_SPDSEL_GEN3_VAL | RX_SPDSEL_GEN3_VAL
diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c
index e1a6623d4696..9cd33a4bcfb1 100644
--- a/drivers/phy/phy-twl4030-usb.c
+++ b/drivers/phy/phy-twl4030-usb.c
@@ -34,6 +34,7 @@
34#include <linux/delay.h> 34#include <linux/delay.h>
35#include <linux/usb/otg.h> 35#include <linux/usb/otg.h>
36#include <linux/phy/phy.h> 36#include <linux/phy/phy.h>
37#include <linux/pm_runtime.h>
37#include <linux/usb/musb-omap.h> 38#include <linux/usb/musb-omap.h>
38#include <linux/usb/ulpi.h> 39#include <linux/usb/ulpi.h>
39#include <linux/i2c/twl.h> 40#include <linux/i2c/twl.h>
@@ -422,37 +423,55 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on)
422 } 423 }
423} 424}
424 425
425static int twl4030_phy_power_off(struct phy *phy) 426static int twl4030_usb_runtime_suspend(struct device *dev)
426{ 427{
427 struct twl4030_usb *twl = phy_get_drvdata(phy); 428 struct twl4030_usb *twl = dev_get_drvdata(dev);
428 429
430 dev_dbg(twl->dev, "%s\n", __func__);
429 if (twl->asleep) 431 if (twl->asleep)
430 return 0; 432 return 0;
431 433
432 twl4030_phy_power(twl, 0); 434 twl4030_phy_power(twl, 0);
433 twl->asleep = 1; 435 twl->asleep = 1;
434 dev_dbg(twl->dev, "%s\n", __func__); 436
435 return 0; 437 return 0;
436} 438}
437 439
438static void __twl4030_phy_power_on(struct twl4030_usb *twl) 440static int twl4030_usb_runtime_resume(struct device *dev)
439{ 441{
442 struct twl4030_usb *twl = dev_get_drvdata(dev);
443
444 dev_dbg(twl->dev, "%s\n", __func__);
445 if (!twl->asleep)
446 return 0;
447
440 twl4030_phy_power(twl, 1); 448 twl4030_phy_power(twl, 1);
441 twl4030_i2c_access(twl, 1); 449 twl->asleep = 0;
442 twl4030_usb_set_mode(twl, twl->usb_mode); 450
443 if (twl->usb_mode == T2_USB_MODE_ULPI) 451 return 0;
444 twl4030_i2c_access(twl, 0); 452}
453
454static int twl4030_phy_power_off(struct phy *phy)
455{
456 struct twl4030_usb *twl = phy_get_drvdata(phy);
457
458 dev_dbg(twl->dev, "%s\n", __func__);
459 pm_runtime_mark_last_busy(twl->dev);
460 pm_runtime_put_autosuspend(twl->dev);
461
462 return 0;
445} 463}
446 464
447static int twl4030_phy_power_on(struct phy *phy) 465static int twl4030_phy_power_on(struct phy *phy)
448{ 466{
449 struct twl4030_usb *twl = phy_get_drvdata(phy); 467 struct twl4030_usb *twl = phy_get_drvdata(phy);
450 468
451 if (!twl->asleep)
452 return 0;
453 __twl4030_phy_power_on(twl);
454 twl->asleep = 0;
455 dev_dbg(twl->dev, "%s\n", __func__); 469 dev_dbg(twl->dev, "%s\n", __func__);
470 pm_runtime_get_sync(twl->dev);
471 twl4030_i2c_access(twl, 1);
472 twl4030_usb_set_mode(twl, twl->usb_mode);
473 if (twl->usb_mode == T2_USB_MODE_ULPI)
474 twl4030_i2c_access(twl, 0);
456 475
457 /* 476 /*
458 * XXX When VBUS gets driven after musb goes to A mode, 477 * XXX When VBUS gets driven after musb goes to A mode,
@@ -558,9 +577,27 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
558 * USB_LINK_VBUS state. musb_hdrc won't care until it 577 * USB_LINK_VBUS state. musb_hdrc won't care until it
559 * starts to handle softconnect right. 578 * starts to handle softconnect right.
560 */ 579 */
580 if ((status == OMAP_MUSB_VBUS_VALID) ||
581 (status == OMAP_MUSB_ID_GROUND)) {
582 if (twl->asleep)
583 pm_runtime_get_sync(twl->dev);
584 } else {
585 if (!twl->asleep) {
586 pm_runtime_mark_last_busy(twl->dev);
587 pm_runtime_put_autosuspend(twl->dev);
588 }
589 }
561 omap_musb_mailbox(status); 590 omap_musb_mailbox(status);
562 } 591 }
563 sysfs_notify(&twl->dev->kobj, NULL, "vbus"); 592
593 /* don't schedule during sleep - irq works right then */
594 if (status == OMAP_MUSB_ID_GROUND && !twl->asleep) {
595 cancel_delayed_work(&twl->id_workaround_work);
596 schedule_delayed_work(&twl->id_workaround_work, HZ);
597 }
598
599 if (irq)
600 sysfs_notify(&twl->dev->kobj, NULL, "vbus");
564 601
565 return IRQ_HANDLED; 602 return IRQ_HANDLED;
566} 603}
@@ -569,29 +606,8 @@ static void twl4030_id_workaround_work(struct work_struct *work)
569{ 606{
570 struct twl4030_usb *twl = container_of(work, struct twl4030_usb, 607 struct twl4030_usb *twl = container_of(work, struct twl4030_usb,
571 id_workaround_work.work); 608 id_workaround_work.work);
572 enum omap_musb_vbus_id_status status;
573 bool status_changed = false;
574
575 status = twl4030_usb_linkstat(twl);
576
577 spin_lock_irq(&twl->lock);
578 if (status >= 0 && status != twl->linkstat) {
579 twl->linkstat = status;
580 status_changed = true;
581 }
582 spin_unlock_irq(&twl->lock);
583
584 if (status_changed) {
585 dev_dbg(twl->dev, "handle missing status change to %d\n",
586 status);
587 omap_musb_mailbox(status);
588 }
589 609
590 /* don't schedule during sleep - irq works right then */ 610 twl4030_usb_irq(0, twl);
591 if (status == OMAP_MUSB_ID_GROUND && !twl->asleep) {
592 cancel_delayed_work(&twl->id_workaround_work);
593 schedule_delayed_work(&twl->id_workaround_work, HZ);
594 }
595} 611}
596 612
597static int twl4030_phy_init(struct phy *phy) 613static int twl4030_phy_init(struct phy *phy)
@@ -599,22 +615,17 @@ static int twl4030_phy_init(struct phy *phy)
599 struct twl4030_usb *twl = phy_get_drvdata(phy); 615 struct twl4030_usb *twl = phy_get_drvdata(phy);
600 enum omap_musb_vbus_id_status status; 616 enum omap_musb_vbus_id_status status;
601 617
602 /* 618 pm_runtime_get_sync(twl->dev);
603 * Start in sleep state, we'll get called through set_suspend()
604 * callback when musb is runtime resumed and it's time to start.
605 */
606 __twl4030_phy_power(twl, 0);
607 twl->asleep = 1;
608
609 status = twl4030_usb_linkstat(twl); 619 status = twl4030_usb_linkstat(twl);
610 twl->linkstat = status; 620 twl->linkstat = status;
611 621
612 if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID) { 622 if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID)
613 omap_musb_mailbox(twl->linkstat); 623 omap_musb_mailbox(twl->linkstat);
614 twl4030_phy_power_on(phy);
615 }
616 624
617 sysfs_notify(&twl->dev->kobj, NULL, "vbus"); 625 sysfs_notify(&twl->dev->kobj, NULL, "vbus");
626 pm_runtime_mark_last_busy(twl->dev);
627 pm_runtime_put_autosuspend(twl->dev);
628
618 return 0; 629 return 0;
619} 630}
620 631
@@ -650,6 +661,11 @@ static const struct phy_ops ops = {
650 .owner = THIS_MODULE, 661 .owner = THIS_MODULE,
651}; 662};
652 663
664static const struct dev_pm_ops twl4030_usb_pm_ops = {
665 SET_RUNTIME_PM_OPS(twl4030_usb_runtime_suspend,
666 twl4030_usb_runtime_resume, NULL)
667};
668
653static int twl4030_usb_probe(struct platform_device *pdev) 669static int twl4030_usb_probe(struct platform_device *pdev)
654{ 670{
655 struct twl4030_usb_data *pdata = dev_get_platdata(&pdev->dev); 671 struct twl4030_usb_data *pdata = dev_get_platdata(&pdev->dev);
@@ -726,6 +742,11 @@ static int twl4030_usb_probe(struct platform_device *pdev)
726 742
727 ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier); 743 ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier);
728 744
745 pm_runtime_use_autosuspend(&pdev->dev);
746 pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);
747 pm_runtime_enable(&pdev->dev);
748 pm_runtime_get_sync(&pdev->dev);
749
729 /* Our job is to use irqs and status from the power module 750 /* Our job is to use irqs and status from the power module
730 * to keep the transceiver disabled when nothing's connected. 751 * to keep the transceiver disabled when nothing's connected.
731 * 752 *
@@ -744,6 +765,9 @@ static int twl4030_usb_probe(struct platform_device *pdev)
744 return status; 765 return status;
745 } 766 }
746 767
768 pm_runtime_mark_last_busy(&pdev->dev);
769 pm_runtime_put_autosuspend(twl->dev);
770
747 dev_info(&pdev->dev, "Initialized TWL4030 USB module\n"); 771 dev_info(&pdev->dev, "Initialized TWL4030 USB module\n");
748 return 0; 772 return 0;
749} 773}
@@ -753,6 +777,7 @@ static int twl4030_usb_remove(struct platform_device *pdev)
753 struct twl4030_usb *twl = platform_get_drvdata(pdev); 777 struct twl4030_usb *twl = platform_get_drvdata(pdev);
754 int val; 778 int val;
755 779
780 pm_runtime_get_sync(twl->dev);
756 cancel_delayed_work(&twl->id_workaround_work); 781 cancel_delayed_work(&twl->id_workaround_work);
757 device_remove_file(twl->dev, &dev_attr_vbus); 782 device_remove_file(twl->dev, &dev_attr_vbus);
758 783
@@ -772,9 +797,8 @@ static int twl4030_usb_remove(struct platform_device *pdev)
772 797
773 /* disable complete OTG block */ 798 /* disable complete OTG block */
774 twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); 799 twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB);
775 800 pm_runtime_mark_last_busy(twl->dev);
776 if (!twl->asleep) 801 pm_runtime_put(twl->dev);
777 twl4030_phy_power(twl, 0);
778 802
779 return 0; 803 return 0;
780} 804}
@@ -792,6 +816,7 @@ static struct platform_driver twl4030_usb_driver = {
792 .remove = twl4030_usb_remove, 816 .remove = twl4030_usb_remove,
793 .driver = { 817 .driver = {
794 .name = "twl4030_usb", 818 .name = "twl4030_usb",
819 .pm = &twl4030_usb_pm_ops,
795 .owner = THIS_MODULE, 820 .owner = THIS_MODULE,
796 .of_match_table = of_match_ptr(twl4030_usb_id_table), 821 .of_match_table = of_match_ptr(twl4030_usb_id_table),
797 }, 822 },