summaryrefslogtreecommitdiffstats
path: root/drivers/platform/chrome/cros_ec_typec.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2021-02-22 09:36:23 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2021-02-22 09:36:23 -0800
commitb996c10e0f5b2cfd5b2cbf048cce83982bfe662d (patch)
treeab8fd03ea3b223b80800d912867007d88c3552bc /drivers/platform/chrome/cros_ec_typec.c
parentf158bbee9403b7bd2ad22f0c03b7e9762c20ad18 (diff)
parenta59e12218c4f5498d5669a0ee0c725101ca89d52 (diff)
downloadlinux-stable-b996c10e0f5b2cfd5b2cbf048cce83982bfe662d.tar.gz
linux-stable-b996c10e0f5b2cfd5b2cbf048cce83982bfe662d.tar.bz2
linux-stable-b996c10e0f5b2cfd5b2cbf048cce83982bfe662d.zip
Merge tag 'tag-chrome-platform-for-v5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux
Pull chrome platform updates from Benson Leung: "Lots of changes to the cros_ec_typec driver for 5.12. A portion of this this set of cros_ec_typec driver's changes was merged through GregKH's USB tree in order to satisfy cros_ec_typec driver and typec connector class subsystem dependencies of subsequent changes. Summary: cros_ec_typec: - Registration of cable plug information - Support for SOP' plug registration and altmodes - Support for reporting number of altmodes supported by partners and plugs - Send mux configuration ack to EC via a new host command - Support mux control with no port partner present - Decouple cable removal from partner removal cros_ec misc: - Fix some event masking in cros_ec_proto. - Gwendal reworked cros_ec's top and bottom half for consistency in ishtp and rpmsg - Constify static attribute_group structs" * tag 'tag-chrome-platform-for-v5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux: platform/chrome: cros_ec_typec: Flush pending work platform/chrome: cros_ec_types: Support disconnect events without partners platform/chrome: cros_ec_typec: Skip port partner check in configure_mux() platform/chrome: cros_ec_typec: Decouple partner removal platform/chrome: cros_ec: Call interrupt bottom half at probe time platform/chrome: cros_ec: Call interrupt bottom half in ISH or RPMSG mode platform/chrome: cros_ec_sysfs: Add cold-ap-off to sysfs reboot. platform/chrome: cros_ec_commands: Add host command to keep AP off after EC reset. platform/chrome: Constify static attribute_group structs platform/chrome: cros_ec_proto: Add LID and BATTERY to default mask platform/chrome: cros_ec_proto: Use EC_HOST_EVENT_MASK not BIT
Diffstat (limited to 'drivers/platform/chrome/cros_ec_typec.c')
-rw-r--r--drivers/platform/chrome/cros_ec_typec.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c
index 0abd21044882..0811562deecc 100644
--- a/drivers/platform/chrome/cros_ec_typec.c
+++ b/drivers/platform/chrome/cros_ec_typec.c
@@ -203,20 +203,26 @@ static void cros_typec_unregister_altmodes(struct cros_typec_data *typec, int po
}
}
-static void cros_typec_remove_partner(struct cros_typec_data *typec,
- int port_num)
+static int cros_typec_usb_disconnect_state(struct cros_typec_port *port)
{
- struct cros_typec_port *port = typec->ports[port_num];
-
- cros_typec_unregister_altmodes(typec, port_num, true);
-
port->state.alt = NULL;
port->state.mode = TYPEC_STATE_USB;
port->state.data = NULL;
usb_role_switch_set_role(port->role_sw, USB_ROLE_NONE);
typec_switch_set(port->ori_sw, TYPEC_ORIENTATION_NONE);
- typec_mux_set(port->mux, &port->state);
+
+ return typec_mux_set(port->mux, &port->state);
+}
+
+static void cros_typec_remove_partner(struct cros_typec_data *typec,
+ int port_num)
+{
+ struct cros_typec_port *port = typec->ports[port_num];
+
+ cros_typec_unregister_altmodes(typec, port_num, true);
+
+ cros_typec_usb_disconnect_state(port);
typec_unregister_partner(port->partner);
port->partner = NULL;
@@ -536,8 +542,10 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
enum typec_orientation orientation;
int ret;
- if (!port->partner)
- return 0;
+ if (mux_flags == USB_PD_MUX_NONE) {
+ ret = cros_typec_usb_disconnect_state(port);
+ goto mux_ack;
+ }
if (mux_flags & USB_PD_MUX_POLARITY_INVERTED)
orientation = TYPEC_ORIENTATION_REVERSE;
@@ -572,6 +580,7 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
mux_flags);
}
+mux_ack:
if (!typec->needs_mux_ack)
return ret;
@@ -638,9 +647,8 @@ static void cros_typec_set_port_params_v1(struct cros_typec_data *typec,
"Failed to register partner on port: %d\n",
port_num);
} else {
- if (!typec->ports[port_num]->partner)
- return;
- cros_typec_remove_partner(typec, port_num);
+ if (typec->ports[port_num]->partner)
+ cros_typec_remove_partner(typec, port_num);
if (typec->ports[port_num]->cable)
cros_typec_remove_cable(typec, port_num);
@@ -1060,6 +1068,7 @@ static int cros_ec_typec_event(struct notifier_block *nb,
{
struct cros_typec_data *typec = container_of(nb, struct cros_typec_data, nb);
+ flush_work(&typec->port_work);
schedule_work(&typec->port_work);
return NOTIFY_OK;