From: Ivo van Doorn <ivdoorn@gmail.com>
To: "John W. Linville" <linville@redhat.com>
Cc: "linux-wireless" <linux-wireless@vger.kernel.org>,
rt2400-devel@lists.sourceforge.net
Subject: [PATCH 17/24] rt2x00: Add suspend/resume handlers to rt2x00rfkill
Date: Sun, 9 Mar 2008 22:46:45 +0100 [thread overview]
Message-ID: <200803092246.45852.IvDoorn@gmail.com> (raw)
In-Reply-To: <200803092237.43451.IvDoorn@gmail.com>
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.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00.h | 4 +
drivers/net/wireless/rt2x00/rt2x00dev.c | 43 ++++-------
drivers/net/wireless/rt2x00/rt2x00lib.h | 15 ++--
drivers/net/wireless/rt2x00/rt2x00rfkill.c | 116 ++++++++++++++++++----------
4 files changed, 102 insertions(+), 76 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index a324ff3..d71b3c4 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -671,6 +671,10 @@ 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 2
+
struct rfkill *rfkill;
struct input_polled_dev *poll_dev;
#endif /* CONFIG_RT2X00_LIB_RFKILL */
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index d6b1278..eeb39e8 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -999,7 +999,7 @@ static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev)
return;
/*
- * Unregister rfkill.
+ * Unregister extra components.
*/
rt2x00rfkill_unregister(rt2x00dev);
@@ -1038,11 +1038,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;
+ rt2x00rfkill_register(rt2x00dev);
return 0;
@@ -1156,20 +1154,10 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
}
/*
- * Register LED.
+ * Register extra components.
*/
rt2x00leds_register(rt2x00dev);
-
- /*
- * Allocatie rfkill.
- */
- retval = rt2x00rfkill_allocate(rt2x00dev);
- if (retval)
- goto exit;
-
- /*
- * Open the debugfs entry.
- */
+ rt2x00rfkill_allocate(rt2x00dev);
rt2x00debug_register(rt2x00dev);
__set_bit(DEVICE_PRESENT, &rt2x00dev->flags);
@@ -1198,18 +1186,10 @@ 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);
-
- /*
- * Free LED.
- */
rt2x00leds_unregister(rt2x00dev);
/*
@@ -1248,12 +1228,16 @@ 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.
+ */
rt2x00leds_suspend(rt2x00dev);
+ rt2x00rfkill_suspend(rt2x00dev);
rt2x00debug_deregister(rt2x00dev);
exit:
@@ -1297,9 +1281,10 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
NOTICE(rt2x00dev, "Waking up.\n");
/*
- * Open the debugfs entry and restore led handling.
+ * Restore/enable extra components.
*/
rt2x00debug_register(rt2x00dev);
+ rt2x00rfkill_resume(rt2x00dev);
rt2x00leds_resume(rt2x00dev);
/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 6bd5a01..b9d7e0e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -160,28 +160,31 @@ 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 */
/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
index 6712142..fcef988 100644
--- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c
+++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
@@ -69,56 +69,81 @@ static void rt2x00rfkill_poll(struct input_polled_dev *poll_dev)
}
}
-int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
+void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
{
- int retval;
-
- if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
- return 0;
+ if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) ||
+ !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
+ return;
- retval = rfkill_register(rt2x00dev->rfkill);
- if (retval) {
+ if (rfkill_register(rt2x00dev->rfkill)) {
ERROR(rt2x00dev, "Failed to register rfkill handler.\n");
- return retval;
+ return;
}
- retval = input_register_polled_device(rt2x00dev->poll_dev);
- if (retval) {
+ if (input_register_polled_device(rt2x00dev->poll_dev)) {
ERROR(rt2x00dev, "Failed to register polled device.\n");
rfkill_unregister(rt2x00dev->rfkill);
- return retval;
+ return;
}
+ __set_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state);
+
/*
* Force initial poll which will detect the initial device state,
* and correctly sends the signal to the rfkill layer about this
* state.
*/
rt2x00rfkill_poll(rt2x00dev->poll_dev);
-
- return 0;
}
void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
{
- if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
+ if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) ||
+ !test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state))
return;
input_unregister_polled_device(rt2x00dev->poll_dev);
rfkill_unregister(rt2x00dev->rfkill);
+
+ __clear_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state);
}
-int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
+static struct input_polled_dev *
+rt2x00rfkill_allocate_polldev(struct rt2x00_dev *rt2x00dev)
{
- struct device *device = wiphy_dev(rt2x00dev->hw->wiphy);
+ struct input_polled_dev *poll_dev;
+
+ poll_dev = input_allocate_polled_device();
+ if (!poll_dev)
+ return NULL;
+
+ poll_dev->private = rt2x00dev;
+ poll_dev->poll = rt2x00rfkill_poll;
+ poll_dev->poll_interval = RFKILL_POLL_INTERVAL;
+
+ poll_dev->input->name = rt2x00dev->ops->name;
+ poll_dev->input->phys = wiphy_name(rt2x00dev->hw->wiphy);
+ poll_dev->input->id.bustype = BUS_HOST;
+ poll_dev->input->id.vendor = 0x1814;
+ poll_dev->input->id.product = rt2x00dev->chip.rt;
+ poll_dev->input->id.version = rt2x00dev->chip.rev;
+ poll_dev->input->dev.parent = wiphy_dev(rt2x00dev->hw->wiphy);
+ poll_dev->input->evbit[0] = BIT(EV_KEY);
+ set_bit(KEY_WLAN, poll_dev->input->keybit);
+
+ return poll_dev;
+}
+void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
+{
if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
- return 0;
+ return;
- rt2x00dev->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
+ rt2x00dev->rfkill =
+ rfkill_allocate(wiphy_dev(rt2x00dev->hw->wiphy), RFKILL_TYPE_WLAN);
if (!rt2x00dev->rfkill) {
ERROR(rt2x00dev, "Failed to allocate rfkill handler.\n");
- goto exit;
+ return;
}
rt2x00dev->rfkill->name = rt2x00dev->ops->name;
@@ -126,40 +151,49 @@ int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
rt2x00dev->rfkill->state = -1;
rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio;
- rt2x00dev->poll_dev = input_allocate_polled_device();
+ rt2x00dev->poll_dev = rt2x00rfkill_allocate_polldev(rt2x00dev);
if (!rt2x00dev->poll_dev) {
ERROR(rt2x00dev, "Failed to allocate polled device.\n");
- goto exit_free_rfkill;
+ rfkill_free(rt2x00dev->rfkill);
+ rt2x00dev->rfkill = NULL;
+ return;
}
- rt2x00dev->poll_dev->private = rt2x00dev;
- rt2x00dev->poll_dev->poll = rt2x00rfkill_poll;
- rt2x00dev->poll_dev->poll_interval = RFKILL_POLL_INTERVAL;
+ return;
+}
- rt2x00dev->poll_dev->input->name = rt2x00dev->ops->name;
- rt2x00dev->poll_dev->input->phys = wiphy_name(rt2x00dev->hw->wiphy);
- rt2x00dev->poll_dev->input->id.bustype = BUS_HOST;
- rt2x00dev->poll_dev->input->id.vendor = 0x1814;
- rt2x00dev->poll_dev->input->id.product = rt2x00dev->chip.rt;
- rt2x00dev->poll_dev->input->id.version = rt2x00dev->chip.rev;
- rt2x00dev->poll_dev->input->dev.parent = device;
- rt2x00dev->poll_dev->input->evbit[0] = BIT(EV_KEY);
- set_bit(KEY_WLAN, rt2x00dev->poll_dev->input->keybit);
+void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
+{
+ if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) ||
+ !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
+ return;
- return 0;
+ input_free_polled_device(rt2x00dev->poll_dev);
+ rt2x00dev->poll_dev = NULL;
-exit_free_rfkill:
rfkill_free(rt2x00dev->rfkill);
-
-exit:
- return -ENOMEM;
+ rt2x00dev->rfkill = NULL;
}
-void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
+void rt2x00rfkill_suspend(struct rt2x00_dev *rt2x00dev)
{
- if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
+ if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) ||
+ !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
return;
input_free_polled_device(rt2x00dev->poll_dev);
- rfkill_free(rt2x00dev->rfkill);
+ rt2x00dev->poll_dev = NULL;
+}
+
+void rt2x00rfkill_resume(struct rt2x00_dev *rt2x00dev)
+{
+ if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) ||
+ !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
+ return;
+
+ rt2x00dev->poll_dev = rt2x00rfkill_allocate_polldev(rt2x00dev);
+ if (!rt2x00dev->poll_dev) {
+ ERROR(rt2x00dev, "Failed to allocate polled device.\n");
+ return;
+ }
}
--
1.5.4.3
next prev parent reply other threads:[~2008-03-09 21:51 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-03-09 21:37 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
2008-03-09 21:38 ` [PATCH 01/24] rt2x00: Align RX descriptor to 4 bytes Ivo van Doorn
2008-03-09 21:38 ` [PATCH 02/24] rt2x00: Initialize TX control field in data entries Ivo van Doorn
2008-03-09 21:39 ` [PATCH 03/24] rt2x00: Use the correct size when copying the control info in txdone Ivo van Doorn
2008-03-09 21:40 ` [PATCH 04/24] rt2x00: Don't use uninitialized desc_len Ivo van Doorn
2008-03-09 21:40 ` [PATCH 05/24] rt2x00: never disable multicast because it disables broadcast too Ivo van Doorn
2008-03-09 21:41 ` [PATCH 06/24] rt2x00: Don't use unitialized rxdesc->size Ivo van Doorn
2008-03-09 21:41 ` [PATCH 07/24] rt2x00: Use skbdesc fields for descriptor initialization Ivo van Doorn
2008-03-09 21:42 ` [PATCH 08/24] rt2x00: Add new D-Link USB ID Ivo van Doorn
2008-03-09 21:42 ` [PATCH 09/24] rt2x00: Only disable beaconing just before beacon update Ivo van Doorn
2008-03-09 21:43 ` [PATCH 10/24] rt2x00:correct rx packet length for USB devices Ivo van Doorn
2008-03-09 21:43 ` [PATCH 11/24] rt2x00: Fix trivial log message Ivo van Doorn
2008-03-09 21:44 ` [PATCH 12/24] rt2x00: Upgrade queue->lock to use irqsave Ivo van Doorn
2008-03-09 21:44 ` [PATCH 13/24] rt2x00: Move firmware checksumming to driver Ivo van Doorn
2008-03-09 21:45 ` [PATCH 14/24] rt2x00: Start bugging when rt2x00lib doesn't filter SW diversity Ivo van Doorn
2008-03-09 21:45 ` [PATCH 15/24] rt2x00: Check IEEE80211_TXCTL_SEND_AFTER_DTIM flag Ivo van Doorn
2008-03-09 21:46 ` [PATCH 16/24] rt2x00: Rename config_preamble() to config_erp() Ivo van Doorn
2008-03-09 21:46 ` Ivo van Doorn [this message]
2008-03-09 21:47 ` [PATCH 18/24] rt2x00: Make rt2x00leds_register return void Ivo van Doorn
2008-03-09 21:47 ` [PATCH 19/24] rt2x00: Always enable TSF ticking Ivo van Doorn
2008-03-09 21:48 ` [PATCH 20/24] rt2x00: Fix basic rate initialization Ivo van Doorn
2008-03-09 21:48 ` [PATCH 21/24] rt2x00: Fix compile error when rfkill is disabled Ivo van Doorn
2008-03-09 21:48 ` [PATCH 22/24] rt2x00: Fix RX DMA ring initialization Ivo van Doorn
2008-03-09 21:49 ` [PATCH 23/24] rt2x00: Fix rt2400pci signal Ivo van Doorn
2008-03-09 21:49 ` [PATCH 24/24] rt2x00: Release rt2x00 2.1.4 Ivo van Doorn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200803092246.45852.IvDoorn@gmail.com \
--to=ivdoorn@gmail.com \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@redhat.com \
--cc=rt2400-devel@lists.sourceforge.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.