usb: typec: Factor out non-PD fwnode properties
authorSamuel Holland <samuel@sholland.org>
Mon, 14 Feb 2022 05:01:16 +0000 (23:01 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 31 Dec 2022 12:14:28 +0000 (13:14 +0100)
[ Upstream commit 2e7dfb0e9cacad0f1adbc4b97f0b96ba35027f24 ]

Basic programmable non-PD Type-C port controllers do not need the full
TCPM library, but they share the same devicetree binding and the same
typec_capability structure. Factor out a helper for parsing those
properties which map to fields in struct typec_capability, so the code
can be shared between TCPM and basic non-TCPM drivers.

Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Samuel Holland <samuel@sholland.org>
Link: https://lore.kernel.org/r/20220214050118.61015-4-samuel@sholland.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: 581c848b610d ("extcon: usbc-tusb320: Update state on probe even if no IRQ pending")
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/usb/typec/class.c
drivers/usb/typec/tcpm/tcpm.c
include/linux/usb/typec.h

index ff6c14d..339752f 100644 (file)
@@ -1895,6 +1895,49 @@ void *typec_get_drvdata(struct typec_port *port)
 }
 EXPORT_SYMBOL_GPL(typec_get_drvdata);
 
+int typec_get_fw_cap(struct typec_capability *cap,
+                    struct fwnode_handle *fwnode)
+{
+       const char *cap_str;
+       int ret;
+
+       cap->fwnode = fwnode;
+
+       ret = fwnode_property_read_string(fwnode, "power-role", &cap_str);
+       if (ret < 0)
+               return ret;
+
+       ret = typec_find_port_power_role(cap_str);
+       if (ret < 0)
+               return ret;
+       cap->type = ret;
+
+       /* USB data support is optional */
+       ret = fwnode_property_read_string(fwnode, "data-role", &cap_str);
+       if (ret == 0) {
+               ret = typec_find_port_data_role(cap_str);
+               if (ret < 0)
+                       return ret;
+               cap->data = ret;
+       }
+
+       /* Get the preferred power role for a DRP */
+       if (cap->type == TYPEC_PORT_DRP) {
+               cap->prefer_role = TYPEC_NO_PREFERRED_ROLE;
+
+               ret = fwnode_property_read_string(fwnode, "try-power-role", &cap_str);
+               if (ret == 0) {
+                       ret = typec_find_power_role(cap_str);
+                       if (ret < 0)
+                               return ret;
+                       cap->prefer_role = ret;
+               }
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(typec_get_fw_cap);
+
 /**
  * typec_port_register_altmode - Register USB Type-C Port Alternate Mode
  * @port: USB Type-C Port that supports the alternate mode
index 33aadc0..984a13a 100644 (file)
@@ -5928,7 +5928,6 @@ static int tcpm_fw_get_caps(struct tcpm_port *port,
                            struct fwnode_handle *fwnode)
 {
        const char *opmode_str;
-       const char *cap_str;
        int ret;
        u32 mw, frs_current;
 
@@ -5944,23 +5943,10 @@ static int tcpm_fw_get_caps(struct tcpm_port *port,
         */
        fw_devlink_purge_absent_suppliers(fwnode);
 
-       /* USB data support is optional */
-       ret = fwnode_property_read_string(fwnode, "data-role", &cap_str);
-       if (ret == 0) {
-               ret = typec_find_port_data_role(cap_str);
-               if (ret < 0)
-                       return ret;
-               port->typec_caps.data = ret;
-       }
-
-       ret = fwnode_property_read_string(fwnode, "power-role", &cap_str);
+       ret = typec_get_fw_cap(&port->typec_caps, fwnode);
        if (ret < 0)
                return ret;
 
-       ret = typec_find_port_power_role(cap_str);
-       if (ret < 0)
-               return ret;
-       port->typec_caps.type = ret;
        port->port_type = port->typec_caps.type;
        port->pd_supported = !fwnode_property_read_bool(fwnode, "pd-disable");
 
@@ -5997,14 +5983,6 @@ static int tcpm_fw_get_caps(struct tcpm_port *port,
        if (port->port_type == TYPEC_PORT_SRC)
                return 0;
 
-       /* Get the preferred power role for DRP */
-       ret = fwnode_property_read_string(fwnode, "try-power-role", &cap_str);
-       if (ret < 0)
-               return ret;
-
-       port->typec_caps.prefer_role = typec_find_power_role(cap_str);
-       if (port->typec_caps.prefer_role < 0)
-               return -EINVAL;
 sink:
        port->self_powered = fwnode_property_read_bool(fwnode, "self-powered");
 
index e2e44bb..c1e5910 100644 (file)
@@ -295,6 +295,9 @@ int typec_set_mode(struct typec_port *port, int mode);
 
 void *typec_get_drvdata(struct typec_port *port);
 
+int typec_get_fw_cap(struct typec_capability *cap,
+                    struct fwnode_handle *fwnode);
+
 int typec_find_pwr_opmode(const char *name);
 int typec_find_orientation(const char *name);
 int typec_find_port_power_role(const char *name);