Commit a94ecde4 authored by Ajay Gupta's avatar Ajay Gupta Committed by Wolfram Sang

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: default avatarAjay Gupta <ajayg@nvidia.com>
Acked-by: default avatarHeikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent d4a4f927
...@@ -206,7 +206,17 @@ int ucsi_send_command(struct ucsi *ucsi, struct ucsi_control *ctrl, ...@@ -206,7 +206,17 @@ int ucsi_send_command(struct ucsi *ucsi, struct ucsi_control *ctrl,
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(ucsi_send_command);
int ucsi_resume(struct ucsi *ucsi)
{
struct ucsi_control ctrl;
/* Restore UCSI notification enable mask after system resume */
UCSI_CMD_SET_NTFY_ENABLE(ctrl, UCSI_ENABLE_NTFY_ALL);
return ucsi_send_command(ucsi, &ctrl, NULL, 0);
}
EXPORT_SYMBOL_GPL(ucsi_resume);
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
void ucsi_altmode_update_active(struct ucsi_connector *con) void ucsi_altmode_update_active(struct ucsi_connector *con)
......
...@@ -430,6 +430,7 @@ int ucsi_send_command(struct ucsi *ucsi, struct ucsi_control *ctrl, ...@@ -430,6 +430,7 @@ int ucsi_send_command(struct ucsi *ucsi, struct ucsi_control *ctrl,
void *retval, size_t size); void *retval, size_t size);
void ucsi_altmode_update_active(struct ucsi_connector *con); void ucsi_altmode_update_active(struct ucsi_connector *con);
int ucsi_resume(struct ucsi *ucsi);
#if IS_ENABLED(CONFIG_TYPEC_DP_ALTMODE) #if IS_ENABLED(CONFIG_TYPEC_DP_ALTMODE)
struct typec_altmode * struct typec_altmode *
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include "ucsi.h" #include "ucsi.h"
...@@ -210,6 +212,7 @@ static int ccg_read(struct ucsi_ccg *uc, u16 rab, u8 *data, u32 len) ...@@ -210,6 +212,7 @@ static int ccg_read(struct ucsi_ccg *uc, u16 rab, u8 *data, u32 len)
if (quirks && quirks->max_read_len) if (quirks && quirks->max_read_len)
max_read_len = quirks->max_read_len; max_read_len = quirks->max_read_len;
pm_runtime_get_sync(uc->dev);
while (rem_len > 0) { while (rem_len > 0) {
msgs[1].buf = &data[len - rem_len]; msgs[1].buf = &data[len - rem_len];
rlen = min_t(u16, rem_len, max_read_len); 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) ...@@ -218,12 +221,14 @@ static int ccg_read(struct ucsi_ccg *uc, u16 rab, u8 *data, u32 len)
status = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); status = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
if (status < 0) { if (status < 0) {
dev_err(uc->dev, "i2c_transfer failed %d\n", status); dev_err(uc->dev, "i2c_transfer failed %d\n", status);
pm_runtime_put_sync(uc->dev);
return status; return status;
} }
rab += rlen; rab += rlen;
rem_len -= rlen; rem_len -= rlen;
} }
pm_runtime_put_sync(uc->dev);
return 0; return 0;
} }
...@@ -249,13 +254,16 @@ static int ccg_write(struct ucsi_ccg *uc, u16 rab, u8 *data, u32 len) ...@@ -249,13 +254,16 @@ static int ccg_write(struct ucsi_ccg *uc, u16 rab, u8 *data, u32 len)
msgs[0].len = len + sizeof(rab); msgs[0].len = len + sizeof(rab);
msgs[0].buf = buf; msgs[0].buf = buf;
pm_runtime_get_sync(uc->dev);
status = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); status = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
if (status < 0) { if (status < 0) {
dev_err(uc->dev, "i2c_transfer failed %d\n", status); dev_err(uc->dev, "i2c_transfer failed %d\n", status);
pm_runtime_put_sync(uc->dev);
kfree(buf); kfree(buf);
return status; return status;
} }
pm_runtime_put_sync(uc->dev);
kfree(buf); kfree(buf);
return 0; return 0;
} }
...@@ -1134,6 +1142,10 @@ static int ucsi_ccg_probe(struct i2c_client *client, ...@@ -1134,6 +1142,10 @@ static int ucsi_ccg_probe(struct i2c_client *client,
if (status) if (status)
dev_err(uc->dev, "cannot create sysfs group: %d\n", status); dev_err(uc->dev, "cannot create sysfs group: %d\n", status);
pm_runtime_set_active(uc->dev);
pm_runtime_enable(uc->dev);
pm_runtime_idle(uc->dev);
return 0; return 0;
} }
...@@ -1143,6 +1155,7 @@ static int ucsi_ccg_remove(struct i2c_client *client) ...@@ -1143,6 +1155,7 @@ static int ucsi_ccg_remove(struct i2c_client *client)
cancel_work_sync(&uc->work); cancel_work_sync(&uc->work);
ucsi_unregister_ppm(uc->ucsi); ucsi_unregister_ppm(uc->ucsi);
pm_runtime_disable(uc->dev);
free_irq(uc->irq, uc); free_irq(uc->irq, uc);
sysfs_remove_group(&uc->dev->kobj, &ucsi_ccg_attr_group); sysfs_remove_group(&uc->dev->kobj, &ucsi_ccg_attr_group);
...@@ -1155,9 +1168,34 @@ static const struct i2c_device_id ucsi_ccg_device_id[] = { ...@@ -1155,9 +1168,34 @@ static const struct i2c_device_id ucsi_ccg_device_id[] = {
}; };
MODULE_DEVICE_TABLE(i2c, ucsi_ccg_device_id); MODULE_DEVICE_TABLE(i2c, ucsi_ccg_device_id);
static int ucsi_ccg_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct ucsi_ccg *uc = i2c_get_clientdata(client);
return ucsi_resume(uc->ucsi);
}
static int ucsi_ccg_runtime_suspend(struct device *dev)
{
return 0;
}
static int ucsi_ccg_runtime_resume(struct device *dev)
{
return 0;
}
static const struct dev_pm_ops ucsi_ccg_pm = {
.resume = ucsi_ccg_resume,
.runtime_suspend = ucsi_ccg_runtime_suspend,
.runtime_resume = ucsi_ccg_runtime_resume,
};
static struct i2c_driver ucsi_ccg_driver = { static struct i2c_driver ucsi_ccg_driver = {
.driver = { .driver = {
.name = "ucsi_ccg", .name = "ucsi_ccg",
.pm = &ucsi_ccg_pm,
}, },
.probe = ucsi_ccg_probe, .probe = ucsi_ccg_probe,
.remove = ucsi_ccg_remove, .remove = ucsi_ccg_remove,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment