Skip to content

Commit a94ecde

Browse files
Ajay GuptaWolfram Sang
authored andcommitted
usb: typec: ucsi: ccg: enable runtime pm support
The change enables runtime pm support to UCSI CCG driver. Added ucsi_resume() function to enable notification after system reusme. Exported both ucsi_resume() and ucsi_send_command() symbols in ucsi.c for modular build. Signed-off-by: Ajay Gupta <ajayg@nvidia.com> Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
1 parent d4a4f92 commit a94ecde

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

drivers/usb/typec/ucsi/ucsi.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,17 @@ int ucsi_send_command(struct ucsi *ucsi, struct ucsi_control *ctrl,
206206

207207
return ret;
208208
}
209+
EXPORT_SYMBOL_GPL(ucsi_send_command);
209210

211+
int ucsi_resume(struct ucsi *ucsi)
212+
{
213+
struct ucsi_control ctrl;
214+
215+
/* Restore UCSI notification enable mask after system resume */
216+
UCSI_CMD_SET_NTFY_ENABLE(ctrl, UCSI_ENABLE_NTFY_ALL);
217+
return ucsi_send_command(ucsi, &ctrl, NULL, 0);
218+
}
219+
EXPORT_SYMBOL_GPL(ucsi_resume);
210220
/* -------------------------------------------------------------------------- */
211221

212222
void ucsi_altmode_update_active(struct ucsi_connector *con)

drivers/usb/typec/ucsi/ucsi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,7 @@ int ucsi_send_command(struct ucsi *ucsi, struct ucsi_control *ctrl,
430430
void *retval, size_t size);
431431

432432
void ucsi_altmode_update_active(struct ucsi_connector *con);
433+
int ucsi_resume(struct ucsi *ucsi);
433434

434435
#if IS_ENABLED(CONFIG_TYPEC_DP_ALTMODE)
435436
struct typec_altmode *

drivers/usb/typec/ucsi/ucsi_ccg.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include <linux/module.h>
1515
#include <linux/pci.h>
1616
#include <linux/platform_device.h>
17+
#include <linux/pm.h>
18+
#include <linux/pm_runtime.h>
1719

1820
#include <asm/unaligned.h>
1921
#include "ucsi.h"
@@ -210,6 +212,7 @@ static int ccg_read(struct ucsi_ccg *uc, u16 rab, u8 *data, u32 len)
210212
if (quirks && quirks->max_read_len)
211213
max_read_len = quirks->max_read_len;
212214

215+
pm_runtime_get_sync(uc->dev);
213216
while (rem_len > 0) {
214217
msgs[1].buf = &data[len - rem_len];
215218
rlen = min_t(u16, rem_len, max_read_len);
@@ -218,12 +221,14 @@ static int ccg_read(struct ucsi_ccg *uc, u16 rab, u8 *data, u32 len)
218221
status = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
219222
if (status < 0) {
220223
dev_err(uc->dev, "i2c_transfer failed %d\n", status);
224+
pm_runtime_put_sync(uc->dev);
221225
return status;
222226
}
223227
rab += rlen;
224228
rem_len -= rlen;
225229
}
226230

231+
pm_runtime_put_sync(uc->dev);
227232
return 0;
228233
}
229234

@@ -249,13 +254,16 @@ static int ccg_write(struct ucsi_ccg *uc, u16 rab, u8 *data, u32 len)
249254
msgs[0].len = len + sizeof(rab);
250255
msgs[0].buf = buf;
251256

257+
pm_runtime_get_sync(uc->dev);
252258
status = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
253259
if (status < 0) {
254260
dev_err(uc->dev, "i2c_transfer failed %d\n", status);
261+
pm_runtime_put_sync(uc->dev);
255262
kfree(buf);
256263
return status;
257264
}
258265

266+
pm_runtime_put_sync(uc->dev);
259267
kfree(buf);
260268
return 0;
261269
}
@@ -1134,6 +1142,10 @@ static int ucsi_ccg_probe(struct i2c_client *client,
11341142
if (status)
11351143
dev_err(uc->dev, "cannot create sysfs group: %d\n", status);
11361144

1145+
pm_runtime_set_active(uc->dev);
1146+
pm_runtime_enable(uc->dev);
1147+
pm_runtime_idle(uc->dev);
1148+
11371149
return 0;
11381150
}
11391151

@@ -1143,6 +1155,7 @@ static int ucsi_ccg_remove(struct i2c_client *client)
11431155

11441156
cancel_work_sync(&uc->work);
11451157
ucsi_unregister_ppm(uc->ucsi);
1158+
pm_runtime_disable(uc->dev);
11461159
free_irq(uc->irq, uc);
11471160
sysfs_remove_group(&uc->dev->kobj, &ucsi_ccg_attr_group);
11481161

@@ -1155,9 +1168,34 @@ static const struct i2c_device_id ucsi_ccg_device_id[] = {
11551168
};
11561169
MODULE_DEVICE_TABLE(i2c, ucsi_ccg_device_id);
11571170

1171+
static int ucsi_ccg_resume(struct device *dev)
1172+
{
1173+
struct i2c_client *client = to_i2c_client(dev);
1174+
struct ucsi_ccg *uc = i2c_get_clientdata(client);
1175+
1176+
return ucsi_resume(uc->ucsi);
1177+
}
1178+
1179+
static int ucsi_ccg_runtime_suspend(struct device *dev)
1180+
{
1181+
return 0;
1182+
}
1183+
1184+
static int ucsi_ccg_runtime_resume(struct device *dev)
1185+
{
1186+
return 0;
1187+
}
1188+
1189+
static const struct dev_pm_ops ucsi_ccg_pm = {
1190+
.resume = ucsi_ccg_resume,
1191+
.runtime_suspend = ucsi_ccg_runtime_suspend,
1192+
.runtime_resume = ucsi_ccg_runtime_resume,
1193+
};
1194+
11581195
static struct i2c_driver ucsi_ccg_driver = {
11591196
.driver = {
11601197
.name = "ucsi_ccg",
1198+
.pm = &ucsi_ccg_pm,
11611199
},
11621200
.probe = ucsi_ccg_probe,
11631201
.remove = ucsi_ccg_remove,

0 commit comments

Comments
 (0)