Skip to content

Commit

Permalink
rfkill: preserve state across suspend
Browse files Browse the repository at this point in the history
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 <[email protected]>
Acked-by: Ivo van Doorn <[email protected]>
Cc: Matthew Garrett <[email protected]>
Cc: Alan Jenkins <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
  • Loading branch information
hmh authored and linvjw committed Nov 26, 2008
1 parent 5925d97 commit f80b5e9
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 1 deletion.
1 change: 1 addition & 0 deletions include/linux/rfkill.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
7 changes: 6 additions & 1 deletion net/rfkill/rfkill.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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);
Expand Down

0 comments on commit f80b5e9

Please sign in to comment.