summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-09-30 18:23:39 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-09-30 18:23:39 -0700
commite59d6b749b6ceb5bda156d68243fb9b7bb85ff19 (patch)
treee4fe24e213885dc948d3860f1ca4df41eb280dec /drivers/usb
parentabf71ed41976d43bd09090f9edf8bca38301c581 (diff)
parent85cc38fca20f3c5b93314aa992ed3863d437bb39 (diff)
Merge "usb: pd: Add support to set the maximum speed via extcon"
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/dwc3/core.c9
-rw-r--r--drivers/usb/dwc3/dwc3-msm.c20
-rw-r--r--drivers/usb/pd/policy_engine.c19
3 files changed, 43 insertions, 5 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 9fb05bbf3e74..07867ead2413 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -123,6 +123,9 @@ static int dwc3_init_usb_phys(struct dwc3 *dwc)
return ret;
}
+ if (dwc->maximum_speed == USB_SPEED_HIGH)
+ goto generic_phy_init;
+
ret = usb_phy_init(dwc->usb3_phy);
if (ret == -EBUSY) {
/*
@@ -135,6 +138,8 @@ static int dwc3_init_usb_phys(struct dwc3 *dwc)
__func__, ret);
return ret;
}
+
+generic_phy_init:
ret = phy_init(dwc->usb2_generic_phy);
if (ret < 0)
return ret;
@@ -159,7 +164,9 @@ static int dwc3_core_reset(struct dwc3 *dwc)
/* Reset PHYs */
usb_phy_reset(dwc->usb2_phy);
- usb_phy_reset(dwc->usb3_phy);
+
+ if (dwc->maximum_speed == USB_SPEED_SUPER)
+ usb_phy_reset(dwc->usb3_phy);
/* Initialize PHYs */
ret = dwc3_init_usb_phys(dwc);
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 7ce9ff925117..4a4f1083198c 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -1923,7 +1923,7 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc)
usb_phy_set_suspend(mdwc->hs_phy, 1);
/* Suspend SS PHY */
- if (can_suspend_ssphy) {
+ if (dwc->maximum_speed == USB_SPEED_SUPER && can_suspend_ssphy) {
/* indicate phy about SS mode */
if (dwc3_msm_is_superspeed(mdwc))
mdwc->ss_phy->flags |= DEVICE_IN_SS_MODE;
@@ -2068,7 +2068,8 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc)
clk_prepare_enable(mdwc->bus_aggr_clk);
/* Resume SS PHY */
- if (mdwc->lpm_flags & MDWC3_SS_PHY_SUSPEND) {
+ if (dwc->maximum_speed == USB_SPEED_SUPER &&
+ mdwc->lpm_flags & MDWC3_SS_PHY_SUSPEND) {
mdwc->ss_phy->flags &= ~(PHY_LANE_A | PHY_LANE_B);
if (mdwc->typec_orientation == ORIENTATION_CC1)
mdwc->ss_phy->flags |= PHY_LANE_A;
@@ -2422,9 +2423,11 @@ static int dwc3_msm_id_notifier(struct notifier_block *nb,
unsigned long event, void *ptr)
{
struct dwc3_msm *mdwc = container_of(nb, struct dwc3_msm, id_nb);
+ struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);
struct extcon_dev *edev = ptr;
enum dwc3_id_state id;
int cc_state;
+ int speed;
if (!edev) {
dev_err(mdwc->dev, "%s: edev null\n", __func__);
@@ -2444,6 +2447,9 @@ static int dwc3_msm_id_notifier(struct notifier_block *nb,
dbg_event(0xFF, "cc_state", mdwc->typec_orientation);
+ speed = extcon_get_cable_state_(edev, EXTCON_USB_SPEED);
+ dwc->maximum_speed = (speed == 0) ? USB_SPEED_HIGH : USB_SPEED_SUPER;
+
if (mdwc->id_state != id) {
mdwc->id_state = id;
dbg_event(0xFF, "id_state", mdwc->id_state);
@@ -2461,6 +2467,7 @@ static int dwc3_msm_vbus_notifier(struct notifier_block *nb,
struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);
struct extcon_dev *edev = ptr;
int cc_state;
+ int speed;
if (!edev) {
dev_err(mdwc->dev, "%s: edev null\n", __func__);
@@ -2481,6 +2488,9 @@ static int dwc3_msm_vbus_notifier(struct notifier_block *nb,
dbg_event(0xFF, "cc_state", mdwc->typec_orientation);
+ speed = extcon_get_cable_state_(edev, EXTCON_USB_SPEED);
+ dwc->maximum_speed = (speed == 0) ? USB_SPEED_HIGH : USB_SPEED_SUPER;
+
mdwc->vbus_active = event;
if (dwc->is_drd && !mdwc->in_restart) {
dbg_event(0xFF, "Q RW (vbus)", mdwc->vbus_active);
@@ -3026,11 +3036,13 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on)
if (on) {
dev_dbg(mdwc->dev, "%s: turn on host\n", __func__);
+ mdwc->hs_phy->flags |= PHY_HOST_MODE;
+ if (dwc->maximum_speed == USB_SPEED_SUPER)
+ mdwc->ss_phy->flags |= PHY_HOST_MODE;
+
pm_runtime_get_sync(mdwc->dev);
dbg_event(0xFF, "StrtHost gync",
atomic_read(&mdwc->dev->power.usage_count));
- mdwc->hs_phy->flags |= PHY_HOST_MODE;
- mdwc->ss_phy->flags |= PHY_HOST_MODE;
usb_phy_notify_connect(mdwc->hs_phy, USB_SPEED_HIGH);
if (!IS_ERR(mdwc->vbus_reg))
ret = regulator_enable(mdwc->vbus_reg);
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c
index 82ae0b4fe135..0114323d688b 100644
--- a/drivers/usb/pd/policy_engine.c
+++ b/drivers/usb/pd/policy_engine.c
@@ -242,6 +242,12 @@ static void *usbpd_ipc_log;
static int min_sink_current = 900;
module_param(min_sink_current, int, S_IRUSR | S_IWUSR);
+static bool ss_host;
+module_param(ss_host, bool, S_IRUSR | S_IWUSR);
+
+static bool ss_dev = true;
+module_param(ss_dev, bool, S_IRUSR | S_IWUSR);
+
static const u32 default_src_caps[] = { 0x36019096 }; /* VSafe5V @ 1.5A */
static const u32 default_snk_caps[] = { 0x2601905A, /* 5V @ 900mA */
@@ -318,6 +324,7 @@ static const unsigned int usbpd_extcon_cable[] = {
EXTCON_USB,
EXTCON_USB_HOST,
EXTCON_USB_CC,
+ EXTCON_USB_SPEED,
EXTCON_NONE,
};
@@ -685,6 +692,10 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
SVDM_CMD_TYPE_INITIATOR, 0,
NULL, 0);
+ extcon_set_cable_state_(pd->extcon, EXTCON_USB_CC,
+ is_cable_flipped(pd));
+ extcon_set_cable_state_(pd->extcon, EXTCON_USB_SPEED,
+ ss_host);
extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 1);
}
@@ -755,6 +766,8 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
EXTCON_USB_CC,
is_cable_flipped(pd));
extcon_set_cable_state_(pd->extcon,
+ EXTCON_USB_SPEED, ss_dev);
+ extcon_set_cable_state_(pd->extcon,
EXTCON_USB, 1);
}
}
@@ -852,6 +865,8 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
pd->current_dr = DR_UFP;
extcon_set_cable_state_(pd->extcon, EXTCON_USB_CC,
is_cable_flipped(pd));
+ extcon_set_cable_state_(pd->extcon, EXTCON_USB_SPEED,
+ ss_dev);
extcon_set_cable_state_(pd->extcon, EXTCON_USB, 1);
pd_phy_update_roles(pd->current_dr, pd->current_pr);
}
@@ -1194,12 +1209,14 @@ static void dr_swap(struct usbpd *pd)
extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 0);
extcon_set_cable_state_(pd->extcon, EXTCON_USB_CC,
is_cable_flipped(pd));
+ extcon_set_cable_state_(pd->extcon, EXTCON_USB_SPEED, ss_dev);
extcon_set_cable_state_(pd->extcon, EXTCON_USB, 1);
pd->current_dr = DR_UFP;
} else if (pd->current_dr == DR_UFP) {
extcon_set_cable_state_(pd->extcon, EXTCON_USB, 0);
extcon_set_cable_state_(pd->extcon, EXTCON_USB_CC,
is_cable_flipped(pd));
+ extcon_set_cable_state_(pd->extcon, EXTCON_USB_SPEED, ss_host);
extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 1);
pd->current_dr = DR_DFP;
@@ -1345,6 +1362,8 @@ static void usbpd_sm(struct work_struct *w)
extcon_set_cable_state_(pd->extcon,
EXTCON_USB_CC, is_cable_flipped(pd));
extcon_set_cable_state_(pd->extcon,
+ EXTCON_USB_SPEED, ss_host);
+ extcon_set_cable_state_(pd->extcon,
EXTCON_USB_HOST, 1);
} else if (pd->caps_count >= PD_CAPS_COUNT) {
usbpd_dbg(&pd->dev, "Src CapsCounter exceeded, disabling PD\n");