summaryrefslogtreecommitdiff
path: root/drivers/usb/typec
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/typec')
-rw-r--r--drivers/usb/typec/anx7411.c5
-rw-r--r--drivers/usb/typec/bus.c2
-rw-r--r--drivers/usb/typec/class.c19
-rw-r--r--drivers/usb/typec/hd3ss3220.c5
-rw-r--r--drivers/usb/typec/retimer.c16
-rw-r--r--drivers/usb/typec/retimer.h4
-rw-r--r--drivers/usb/typec/tcpm/fusb302.c5
-rw-r--r--drivers/usb/typec/tcpm/tcpci.c10
-rw-r--r--drivers/usb/typec/tcpm/tcpci_maxim.c4
-rw-r--r--drivers/usb/typec/tcpm/tcpci_rt1711h.c5
-rw-r--r--drivers/usb/typec/tipd/core.c20
-rw-r--r--drivers/usb/typec/ucsi/ucsi.c17
-rw-r--r--drivers/usb/typec/ucsi/ucsi.h1
-rw-r--r--drivers/usb/typec/ucsi/ucsi_ccg.c5
-rw-r--r--drivers/usb/typec/ucsi/ucsi_stm32g0.c4
-rw-r--r--drivers/usb/typec/wusb3801.c2
16 files changed, 73 insertions, 51 deletions
diff --git a/drivers/usb/typec/anx7411.c b/drivers/usb/typec/anx7411.c
index b8f3b75fd7eb..3d5edce270a4 100644
--- a/drivers/usb/typec/anx7411.c
+++ b/drivers/usb/typec/anx7411.c
@@ -1440,8 +1440,7 @@ static int anx7411_psy_register(struct anx7411_data *ctx)
return PTR_ERR_OR_ZERO(ctx->psy);
}
-static int anx7411_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int anx7411_i2c_probe(struct i2c_client *client)
{
struct anx7411_data *plat;
struct device *dev = &client->dev;
@@ -1585,7 +1584,7 @@ static struct i2c_driver anx7411_driver = {
.of_match_table = anx_match_table,
.pm = &anx7411_pm_ops,
},
- .probe = anx7411_i2c_probe,
+ .probe_new = anx7411_i2c_probe,
.remove = anx7411_i2c_remove,
.id_table = anx7411_id,
diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c
index 26ea2fdec17d..31c2a3130cad 100644
--- a/drivers/usb/typec/bus.c
+++ b/drivers/usb/typec/bus.c
@@ -134,7 +134,7 @@ int typec_altmode_exit(struct typec_altmode *adev)
if (!adev || !adev->active)
return 0;
- if (!pdev->ops || !pdev->ops->enter)
+ if (!pdev->ops || !pdev->ops->exit)
return -EOPNOTSUPP;
/* Moving to USB Safe State */
diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index bd5e5dd70431..5897905cb4f0 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -822,6 +822,25 @@ void typec_partner_set_svdm_version(struct typec_partner *partner,
EXPORT_SYMBOL_GPL(typec_partner_set_svdm_version);
/**
+ * typec_partner_usb_power_delivery_register - Register Type-C partner USB Power Delivery Support
+ * @partner: Type-C partner device.
+ * @desc: Description of the USB PD contract.
+ *
+ * This routine is a wrapper around usb_power_delivery_register(). It registers
+ * USB Power Delivery Capabilities for a Type-C partner device. Specifically,
+ * it sets the Type-C partner device as a parent for the resulting USB Power Delivery object.
+ *
+ * Returns handle to struct usb_power_delivery or ERR_PTR.
+ */
+struct usb_power_delivery *
+typec_partner_usb_power_delivery_register(struct typec_partner *partner,
+ struct usb_power_delivery_desc *desc)
+{
+ return usb_power_delivery_register(&partner->dev, desc);
+}
+EXPORT_SYMBOL_GPL(typec_partner_usb_power_delivery_register);
+
+/**
* typec_register_partner - Register a USB Type-C Partner
* @port: The USB Type-C Port the partner is connected to
* @desc: Description of the partner
diff --git a/drivers/usb/typec/hd3ss3220.c b/drivers/usb/typec/hd3ss3220.c
index 2a58185fb14c..f128664cb130 100644
--- a/drivers/usb/typec/hd3ss3220.c
+++ b/drivers/usb/typec/hd3ss3220.c
@@ -148,8 +148,7 @@ static const struct regmap_config config = {
.max_register = 0x0A,
};
-static int hd3ss3220_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int hd3ss3220_probe(struct i2c_client *client)
{
struct typec_capability typec_cap = { };
struct hd3ss3220 *hd3ss3220;
@@ -264,7 +263,7 @@ static struct i2c_driver hd3ss3220_driver = {
.name = "hd3ss3220",
.of_match_table = of_match_ptr(dev_ids),
},
- .probe = hd3ss3220_probe,
+ .probe_new = hd3ss3220_probe,
.remove = hd3ss3220_remove,
};
diff --git a/drivers/usb/typec/retimer.c b/drivers/usb/typec/retimer.c
index ee94dbbe4745..3a4146ea6e7c 100644
--- a/drivers/usb/typec/retimer.c
+++ b/drivers/usb/typec/retimer.c
@@ -17,21 +17,9 @@
#include "class.h"
#include "retimer.h"
-static bool dev_name_ends_with(struct device *dev, const char *suffix)
-{
- const char *name = dev_name(dev);
- const int name_len = strlen(name);
- const int suffix_len = strlen(suffix);
-
- if (suffix_len > name_len)
- return false;
-
- return strcmp(name + (name_len - suffix_len), suffix) == 0;
-}
-
static int retimer_fwnode_match(struct device *dev, const void *fwnode)
{
- return device_match_fwnode(dev, fwnode) && dev_name_ends_with(dev, "-retimer");
+ return is_typec_retimer(dev) && device_match_fwnode(dev, fwnode);
}
static void *typec_retimer_match(struct fwnode_handle *fwnode, const char *id, void *data)
@@ -97,7 +85,7 @@ static void typec_retimer_release(struct device *dev)
kfree(to_typec_retimer(dev));
}
-static const struct device_type typec_retimer_dev_type = {
+const struct device_type typec_retimer_dev_type = {
.name = "typec_retimer",
.release = typec_retimer_release,
};
diff --git a/drivers/usb/typec/retimer.h b/drivers/usb/typec/retimer.h
index fa15951d4846..e34bd23323be 100644
--- a/drivers/usb/typec/retimer.h
+++ b/drivers/usb/typec/retimer.h
@@ -12,4 +12,8 @@ struct typec_retimer {
#define to_typec_retimer(_dev_) container_of(_dev_, struct typec_retimer, dev)
+const struct device_type typec_retimer_dev_type;
+
+#define is_typec_retimer(dev) ((dev)->type == &typec_retimer_dev_type)
+
#endif /* __USB_TYPEC_RETIMER__ */
diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c
index 721b2a548084..1ffce00d94b4 100644
--- a/drivers/usb/typec/tcpm/fusb302.c
+++ b/drivers/usb/typec/tcpm/fusb302.c
@@ -1677,8 +1677,7 @@ static struct fwnode_handle *fusb302_fwnode_get(struct device *dev)
return fwnode;
}
-static int fusb302_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int fusb302_probe(struct i2c_client *client)
{
struct fusb302_chip *chip;
struct i2c_adapter *adapter = client->adapter;
@@ -1837,7 +1836,7 @@ static struct i2c_driver fusb302_driver = {
.pm = &fusb302_pm_ops,
.of_match_table = of_match_ptr(fusb302_dt_match),
},
- .probe = fusb302_probe,
+ .probe_new = fusb302_probe,
.remove = fusb302_remove,
.id_table = fusb302_i2c_device_id,
};
diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c
index b2bfcebe218f..fe781a38dc82 100644
--- a/drivers/usb/typec/tcpm/tcpci.c
+++ b/drivers/usb/typec/tcpm/tcpci.c
@@ -794,8 +794,10 @@ struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data)
return ERR_PTR(err);
tcpci->port = tcpm_register_port(tcpci->dev, &tcpci->tcpc);
- if (IS_ERR(tcpci->port))
+ if (IS_ERR(tcpci->port)) {
+ fwnode_handle_put(tcpci->tcpc.fwnode);
return ERR_CAST(tcpci->port);
+ }
return tcpci;
}
@@ -804,11 +806,11 @@ EXPORT_SYMBOL_GPL(tcpci_register_port);
void tcpci_unregister_port(struct tcpci *tcpci)
{
tcpm_unregister_port(tcpci->port);
+ fwnode_handle_put(tcpci->tcpc.fwnode);
}
EXPORT_SYMBOL_GPL(tcpci_unregister_port);
-static int tcpci_probe(struct i2c_client *client,
- const struct i2c_device_id *i2c_id)
+static int tcpci_probe(struct i2c_client *client)
{
struct tcpci_chip *chip;
int err;
@@ -878,7 +880,7 @@ static struct i2c_driver tcpci_i2c_driver = {
.name = "tcpci",
.of_match_table = of_match_ptr(tcpci_of_match),
},
- .probe = tcpci_probe,
+ .probe_new = tcpci_probe,
.remove = tcpci_remove,
.id_table = tcpci_id,
};
diff --git a/drivers/usb/typec/tcpm/tcpci_maxim.c b/drivers/usb/typec/tcpm/tcpci_maxim.c
index 03f89e6f1a78..83e140ffcc3e 100644
--- a/drivers/usb/typec/tcpm/tcpci_maxim.c
+++ b/drivers/usb/typec/tcpm/tcpci_maxim.c
@@ -438,7 +438,7 @@ static int tcpci_init(struct tcpci *tcpci, struct tcpci_data *data)
return -1;
}
-static int max_tcpci_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id)
+static int max_tcpci_probe(struct i2c_client *client)
{
int ret;
struct max_tcpci_chip *chip;
@@ -519,7 +519,7 @@ static struct i2c_driver max_tcpci_i2c_driver = {
.name = "maxtcpc",
.of_match_table = of_match_ptr(max_tcpci_of_match),
},
- .probe = max_tcpci_probe,
+ .probe_new = max_tcpci_probe,
.remove = max_tcpci_remove,
.id_table = max_tcpci_id,
};
diff --git a/drivers/usb/typec/tcpm/tcpci_rt1711h.c b/drivers/usb/typec/tcpm/tcpci_rt1711h.c
index 7b217c712c11..a0e9e3fe8564 100644
--- a/drivers/usb/typec/tcpm/tcpci_rt1711h.c
+++ b/drivers/usb/typec/tcpm/tcpci_rt1711h.c
@@ -327,8 +327,7 @@ static int rt1711h_check_revision(struct i2c_client *i2c, struct rt1711h_chip *c
return ret;
}
-static int rt1711h_probe(struct i2c_client *client,
- const struct i2c_device_id *i2c_id)
+static int rt1711h_probe(struct i2c_client *client)
{
int ret;
struct rt1711h_chip *chip;
@@ -413,7 +412,7 @@ static struct i2c_driver rt1711h_i2c_driver = {
.name = "rt1711h",
.of_match_table = of_match_ptr(rt1711h_of_match),
},
- .probe = rt1711h_probe,
+ .probe_new = rt1711h_probe,
.remove = rt1711h_remove,
.id_table = rt1711h_id,
};
diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
index 2a77bab948f5..46a4d8b128f0 100644
--- a/drivers/usb/typec/tipd/core.c
+++ b/drivers/usb/typec/tipd/core.c
@@ -14,6 +14,7 @@
#include <linux/regmap.h>
#include <linux/interrupt.h>
#include <linux/usb/typec.h>
+#include <linux/usb/typec_altmode.h>
#include <linux/usb/role.h>
#include "tps6598x.h"
@@ -257,6 +258,7 @@ static int tps6598x_connect(struct tps6598x *tps, u32 status)
typec_set_orientation(tps->port, TYPEC_ORIENTATION_REVERSE);
else
typec_set_orientation(tps->port, TYPEC_ORIENTATION_NORMAL);
+ typec_set_mode(tps->port, TYPEC_STATE_USB);
tps6598x_set_data_role(tps, TPS_STATUS_TO_TYPEC_DATAROLE(status), true);
tps->partner = typec_register_partner(tps->port, &desc);
@@ -280,6 +282,7 @@ static void tps6598x_disconnect(struct tps6598x *tps, u32 status)
typec_set_pwr_role(tps->port, TPS_STATUS_TO_TYPEC_PORTROLE(status));
typec_set_vconn_role(tps->port, TPS_STATUS_TO_TYPEC_VCONN(status));
typec_set_orientation(tps->port, TYPEC_ORIENTATION_NONE);
+ typec_set_mode(tps->port, TYPEC_STATE_SAFE);
tps6598x_set_data_role(tps, TPS_STATUS_TO_TYPEC_DATAROLE(status), false);
power_supply_changed(tps->psy);
@@ -814,20 +817,19 @@ static int tps6598x_probe(struct i2c_client *client)
ret = devm_tps6598_psy_register(tps);
if (ret)
- return ret;
+ goto err_role_put;
tps->port = typec_register_port(&client->dev, &typec_cap);
if (IS_ERR(tps->port)) {
ret = PTR_ERR(tps->port);
goto err_role_put;
}
- fwnode_handle_put(fwnode);
if (status & TPS_STATUS_PLUG_PRESENT) {
ret = tps6598x_read16(tps, TPS_REG_POWER_STATUS, &tps->pwr_status);
if (ret < 0) {
dev_err(tps->dev, "failed to read power status: %d\n", ret);
- goto err_role_put;
+ goto err_unregister_port;
}
ret = tps6598x_connect(tps, status);
if (ret)
@@ -838,16 +840,18 @@ static int tps6598x_probe(struct i2c_client *client)
irq_handler,
IRQF_SHARED | IRQF_ONESHOT,
dev_name(&client->dev), tps);
- if (ret) {
- tps6598x_disconnect(tps, 0);
- typec_unregister_port(tps->port);
- goto err_role_put;
- }
+ if (ret)
+ goto err_disconnect;
i2c_set_clientdata(client, tps);
+ fwnode_handle_put(fwnode);
return 0;
+err_disconnect:
+ tps6598x_disconnect(tps, 0);
+err_unregister_port:
+ typec_unregister_port(tps->port);
err_role_put:
usb_role_switch_put(tps->role_sw);
err_fwnode_put:
diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index a7987fc764cc..eabe519013e7 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -1270,8 +1270,9 @@ err:
return ret;
}
-int ucsi_resume(struct ucsi *ucsi)
+static void ucsi_resume_work(struct work_struct *work)
{
+ struct ucsi *ucsi = container_of(work, struct ucsi, resume_work);
struct ucsi_connector *con;
u64 command;
int ret;
@@ -1279,15 +1280,21 @@ int ucsi_resume(struct ucsi *ucsi)
/* Restore UCSI notification enable mask after system resume */
command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
ret = ucsi_send_command(ucsi, command, NULL, 0);
- if (ret < 0)
- return ret;
+ if (ret < 0) {
+ dev_err(ucsi->dev, "failed to re-enable notifications (%d)\n", ret);
+ return;
+ }
for (con = ucsi->connector; con->port; con++) {
mutex_lock(&con->lock);
- ucsi_check_connection(con);
+ ucsi_partner_task(con, ucsi_check_connection, 1, 0);
mutex_unlock(&con->lock);
}
+}
+int ucsi_resume(struct ucsi *ucsi)
+{
+ queue_work(system_long_wq, &ucsi->resume_work);
return 0;
}
EXPORT_SYMBOL_GPL(ucsi_resume);
@@ -1347,6 +1354,7 @@ struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops)
if (!ucsi)
return ERR_PTR(-ENOMEM);
+ INIT_WORK(&ucsi->resume_work, ucsi_resume_work);
INIT_DELAYED_WORK(&ucsi->work, ucsi_init_work);
mutex_init(&ucsi->ppm_lock);
ucsi->dev = dev;
@@ -1401,6 +1409,7 @@ void ucsi_unregister(struct ucsi *ucsi)
/* Make sure that we are not in the middle of driver initialization */
cancel_delayed_work_sync(&ucsi->work);
+ cancel_work_sync(&ucsi->resume_work);
/* Disable notifications */
ucsi->ops->async_write(ucsi, UCSI_CONTROL, &cmd, sizeof(cmd));
diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
index 8eb391e3e592..c968474ee547 100644
--- a/drivers/usb/typec/ucsi/ucsi.h
+++ b/drivers/usb/typec/ucsi/ucsi.h
@@ -287,6 +287,7 @@ struct ucsi {
struct ucsi_capability cap;
struct ucsi_connector *connector;
+ struct work_struct resume_work;
struct delayed_work work;
int work_count;
#define UCSI_ROLE_SWITCH_RETRY_PER_HZ 10
diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c
index 835f1c4372ba..46441f1477f2 100644
--- a/drivers/usb/typec/ucsi/ucsi_ccg.c
+++ b/drivers/usb/typec/ucsi/ucsi_ccg.c
@@ -1338,8 +1338,7 @@ static struct attribute *ucsi_ccg_attrs[] = {
};
ATTRIBUTE_GROUPS(ucsi_ccg);
-static int ucsi_ccg_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int ucsi_ccg_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct ucsi_ccg *uc;
@@ -1482,7 +1481,7 @@ static struct i2c_driver ucsi_ccg_driver = {
.dev_groups = ucsi_ccg_groups,
.acpi_match_table = amd_i2c_ucsi_match,
},
- .probe = ucsi_ccg_probe,
+ .probe_new = ucsi_ccg_probe,
.remove = ucsi_ccg_remove,
.id_table = ucsi_ccg_device_id,
};
diff --git a/drivers/usb/typec/ucsi/ucsi_stm32g0.c b/drivers/usb/typec/ucsi/ucsi_stm32g0.c
index 7b92f0c8de70..93fead0096b7 100644
--- a/drivers/usb/typec/ucsi/ucsi_stm32g0.c
+++ b/drivers/usb/typec/ucsi/ucsi_stm32g0.c
@@ -626,7 +626,7 @@ static int ucsi_stm32g0_probe_bootloader(struct ucsi *ucsi)
return 0;
}
-static int ucsi_stm32g0_probe(struct i2c_client *client, const struct i2c_device_id *id)
+static int ucsi_stm32g0_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct ucsi_stm32g0 *g0;
@@ -763,7 +763,7 @@ static struct i2c_driver ucsi_stm32g0_i2c_driver = {
.of_match_table = of_match_ptr(ucsi_stm32g0_typec_of_match),
.pm = pm_sleep_ptr(&ucsi_stm32g0_pm_ops),
},
- .probe = ucsi_stm32g0_probe,
+ .probe_new = ucsi_stm32g0_probe,
.remove = ucsi_stm32g0_remove,
.id_table = ucsi_stm32g0_typec_i2c_devid
};
diff --git a/drivers/usb/typec/wusb3801.c b/drivers/usb/typec/wusb3801.c
index 3cc7a15ecbd3..a43a18d4b02e 100644
--- a/drivers/usb/typec/wusb3801.c
+++ b/drivers/usb/typec/wusb3801.c
@@ -364,7 +364,7 @@ static int wusb3801_probe(struct i2c_client *client)
/* Initialize the hardware with the devicetree settings. */
ret = wusb3801_hw_init(wusb3801);
if (ret)
- return ret;
+ goto err_put_connector;
wusb3801->cap.revision = USB_TYPEC_REV_1_2;
wusb3801->cap.accessory[0] = TYPEC_ACCESSORY_AUDIO;