From 9eae9656e2c19d2625a7764f86298a9c188cf62a Mon Sep 17 00:00:00 2001 From: Wu Liang feng Date: Sat, 10 Sep 2016 18:32:40 +0800 Subject: [PATCH] phy: rockchip-inno-usb2: support host only mode for otg port With this patch, we can support host only mode for otg port (e.g. rk3399 Type-C1 USB). We use of_usb_get_dr_mode_by_phy() to get the string from property 'dr_mode' of the controller device node. Right now, we only support host only mode for phys which do not have phy-cells, and don't support #phy-cells >= 1. Change-Id: Ic15b4afdfd954d91e38dbce3c996176bf2d6f101 Signed-off-by: Wu Liang feng --- drivers/phy/phy-rockchip-inno-usb2.c | 40 ++++++++++++++++------------ 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/drivers/phy/phy-rockchip-inno-usb2.c b/drivers/phy/phy-rockchip-inno-usb2.c index 4b07f2092fe2..011748235b2e 100644 --- a/drivers/phy/phy-rockchip-inno-usb2.c +++ b/drivers/phy/phy-rockchip-inno-usb2.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -185,6 +186,7 @@ struct rockchip_usb2phy_cfg { * @wakelock: wake lock struct to prevent system suspend * when USB is active. * @state: define OTG enumeration states before device reset. + * @mode: the dr_mode of the controller. */ struct rockchip_usb2phy_port { struct phy *phy; @@ -202,6 +204,7 @@ struct rockchip_usb2phy_port { struct notifier_block event_nb; struct wake_lock wakelock; enum usb_otg_state state; + enum usb_dr_mode mode; }; /** @@ -411,21 +414,18 @@ static int rockchip_usb2phy_init(struct phy *phy) mutex_lock(&rport->mutex); - if (rport->port_id == USB2PHY_PORT_OTG) { + if (rport->port_id == USB2PHY_PORT_OTG && + rport->mode != USB_DR_MODE_HOST) { /* clear bvalid status and enable bvalid detect irq */ ret = property_enable(rphy, &rport->port_cfg->bvalid_det_clr, true); - if (ret) { - mutex_unlock(&rport->mutex); - return ret; - } + if (ret) + goto err; ret = property_enable(rphy, &rport->port_cfg->bvalid_det_en, true); - if (ret) { - mutex_unlock(&rport->mutex); - return ret; - } + if (ret) + goto err; mutex_unlock(&rport->mutex); schedule_delayed_work(&rport->otg_sm_work, OTG_SCHEDULE_DELAY); @@ -433,22 +433,22 @@ static int rockchip_usb2phy_init(struct phy *phy) } else if (rport->port_id == USB2PHY_PORT_HOST) { /* clear linestate and enable linestate detect irq */ ret = property_enable(rphy, &rport->port_cfg->ls_det_clr, true); - if (ret) { - mutex_unlock(&rport->mutex); - return ret; - } + if (ret) + goto err; ret = property_enable(rphy, &rport->port_cfg->ls_det_en, true); - if (ret) { - mutex_unlock(&rport->mutex); - return ret; - } + if (ret) + goto err; mutex_unlock(&rport->mutex); schedule_delayed_work(&rport->sm_work, SCHEDULE_DELAY); } return 0; + +err: + mutex_unlock(&rport->mutex); + return ret; } static int rockchip_usb2phy_power_on(struct phy *phy) @@ -987,6 +987,7 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy, rport->port_id = USB2PHY_PORT_OTG; rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG]; rport->state = OTG_STATE_UNDEFINED; + /* * set suspended flag to true, but actually don't * put phy in suspend mode, it aims to enable usb @@ -997,6 +998,11 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy, rport->vbus_attached = false; mutex_init(&rport->mutex); + + rport->mode = of_usb_get_dr_mode_by_phy(child_np, -1); + if (rport->mode == USB_DR_MODE_HOST) + return 0; + wake_lock_init(&rport->wakelock, WAKE_LOCK_SUSPEND, "rockchip_otg"); INIT_DELAYED_WORK(&rport->chg_work, rockchip_chg_detect_work); INIT_DELAYED_WORK(&rport->otg_sm_work, rockchip_usb2phy_otg_sm_work); -- 2.34.1