-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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>
- Loading branch information
Sagar Dharia
authored and
Greg Kroah-Hartman
committed
Dec 19, 2017
1 parent
afbdcc7
commit 4b14e62
Showing
5 changed files
with
225 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Copyright (c) 2011-2017, The Linux Foundation | ||
*/ | ||
|
||
#include <linux/errno.h> | ||
#include "slimbus.h" | ||
|
||
/** | ||
* slim_ctrl_clk_pause() - Called by slimbus controller to enter/exit | ||
* 'clock pause' | ||
* @ctrl: controller requesting bus to be paused or woken up | ||
* @wakeup: Wakeup this controller from clock pause. | ||
* @restart: Restart time value per spec used for clock pause. This value | ||
* isn't used when controller is to be woken up. | ||
* | ||
* Slimbus specification needs this sequence to turn-off clocks for the bus. | ||
* The sequence involves sending 3 broadcast messages (reconfiguration | ||
* sequence) to inform all devices on the bus. | ||
* To exit clock-pause, controller typically wakes up active framer device. | ||
* This API executes clock pause reconfiguration sequence if wakeup is false. | ||
* If wakeup is true, controller's wakeup is called. | ||
* For entering clock-pause, -EBUSY is returned if a message txn in pending. | ||
*/ | ||
int slim_ctrl_clk_pause(struct slim_controller *ctrl, bool wakeup, u8 restart) | ||
{ | ||
int i, ret = 0; | ||
unsigned long flags; | ||
struct slim_sched *sched = &ctrl->sched; | ||
struct slim_val_inf msg = {0, 0, NULL, NULL}; | ||
|
||
DEFINE_SLIM_BCAST_TXN(txn, SLIM_MSG_MC_BEGIN_RECONFIGURATION, | ||
3, SLIM_LA_MANAGER, &msg); | ||
|
||
if (wakeup == false && restart > SLIM_CLK_UNSPECIFIED) | ||
return -EINVAL; | ||
|
||
mutex_lock(&sched->m_reconf); | ||
if (wakeup) { | ||
if (sched->clk_state == SLIM_CLK_ACTIVE) { | ||
mutex_unlock(&sched->m_reconf); | ||
return 0; | ||
} | ||
|
||
/* | ||
* Fine-tune calculation based on clock gear, | ||
* message-bandwidth after bandwidth management | ||
*/ | ||
ret = wait_for_completion_timeout(&sched->pause_comp, | ||
msecs_to_jiffies(100)); | ||
if (!ret) { | ||
mutex_unlock(&sched->m_reconf); | ||
pr_err("Previous clock pause did not finish"); | ||
return -ETIMEDOUT; | ||
} | ||
ret = 0; | ||
|
||
/* | ||
* Slimbus framework will call controller wakeup | ||
* Controller should make sure that it sets active framer | ||
* out of clock pause | ||
*/ | ||
if (sched->clk_state == SLIM_CLK_PAUSED && ctrl->wakeup) | ||
ret = ctrl->wakeup(ctrl); | ||
if (!ret) | ||
sched->clk_state = SLIM_CLK_ACTIVE; | ||
mutex_unlock(&sched->m_reconf); | ||
|
||
return ret; | ||
} | ||
|
||
/* already paused */ | ||
if (ctrl->sched.clk_state == SLIM_CLK_PAUSED) { | ||
mutex_unlock(&sched->m_reconf); | ||
return 0; | ||
} | ||
|
||
spin_lock_irqsave(&ctrl->txn_lock, flags); | ||
for (i = 0; i < SLIM_MAX_TIDS; i++) { | ||
/* Pending response for a message */ | ||
if (idr_find(&ctrl->tid_idr, i)) { | ||
spin_unlock_irqrestore(&ctrl->txn_lock, flags); | ||
mutex_unlock(&sched->m_reconf); | ||
return -EBUSY; | ||
} | ||
} | ||
spin_unlock_irqrestore(&ctrl->txn_lock, flags); | ||
|
||
sched->clk_state = SLIM_CLK_ENTERING_PAUSE; | ||
|
||
/* clock pause sequence */ | ||
ret = slim_do_transfer(ctrl, &txn); | ||
if (ret) | ||
goto clk_pause_ret; | ||
|
||
txn.mc = SLIM_MSG_MC_NEXT_PAUSE_CLOCK; | ||
txn.rl = 4; | ||
msg.num_bytes = 1; | ||
msg.wbuf = &restart; | ||
ret = slim_do_transfer(ctrl, &txn); | ||
if (ret) | ||
goto clk_pause_ret; | ||
|
||
txn.mc = SLIM_MSG_MC_RECONFIGURE_NOW; | ||
txn.rl = 3; | ||
msg.num_bytes = 1; | ||
msg.wbuf = NULL; | ||
ret = slim_do_transfer(ctrl, &txn); | ||
|
||
clk_pause_ret: | ||
if (ret) { | ||
sched->clk_state = SLIM_CLK_ACTIVE; | ||
} else { | ||
sched->clk_state = SLIM_CLK_PAUSED; | ||
complete(&sched->pause_comp); | ||
} | ||
mutex_unlock(&sched->m_reconf); | ||
|
||
return ret; | ||
} | ||
EXPORT_SYMBOL_GPL(slim_ctrl_clk_pause); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters