summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/platform/msm/mhi/mhi.h12
-rw-r--r--drivers/platform/msm/mhi/mhi_iface.c10
-rw-r--r--drivers/platform/msm/mhi/mhi_init.c8
-rw-r--r--drivers/platform/msm/mhi/mhi_macros.h1
-rw-r--r--drivers/platform/msm/mhi/mhi_main.c111
-rw-r--r--drivers/platform/msm/mhi/mhi_pm.c31
-rw-r--r--drivers/platform/msm/mhi/mhi_states.c98
-rw-r--r--drivers/platform/msm/mhi/mhi_sys.c3
8 files changed, 120 insertions, 154 deletions
diff --git a/drivers/platform/msm/mhi/mhi.h b/drivers/platform/msm/mhi/mhi.h
index 9db159b6d8c1..907eb5413e55 100644
--- a/drivers/platform/msm/mhi/mhi.h
+++ b/drivers/platform/msm/mhi/mhi.h
@@ -392,8 +392,6 @@ struct mhi_flags {
u32 kill_threads;
atomic_t data_pending;
atomic_t events_pending;
- atomic_t m0_work_enabled;
- atomic_t m3_work_enabled;
atomic_t pending_resume;
atomic_t pending_ssr;
atomic_t pending_powerup;
@@ -460,10 +458,7 @@ struct mhi_device_ctxt {
rwlock_t xfer_lock;
struct hrtimer m1_timer;
ktime_t m1_timeout;
- struct delayed_work m3_work;
- struct work_struct m0_work;
-
- struct workqueue_struct *work_queue;
+ ktime_t ul_acc_tmr_timeout;
struct mhi_chan_counters mhi_chan_cntr[MHI_MAX_CHANNELS];
u32 ev_counter[MHI_MAX_CHANNELS];
u32 bus_client;
@@ -574,8 +569,6 @@ int mhi_cpu_notifier_cb(struct notifier_block *nfb, unsigned long action,
enum MHI_STATUS init_mhi_base_state(struct mhi_device_ctxt *mhi_dev_ctxt);
enum MHI_STATUS mhi_turn_off_pcie_link(struct mhi_device_ctxt *mhi_dev_ctxt);
enum MHI_STATUS mhi_turn_on_pcie_link(struct mhi_device_ctxt *mhi_dev_ctxt);
-void delayed_m3(struct work_struct *work);
-void m0_work(struct work_struct *work);
int mhi_initiate_m0(struct mhi_device_ctxt *mhi_dev_ctxt);
int mhi_initiate_m3(struct mhi_device_ctxt *mhi_dev_ctxt);
int mhi_set_bus_request(struct mhi_device_ctxt *mhi_dev_ctxt,
@@ -592,5 +585,8 @@ void mhi_reg_write(struct mhi_device_ctxt *mhi_dev_ctxt,
u32 mhi_reg_read(void __iomem *io_addr, uintptr_t io_offset);
u32 mhi_reg_read_field(void __iomem *io_addr, uintptr_t io_offset,
u32 mask, u32 shift);
+void mhi_exit_m2(struct mhi_device_ctxt *mhi_dev_ctxt);
+int mhi_runtime_suspend(struct device *dev);
+int mhi_runtime_resume(struct device *dev);
#endif
diff --git a/drivers/platform/msm/mhi/mhi_iface.c b/drivers/platform/msm/mhi/mhi_iface.c
index 4fb1c2547612..662f5c68be4a 100644
--- a/drivers/platform/msm/mhi/mhi_iface.c
+++ b/drivers/platform/msm/mhi/mhi_iface.c
@@ -18,6 +18,7 @@
#include <linux/msm-bus.h>
#include <linux/delay.h>
#include <linux/debugfs.h>
+#include <linux/pm_runtime.h>
#define CREATE_TRACE_POINTS
#include "mhi_trace.h"
@@ -157,6 +158,8 @@ int mhi_ctxt_init(struct mhi_pcie_dev_info *mhi_pcie_dev)
mhi_pcie_dev->mhi_ctxt.mmio_addr = mhi_pcie_dev->core.bar0_base;
pcie_device->dev.platform_data = &mhi_pcie_dev->mhi_ctxt;
+ mhi_pcie_dev->mhi_ctxt.dev_info->plat_dev->dev.platform_data =
+ &mhi_pcie_dev->mhi_ctxt;
if (mhi_pcie_dev->mhi_ctxt.base_state == STATE_TRANSITION_BHI) {
ret_val = bhi_probe(mhi_pcie_dev);
if (ret_val) {
@@ -189,6 +192,12 @@ msi_config_err:
return ret_val;
}
+static const struct dev_pm_ops pm_ops = {
+ .runtime_suspend = mhi_runtime_suspend,
+ .runtime_resume = mhi_runtime_resume,
+ .runtime_idle = NULL,
+};
+
static struct pci_driver mhi_pcie_driver = {
.name = "mhi_pcie_drv",
.id_table = mhi_pcie_device_id,
@@ -247,6 +256,7 @@ static struct platform_driver mhi_plat_driver = {
.name = "mhi",
.owner = THIS_MODULE,
.of_match_table = mhi_plat_match,
+ .pm = &pm_ops,
},
};
diff --git a/drivers/platform/msm/mhi/mhi_init.c b/drivers/platform/msm/mhi/mhi_init.c
index 0b9fb890e8c5..c11ac2faeeaa 100644
--- a/drivers/platform/msm/mhi/mhi_init.c
+++ b/drivers/platform/msm/mhi/mhi_init.c
@@ -473,14 +473,6 @@ static enum MHI_STATUS mhi_init_contexts(struct mhi_device_ctxt *mhi_dev_ctxt)
static enum MHI_STATUS mhi_init_work_queues(
struct mhi_device_ctxt *mhi_dev_ctxt)
{
- mhi_dev_ctxt->work_queue = create_singlethread_workqueue("mhi");
- if (NULL == mhi_dev_ctxt->work_queue) {
- mhi_log(MHI_MSG_CRITICAL | MHI_DBG_POWER,
- "Failed to create MHI work queue.\n");
- return MHI_STATUS_ERROR;
- }
- INIT_DELAYED_WORK(&mhi_dev_ctxt->m3_work, delayed_m3);
- INIT_WORK(&mhi_dev_ctxt->m0_work, m0_work);
return MHI_STATUS_SUCCESS;
}
diff --git a/drivers/platform/msm/mhi/mhi_macros.h b/drivers/platform/msm/mhi/mhi_macros.h
index 791f8a484464..8b8505bd3563 100644
--- a/drivers/platform/msm/mhi/mhi_macros.h
+++ b/drivers/platform/msm/mhi/mhi_macros.h
@@ -28,6 +28,7 @@
#define MHI_MAX_RESUME_TIMEOUT 5000
#define MHI_MAX_SUSPEND_TIMEOUT 5000
#define MHI_MAX_CMD_TIMEOUT 500
+#define MHI_RPM_AUTOSUSPEND_TMR_VAL_MS 1000
#define MAX_NR_MSI 4
diff --git a/drivers/platform/msm/mhi/mhi_main.c b/drivers/platform/msm/mhi/mhi_main.c
index faf066b482b5..f9459125e1ee 100644
--- a/drivers/platform/msm/mhi/mhi_main.c
+++ b/drivers/platform/msm/mhi/mhi_main.c
@@ -21,6 +21,7 @@
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/completion.h>
+#include <linux/pm_runtime.h>
#include "mhi_sys.h"
#include "mhi.h"
@@ -234,6 +235,7 @@ enum MHI_STATUS mhi_open_channel(struct mhi_client_handle *client_handle)
chan = client_handle->chan;
mhi_log(MHI_MSG_INFO,
"Entered: Client opening chan 0x%x\n", chan);
+ init_completion(&client_handle->chan_open_complete);
mhi_dev_ctxt = client_handle->mhi_dev_ctxt;
switch (mhi_dev_ctxt->dev_exec_env) {
case MHI_EXEC_ENV_PBL:
@@ -314,9 +316,6 @@ enum MHI_STATUS mhi_register_channel(struct mhi_client_handle **client_handle,
(*client_handle)->user_data = UserData;
- init_completion(&(*client_handle)->chan_reset_complete);
- init_completion(&(*client_handle)->chan_open_complete);
-
(*client_handle)->cb_mod = 1;
(*client_handle)->chan_status = 0;
(*client_handle)->magic = MHI_HANDLE_MAGIC;
@@ -353,6 +352,7 @@ void mhi_close_channel(struct mhi_client_handle *mhi_handle)
return;
chan = mhi_handle->chan;
mhi_log(MHI_MSG_INFO, "Client attempting to close chan 0x%x\n", chan);
+ init_completion(&mhi_handle->chan_reset_complete);
index = mhi_handle->device_index;
if (!atomic_read(&mhi_handle->mhi_dev_ctxt->flags.pending_ssr)) {
ret_val = mhi_send_cmd(mhi_handle->mhi_dev_ctxt,
@@ -362,15 +362,14 @@ void mhi_close_channel(struct mhi_client_handle *mhi_handle)
"Failed to send reset cmd for chan %d ret %d\n",
chan, ret_val);
}
- r = wait_for_completion_interruptible_timeout(
+ r = wait_for_completion_timeout(
&mhi_handle->chan_reset_complete,
msecs_to_jiffies(MHI_MAX_CMD_TIMEOUT));
- if (0 == r || -ERESTARTSYS == r) {
+ if (!r)
mhi_log(MHI_MSG_ERROR,
"Failed to reset chan %d ret %d\n",
chan, r);
- }
} else {
/*
* Assumption: Device is not playing with our
@@ -473,87 +472,62 @@ enum MHI_STATUS mhi_add_elements_to_event_rings(
return ret_val;
}
-static enum MHI_STATUS mhi_wake_dev_from_m3(
- struct mhi_device_ctxt *mhi_dev_ctxt)
+void mhi_update_chan_db(struct mhi_device_ctxt *mhi_dev_ctxt,
+ u32 chan)
{
- int r = 0;
- if (!atomic_cmpxchg(&mhi_dev_ctxt->flags.m0_work_enabled, 0, 1)) {
- mhi_log(MHI_MSG_INFO,
- "Initiating M0 work...\n");
- if (atomic_read(&mhi_dev_ctxt->flags.pending_resume)) {
- mhi_log(MHI_MSG_INFO,
- "Resume is pending, quitting ...\n");
- atomic_set(&mhi_dev_ctxt->flags.m0_work_enabled, 0);
- __pm_stay_awake(&mhi_dev_ctxt->w_lock);
- __pm_relax(&mhi_dev_ctxt->w_lock);
- return MHI_STATUS_SUCCESS;
+ u64 db_value = mhi_v2p_addr(mhi_dev_ctxt->mhi_ctrl_seg_info,
+ (uintptr_t)mhi_dev_ctxt->mhi_local_chan_ctxt[chan].wp);
+ mhi_dev_ctxt->mhi_chan_db_order[chan]++;
+ if (IS_HARDWARE_CHANNEL(chan) && (chan % 2)) {
+ if (unlikely(mhi_xfer_db_interval != 0)) {
+ if ((mhi_dev_ctxt->
+ mhi_chan_cntr[chan].pkts_xferd %
+ mhi_xfer_db_interval) == 0)
+ mhi_process_db(mhi_dev_ctxt,
+ mhi_dev_ctxt->channel_db_addr,
+ chan, db_value);
+ } else {
+ if ((mhi_dev_ctxt->
+ mhi_chan_cntr[chan].pkts_xferd %
+ MHI_XFER_DB_INTERVAL) == 0)
+ mhi_process_db(mhi_dev_ctxt,
+ mhi_dev_ctxt->channel_db_addr,
+ chan, db_value);
}
- r = queue_work(mhi_dev_ctxt->work_queue,
- &mhi_dev_ctxt->m0_work);
- if (!r)
- mhi_log(MHI_MSG_CRITICAL,
- "Failed to start M0 work.\n");
} else {
- mhi_log(MHI_MSG_VERBOSE,
- "M0 work pending.\n");
+ mhi_process_db(mhi_dev_ctxt,
+ mhi_dev_ctxt->channel_db_addr,
+ chan, db_value);
}
- return MHI_STATUS_SUCCESS;
}
static enum MHI_STATUS mhi_notify_device(
struct mhi_device_ctxt *mhi_dev_ctxt, u32 chan)
{
unsigned long flags = 0;
- u64 db_value;
struct mhi_chan_ctxt *chan_ctxt;
+ enum MHI_STATUS ret_val = MHI_STATUS_SUCCESS;
chan_ctxt = &mhi_dev_ctxt->mhi_ctrl_seg->mhi_cc_list[chan];
+
spin_lock_irqsave(&mhi_dev_ctxt->db_write_lock[chan], flags);
if (likely(((MHI_STATE_M0 == mhi_dev_ctxt->mhi_state) ||
(MHI_STATE_M1 == mhi_dev_ctxt->mhi_state)) &&
(chan_ctxt->mhi_chan_state != MHI_CHAN_STATE_ERROR) &&
!mhi_dev_ctxt->flags.pending_M3)) {
-
- mhi_dev_ctxt->mhi_chan_db_order[chan]++;
- db_value = mhi_v2p_addr(mhi_dev_ctxt->mhi_ctrl_seg_info,
- (uintptr_t)mhi_dev_ctxt->mhi_local_chan_ctxt[chan].wp);
- if (IS_HARDWARE_CHANNEL(chan) && (chan % 2)) {
- if (unlikely(mhi_xfer_db_interval != 0)) {
- if ((mhi_dev_ctxt->
- mhi_chan_cntr[chan].pkts_xferd %
- mhi_xfer_db_interval) == 0) {
- mhi_process_db(mhi_dev_ctxt,
- mhi_dev_ctxt->channel_db_addr,
- chan, db_value);
- }
- } else {
- if ((mhi_dev_ctxt->
- mhi_chan_cntr[chan].pkts_xferd %
- MHI_XFER_DB_INTERVAL) == 0) {
- mhi_process_db(mhi_dev_ctxt,
- mhi_dev_ctxt->channel_db_addr,
- chan, db_value);
- }
- }
- } else {
- mhi_process_db(mhi_dev_ctxt,
- mhi_dev_ctxt->channel_db_addr,
- chan, db_value);
- }
+ mhi_update_chan_db(mhi_dev_ctxt, chan);
} else {
mhi_log(MHI_MSG_VERBOSE,
- "Wakeup, pending data MHI state %d, chan state %d\n",
- mhi_dev_ctxt->mhi_state, chan_ctxt->mhi_chan_state);
- if (mhi_dev_ctxt->flags.pending_M3 ||
- mhi_dev_ctxt->mhi_state == MHI_STATE_M3) {
- mhi_wake_dev_from_m3(mhi_dev_ctxt);
- }
+ "Wakeup, pending data state %d chan state %d\n",
+ mhi_dev_ctxt->mhi_state,
+ chan_ctxt->mhi_chan_state);
+ ret_val = MHI_STATUS_SUCCESS;
}
spin_unlock_irqrestore(&mhi_dev_ctxt->db_write_lock[chan], flags);
/*
* If there are no clients still sending we can trigger our
* inactivity timer
*/
- return MHI_STATUS_SUCCESS;
+ return ret_val;
}
enum MHI_STATUS mhi_queue_xfer(struct mhi_client_handle *client_handle,
@@ -574,6 +548,7 @@ enum MHI_STATUS mhi_queue_xfer(struct mhi_client_handle *client_handle,
"Client buffer is of invalid length\n");
mhi_dev_ctxt = client_handle->mhi_dev_ctxt;
chan = client_handle->chan;
+ pm_runtime_get(&mhi_dev_ctxt->dev_info->plat_dev->dev);
/* Bump up the vote for pending data */
read_lock_irqsave(&mhi_dev_ctxt->xfer_lock, flags);
@@ -617,10 +592,10 @@ enum MHI_STATUS mhi_queue_xfer(struct mhi_client_handle *client_handle,
}
mhi_notify_device(mhi_dev_ctxt, chan);
- atomic_dec(&mhi_dev_ctxt->flags.data_pending);
- return MHI_STATUS_SUCCESS;
error:
atomic_dec(&mhi_dev_ctxt->flags.data_pending);
+ pm_runtime_mark_last_busy(&mhi_dev_ctxt->dev_info->plat_dev->dev);
+ pm_runtime_put_noidle(&mhi_dev_ctxt->dev_info->plat_dev->dev);
return ret_val;
}
EXPORT_SYMBOL(mhi_queue_xfer);
@@ -649,6 +624,7 @@ enum MHI_STATUS mhi_send_cmd(struct mhi_device_ctxt *mhi_dev_ctxt,
chan, cmd);
mhi_assert_device_wake(mhi_dev_ctxt);
+ pm_runtime_get(&mhi_dev_ctxt->dev_info->plat_dev->dev);
/*
* If there is a cmd pending a struct device confirmation,
* do not send anymore for this channel
@@ -725,16 +701,13 @@ enum MHI_STATUS mhi_send_cmd(struct mhi_device_ctxt *mhi_dev_ctxt,
mhi_dev_ctxt->cmd_ring_order++;
mhi_process_db(mhi_dev_ctxt, mhi_dev_ctxt->cmd_db_addr, 0,
db_value);
- } else {
- mhi_log(MHI_MSG_INFO,
- "Waking dev from M3 for cmd %d on chan %d\n",
- cmd, chan);
- mhi_wake_dev_from_m3(mhi_dev_ctxt);
}
mhi_log(MHI_MSG_VERBOSE, "Sent command 0x%x for chan %d\n",
cmd, chan);
mutex_unlock(&mhi_dev_ctxt->mhi_cmd_mutex_list[PRIMARY_CMD_RING]);
+ pm_runtime_mark_last_busy(&mhi_dev_ctxt->dev_info->plat_dev->dev);
+ pm_runtime_put_noidle(&mhi_dev_ctxt->dev_info->plat_dev->dev);
mhi_log(MHI_MSG_INFO, "Exited.\n");
return MHI_STATUS_SUCCESS;
diff --git a/drivers/platform/msm/mhi/mhi_pm.c b/drivers/platform/msm/mhi/mhi_pm.c
index a12bdef7a8fa..6878b5dd7af8 100644
--- a/drivers/platform/msm/mhi/mhi_pm.c
+++ b/drivers/platform/msm/mhi/mhi_pm.c
@@ -15,6 +15,7 @@
#include <linux/pm.h>
#include <linux/fs.h>
#include <linux/hrtimer.h>
+#include <linux/pm_runtime.h>
#include "mhi_sys.h"
#include "mhi.h"
@@ -46,11 +47,6 @@ int mhi_pci_suspend(struct pci_dev *pcie_dev, pm_message_t state)
mhi_log(MHI_MSG_INFO, "Entered, sys state %d, MHI state %d\n",
state.event, mhi_dev_ctxt->mhi_state);
atomic_set(&mhi_dev_ctxt->flags.pending_resume, 1);
- r = cancel_work_sync(&mhi_dev_ctxt->m0_work);
- if (!r) {
- atomic_set(&mhi_dev_ctxt->flags.m0_work_enabled, 0);
- mhi_log(MHI_MSG_INFO, "M0 work cancelled\n");
- }
r = mhi_initiate_m3(mhi_dev_ctxt);
@@ -58,8 +54,29 @@ int mhi_pci_suspend(struct pci_dev *pcie_dev, pm_message_t state)
return r;
atomic_set(&mhi_dev_ctxt->flags.pending_resume, 0);
- mhi_log(MHI_MSG_ERROR, "Failing suspend sequence ret: %d\n",
- r);
+ mhi_log(MHI_MSG_INFO, "Exited, ret %d\n", r);
+ return r;
+}
+
+int mhi_runtime_suspend(struct device *dev)
+{
+ int r = 0;
+ struct mhi_device_ctxt *mhi_dev_ctxt = dev->platform_data;
+ mhi_log(MHI_MSG_INFO, "Runtime Suspend - Entered\n");
+ r = mhi_initiate_m3(mhi_dev_ctxt);
+ pm_runtime_mark_last_busy(dev);
+ mhi_log(MHI_MSG_INFO, "Runtime Suspend - Exited\n");
+ return r;
+}
+
+int mhi_runtime_resume(struct device *dev)
+{
+ int r = 0;
+ struct mhi_device_ctxt *mhi_dev_ctxt = dev->platform_data;
+ mhi_log(MHI_MSG_INFO, "Runtime Resume - Entered\n");
+ r = mhi_initiate_m0(mhi_dev_ctxt);
+ pm_runtime_mark_last_busy(dev);
+ mhi_log(MHI_MSG_INFO, "Runtime Resume - Exited\n");
return r;
}
diff --git a/drivers/platform/msm/mhi/mhi_states.c b/drivers/platform/msm/mhi/mhi_states.c
index 4d4b81873340..65cbe88754b6 100644
--- a/drivers/platform/msm/mhi/mhi_states.c
+++ b/drivers/platform/msm/mhi/mhi_states.c
@@ -14,6 +14,9 @@
#include "mhi_hwio.h"
#include "mhi_trace.h"
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
static void conditional_chan_db_write(
struct mhi_device_ctxt *mhi_dev_ctxt, u32 chan)
{
@@ -111,14 +114,7 @@ static enum MHI_STATUS process_m0_transition(
unsigned long flags;
int ret_val;
mhi_log(MHI_MSG_INFO, "Entered\n");
- ret_val = cancel_delayed_work(&mhi_dev_ctxt->m3_work);
- if (ret_val) {
- atomic_set(&mhi_dev_ctxt->flags.m3_work_enabled, 0);
- mhi_log(MHI_MSG_INFO, "M3 work was cancelled\n");
- } else {
- mhi_log(MHI_MSG_INFO,
- "M3 work NOT cancelled, either running or never started\n");
- }
+
if (mhi_dev_ctxt->mhi_state == MHI_STATE_M2) {
mhi_dev_ctxt->counters.m2_m0++;
} else if (mhi_dev_ctxt->mhi_state == MHI_STATE_M3) {
@@ -175,6 +171,7 @@ static enum MHI_STATUS process_m1_transition(
{
unsigned long flags = 0;
int ret_val = 0;
+ int r = 0;
mhi_log(MHI_MSG_INFO,
"Processing M1 state transition from state %d\n",
mhi_dev_ctxt->mhi_state);
@@ -213,15 +210,20 @@ static enum MHI_STATUS process_m1_transition(
0);
if (ret_val)
mhi_log(MHI_MSG_INFO, "Failed to update bus request\n");
- if (!atomic_cmpxchg(&mhi_dev_ctxt->flags.m3_work_enabled, 0, 1)) {
- mhi_log(MHI_MSG_INFO, "Starting M3 deferred work\n");
- ret_val = queue_delayed_work(mhi_dev_ctxt->work_queue,
- &mhi_dev_ctxt->m3_work,
- msecs_to_jiffies(m3_timer_val_ms));
- if (ret_val == 0)
- mhi_log(MHI_MSG_CRITICAL,
- "Failed to start M3 delayed work.\n");
+
+ mhi_log(MHI_MSG_INFO, "Start Deferred Suspend usage_count: %d\n",
+ atomic_read(
+ &mhi_dev_ctxt->dev_info->plat_dev->dev.power.usage_count));
+
+ pm_runtime_mark_last_busy(&mhi_dev_ctxt->dev_info->plat_dev->dev);
+ r = pm_request_autosuspend(&mhi_dev_ctxt->dev_info->plat_dev->dev);
+ if (r) {
+ mhi_log(MHI_MSG_ERROR, "Failed to remove counter ret %d\n", r);
+ mhi_log(MHI_MSG_ERROR, "Usage counter is %d\n",
+ atomic_read(
+ &mhi_dev_ctxt->dev_info->plat_dev->dev.power.usage_count));
}
+
return MHI_STATUS_SUCCESS;
}
@@ -269,17 +271,7 @@ static enum MHI_STATUS mhi_process_link_down(
mhi_deassert_device_wake(mhi_dev_ctxt);
write_unlock_irqrestore(&mhi_dev_ctxt->xfer_lock, flags);
- r = cancel_delayed_work_sync(&mhi_dev_ctxt->m3_work);
- if (r) {
- atomic_set(&mhi_dev_ctxt->flags.m3_work_enabled, 0);
- mhi_log(MHI_MSG_INFO, "M3 work cancelled\n");
- }
- r = cancel_work_sync(&mhi_dev_ctxt->m0_work);
- if (r) {
- atomic_set(&mhi_dev_ctxt->flags.m0_work_enabled, 0);
- mhi_log(MHI_MSG_INFO, "M0 work cancelled\n");
- }
mhi_dev_ctxt->flags.stop_threads = 1;
while (!mhi_dev_ctxt->ev_thread_stopped) {
@@ -541,10 +533,10 @@ enum MHI_STATUS start_chan_sync(struct mhi_client_handle *client_handle)
MHI_CLIENT_SAHARA_OUT, ret_val);
return ret_val;
}
- r = wait_for_completion_interruptible_timeout(
+ r = wait_for_completion_timeout(
&client_handle->chan_open_complete,
msecs_to_jiffies(MHI_MAX_CMD_TIMEOUT));
- if (0 == r || -ERESTARTSYS == r) {
+ if (!r) {
mhi_log(MHI_MSG_ERROR,
"Failed to start chan %d ret %d\n",
client_handle->chan, r);
@@ -600,7 +592,19 @@ static enum MHI_STATUS process_sbl_transition(
struct mhi_device_ctxt *mhi_dev_ctxt,
enum STATE_TRANSITION cur_work_item)
{
+ int r;
mhi_log(MHI_MSG_INFO, "Processing SBL state transition\n");
+
+ pm_runtime_set_autosuspend_delay(&mhi_dev_ctxt->dev_info->plat_dev->dev,
+ MHI_RPM_AUTOSUSPEND_TMR_VAL_MS);
+ pm_runtime_use_autosuspend(&mhi_dev_ctxt->dev_info->plat_dev->dev);
+ r = pm_runtime_set_active(&mhi_dev_ctxt->dev_info->plat_dev->dev);
+ if (r) {
+ mhi_log(MHI_MSG_ERROR,
+ "Failed to activate runtime pm ret %d\n", r);
+ }
+ pm_runtime_enable(&mhi_dev_ctxt->dev_info->plat_dev->dev);
+ mhi_log(MHI_MSG_INFO, "Enabled runtime pm\n");
mhi_dev_ctxt->dev_exec_env = MHI_EXEC_ENV_SBL;
wmb();
enable_clients(mhi_dev_ctxt, mhi_dev_ctxt->dev_exec_env);
@@ -612,6 +616,7 @@ static enum MHI_STATUS process_amss_transition(
enum STATE_TRANSITION cur_work_item)
{
enum MHI_STATUS ret_val;
+
mhi_log(MHI_MSG_INFO, "Processing AMSS state transition\n");
mhi_dev_ctxt->dev_exec_env = MHI_EXEC_ENV_AMSS;
atomic_inc(&mhi_dev_ctxt->flags.data_pending);
@@ -843,30 +848,6 @@ enum MHI_STATUS mhi_init_state_transition(struct mhi_device_ctxt *mhi_dev_ctxt,
return ret_val;
}
-void delayed_m3(struct work_struct *work)
-{
- int r;
- struct delayed_work *del_work = to_delayed_work(work);
- struct mhi_device_ctxt *mhi_dev_ctxt = container_of(del_work,
- struct mhi_device_ctxt, m3_work);
- r = mhi_initiate_m3(mhi_dev_ctxt);
- if (r)
- mhi_log(MHI_MSG_INFO, "Failed to initiate M3 ret: %d\n", r);
-
-}
-
-void m0_work(struct work_struct *work)
-{
- struct mhi_device_ctxt *mhi_dev_ctxt =
- container_of(work, struct mhi_device_ctxt, m0_work);
- if (!atomic_read(&mhi_dev_ctxt->flags.pending_resume)) {
- mhi_log(MHI_MSG_INFO, "No pending resume, initiating M0.\n");
- mhi_initiate_m0(mhi_dev_ctxt);
- } else {
- mhi_log(MHI_MSG_INFO, "Pending resume, quitting.\n");
- }
-}
-
int mhi_initiate_m0(struct mhi_device_ctxt *mhi_dev_ctxt)
{
int r = 0;
@@ -939,7 +920,6 @@ int mhi_initiate_m0(struct mhi_device_ctxt *mhi_dev_ctxt)
write_unlock_irqrestore(&mhi_dev_ctxt->xfer_lock, flags);
}
exit:
- atomic_set(&mhi_dev_ctxt->flags.m0_work_enabled, 0);
mutex_unlock(&mhi_dev_ctxt->pm_lock);
mhi_log(MHI_MSG_INFO, "Exited...\n");
return r;
@@ -949,7 +929,7 @@ int mhi_initiate_m3(struct mhi_device_ctxt *mhi_dev_ctxt)
{
unsigned long flags;
- int r;
+ int r = 0;
int abort_m3 = 0;
mhi_log(MHI_MSG_INFO,
@@ -982,6 +962,7 @@ int mhi_initiate_m3(struct mhi_device_ctxt *mhi_dev_ctxt)
if (0 == r || -ERESTARTSYS == r) {
mhi_log(MHI_MSG_INFO,
"MDM failed to come out of M2.\n");
+ r = -EAGAIN;
goto exit;
}
break;
@@ -991,7 +972,7 @@ int mhi_initiate_m3(struct mhi_device_ctxt *mhi_dev_ctxt)
mhi_dev_ctxt->mhi_state,
mhi_dev_ctxt->flags.link_up);
if (mhi_dev_ctxt->flags.link_up)
- r = -EPERM;
+ r = -EAGAIN;
else
r = 0;
goto exit;
@@ -1009,11 +990,13 @@ int mhi_initiate_m3(struct mhi_device_ctxt *mhi_dev_ctxt)
__pm_stay_awake(&mhi_dev_ctxt->w_lock);
__pm_relax(&mhi_dev_ctxt->w_lock);
abort_m3 = 1;
+ r = -EAGAIN;
goto exit;
}
if (atomic_read(&mhi_dev_ctxt->flags.data_pending)) {
abort_m3 = 1;
+ r = -EAGAIN;
goto exit;
}
r = hrtimer_cancel(&mhi_dev_ctxt->m1_timer);
@@ -1025,9 +1008,7 @@ int mhi_initiate_m3(struct mhi_device_ctxt *mhi_dev_ctxt)
write_lock_irqsave(&mhi_dev_ctxt->xfer_lock, flags);
if (mhi_dev_ctxt->flags.pending_M0) {
write_unlock_irqrestore(&mhi_dev_ctxt->xfer_lock, flags);
- mhi_log(MHI_MSG_INFO,
- "Pending M0 detected, aborting M3 procedure\n");
- r = -EPERM;
+ r = -EAGAIN;
goto exit;
}
mhi_dev_ctxt->flags.pending_M3 = 1;
@@ -1072,7 +1053,6 @@ exit:
ring_all_chan_dbs(mhi_dev_ctxt);
atomic_dec(&mhi_dev_ctxt->flags.data_pending);
}
- atomic_set(&mhi_dev_ctxt->flags.m3_work_enabled, 0);
mhi_dev_ctxt->flags.pending_M3 = 0;
mutex_unlock(&mhi_dev_ctxt->pm_lock);
return r;
diff --git a/drivers/platform/msm/mhi/mhi_sys.c b/drivers/platform/msm/mhi/mhi_sys.c
index 07cd5f8b03c6..53cdc8828b92 100644
--- a/drivers/platform/msm/mhi/mhi_sys.c
+++ b/drivers/platform/msm/mhi/mhi_sys.c
@@ -39,9 +39,6 @@ MODULE_PARM_DESC(mhi_ipc_log_lvl, "dbg lvl");
module_param(mhi_msg_class , uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(mhi_msg_class, "dbg class");
-u32 m3_timer_val_ms = 1000;
-module_param(m3_timer_val_ms, uint, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(m3_timer_val_ms, "timer val");
static ssize_t mhi_dbgfs_chan_read(struct file *fp, char __user *buf,
size_t count, loff_t *offp)