aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/phy
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2016-09-07 16:20:38 -0400
committerKishon Vijay Abraham I <kishon@ti.com>2016-09-10 07:45:19 -0400
commit36f9159ba99076ab643794a83735197b4042b16f (patch)
tree8e6cec1166753ff1ab240ff06fc53aaebb703b73 /drivers/phy
parent9745ceebc4e1e593ddba1b1a104a4a99f2b9a556 (diff)
phy-sun4i-usb: Refactor forced session ending
The phy-sun4i-usb code supports forced ending a session on systems which lack Vbus detection, to allow switching between host and peripheral mode on such systems. Role switching via the musb driver "mode" sysfs attribute requires force ending the session too. This commit refactors the code to allow other parts of the phy-sun4i-usb code to request a forced session end. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Diffstat (limited to 'drivers/phy')
-rw-r--r--drivers/phy/phy-sun4i-usb.c27
1 files changed, 13 insertions, 14 deletions
diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
index 1cb84a8a4253..02cb65ef52d0 100644
--- a/drivers/phy/phy-sun4i-usb.c
+++ b/drivers/phy/phy-sun4i-usb.c
@@ -133,6 +133,7 @@ struct sun4i_usb_phy_data {
133 struct power_supply *vbus_power_supply; 133 struct power_supply *vbus_power_supply;
134 struct notifier_block vbus_power_nb; 134 struct notifier_block vbus_power_nb;
135 bool vbus_power_nb_registered; 135 bool vbus_power_nb_registered;
136 bool force_session_end;
136 int id_det_irq; 137 int id_det_irq;
137 int vbus_det_irq; 138 int vbus_det_irq;
138 int id_det; 139 int id_det;
@@ -445,7 +446,7 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
445 struct sun4i_usb_phy_data *data = 446 struct sun4i_usb_phy_data *data =
446 container_of(work, struct sun4i_usb_phy_data, detect.work); 447 container_of(work, struct sun4i_usb_phy_data, detect.work);
447 struct phy *phy0 = data->phys[0].phy; 448 struct phy *phy0 = data->phys[0].phy;
448 bool id_notify = false, vbus_notify = false; 449 bool force_session_end, id_notify = false, vbus_notify = false;
449 int id_det, vbus_det; 450 int id_det, vbus_det;
450 451
451 if (phy0 == NULL) 452 if (phy0 == NULL)
@@ -461,14 +462,17 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
461 return; 462 return;
462 } 463 }
463 464
465 force_session_end = data->force_session_end;
466 data->force_session_end = false;
467
464 if (id_det != data->id_det) { 468 if (id_det != data->id_det) {
465 /* 469 /* id-change, force session end if we've no vbus detection */
466 * When a host cable (id == 0) gets plugged in on systems
467 * without vbus detection report vbus low for long enough for
468 * the musb-ip to end the current device session.
469 */
470 if (data->dr_mode == USB_DR_MODE_OTG && 470 if (data->dr_mode == USB_DR_MODE_OTG &&
471 !sun4i_usb_phy0_have_vbus_det(data) && id_det == 0) { 471 !sun4i_usb_phy0_have_vbus_det(data))
472 force_session_end = true;
473
474 /* When entering host mode (id = 0) force end the session now */
475 if (force_session_end && id_det == 0) {
472 sun4i_usb_phy0_set_vbus_detect(phy0, 0); 476 sun4i_usb_phy0_set_vbus_detect(phy0, 0);
473 msleep(200); 477 msleep(200);
474 sun4i_usb_phy0_set_vbus_detect(phy0, 1); 478 sun4i_usb_phy0_set_vbus_detect(phy0, 1);
@@ -489,13 +493,8 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
489 if (id_notify) { 493 if (id_notify) {
490 extcon_set_cable_state_(data->extcon, EXTCON_USB_HOST, 494 extcon_set_cable_state_(data->extcon, EXTCON_USB_HOST,
491 !id_det); 495 !id_det);
492 /* 496 /* When leaving host mode force end the session here */
493 * When a host cable gets unplugged (id == 1) on systems 497 if (force_session_end && id_det == 1) {
494 * without vbus detection report vbus low for long enough to
495 * the musb-ip to end the current host session.
496 */
497 if (data->dr_mode == USB_DR_MODE_OTG &&
498 !sun4i_usb_phy0_have_vbus_det(data) && id_det == 1) {
499 mutex_lock(&phy0->mutex); 498 mutex_lock(&phy0->mutex);
500 sun4i_usb_phy0_set_vbus_detect(phy0, 0); 499 sun4i_usb_phy0_set_vbus_detect(phy0, 0);
501 msleep(1000); 500 msleep(1000);