diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-28 20:30:00 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-28 20:30:00 -0800 |
commit | c0ea81b4d37837409d0dfd2036098a7babb312ed (patch) | |
tree | 5d20f117ff03ec3d665487fb7fb045910d148ab1 /drivers/usb/typec | |
parent | 4d6ad6fba6b7af06143c67964f4095c74c9ce87c (diff) | |
parent | 4b2c01ad902ec02fa962b233decd2f14be3714ba (diff) | |
download | linux-stable-c0ea81b4d37837409d0dfd2036098a7babb312ed.tar.gz linux-stable-c0ea81b4d37837409d0dfd2036098a7babb312ed.tar.bz2 linux-stable-c0ea81b4d37837409d0dfd2036098a7babb312ed.zip |
Merge tag 'usb-4.21-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB/PHY updates from Greg KH:
"Here is the big set of USB and PHY driver patches for 4.21-rc1.
All of the usual bits are in here:
- loads of USB gadget driver updates and additions
- new device ids
- phy driver updates
- xhci reworks and new features
- typec updates
Full details are in the shortlog.
All of these have been in linux-next for a long time with no reported
issues"
* tag 'usb-4.21-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (142 commits)
USB: serial: option: add Fibocom NL678 series
cdc-acm: fix abnormal DATA RX issue for Mediatek Preloader.
usb: r8a66597: Fix a possible concurrency use-after-free bug in r8a66597_endpoint_disable()
usb: typec: tcpm: Extend the matching rules on PPS APDO selection
usb: typec: Improve Alt Mode documentation
usb: musb: dsps: fix runtime pm for peripheral mode
usb: musb: dsps: fix otg state machine
USB: serial: pl2303: add ids for Hewlett-Packard HP POS pole displays
usb: renesas_usbhs: add support for RZ/G2E
usb: ehci-omap: Fix deferred probe for phy handling
usb: roles: Add a description for the class to Kconfig
usb: renesas_usbhs: mark PM functions as __maybe_unused
usb: core: Remove unnecessary memset()
usb: host: isp1362-hcd: convert to DEFINE_SHOW_ATTRIBUTE
phy: qcom-qmp: Expose provided clocks to DT
dt-bindings: phy-qcom-qmp: Move #clock-cells to child
phy: qcom-qmp: Utilize fully-specified DT registers
dt-bindings: phy-qcom-qmp: Fix register underspecification
phy: ti: fix semicolon.cocci warnings
phy: dphy: Add configuration helpers
...
Diffstat (limited to 'drivers/usb/typec')
-rw-r--r-- | drivers/usb/typec/tcpm/fusb302.c | 2 | ||||
-rw-r--r-- | drivers/usb/typec/tcpm/tcpm.c | 56 |
2 files changed, 39 insertions, 19 deletions
diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c index 43b64d9309d0..e9344997329c 100644 --- a/drivers/usb/typec/tcpm/fusb302.c +++ b/drivers/usb/typec/tcpm/fusb302.c @@ -1765,7 +1765,7 @@ static int fusb302_probe(struct i2c_client *client, * to be set by the platform code which also registers the i2c client * for the fusb302. */ - if (device_property_read_string(dev, "fcs,extcon-name", &name) == 0) { + if (device_property_read_string(dev, "linux,extcon-name", &name) == 0) { chip->extcon = extcon_get_extcon_dev(name); if (!chip->extcon) return -EPROBE_DEFER; diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index dbbd71f754d0..4bc29b586698 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -317,6 +317,9 @@ struct tcpm_port { /* Deadline in jiffies to exit src_try_wait state */ unsigned long max_wait; + /* port belongs to a self powered device */ + bool self_powered; + #ifdef CONFIG_DEBUG_FS struct dentry *dentry; struct mutex logbuffer_lock; /* log buffer access lock */ @@ -2210,7 +2213,8 @@ static unsigned int tcpm_pd_select_pps_apdo(struct tcpm_port *port) unsigned int i, j, max_mw = 0, max_mv = 0; unsigned int min_src_mv, max_src_mv, src_ma, src_mw; unsigned int min_snk_mv, max_snk_mv; - u32 pdo; + unsigned int max_op_mv; + u32 pdo, src, snk; unsigned int src_pdo = 0, snk_pdo = 0; /* @@ -2260,16 +2264,18 @@ static unsigned int tcpm_pd_select_pps_apdo(struct tcpm_port *port) continue; } - if (max_src_mv <= max_snk_mv && - min_src_mv >= min_snk_mv) { + if (min_src_mv <= max_snk_mv && + max_src_mv >= min_snk_mv) { + max_op_mv = min(max_src_mv, max_snk_mv); + src_mw = (max_op_mv * src_ma) / 1000; /* Prefer higher voltages if available */ if ((src_mw == max_mw && - min_src_mv > max_mv) || + max_op_mv > max_mv) || src_mw > max_mw) { src_pdo = i; snk_pdo = j; max_mw = src_mw; - max_mv = max_src_mv; + max_mv = max_op_mv; } } } @@ -2282,16 +2288,18 @@ static unsigned int tcpm_pd_select_pps_apdo(struct tcpm_port *port) } if (src_pdo) { - pdo = port->source_caps[src_pdo]; - - port->pps_data.min_volt = pdo_pps_apdo_min_voltage(pdo); - port->pps_data.max_volt = pdo_pps_apdo_max_voltage(pdo); - port->pps_data.max_curr = - min_pps_apdo_current(pdo, port->snk_pdo[snk_pdo]); - port->pps_data.out_volt = - min(pdo_pps_apdo_max_voltage(pdo), port->pps_data.out_volt); - port->pps_data.op_curr = - min(port->pps_data.max_curr, port->pps_data.op_curr); + src = port->source_caps[src_pdo]; + snk = port->snk_pdo[snk_pdo]; + + port->pps_data.min_volt = max(pdo_pps_apdo_min_voltage(src), + pdo_pps_apdo_min_voltage(snk)); + port->pps_data.max_volt = min(pdo_pps_apdo_max_voltage(src), + pdo_pps_apdo_max_voltage(snk)); + port->pps_data.max_curr = min_pps_apdo_current(src, snk); + port->pps_data.out_volt = min(port->pps_data.max_volt, + port->pps_data.out_volt); + port->pps_data.op_curr = min(port->pps_data.max_curr, + port->pps_data.op_curr); } return src_pdo; @@ -3254,7 +3262,8 @@ static void run_state_machine(struct tcpm_port *port) case SRC_HARD_RESET_VBUS_OFF: tcpm_set_vconn(port, true); tcpm_set_vbus(port, false); - tcpm_set_roles(port, false, TYPEC_SOURCE, TYPEC_HOST); + tcpm_set_roles(port, port->self_powered, TYPEC_SOURCE, + TYPEC_HOST); tcpm_set_state(port, SRC_HARD_RESET_VBUS_ON, PD_T_SRC_RECOVER); break; case SRC_HARD_RESET_VBUS_ON: @@ -3266,8 +3275,10 @@ static void run_state_machine(struct tcpm_port *port) case SNK_HARD_RESET_SINK_OFF: memset(&port->pps_data, 0, sizeof(port->pps_data)); tcpm_set_vconn(port, false); - tcpm_set_charge(port, false); - tcpm_set_roles(port, false, TYPEC_SINK, TYPEC_DEVICE); + if (port->pd_capable) + tcpm_set_charge(port, false); + tcpm_set_roles(port, port->self_powered, TYPEC_SINK, + TYPEC_DEVICE); /* * VBUS may or may not toggle, depending on the adapter. * If it doesn't toggle, transition to SNK_HARD_RESET_SINK_ON @@ -3297,6 +3308,12 @@ static void run_state_machine(struct tcpm_port *port) * Similar, dual-mode ports in source mode should transition * to PE_SNK_Transition_to_default. */ + if (port->pd_capable) { + tcpm_set_current_limit(port, + tcpm_get_current_limit(port), + 5000); + tcpm_set_charge(port, true); + } tcpm_set_attached_state(port, true); tcpm_set_state(port, SNK_STARTUP, 0); break; @@ -4412,6 +4429,8 @@ sink: return -EINVAL; port->operating_snk_mw = mw / 1000; + port->self_powered = fwnode_property_read_bool(fwnode, "self-powered"); + return 0; } @@ -4720,6 +4739,7 @@ static int tcpm_copy_caps(struct tcpm_port *port, port->typec_caps.prefer_role = tcfg->default_role; port->typec_caps.type = tcfg->type; port->typec_caps.data = tcfg->data; + port->self_powered = port->tcpc->config->self_powered; return 0; } |