forked from luck/tmp_suning_uos_patched
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: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Acked-by: Ivo van Doorn <IvDoorn@gmail.com> Cc: Matthew Garrett <mjg59@srcf.ucam.org> Cc: Alan Jenkins <alan-jenkins@tuffmail.co.uk> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
5925d976fb
commit
f80b5e99c7
|
@ -108,6 +108,7 @@ struct rfkill {
|
|||
|
||||
struct device dev;
|
||||
struct list_head node;
|
||||
enum rfkill_state state_for_resume;
|
||||
};
|
||||
#define to_rfkill(d) container_of(d, struct rfkill, dev)
|
||||
|
||||
|
|
|
@ -565,10 +565,15 @@ static void rfkill_release(struct device *dev)
|
|||
#ifdef CONFIG_PM
|
||||
static int rfkill_suspend(struct device *dev, pm_message_t state)
|
||||
{
|
||||
struct rfkill *rfkill = to_rfkill(dev);
|
||||
|
||||
/* mark class device as suspended */
|
||||
if (dev->power.power_state.event != state.event)
|
||||
dev->power.power_state = state;
|
||||
|
||||
/* store state for the resume handler */
|
||||
rfkill->state_for_resume = rfkill->state;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -590,7 +595,7 @@ static int rfkill_resume(struct device *dev)
|
|||
rfkill_toggle_radio(rfkill,
|
||||
rfkill_epo_lock_active ?
|
||||
RFKILL_STATE_SOFT_BLOCKED :
|
||||
rfkill->state,
|
||||
rfkill->state_for_resume,
|
||||
1);
|
||||
|
||||
mutex_unlock(&rfkill->mutex);
|
||||
|
|
Loading…
Reference in New Issue
Block a user