Commit 231a4c89 authored by Kalle Valo's avatar Kalle Valo

Merge branch 'mhi-immutable' of...

Merge branch 'mhi-immutable' of git://git.kernel.org/pub/scm/linux/kernel/git/mani/mhi into ath-next

This is needed for patch 'wifi: ath11k: support hibernation'.
parents 5abf2597 813e0ae6
...@@ -80,6 +80,7 @@ enum dev_st_transition { ...@@ -80,6 +80,7 @@ enum dev_st_transition {
DEV_ST_TRANSITION_FP, DEV_ST_TRANSITION_FP,
DEV_ST_TRANSITION_SYS_ERR, DEV_ST_TRANSITION_SYS_ERR,
DEV_ST_TRANSITION_DISABLE, DEV_ST_TRANSITION_DISABLE,
DEV_ST_TRANSITION_DISABLE_DESTROY_DEVICE,
DEV_ST_TRANSITION_MAX, DEV_ST_TRANSITION_MAX,
}; };
...@@ -90,7 +91,8 @@ enum dev_st_transition { ...@@ -90,7 +91,8 @@ enum dev_st_transition {
dev_st_trans(MISSION_MODE, "MISSION MODE") \ dev_st_trans(MISSION_MODE, "MISSION MODE") \
dev_st_trans(FP, "FLASH PROGRAMMER") \ dev_st_trans(FP, "FLASH PROGRAMMER") \
dev_st_trans(SYS_ERR, "SYS ERROR") \ dev_st_trans(SYS_ERR, "SYS ERROR") \
dev_st_trans_end(DISABLE, "DISABLE") dev_st_trans(DISABLE, "DISABLE") \
dev_st_trans_end(DISABLE_DESTROY_DEVICE, "DISABLE (DESTROY DEVICE)")
extern const char * const dev_state_tran_str[DEV_ST_TRANSITION_MAX]; extern const char * const dev_state_tran_str[DEV_ST_TRANSITION_MAX];
#define TO_DEV_STATE_TRANS_STR(state) (((state) >= DEV_ST_TRANSITION_MAX) ? \ #define TO_DEV_STATE_TRANS_STR(state) (((state) >= DEV_ST_TRANSITION_MAX) ? \
......
...@@ -468,7 +468,8 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) ...@@ -468,7 +468,8 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl)
} }
/* Handle shutdown transitions */ /* Handle shutdown transitions */
static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl) static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl,
bool destroy_device)
{ {
enum mhi_pm_state cur_state; enum mhi_pm_state cur_state;
struct mhi_event *mhi_event; struct mhi_event *mhi_event;
...@@ -530,8 +531,16 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl) ...@@ -530,8 +531,16 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl)
dev_dbg(dev, "Waiting for all pending threads to complete\n"); dev_dbg(dev, "Waiting for all pending threads to complete\n");
wake_up_all(&mhi_cntrl->state_event); wake_up_all(&mhi_cntrl->state_event);
/*
* Only destroy the 'struct device' for channels if indicated by the
* 'destroy_device' flag. Because, during system suspend or hibernation
* state, there is no need to destroy the 'struct device' as the endpoint
* device would still be physically attached to the machine.
*/
if (destroy_device) {
dev_dbg(dev, "Reset all active channels and remove MHI devices\n"); dev_dbg(dev, "Reset all active channels and remove MHI devices\n");
device_for_each_child(&mhi_cntrl->mhi_dev->dev, NULL, mhi_destroy_device); device_for_each_child(&mhi_cntrl->mhi_dev->dev, NULL, mhi_destroy_device);
}
mutex_lock(&mhi_cntrl->pm_mutex); mutex_lock(&mhi_cntrl->pm_mutex);
...@@ -821,7 +830,10 @@ void mhi_pm_st_worker(struct work_struct *work) ...@@ -821,7 +830,10 @@ void mhi_pm_st_worker(struct work_struct *work)
mhi_pm_sys_error_transition(mhi_cntrl); mhi_pm_sys_error_transition(mhi_cntrl);
break; break;
case DEV_ST_TRANSITION_DISABLE: case DEV_ST_TRANSITION_DISABLE:
mhi_pm_disable_transition(mhi_cntrl); mhi_pm_disable_transition(mhi_cntrl, false);
break;
case DEV_ST_TRANSITION_DISABLE_DESTROY_DEVICE:
mhi_pm_disable_transition(mhi_cntrl, true);
break; break;
default: default:
break; break;
...@@ -1175,7 +1187,8 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) ...@@ -1175,7 +1187,8 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl)
} }
EXPORT_SYMBOL_GPL(mhi_async_power_up); EXPORT_SYMBOL_GPL(mhi_async_power_up);
void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful) static void __mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful,
bool destroy_device)
{ {
enum mhi_pm_state cur_state, transition_state; enum mhi_pm_state cur_state, transition_state;
struct device *dev = &mhi_cntrl->mhi_dev->dev; struct device *dev = &mhi_cntrl->mhi_dev->dev;
...@@ -1211,15 +1224,32 @@ void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful) ...@@ -1211,15 +1224,32 @@ void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful)
write_unlock_irq(&mhi_cntrl->pm_lock); write_unlock_irq(&mhi_cntrl->pm_lock);
mutex_unlock(&mhi_cntrl->pm_mutex); mutex_unlock(&mhi_cntrl->pm_mutex);
mhi_queue_state_transition(mhi_cntrl, DEV_ST_TRANSITION_DISABLE); if (destroy_device)
mhi_queue_state_transition(mhi_cntrl,
DEV_ST_TRANSITION_DISABLE_DESTROY_DEVICE);
else
mhi_queue_state_transition(mhi_cntrl,
DEV_ST_TRANSITION_DISABLE);
/* Wait for shutdown to complete */ /* Wait for shutdown to complete */
flush_work(&mhi_cntrl->st_worker); flush_work(&mhi_cntrl->st_worker);
disable_irq(mhi_cntrl->irq[0]); disable_irq(mhi_cntrl->irq[0]);
} }
void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful)
{
__mhi_power_down(mhi_cntrl, graceful, true);
}
EXPORT_SYMBOL_GPL(mhi_power_down); EXPORT_SYMBOL_GPL(mhi_power_down);
void mhi_power_down_keep_dev(struct mhi_controller *mhi_cntrl,
bool graceful)
{
__mhi_power_down(mhi_cntrl, graceful, false);
}
EXPORT_SYMBOL_GPL(mhi_power_down_keep_dev);
int mhi_sync_power_up(struct mhi_controller *mhi_cntrl) int mhi_sync_power_up(struct mhi_controller *mhi_cntrl)
{ {
int ret = mhi_async_power_up(mhi_cntrl); int ret = mhi_async_power_up(mhi_cntrl);
......
...@@ -630,12 +630,28 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl); ...@@ -630,12 +630,28 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl);
int mhi_sync_power_up(struct mhi_controller *mhi_cntrl); int mhi_sync_power_up(struct mhi_controller *mhi_cntrl);
/** /**
* mhi_power_down - Start MHI power down sequence * mhi_power_down - Power down the MHI device and also destroy the
* 'struct device' for the channels associated with it.
* See also mhi_power_down_keep_dev() which is a variant
* of this API that keeps the 'struct device' for channels
* (useful during suspend/hibernation).
* @mhi_cntrl: MHI controller * @mhi_cntrl: MHI controller
* @graceful: Link is still accessible, so do a graceful shutdown process * @graceful: Link is still accessible, so do a graceful shutdown process
*/ */
void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful); void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful);
/**
* mhi_power_down_keep_dev - Power down the MHI device but keep the 'struct
* device' for the channels associated with it.
* This is a variant of 'mhi_power_down()' and
* useful in scenarios such as suspend/hibernation
* where destroying of the 'struct device' is not
* needed.
* @mhi_cntrl: MHI controller
* @graceful: Link is still accessible, so do a graceful shutdown process
*/
void mhi_power_down_keep_dev(struct mhi_controller *mhi_cntrl, bool graceful);
/** /**
* mhi_unprepare_after_power_down - Free any allocated memory after power down * mhi_unprepare_after_power_down - Free any allocated memory after power down
* @mhi_cntrl: MHI controller * @mhi_cntrl: MHI controller
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment