From 1b9932e154a1ce720766a280f9ab8e6d1f2dec48 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 31 Aug 2018 23:47:20 +0530 Subject: [PATCH] SoC: soundwire: Add support for device wakeup Add soundwire API to wakeup soundwire master and slave devices. These APIs will be used by slave driver to vote and unvote for master wakeup, when it requires master for register access operations. Master will be aware of the slave usage with the vote for device wakeup. Change-Id: Ifa93f35ab2cffba778cd2fd9a2461e5a58445b75 Signed-off-by: Sudheer Papothi Signed-off-by: Ramprasad Katkam --- include/soc/soundwire.h | 6 +++++ soc/soundwire.c | 55 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) 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