diff options
author | 2017-12-11 23:43:01 +0000 | |
---|---|---|
committer | 2017-12-19 11:01:03 +0100 | |
commit | 4b14e62ad3c9e6e6774517f4077e197c0537fb07 (patch) | |
tree | c944a1253b54bee25c13fe0841bfdd4dd3bb641c /drivers/slimbus/core.c | |
parent | slimbus: Add messaging APIs to slimbus framework (diff) | |
download | linux-4b14e62ad3c9e6e6774517f4077e197c0537fb07.tar.gz linux-4b14e62ad3c9e6e6774517f4077e197c0537fb07.tar.bz2 linux-4b14e62ad3c9e6e6774517f4077e197c0537fb07.zip |
slimbus: Add support for 'clock-pause' feature
Per SLIMbus specification, a reconfiguration sequence known as
'clock pause' needs to be broadcast over the bus while entering low-
power mode. Clock-pause is initiated by the controller driver.
To exit clock-pause, controller typically wakes up the framer device.
Since wakeup precedure is controller-specific, framework calls it via
controller's function pointer to invoke it.
Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Reviwed-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/slimbus/core.c')
-rw-r--r-- | drivers/slimbus/core.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/slimbus/core.c b/drivers/slimbus/core.c index 1accb20ed5cd..4988a8f4d905 100644 --- a/drivers/slimbus/core.c +++ b/drivers/slimbus/core.c @@ -9,6 +9,7 @@ #include <linux/init.h> #include <linux/idr.h> #include <linux/of.h> +#include <linux/pm_runtime.h> #include <linux/slimbus.h> #include "slimbus.h" @@ -218,6 +219,8 @@ int slim_register_controller(struct slim_controller *ctrl) ida_init(&ctrl->laddr_ida); idr_init(&ctrl->tid_idr); mutex_init(&ctrl->lock); + mutex_init(&ctrl->sched.m_reconf); + init_completion(&ctrl->sched.pause_comp); dev_dbg(ctrl->dev, "Bus [%s] registered:dev:%p\n", ctrl->name, ctrl->dev); @@ -249,6 +252,8 @@ int slim_unregister_controller(struct slim_controller *ctrl) { /* Remove all clients */ device_for_each_child(ctrl->dev, NULL, slim_ctrl_remove_device); + /* Enter Clock Pause */ + slim_ctrl_clk_pause(ctrl, false, 0); ida_simple_remove(&ctrl_ida, ctrl->id); return 0; @@ -416,6 +421,14 @@ int slim_device_report_present(struct slim_controller *ctrl, struct slim_device *sbdev; int ret; + ret = pm_runtime_get_sync(ctrl->dev); + + if (ctrl->sched.clk_state != SLIM_CLK_ACTIVE) { + dev_err(ctrl->dev, "slim ctrl not active,state:%d, ret:%d\n", + ctrl->sched.clk_state, ret); + goto slimbus_not_active; + } + sbdev = slim_get_device(ctrl, e_addr); if (IS_ERR(sbdev)) return -ENODEV; @@ -427,6 +440,9 @@ int slim_device_report_present(struct slim_controller *ctrl, ret = slim_device_alloc_laddr(sbdev, true); +slimbus_not_active: + pm_runtime_mark_last_busy(ctrl->dev); + pm_runtime_put_autosuspend(ctrl->dev); return ret; } EXPORT_SYMBOL_GPL(slim_device_report_present); |