aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/chipidea/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/chipidea/core.c')
-rw-r--r--drivers/usb/chipidea/core.c173
1 files changed, 69 insertions, 104 deletions
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 3dbb4a21ab44..79ad8e91632e 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -62,7 +62,6 @@
62#include <linux/usb/chipidea.h> 62#include <linux/usb/chipidea.h>
63#include <linux/usb/of.h> 63#include <linux/usb/of.h>
64#include <linux/of.h> 64#include <linux/of.h>
65#include <linux/phy.h>
66#include <linux/regulator/consumer.h> 65#include <linux/regulator/consumer.h>
67#include <linux/usb/ehci_def.h> 66#include <linux/usb/ehci_def.h>
68 67
@@ -86,6 +85,7 @@ static const u8 ci_regs_nolpm[] = {
86 [OP_ENDPTLISTADDR] = 0x18U, 85 [OP_ENDPTLISTADDR] = 0x18U,
87 [OP_TTCTRL] = 0x1CU, 86 [OP_TTCTRL] = 0x1CU,
88 [OP_BURSTSIZE] = 0x20U, 87 [OP_BURSTSIZE] = 0x20U,
88 [OP_ULPI_VIEWPORT] = 0x30U,
89 [OP_PORTSC] = 0x44U, 89 [OP_PORTSC] = 0x44U,
90 [OP_DEVLC] = 0x84U, 90 [OP_DEVLC] = 0x84U,
91 [OP_OTGSC] = 0x64U, 91 [OP_OTGSC] = 0x64U,
@@ -110,6 +110,7 @@ static const u8 ci_regs_lpm[] = {
110 [OP_ENDPTLISTADDR] = 0x18U, 110 [OP_ENDPTLISTADDR] = 0x18U,
111 [OP_TTCTRL] = 0x1CU, 111 [OP_TTCTRL] = 0x1CU,
112 [OP_BURSTSIZE] = 0x20U, 112 [OP_BURSTSIZE] = 0x20U,
113 [OP_ULPI_VIEWPORT] = 0x30U,
113 [OP_PORTSC] = 0x44U, 114 [OP_PORTSC] = 0x44U,
114 [OP_DEVLC] = 0x84U, 115 [OP_DEVLC] = 0x84U,
115 [OP_OTGSC] = 0xC4U, 116 [OP_OTGSC] = 0xC4U,
@@ -285,7 +286,7 @@ static int hw_device_init(struct ci_hdrc *ci, void __iomem *base)
285 return 0; 286 return 0;
286} 287}
287 288
288static void hw_phymode_configure(struct ci_hdrc *ci) 289void hw_phymode_configure(struct ci_hdrc *ci)
289{ 290{
290 u32 portsc, lpm, sts = 0; 291 u32 portsc, lpm, sts = 0;
291 292
@@ -325,6 +326,7 @@ static void hw_phymode_configure(struct ci_hdrc *ci)
325 hw_write(ci, OP_PORTSC, PORTSC_STS, PORTSC_STS); 326 hw_write(ci, OP_PORTSC, PORTSC_STS, PORTSC_STS);
326 } 327 }
327} 328}
329EXPORT_SYMBOL_GPL(hw_phymode_configure);
328 330
329/** 331/**
330 * _ci_usb_phy_init: initialize phy taking in account both phy and usb_phy 332 * _ci_usb_phy_init: initialize phy taking in account both phy and usb_phy
@@ -361,6 +363,9 @@ static int _ci_usb_phy_init(struct ci_hdrc *ci)
361 */ 363 */
362static void ci_usb_phy_exit(struct ci_hdrc *ci) 364static void ci_usb_phy_exit(struct ci_hdrc *ci)
363{ 365{
366 if (ci->platdata->flags & CI_HDRC_OVERRIDE_PHY_CONTROL)
367 return;
368
364 if (ci->phy) { 369 if (ci->phy) {
365 phy_power_off(ci->phy); 370 phy_power_off(ci->phy);
366 phy_exit(ci->phy); 371 phy_exit(ci->phy);
@@ -379,6 +384,9 @@ static int ci_usb_phy_init(struct ci_hdrc *ci)
379{ 384{
380 int ret; 385 int ret;
381 386
387 if (ci->platdata->flags & CI_HDRC_OVERRIDE_PHY_CONTROL)
388 return 0;
389
382 switch (ci->platdata->phy_mode) { 390 switch (ci->platdata->phy_mode) {
383 case USBPHY_INTERFACE_MODE_UTMI: 391 case USBPHY_INTERFACE_MODE_UTMI:
384 case USBPHY_INTERFACE_MODE_UTMIW: 392 case USBPHY_INTERFACE_MODE_UTMIW:
@@ -419,13 +427,21 @@ void ci_platform_configure(struct ci_hdrc *ci)
419 is_device_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_DC; 427 is_device_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_DC;
420 is_host_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_HC; 428 is_host_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_HC;
421 429
422 if (is_device_mode && 430 if (is_device_mode) {
423 (ci->platdata->flags & CI_HDRC_DISABLE_DEVICE_STREAMING)) 431 phy_set_mode(ci->phy, PHY_MODE_USB_DEVICE);
424 hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS); 432
433 if (ci->platdata->flags & CI_HDRC_DISABLE_DEVICE_STREAMING)
434 hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS,
435 USBMODE_CI_SDIS);
436 }
437
438 if (is_host_mode) {
439 phy_set_mode(ci->phy, PHY_MODE_USB_HOST);
425 440
426 if (is_host_mode && 441 if (ci->platdata->flags & CI_HDRC_DISABLE_HOST_STREAMING)
427 (ci->platdata->flags & CI_HDRC_DISABLE_HOST_STREAMING)) 442 hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS,
428 hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS); 443 USBMODE_CI_SDIS);
444 }
429 445
430 if (ci->platdata->flags & CI_HDRC_FORCE_FULLSPEED) { 446 if (ci->platdata->flags & CI_HDRC_FORCE_FULLSPEED) {
431 if (ci->hw_bank.lpm) 447 if (ci->hw_bank.lpm)
@@ -495,9 +511,12 @@ int hw_device_reset(struct ci_hdrc *ci)
495 return ret; 511 return ret;
496 } 512 }
497 513
498 if (ci->platdata->notify_event) 514 if (ci->platdata->notify_event) {
499 ci->platdata->notify_event(ci, 515 ret = ci->platdata->notify_event(ci,
500 CI_HDRC_CONTROLLER_RESET_EVENT); 516 CI_HDRC_CONTROLLER_RESET_EVENT);
517 if (ret)
518 return ret;
519 }
501 520
502 /* USBMODE should be configured step by step */ 521 /* USBMODE should be configured step by step */
503 hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE); 522 hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE);
@@ -516,38 +535,6 @@ int hw_device_reset(struct ci_hdrc *ci)
516 return 0; 535 return 0;
517} 536}
518 537
519/**
520 * hw_wait_reg: wait the register value
521 *
522 * Sometimes, it needs to wait register value before going on.
523 * Eg, when switch to device mode, the vbus value should be lower
524 * than OTGSC_BSV before connects to host.
525 *
526 * @ci: the controller
527 * @reg: register index
528 * @mask: mast bit
529 * @value: the bit value to wait
530 * @timeout_ms: timeout in millisecond
531 *
532 * This function returns an error code if timeout
533 */
534int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
535 u32 value, unsigned int timeout_ms)
536{
537 unsigned long elapse = jiffies + msecs_to_jiffies(timeout_ms);
538
539 while (hw_read(ci, reg, mask) != value) {
540 if (time_after(jiffies, elapse)) {
541 dev_err(ci->dev, "timeout waiting for %08x in %d\n",
542 mask, reg);
543 return -ETIMEDOUT;
544 }
545 msleep(20);
546 }
547
548 return 0;
549}
550
551static irqreturn_t ci_irq(int irq, void *data) 538static irqreturn_t ci_irq(int irq, void *data)
552{ 539{
553 struct ci_hdrc *ci = data; 540 struct ci_hdrc *ci = data;
@@ -601,35 +588,14 @@ static irqreturn_t ci_irq(int irq, void *data)
601 return ret; 588 return ret;
602} 589}
603 590
604static int ci_vbus_notifier(struct notifier_block *nb, unsigned long event, 591static int ci_cable_notifier(struct notifier_block *nb, unsigned long event,
605 void *ptr) 592 void *ptr)
606{
607 struct ci_hdrc_cable *vbus = container_of(nb, struct ci_hdrc_cable, nb);
608 struct ci_hdrc *ci = vbus->ci;
609
610 if (event)
611 vbus->state = true;
612 else
613 vbus->state = false;
614
615 vbus->changed = true;
616
617 ci_irq(ci->irq, ci);
618 return NOTIFY_DONE;
619}
620
621static int ci_id_notifier(struct notifier_block *nb, unsigned long event,
622 void *ptr)
623{ 593{
624 struct ci_hdrc_cable *id = container_of(nb, struct ci_hdrc_cable, nb); 594 struct ci_hdrc_cable *cbl = container_of(nb, struct ci_hdrc_cable, nb);
625 struct ci_hdrc *ci = id->ci; 595 struct ci_hdrc *ci = cbl->ci;
626 596
627 if (event) 597 cbl->connected = event;
628 id->state = false; 598 cbl->changed = true;
629 else
630 id->state = true;
631
632 id->changed = true;
633 599
634 ci_irq(ci->irq, ci); 600 ci_irq(ci->irq, ci);
635 return NOTIFY_DONE; 601 return NOTIFY_DONE;
@@ -738,27 +704,27 @@ static int ci_get_platdata(struct device *dev,
738 } 704 }
739 705
740 cable = &platdata->vbus_extcon; 706 cable = &platdata->vbus_extcon;
741 cable->nb.notifier_call = ci_vbus_notifier; 707 cable->nb.notifier_call = ci_cable_notifier;
742 cable->edev = ext_vbus; 708 cable->edev = ext_vbus;
743 709
744 if (!IS_ERR(ext_vbus)) { 710 if (!IS_ERR(ext_vbus)) {
745 ret = extcon_get_cable_state_(cable->edev, EXTCON_USB); 711 ret = extcon_get_state(cable->edev, EXTCON_USB);
746 if (ret) 712 if (ret)
747 cable->state = true; 713 cable->connected = true;
748 else 714 else
749 cable->state = false; 715 cable->connected = false;
750 } 716 }
751 717
752 cable = &platdata->id_extcon; 718 cable = &platdata->id_extcon;
753 cable->nb.notifier_call = ci_id_notifier; 719 cable->nb.notifier_call = ci_cable_notifier;
754 cable->edev = ext_id; 720 cable->edev = ext_id;
755 721
756 if (!IS_ERR(ext_id)) { 722 if (!IS_ERR(ext_id)) {
757 ret = extcon_get_cable_state_(cable->edev, EXTCON_USB_HOST); 723 ret = extcon_get_state(cable->edev, EXTCON_USB_HOST);
758 if (ret) 724 if (ret)
759 cable->state = false; 725 cable->connected = true;
760 else 726 else
761 cable->state = true; 727 cable->connected = false;
762 } 728 }
763 return 0; 729 return 0;
764} 730}
@@ -771,8 +737,8 @@ static int ci_extcon_register(struct ci_hdrc *ci)
771 id = &ci->platdata->id_extcon; 737 id = &ci->platdata->id_extcon;
772 id->ci = ci; 738 id->ci = ci;
773 if (!IS_ERR(id->edev)) { 739 if (!IS_ERR(id->edev)) {
774 ret = extcon_register_notifier(id->edev, EXTCON_USB_HOST, 740 ret = devm_extcon_register_notifier(ci->dev, id->edev,
775 &id->nb); 741 EXTCON_USB_HOST, &id->nb);
776 if (ret < 0) { 742 if (ret < 0) {
777 dev_err(ci->dev, "register ID failed\n"); 743 dev_err(ci->dev, "register ID failed\n");
778 return ret; 744 return ret;
@@ -782,11 +748,9 @@ static int ci_extcon_register(struct ci_hdrc *ci)
782 vbus = &ci->platdata->vbus_extcon; 748 vbus = &ci->platdata->vbus_extcon;
783 vbus->ci = ci; 749 vbus->ci = ci;
784 if (!IS_ERR(vbus->edev)) { 750 if (!IS_ERR(vbus->edev)) {
785 ret = extcon_register_notifier(vbus->edev, EXTCON_USB, 751 ret = devm_extcon_register_notifier(ci->dev, vbus->edev,
786 &vbus->nb); 752 EXTCON_USB, &vbus->nb);
787 if (ret < 0) { 753 if (ret < 0) {
788 extcon_unregister_notifier(id->edev, EXTCON_USB_HOST,
789 &id->nb);
790 dev_err(ci->dev, "register VBUS failed\n"); 754 dev_err(ci->dev, "register VBUS failed\n");
791 return ret; 755 return ret;
792 } 756 }
@@ -795,20 +759,6 @@ static int ci_extcon_register(struct ci_hdrc *ci)
795 return 0; 759 return 0;
796} 760}
797 761
798static void ci_extcon_unregister(struct ci_hdrc *ci)
799{
800 struct ci_hdrc_cable *cable;
801
802 cable = &ci->platdata->id_extcon;
803 if (!IS_ERR(cable->edev))
804 extcon_unregister_notifier(cable->edev, EXTCON_USB_HOST,
805 &cable->nb);
806
807 cable = &ci->platdata->vbus_extcon;
808 if (!IS_ERR(cable->edev))
809 extcon_unregister_notifier(cable->edev, EXTCON_USB, &cable->nb);
810}
811
812static DEFINE_IDA(ci_ida); 762static DEFINE_IDA(ci_ida);
813 763
814struct platform_device *ci_hdrc_add_device(struct device *dev, 764struct platform_device *ci_hdrc_add_device(struct device *dev,
@@ -921,6 +871,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
921 CI_HDRC_IMX28_WRITE_FIX); 871 CI_HDRC_IMX28_WRITE_FIX);
922 ci->supports_runtime_pm = !!(ci->platdata->flags & 872 ci->supports_runtime_pm = !!(ci->platdata->flags &
923 CI_HDRC_SUPPORTS_RUNTIME_PM); 873 CI_HDRC_SUPPORTS_RUNTIME_PM);
874 platform_set_drvdata(pdev, ci);
924 875
925 ret = hw_device_init(ci, base); 876 ret = hw_device_init(ci, base);
926 if (ret < 0) { 877 if (ret < 0) {
@@ -928,6 +879,10 @@ static int ci_hdrc_probe(struct platform_device *pdev)
928 return -ENODEV; 879 return -ENODEV;
929 } 880 }
930 881
882 ret = ci_ulpi_init(ci);
883 if (ret)
884 return ret;
885
931 if (ci->platdata->phy) { 886 if (ci->platdata->phy) {
932 ci->phy = ci->platdata->phy; 887 ci->phy = ci->platdata->phy;
933 } else if (ci->platdata->usb_phy) { 888 } else if (ci->platdata->usb_phy) {
@@ -938,11 +893,15 @@ static int ci_hdrc_probe(struct platform_device *pdev)
938 893
939 /* if both generic PHY and USB PHY layers aren't enabled */ 894 /* if both generic PHY and USB PHY layers aren't enabled */
940 if (PTR_ERR(ci->phy) == -ENOSYS && 895 if (PTR_ERR(ci->phy) == -ENOSYS &&
941 PTR_ERR(ci->usb_phy) == -ENXIO) 896 PTR_ERR(ci->usb_phy) == -ENXIO) {
942 return -ENXIO; 897 ret = -ENXIO;
898 goto ulpi_exit;
899 }
943 900
944 if (IS_ERR(ci->phy) && IS_ERR(ci->usb_phy)) 901 if (IS_ERR(ci->phy) && IS_ERR(ci->usb_phy)) {
945 return -EPROBE_DEFER; 902 ret = -EPROBE_DEFER;
903 goto ulpi_exit;
904 }
946 905
947 if (IS_ERR(ci->phy)) 906 if (IS_ERR(ci->phy))
948 ci->phy = NULL; 907 ci->phy = NULL;
@@ -1027,7 +986,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
1027 } 986 }
1028 } 987 }
1029 988
1030 platform_set_drvdata(pdev, ci);
1031 ret = devm_request_irq(dev, ci->irq, ci_irq, IRQF_SHARED, 989 ret = devm_request_irq(dev, ci->irq, ci_irq, IRQF_SHARED,
1032 ci->platdata->name, ci); 990 ci->platdata->name, ci);
1033 if (ret) 991 if (ret)
@@ -1054,11 +1012,12 @@ static int ci_hdrc_probe(struct platform_device *pdev)
1054 if (!ret) 1012 if (!ret)
1055 return 0; 1013 return 0;
1056 1014
1057 ci_extcon_unregister(ci);
1058stop: 1015stop:
1059 ci_role_destroy(ci); 1016 ci_role_destroy(ci);
1060deinit_phy: 1017deinit_phy:
1061 ci_usb_phy_exit(ci); 1018 ci_usb_phy_exit(ci);
1019ulpi_exit:
1020 ci_ulpi_exit(ci);
1062 1021
1063 return ret; 1022 return ret;
1064} 1023}
@@ -1074,10 +1033,10 @@ static int ci_hdrc_remove(struct platform_device *pdev)
1074 } 1033 }
1075 1034
1076 dbg_remove_files(ci); 1035 dbg_remove_files(ci);
1077 ci_extcon_unregister(ci);
1078 ci_role_destroy(ci); 1036 ci_role_destroy(ci);
1079 ci_hdrc_enter_lpm(ci, true); 1037 ci_hdrc_enter_lpm(ci, true);
1080 ci_usb_phy_exit(ci); 1038 ci_usb_phy_exit(ci);
1039 ci_ulpi_exit(ci);
1081 1040
1082 return 0; 1041 return 0;
1083} 1042}
@@ -1125,6 +1084,7 @@ static void ci_controller_suspend(struct ci_hdrc *ci)
1125static int ci_controller_resume(struct device *dev) 1084static int ci_controller_resume(struct device *dev)
1126{ 1085{
1127 struct ci_hdrc *ci = dev_get_drvdata(dev); 1086 struct ci_hdrc *ci = dev_get_drvdata(dev);
1087 int ret;
1128 1088
1129 dev_dbg(dev, "at %s\n", __func__); 1089 dev_dbg(dev, "at %s\n", __func__);
1130 1090
@@ -1134,6 +1094,11 @@ static int ci_controller_resume(struct device *dev)
1134 } 1094 }
1135 1095
1136 ci_hdrc_enter_lpm(ci, false); 1096 ci_hdrc_enter_lpm(ci, false);
1097
1098 ret = ci_ulpi_resume(ci);
1099 if (ret)
1100 return ret;
1101
1137 if (ci->usb_phy) { 1102 if (ci->usb_phy) {
1138 usb_phy_set_suspend(ci->usb_phy, 0); 1103 usb_phy_set_suspend(ci->usb_phy, 0);
1139 usb_phy_set_wakeup(ci->usb_phy, false); 1104 usb_phy_set_wakeup(ci->usb_phy, false);