rt2x00: Add suspend/resume handlers to rt2x00rfkill
PATCH 1/1 rt2x00: Add suspend/resume handlers to rt2x00rfkill
Add suspend/resume handlers to rt2x00rfkill to have it stop the input-polldev and prevent it from calling rt2x00 during suspend period. This could lead to a NULL pointer fault when rt2x00 suspended, but polldev send a request, because the csr_addr is NULL.
Also don't let the rfkill allocation/registration block the initialization of the entire device. Just print a warning and continue as if nothing happened.
---
John, this patch was send as part of the rt2x00 2.1.4 release for the 2.6.26 kernel. Kernel bug [9585] however indicates this patch is also needed for 2.6.25 to fix a segmentation fault during resume.
Due to the presence of LED classes in rt2x00 2.1.*, the original patch won't apply cleanly against the 2.6.25 tree, so this is an updated patch for 2.6.25 only.
drivers/net/wireless/rt2x00/rt2x00.h +3 -0
@@ -620,6 +620,9 @@ struct rt2x00_dev {* This will only be compiled in when required. */ #ifdef CONFIG_RT2X00_LIB_RFKILL +unsigned long rfkill_state; +#define RFKILL_STATE_ALLOCATED 1 +#define RFKILL_STATE_REGISTERED 2struct rfkill *rfkill;struct input_polled_dev *poll_dev;#endif /* CONFIG_RT2X00_LIB_RFKILL */
drivers/net/wireless/rt2x00/rt2x00dev.c +14 -21
@@ -1098,7 +1098,7 @@ static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev)return ;/* -* Unregister rfkill. +* Unregister extra components. */ rt2x00rfkill_unregister (rt2x00dev);
@@ -1139,11 +1139,9 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)__set_bit (DEVICE_INITIALIZED , &rt2x00dev->flags);/* -* Register the rfkill handler. +* Register the extra components. */ - status =rt2x00rfkill_register (rt2x00dev); -if (status) - goto exit_unitialize; +rt2x00rfkill_register (rt2x00dev);return 0 ;
@@ -1313,15 +1311,9 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) }/* -* Allocatie rfkill. -*/ - retval =rt2x00rfkill_allocate (rt2x00dev); -if (retval) - goto exit; - -/* -* Open the debugfs entry. +* Register extra components. */ +rt2x00rfkill_allocate (rt2x00dev);rt2x00debug_register (rt2x00dev);__set_bit (DEVICE_PRESENT , &rt2x00dev->flags);
@@ -1350,13 +1342,9 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)rt2x00lib_uninitialize (rt2x00dev);/* -* Close debugfs entry. +* Free extra components */ rt2x00debug_deregister (rt2x00dev); - -/* -* Free rfkill -*/ rt2x00rfkill_free (rt2x00dev);/*
@@ -1395,11 +1383,15 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)__set_bit (DEVICE_STARTED_SUSPEND , &rt2x00dev->flags);/* -* Disable radio and unitialize all items -* that must be recreated on resume. +* Disable radio. */ rt2x00lib_stop (rt2x00dev);rt2x00lib_uninitialize (rt2x00dev); + +/* +* Suspend/disable extra components. +*/ +rt2x00rfkill_suspend (rt2x00dev);rt2x00debug_deregister (rt2x00dev); exit:
@@ -1422,9 +1414,10 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)NOTICE (rt2x00dev,"Waking up.\n" );/* -* Open the debugfs entry. +* Restore/enable extra components. */ rt2x00debug_register (rt2x00dev); +rt2x00rfkill_resume (rt2x00dev);/* * Only continue if mac80211 had open interfaces.
drivers/net/wireless/rt2x00/rt2x00lib.h +14 -6
@@ -100,28 +100,36 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,* RFkill handlers. */ #ifdef CONFIG_RT2X00_LIB_RFKILL -int rt2x00rfkill_register (struct rt2x00_dev *rt2x00dev); +void rt2x00rfkill_register (struct rt2x00_dev *rt2x00dev);void rt2x00rfkill_unregister (struct rt2x00_dev *rt2x00dev); -int rt2x00rfkill_allocate (struct rt2x00_dev *rt2x00dev); +void rt2x00rfkill_allocate (struct rt2x00_dev *rt2x00dev);void rt2x00rfkill_free (struct rt2x00_dev *rt2x00dev); +void rt2x00rfkill_suspend (struct rt2x00_dev *rt2x00dev); +void rt2x00rfkill_resume (struct rt2x00_dev *rt2x00dev);#else -static inline int rt2x00rfkill_register (struct rt2x00_dev *rt2x00dev) +static inline void rt2x00rfkill_register (struct rt2x00_dev *rt2x00dev) { -return 0 ; }static inline void rt2x00rfkill_unregister (struct rt2x00_dev *rt2x00dev) { } -static inline int rt2x00rfkill_allocate (struct rt2x00_dev *rt2x00dev) +static inline void rt2x00rfkill_allocate (struct rt2x00_dev *rt2x00dev) { -return 0 ; }static inline void rt2x00rfkill_free (struct rt2x00_dev *rt2x00dev) { } + +static inline void rt2x00rfkill_suspend (struct rt2x00_dev *rt2x00dev) +{ +} + +static inline void rt2x00rfkill_resume (struct rt2x00_dev *rt2x00dev) +{ +}#endif /* CONFIG_RT2X00_LIB_RFKILL */ #endif /* RT2X00LIB_H */
drivers/net/wireless/rt2x00/rt2x00rfkill.c +75 -41
171 lines not on this page · raw message