@@ -53,6 +53,7 @@ struct typec_port {
5353 struct typec_mux * mux ;
5454
5555 const struct typec_capability * cap ;
56+ const struct typec_operations * ops ;
5657};
5758
5859#define to_typec_port (_dev_ ) container_of(_dev_, struct typec_port, dev)
@@ -955,7 +956,7 @@ preferred_role_store(struct device *dev, struct device_attribute *attr,
955956 return - EOPNOTSUPP ;
956957 }
957958
958- if (!port -> cap -> try_role ) {
959+ if (!port -> ops || ! port -> ops -> try_role ) {
959960 dev_dbg (dev , "Setting preferred role not supported\n" );
960961 return - EOPNOTSUPP ;
961962 }
@@ -968,7 +969,7 @@ preferred_role_store(struct device *dev, struct device_attribute *attr,
968969 return - EINVAL ;
969970 }
970971
971- ret = port -> cap -> try_role (port -> cap , role );
972+ ret = port -> ops -> try_role (port , role );
972973 if (ret )
973974 return ret ;
974975
@@ -999,7 +1000,7 @@ static ssize_t data_role_store(struct device *dev,
9991000 struct typec_port * port = to_typec_port (dev );
10001001 int ret ;
10011002
1002- if (!port -> cap -> dr_set ) {
1003+ if (!port -> ops || ! port -> ops -> dr_set ) {
10031004 dev_dbg (dev , "data role swapping not supported\n" );
10041005 return - EOPNOTSUPP ;
10051006 }
@@ -1014,7 +1015,7 @@ static ssize_t data_role_store(struct device *dev,
10141015 goto unlock_and_ret ;
10151016 }
10161017
1017- ret = port -> cap -> dr_set (port -> cap , ret );
1018+ ret = port -> ops -> dr_set (port , ret );
10181019 if (ret )
10191020 goto unlock_and_ret ;
10201021
@@ -1049,7 +1050,7 @@ static ssize_t power_role_store(struct device *dev,
10491050 return - EOPNOTSUPP ;
10501051 }
10511052
1052- if (!port -> cap -> pr_set ) {
1053+ if (!port -> ops || ! port -> ops -> pr_set ) {
10531054 dev_dbg (dev , "power role swapping not supported\n" );
10541055 return - EOPNOTSUPP ;
10551056 }
@@ -1071,7 +1072,7 @@ static ssize_t power_role_store(struct device *dev,
10711072 goto unlock_and_ret ;
10721073 }
10731074
1074- ret = port -> cap -> pr_set (port -> cap , ret );
1075+ ret = port -> ops -> pr_set (port , ret );
10751076 if (ret )
10761077 goto unlock_and_ret ;
10771078
@@ -1102,7 +1103,8 @@ port_type_store(struct device *dev, struct device_attribute *attr,
11021103 int ret ;
11031104 enum typec_port_type type ;
11041105
1105- if (!port -> cap -> port_type_set || port -> cap -> type != TYPEC_PORT_DRP ) {
1106+ if (port -> cap -> type != TYPEC_PORT_DRP ||
1107+ !port -> ops || !port -> ops -> port_type_set ) {
11061108 dev_dbg (dev , "changing port type not supported\n" );
11071109 return - EOPNOTSUPP ;
11081110 }
@@ -1119,7 +1121,7 @@ port_type_store(struct device *dev, struct device_attribute *attr,
11191121 goto unlock_and_ret ;
11201122 }
11211123
1122- ret = port -> cap -> port_type_set (port -> cap , type );
1124+ ret = port -> ops -> port_type_set (port , type );
11231125 if (ret )
11241126 goto unlock_and_ret ;
11251127
@@ -1175,7 +1177,7 @@ static ssize_t vconn_source_store(struct device *dev,
11751177 return - EOPNOTSUPP ;
11761178 }
11771179
1178- if (!port -> cap -> vconn_set ) {
1180+ if (!port -> ops || ! port -> ops -> vconn_set ) {
11791181 dev_dbg (dev , "VCONN swapping not supported\n" );
11801182 return - EOPNOTSUPP ;
11811183 }
@@ -1184,7 +1186,7 @@ static ssize_t vconn_source_store(struct device *dev,
11841186 if (ret )
11851187 return ret ;
11861188
1187- ret = port -> cap -> vconn_set (port -> cap , (enum typec_role )source );
1189+ ret = port -> ops -> vconn_set (port , (enum typec_role )source );
11881190 if (ret )
11891191 return ret ;
11901192
@@ -1278,6 +1280,7 @@ static void typec_release(struct device *dev)
12781280 ida_destroy (& port -> mode_ids );
12791281 typec_switch_put (port -> sw );
12801282 typec_mux_put (port -> mux );
1283+ kfree (port -> cap );
12811284 kfree (port );
12821285}
12831286
@@ -1486,6 +1489,16 @@ EXPORT_SYMBOL_GPL(typec_set_mode);
14861489
14871490/* --------------------------------------- */
14881491
1492+ /**
1493+ * typec_get_drvdata - Return private driver data pointer
1494+ * @port: USB Type-C port
1495+ */
1496+ void * typec_get_drvdata (struct typec_port * port )
1497+ {
1498+ return dev_get_drvdata (& port -> dev );
1499+ }
1500+ EXPORT_SYMBOL_GPL (typec_get_drvdata );
1501+
14891502/**
14901503 * typec_port_register_altmode - Register USB Type-C Port Alternate Mode
14911504 * @port: USB Type-C Port that supports the alternate mode
@@ -1579,7 +1592,7 @@ struct typec_port *typec_register_port(struct device *parent,
15791592 mutex_init (& port -> port_type_lock );
15801593
15811594 port -> id = id ;
1582- port -> cap = cap ;
1595+ port -> ops = cap -> ops ;
15831596 port -> port_type = cap -> type ;
15841597 port -> prefer_role = cap -> prefer_role ;
15851598
@@ -1589,6 +1602,13 @@ struct typec_port *typec_register_port(struct device *parent,
15891602 port -> dev .fwnode = cap -> fwnode ;
15901603 port -> dev .type = & typec_port_dev_type ;
15911604 dev_set_name (& port -> dev , "port%d" , id );
1605+ dev_set_drvdata (& port -> dev , cap -> driver_data );
1606+
1607+ port -> cap = kmemdup (cap , sizeof (* cap ), GFP_KERNEL );
1608+ if (!port -> cap ) {
1609+ put_device (& port -> dev );
1610+ return ERR_PTR (- ENOMEM );
1611+ }
15921612
15931613 port -> sw = typec_switch_get (& port -> dev );
15941614 if (IS_ERR (port -> sw )) {
0 commit comments