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>
This commit is contained in:
parent
9745ceebc4
commit
36f9159ba9
|
@ -133,6 +133,7 @@ struct sun4i_usb_phy_data {
|
||||||
struct power_supply *vbus_power_supply;
|
struct power_supply *vbus_power_supply;
|
||||||
struct notifier_block vbus_power_nb;
|
struct notifier_block vbus_power_nb;
|
||||||
bool vbus_power_nb_registered;
|
bool vbus_power_nb_registered;
|
||||||
|
bool force_session_end;
|
||||||
int id_det_irq;
|
int id_det_irq;
|
||||||
int vbus_det_irq;
|
int vbus_det_irq;
|
||||||
int id_det;
|
int id_det;
|
||||||
|
@ -445,7 +446,7 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
|
||||||
struct sun4i_usb_phy_data *data =
|
struct sun4i_usb_phy_data *data =
|
||||||
container_of(work, struct sun4i_usb_phy_data, detect.work);
|
container_of(work, struct sun4i_usb_phy_data, detect.work);
|
||||||
struct phy *phy0 = data->phys[0].phy;
|
struct phy *phy0 = data->phys[0].phy;
|
||||||
bool id_notify = false, vbus_notify = false;
|
bool force_session_end, id_notify = false, vbus_notify = false;
|
||||||
int id_det, vbus_det;
|
int id_det, vbus_det;
|
||||||
|
|
||||||
if (phy0 == NULL)
|
if (phy0 == NULL)
|
||||||
|
@ -461,14 +462,17 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
force_session_end = data->force_session_end;
|
||||||
|
data->force_session_end = false;
|
||||||
|
|
||||||
if (id_det != data->id_det) {
|
if (id_det != data->id_det) {
|
||||||
/*
|
/* id-change, force session end if we've no vbus detection */
|
||||||
* When a host cable (id == 0) gets plugged in on systems
|
|
||||||
* without vbus detection report vbus low for long enough for
|
|
||||||
* the musb-ip to end the current device session.
|
|
||||||
*/
|
|
||||||
if (data->dr_mode == USB_DR_MODE_OTG &&
|
if (data->dr_mode == USB_DR_MODE_OTG &&
|
||||||
!sun4i_usb_phy0_have_vbus_det(data) && id_det == 0) {
|
!sun4i_usb_phy0_have_vbus_det(data))
|
||||||
|
force_session_end = true;
|
||||||
|
|
||||||
|
/* When entering host mode (id = 0) force end the session now */
|
||||||
|
if (force_session_end && id_det == 0) {
|
||||||
sun4i_usb_phy0_set_vbus_detect(phy0, 0);
|
sun4i_usb_phy0_set_vbus_detect(phy0, 0);
|
||||||
msleep(200);
|
msleep(200);
|
||||||
sun4i_usb_phy0_set_vbus_detect(phy0, 1);
|
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)
|
||||||
if (id_notify) {
|
if (id_notify) {
|
||||||
extcon_set_cable_state_(data->extcon, EXTCON_USB_HOST,
|
extcon_set_cable_state_(data->extcon, EXTCON_USB_HOST,
|
||||||
!id_det);
|
!id_det);
|
||||||
/*
|
/* When leaving host mode force end the session here */
|
||||||
* When a host cable gets unplugged (id == 1) on systems
|
if (force_session_end && id_det == 1) {
|
||||||
* without vbus detection report vbus low for long enough to
|
|
||||||
* the musb-ip to end the current host session.
|
|
||||||
*/
|
|
||||||
if (data->dr_mode == USB_DR_MODE_OTG &&
|
|
||||||
!sun4i_usb_phy0_have_vbus_det(data) && id_det == 1) {
|
|
||||||
mutex_lock(&phy0->mutex);
|
mutex_lock(&phy0->mutex);
|
||||||
sun4i_usb_phy0_set_vbus_detect(phy0, 0);
|
sun4i_usb_phy0_set_vbus_detect(phy0, 0);
|
||||||
msleep(1000);
|
msleep(1000);
|
||||||
|
|
Loading…
Reference in New Issue