aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAntoine Tenart <antoine.tenart@free-electrons.com>2014-10-30 13:41:16 -0400
committerFelipe Balbi <balbi@ti.com>2014-11-03 11:02:50 -0500
commitef44cb4226d132146e44f8ea562a16b27ff61126 (patch)
treecec7cf8bd69f400de0fbdb76e6a43759a154d446 /drivers
parent48bcc18076df4e07ef86226ac6ce795f64c84f7f (diff)
usb: allow to supply the PHY in the drivers when using HCD
This patch modify the generic code handling PHYs to allow them to be supplied from the drivers. This adds checks to ensure no PHY was already there when looking for one in the generic code. This also makes sure we do not modify its state in the generic HCD functions, it was provided by the driver. Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com> Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/chipidea/ci.h5
-rw-r--r--drivers/usb/chipidea/ci_hdrc_imx.c2
-rw-r--r--drivers/usb/chipidea/ci_hdrc_msm.c8
-rw-r--r--drivers/usb/chipidea/core.c20
-rw-r--r--drivers/usb/chipidea/debug.c2
-rw-r--r--drivers/usb/chipidea/host.c7
-rw-r--r--drivers/usb/chipidea/otg_fsm.c16
-rw-r--r--drivers/usb/chipidea/udc.c4
-rw-r--r--drivers/usb/core/hcd.c7
9 files changed, 32 insertions, 39 deletions
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index ea40626e0246..9015139a8027 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -161,7 +161,7 @@ struct hw_bank {
161 * @test_mode: the selected test mode 161 * @test_mode: the selected test mode
162 * @platdata: platform specific information supplied by parent device 162 * @platdata: platform specific information supplied by parent device
163 * @vbus_active: is VBUS active 163 * @vbus_active: is VBUS active
164 * @transceiver: pointer to USB PHY, if any 164 * @usb_phy: pointer to USB PHY, if any
165 * @hcd: pointer to usb_hcd for ehci host driver 165 * @hcd: pointer to usb_hcd for ehci host driver
166 * @debugfs: root dentry for this controller in debugfs 166 * @debugfs: root dentry for this controller in debugfs
167 * @id_event: indicates there is an id event, and handled at ci_otg_work 167 * @id_event: indicates there is an id event, and handled at ci_otg_work
@@ -177,6 +177,7 @@ struct ci_hdrc {
177 struct ci_role_driver *roles[CI_ROLE_END]; 177 struct ci_role_driver *roles[CI_ROLE_END];
178 enum ci_role role; 178 enum ci_role role;
179 bool is_otg; 179 bool is_otg;
180 struct usb_otg otg;
180 struct otg_fsm fsm; 181 struct otg_fsm fsm;
181 struct ci_otg_fsm_timer_list *fsm_timer; 182 struct ci_otg_fsm_timer_list *fsm_timer;
182 struct work_struct work; 183 struct work_struct work;
@@ -201,7 +202,7 @@ struct ci_hdrc {
201 202
202 struct ci_hdrc_platform_data *platdata; 203 struct ci_hdrc_platform_data *platdata;
203 int vbus_active; 204 int vbus_active;
204 struct usb_phy *transceiver; 205 struct usb_phy *usb_phy;
205 struct usb_hcd *hcd; 206 struct usb_hcd *hcd;
206 struct dentry *debugfs; 207 struct dentry *debugfs;
207 bool id_event; 208 bool id_event;
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
index a7ab0f15926e..6f8b1b1045b5 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -147,7 +147,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
147 goto err_clk; 147 goto err_clk;
148 } 148 }
149 149
150 pdata.phy = data->phy; 150 pdata.usb_phy = data->phy;
151 151
152 if (imx_platform_flag->flags & CI_HDRC_IMX_IMX28_WRITE_FIX) 152 if (imx_platform_flag->flags & CI_HDRC_IMX_IMX28_WRITE_FIX)
153 pdata.flags |= CI_HDRC_IMX28_WRITE_FIX; 153 pdata.flags |= CI_HDRC_IMX28_WRITE_FIX;
diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 4935ac38fd00..3edf969ed797 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -26,15 +26,15 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
26 dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n"); 26 dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
27 writel(0, USB_AHBBURST); 27 writel(0, USB_AHBBURST);
28 writel(0, USB_AHBMODE); 28 writel(0, USB_AHBMODE);
29 usb_phy_init(ci->transceiver); 29 usb_phy_init(ci->usb_phy);
30 break; 30 break;
31 case CI_HDRC_CONTROLLER_STOPPED_EVENT: 31 case CI_HDRC_CONTROLLER_STOPPED_EVENT:
32 dev_dbg(dev, "CI_HDRC_CONTROLLER_STOPPED_EVENT received\n"); 32 dev_dbg(dev, "CI_HDRC_CONTROLLER_STOPPED_EVENT received\n");
33 /* 33 /*
34 * Put the transceiver in non-driving mode. Otherwise host 34 * Put the phy in non-driving mode. Otherwise host
35 * may not detect soft-disconnection. 35 * may not detect soft-disconnection.
36 */ 36 */
37 usb_phy_notify_disconnect(ci->transceiver, USB_SPEED_UNKNOWN); 37 usb_phy_notify_disconnect(ci->usb_phy, USB_SPEED_UNKNOWN);
38 break; 38 break;
39 default: 39 default:
40 dev_dbg(dev, "unknown ci_hdrc event\n"); 40 dev_dbg(dev, "unknown ci_hdrc event\n");
@@ -68,7 +68,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
68 if (IS_ERR(phy)) 68 if (IS_ERR(phy))
69 return PTR_ERR(phy); 69 return PTR_ERR(phy);
70 70
71 ci_hdrc_msm_platdata.phy = phy; 71 ci_hdrc_msm_platdata.usb_phy = phy;
72 72
73 plat_ci = ci_hdrc_add_device(&pdev->dev, 73 plat_ci = ci_hdrc_add_device(&pdev->dev,
74 pdev->resource, pdev->num_resources, 74 pdev->resource, pdev->num_resources,
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 9bdc6bd73432..30f89426bf05 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -312,7 +312,7 @@ static int ci_usb_phy_init(struct ci_hdrc *ci)
312 case USBPHY_INTERFACE_MODE_UTMI: 312 case USBPHY_INTERFACE_MODE_UTMI:
313 case USBPHY_INTERFACE_MODE_UTMIW: 313 case USBPHY_INTERFACE_MODE_UTMIW:
314 case USBPHY_INTERFACE_MODE_HSIC: 314 case USBPHY_INTERFACE_MODE_HSIC:
315 ret = usb_phy_init(ci->transceiver); 315 ret = usb_phy_init(ci->usb_phy);
316 if (ret) 316 if (ret)
317 return ret; 317 return ret;
318 hw_phymode_configure(ci); 318 hw_phymode_configure(ci);
@@ -320,12 +320,12 @@ static int ci_usb_phy_init(struct ci_hdrc *ci)
320 case USBPHY_INTERFACE_MODE_ULPI: 320 case USBPHY_INTERFACE_MODE_ULPI:
321 case USBPHY_INTERFACE_MODE_SERIAL: 321 case USBPHY_INTERFACE_MODE_SERIAL:
322 hw_phymode_configure(ci); 322 hw_phymode_configure(ci);
323 ret = usb_phy_init(ci->transceiver); 323 ret = usb_phy_init(ci->usb_phy);
324 if (ret) 324 if (ret)
325 return ret; 325 return ret;
326 break; 326 break;
327 default: 327 default:
328 ret = usb_phy_init(ci->transceiver); 328 ret = usb_phy_init(ci->usb_phy);
329 } 329 }
330 330
331 return ret; 331 return ret;
@@ -605,13 +605,13 @@ static int ci_hdrc_probe(struct platform_device *pdev)
605 return -ENODEV; 605 return -ENODEV;
606 } 606 }
607 607
608 if (ci->platdata->phy) 608 if (ci->platdata->usb_phy)
609 ci->transceiver = ci->platdata->phy; 609 ci->usb_phy = ci->platdata->usb_phy;
610 else 610 else
611 ci->transceiver = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); 611 ci->usb_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
612 612
613 if (IS_ERR(ci->transceiver)) { 613 if (IS_ERR(ci->usb_phy)) {
614 ret = PTR_ERR(ci->transceiver); 614 ret = PTR_ERR(ci->usb_phy);
615 /* 615 /*
616 * if -ENXIO is returned, it means PHY layer wasn't 616 * if -ENXIO is returned, it means PHY layer wasn't
617 * enabled, so it makes no sense to return -EPROBE_DEFER 617 * enabled, so it makes no sense to return -EPROBE_DEFER
@@ -728,7 +728,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
728stop: 728stop:
729 ci_role_destroy(ci); 729 ci_role_destroy(ci);
730deinit_phy: 730deinit_phy:
731 usb_phy_shutdown(ci->transceiver); 731 usb_phy_shutdown(ci->usb_phy);
732 732
733 return ret; 733 return ret;
734} 734}
@@ -741,7 +741,7 @@ static int ci_hdrc_remove(struct platform_device *pdev)
741 free_irq(ci->irq, ci); 741 free_irq(ci->irq, ci);
742 ci_role_destroy(ci); 742 ci_role_destroy(ci);
743 ci_hdrc_enter_lpm(ci, true); 743 ci_hdrc_enter_lpm(ci, true);
744 usb_phy_shutdown(ci->transceiver); 744 usb_phy_shutdown(ci->usb_phy);
745 745
746 return 0; 746 return 0;
747} 747}
diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c
index f038804d13dd..268e4236e84c 100644
--- a/drivers/usb/chipidea/debug.c
+++ b/drivers/usb/chipidea/debug.c
@@ -220,7 +220,7 @@ static int ci_otg_show(struct seq_file *s, void *unused)
220 220
221 /* ------ State ----- */ 221 /* ------ State ----- */
222 seq_printf(s, "OTG state: %s\n\n", 222 seq_printf(s, "OTG state: %s\n\n",
223 usb_otg_state_string(ci->transceiver->otg->state)); 223 usb_otg_state_string(ci->otg.state));
224 224
225 /* ------ State Machine Variables ----- */ 225 /* ------ State Machine Variables ----- */
226 seq_printf(s, "a_bus_drop: %d\n", fsm->a_bus_drop); 226 seq_printf(s, "a_bus_drop: %d\n", fsm->a_bus_drop);
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index ebde7b6ce687..789809f680aa 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -59,7 +59,7 @@ static int host_start(struct ci_hdrc *ci)
59 hcd->has_tt = 1; 59 hcd->has_tt = 1;
60 60
61 hcd->power_budget = ci->platdata->power_budget; 61 hcd->power_budget = ci->platdata->power_budget;
62 hcd->usb_phy = ci->transceiver; 62 hcd->usb_phy = ci->usb_phy;
63 hcd->tpl_support = ci->platdata->tpl_support; 63 hcd->tpl_support = ci->platdata->tpl_support;
64 64
65 ehci = hcd_to_ehci(hcd); 65 ehci = hcd_to_ehci(hcd);
@@ -86,10 +86,11 @@ static int host_start(struct ci_hdrc *ci)
86 if (ret) { 86 if (ret) {
87 goto disable_reg; 87 goto disable_reg;
88 } else { 88 } else {
89 struct usb_otg *otg = ci->transceiver->otg; 89 struct usb_otg *otg = &ci->otg;
90 90
91 ci->hcd = hcd; 91 ci->hcd = hcd;
92 if (otg) { 92
93 if (ci_otg_is_fsm_mode(ci)) {
93 otg->host = &hcd->self; 94 otg->host = &hcd->self;
94 hcd->self.otg_port = 1; 95 hcd->self.otg_port = 1;
95 } 96 }
diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c
index d8490e758a74..862d7cb01b92 100644
--- a/drivers/usb/chipidea/otg_fsm.c
+++ b/drivers/usb/chipidea/otg_fsm.c
@@ -778,20 +778,10 @@ void ci_hdrc_otg_fsm_start(struct ci_hdrc *ci)
778int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci) 778int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci)
779{ 779{
780 int retval = 0; 780 int retval = 0;
781 struct usb_otg *otg;
782 781
783 otg = devm_kzalloc(ci->dev, 782 ci->otg.usb_phy = ci->usb_phy;
784 sizeof(struct usb_otg), GFP_KERNEL); 783 ci->otg.gadget = &ci->gadget;
785 if (!otg) { 784 ci->fsm.otg = &ci->otg;
786 dev_err(ci->dev,
787 "Failed to allocate usb_otg structure for ci hdrc otg!\n");
788 return -ENOMEM;
789 }
790
791 otg->usb_phy = ci->transceiver;
792 otg->gadget = &ci->gadget;
793 ci->fsm.otg = otg;
794 ci->transceiver->otg = ci->fsm.otg;
795 ci->fsm.power_up = 1; 785 ci->fsm.power_up = 1;
796 ci->fsm.id = hw_read_otgsc(ci, OTGSC_ID) ? 1 : 0; 786 ci->fsm.id = hw_read_otgsc(ci, OTGSC_ID) ? 1 : 0;
797 ci->fsm.otg->state = OTG_STATE_UNDEFINED; 787 ci->fsm.otg->state = OTG_STATE_UNDEFINED;
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index f4397b29891f..a2d80ab3d9c4 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1519,8 +1519,8 @@ static int ci_udc_vbus_draw(struct usb_gadget *_gadget, unsigned ma)
1519{ 1519{
1520 struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); 1520 struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget);
1521 1521
1522 if (ci->transceiver) 1522 if (ci->usb_phy)
1523 return usb_phy_set_power(ci->transceiver, ma); 1523 return usb_phy_set_power(ci->usb_phy, ma);
1524 return -ENOTSUPP; 1524 return -ENOTSUPP;
1525} 1525}
1526 1526
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index b84fb141e122..6a2a2fd990ab 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2648,7 +2648,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
2648 } 2648 }
2649 } 2649 }
2650 2650
2651 if (IS_ENABLED(CONFIG_GENERIC_PHY)) { 2651 if (IS_ENABLED(CONFIG_GENERIC_PHY) && !hcd->phy) {
2652 struct phy *phy = phy_get(hcd->self.controller, "usb"); 2652 struct phy *phy = phy_get(hcd->self.controller, "usb");
2653 2653
2654 if (IS_ERR(phy)) { 2654 if (IS_ERR(phy)) {
@@ -2668,6 +2668,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
2668 goto err_phy; 2668 goto err_phy;
2669 } 2669 }
2670 hcd->phy = phy; 2670 hcd->phy = phy;
2671 hcd->remove_phy = 1;
2671 } 2672 }
2672 } 2673 }
2673 2674
@@ -2814,7 +2815,7 @@ err_allocate_root_hub:
2814err_register_bus: 2815err_register_bus:
2815 hcd_buffer_destroy(hcd); 2816 hcd_buffer_destroy(hcd);
2816err_create_buf: 2817err_create_buf:
2817 if (IS_ENABLED(CONFIG_GENERIC_PHY) && hcd->phy) { 2818 if (IS_ENABLED(CONFIG_GENERIC_PHY) && hcd->remove_phy && hcd->phy) {
2818 phy_power_off(hcd->phy); 2819 phy_power_off(hcd->phy);
2819 phy_exit(hcd->phy); 2820 phy_exit(hcd->phy);
2820 phy_put(hcd->phy); 2821 phy_put(hcd->phy);
@@ -2898,7 +2899,7 @@ void usb_remove_hcd(struct usb_hcd *hcd)
2898 usb_deregister_bus(&hcd->self); 2899 usb_deregister_bus(&hcd->self);
2899 hcd_buffer_destroy(hcd); 2900 hcd_buffer_destroy(hcd);
2900 2901
2901 if (IS_ENABLED(CONFIG_GENERIC_PHY) && hcd->phy) { 2902 if (IS_ENABLED(CONFIG_GENERIC_PHY) && hcd->remove_phy && hcd->phy) {
2902 phy_power_off(hcd->phy); 2903 phy_power_off(hcd->phy);
2903 phy_exit(hcd->phy); 2904 phy_exit(hcd->phy);
2904 phy_put(hcd->phy); 2905 phy_put(hcd->phy);