diff options
author | Henrique de Moraes Holschuh <hmh@hmh.eng.br> | 2008-08-26 10:58:01 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-09-15 16:48:25 -0400 |
commit | bed7aac9416f50425d2200df32bcc9bf248ff8cb (patch) | |
tree | 4471647eb3e15d3afb7eba8642537b96561dff7b | |
parent | e35cc4ddcc4c3b11006bcabe8ce28aa7e18da318 (diff) |
rfkill: remove transmitter blocking on suspend
Currently, rfkill would stand in the way of properly supporting wireless
devices that are capable of waking the system up from sleep or hibernation
when they receive a special wireless message. It would also get in the way
of mesh devices that need to remain operational even during platform
suspend.
To avoid that, stop trying to block the transmitters on the rfkill class
suspend handler.
Drivers that need rfkill's older behaviour will have to implement it by
themselves in their own suspend handling.
Do note that rfkill *will* attempt to restore the transmitter state on
resume in any situation. This happens after the driver's resume method is
called by the suspend core (class devices resume after the devices they are
attached to have been resumed).
The following drivers need to check if they need to explicitly block
their transmitters in their own suspend handlers (maintainers Cc'd):
arch/arm/mach-pxa/tosa-bt.c
drivers/net/usb/hso.c
drivers/net/wireless/rt2x00/* (USB might need it?)
drivers/net/wireless/b43/ (SSB over USB might need it?)
drivers/misc/hp-wmi.c
eeepc-laptop w/rfkill support (not in mainline yet)
Compal laptop w/rfkill support (not in mainline yet)
toshiba-acpi w/rfkill support (not in mainline yet)
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Cc: Ivo van Doorn <IvDoorn@gmail.com>
Cc: Matthew Garrett <mjg@redhat.com>
Cc: Andrew Bird <ajb@spheresystems.co.uk>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: Cezary Jackiewicz <cezary.jackiewicz@gmail.com>
Cc: Philip Langdale <philipl@overt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | Documentation/rfkill.txt | 32 | ||||
-rw-r--r-- | net/rfkill/rfkill.c | 16 |
2 files changed, 30 insertions, 18 deletions
diff --git a/Documentation/rfkill.txt b/Documentation/rfkill.txt index 6fcb3060dec5..b65f0799df48 100644 --- a/Documentation/rfkill.txt +++ b/Documentation/rfkill.txt | |||
@@ -341,6 +341,8 @@ key that does nothing by itself, as well as any hot key that is type-specific | |||
341 | 3.1 Guidelines for wireless device drivers | 341 | 3.1 Guidelines for wireless device drivers |
342 | ------------------------------------------ | 342 | ------------------------------------------ |
343 | 343 | ||
344 | (in this text, rfkill->foo means the foo field of struct rfkill). | ||
345 | |||
344 | 1. Each independent transmitter in a wireless device (usually there is only one | 346 | 1. Each independent transmitter in a wireless device (usually there is only one |
345 | transmitter per device) should have a SINGLE rfkill class attached to it. | 347 | transmitter per device) should have a SINGLE rfkill class attached to it. |
346 | 348 | ||
@@ -363,10 +365,32 @@ This rule exists because users of the rfkill subsystem expect to get (and set, | |||
363 | when possible) the overall transmitter rfkill state, not of a particular rfkill | 365 | when possible) the overall transmitter rfkill state, not of a particular rfkill |
364 | line. | 366 | line. |
365 | 367 | ||
366 | 5. During suspend, the rfkill class will attempt to soft-block the radio | 368 | 5. The wireless device driver MUST NOT leave the transmitter enabled during |
367 | through a call to rfkill->toggle_radio, and will try to restore its previous | 369 | suspend and hibernation unless: |
368 | state during resume. After a rfkill class is suspended, it will *not* call | 370 | |
369 | rfkill->toggle_radio until it is resumed. | 371 | 5.1. The transmitter has to be enabled for some sort of functionality |
372 | like wake-on-wireless-packet or autonomous packed forwarding in a mesh | ||
373 | network, and that functionality is enabled for this suspend/hibernation | ||
374 | cycle. | ||
375 | |||
376 | AND | ||
377 | |||
378 | 5.2. The device was not on a user-requested BLOCKED state before | ||
379 | the suspend (i.e. the driver must NOT unblock a device, not even | ||
380 | to support wake-on-wireless-packet or remain in the mesh). | ||
381 | |||
382 | In other words, there is absolutely no allowed scenario where a driver can | ||
383 | automatically take action to unblock a rfkill controller (obviously, this deals | ||
384 | with scenarios where soft-blocking or both soft and hard blocking is happening. | ||
385 | Scenarios where hardware rfkill lines are the only ones blocking the | ||
386 | transmitter are outside of this rule, since the wireless device driver does not | ||
387 | control its input hardware rfkill lines in the first place). | ||
388 | |||
389 | 6. During resume, rfkill will try to restore its previous state. | ||
390 | |||
391 | 7. After a rfkill class is suspended, it will *not* call rfkill->toggle_radio | ||
392 | until it is resumed. | ||
393 | |||
370 | 394 | ||
371 | Example of a WLAN wireless driver connected to the rfkill subsystem: | 395 | Example of a WLAN wireless driver connected to the rfkill subsystem: |
372 | -------------------------------------------------------------------- | 396 | -------------------------------------------------------------------- |
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index d5735799ccd9..ea0dc04b3c77 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c | |||
@@ -512,21 +512,9 @@ static void rfkill_release(struct device *dev) | |||
512 | #ifdef CONFIG_PM | 512 | #ifdef CONFIG_PM |
513 | static int rfkill_suspend(struct device *dev, pm_message_t state) | 513 | static int rfkill_suspend(struct device *dev, pm_message_t state) |
514 | { | 514 | { |
515 | struct rfkill *rfkill = to_rfkill(dev); | 515 | /* mark class device as suspended */ |
516 | 516 | if (dev->power.power_state.event != state.event) | |
517 | if (dev->power.power_state.event != state.event) { | ||
518 | if (state.event & PM_EVENT_SLEEP) { | ||
519 | /* Stop transmitter, keep state, no notifies */ | ||
520 | update_rfkill_state(rfkill); | ||
521 | |||
522 | mutex_lock(&rfkill->mutex); | ||
523 | rfkill->toggle_radio(rfkill->data, | ||
524 | RFKILL_STATE_SOFT_BLOCKED); | ||
525 | mutex_unlock(&rfkill->mutex); | ||
526 | } | ||
527 | |||
528 | dev->power.power_state = state; | 517 | dev->power.power_state = state; |
529 | } | ||
530 | 518 | ||
531 | return 0; | 519 | return 0; |
532 | } | 520 | } |