提交 f80b5e99 编写于 作者: H Henrique de Moraes Holschuh 提交者: John W. Linville

rfkill: preserve state across suspend

The rfkill class API requires that the driver connected to a class
call rfkill_force_state() on resume to update the real state of the
rfkill controller, OR that it provides a get_state() hook.

This means there is potentially a hidden call in the resume code flow
that changes rfkill->state (i.e. rfkill_force_state()), so the
previous state of the transmitter was being lost.

The simplest and most future-proof way to fix this is to explicitly
store the pre-sleep state on the rfkill structure, and restore from
that on resume.
Signed-off-by: NHenrique de Moraes Holschuh <hmh@hmh.eng.br>
Acked-by: NIvo van Doorn <IvDoorn@gmail.com>
Cc: Matthew Garrett <mjg59@srcf.ucam.org>
Cc: Alan Jenkins <alan-jenkins@tuffmail.co.uk>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 5925d976
...@@ -108,6 +108,7 @@ struct rfkill { ...@@ -108,6 +108,7 @@ struct rfkill {
struct device dev; struct device dev;
struct list_head node; struct list_head node;
enum rfkill_state state_for_resume;
}; };
#define to_rfkill(d) container_of(d, struct rfkill, dev) #define to_rfkill(d) container_of(d, struct rfkill, dev)
......
...@@ -565,10 +565,15 @@ static void rfkill_release(struct device *dev) ...@@ -565,10 +565,15 @@ static void rfkill_release(struct device *dev)
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int rfkill_suspend(struct device *dev, pm_message_t state) static int rfkill_suspend(struct device *dev, pm_message_t state)
{ {
struct rfkill *rfkill = to_rfkill(dev);
/* mark class device as suspended */ /* mark class device as suspended */
if (dev->power.power_state.event != state.event) if (dev->power.power_state.event != state.event)
dev->power.power_state = state; dev->power.power_state = state;
/* store state for the resume handler */
rfkill->state_for_resume = rfkill->state;
return 0; return 0;
} }
...@@ -590,7 +595,7 @@ static int rfkill_resume(struct device *dev) ...@@ -590,7 +595,7 @@ static int rfkill_resume(struct device *dev)
rfkill_toggle_radio(rfkill, rfkill_toggle_radio(rfkill,
rfkill_epo_lock_active ? rfkill_epo_lock_active ?
RFKILL_STATE_SOFT_BLOCKED : RFKILL_STATE_SOFT_BLOCKED :
rfkill->state, rfkill->state_for_resume,
1); 1);
mutex_unlock(&rfkill->mutex); mutex_unlock(&rfkill->mutex);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册