diff --git a/include/soc/soundwire.h b/include/soc/soundwire.h index bfd77c3bfb51..655b53ef604c 100644 --- a/include/soc/soundwire.h +++ b/include/soc/soundwire.h @@ -167,6 +167,8 @@ struct swr_master { u8 *dev_num); int (*slvdev_datapath_control)(struct swr_master *mstr, bool enable); bool (*remove_from_group)(struct swr_master *mstr); + void (*device_wakeup_vote)(struct swr_master *mstr); + void (*device_wakeup_unvote)(struct swr_master *mstr); u16 port_en_mask; }; @@ -334,4 +336,8 @@ extern void swr_remove_device(struct swr_device *swr_dev); extern struct swr_device *get_matching_swr_slave_device(struct device_node *np); +extern int swr_device_wakeup_vote(struct swr_device *dev); + +extern int swr_device_wakeup_unvote(struct swr_device *dev); + #endif /* _LINUX_SOUNDWIRE_H */ diff --git a/soc/soundwire.c b/soc/soundwire.c index ef51e16e6cfe..23e373a1f453 100644 --- a/soc/soundwire.c +++ b/soc/soundwire.c @@ -482,6 +482,61 @@ int swr_get_logical_dev_num(struct swr_device *dev, u64 dev_id, } EXPORT_SYMBOL(swr_get_logical_dev_num); +/** + * swr_device_wakeup_vote - Wakeup master and slave devices from clock stop + * @dev: pointer to soundwire slave device + * + * This API will wake up soundwire master and slave device(s) from + * clock stop. + */ +int swr_device_wakeup_vote(struct swr_device *dev) +{ + int ret = 0; + struct swr_master *master = dev->master; + + if (!master) { + pr_err("%s: Master is NULL\n", __func__); + return -EINVAL; + } + mutex_lock(&master->mlock); + if (master->device_wakeup_vote) + master->device_wakeup_vote(master); + else + ret = -EINVAL; + mutex_unlock(&master->mlock); + + return ret; +} +EXPORT_SYMBOL(swr_device_wakeup_vote); + +/** + * swr_device_wakeup_unvote - Unvote Wakeup so that master and slave + * devices can go back to clock stop + * @dev: pointer to soundwire slave device + * + * This API will remove vote for wakeup so that soundwire master and + * slave device(s) can go back to clock stop. + */ +int swr_device_wakeup_unvote(struct swr_device *dev) +{ + int ret = 0; + struct swr_master *master = dev->master; + + if (!master) { + pr_err("%s: Master is NULL\n", __func__); + return -EINVAL; + } + mutex_lock(&master->mlock); + if (master->device_wakeup_unvote) + master->device_wakeup_unvote(master); + else + ret = -EINVAL; + mutex_unlock(&master->mlock); + + return ret; +} +EXPORT_SYMBOL(swr_device_wakeup_unvote); + /** * swr_read - read soundwire slave device registers * @dev: pointer to soundwire slave device