[PATCH 11/15] rfkill: add notifier chains support

!MAILaRCHIVE_VOTE_RePLACE
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: <linux-kernel@...>
Cc: Ivo van Doorn <IvDoorn@...>, Thomas Renninger <trenn@...>, Henrique de Moraes Holschuh <hmh@...>
Date: Sunday, May 18, 2008 - 2:48 pm

Add a notifier chain for use by the rfkill class.  This notifier chain
signals the following events (more to be added when needed):

  1. rfkill: rfkill device state has changed

A pointer to the rfkill struct will be passed as a parameter.

The notifier message types have been added to include/linux/rfkill.h
instead of to include/linux/notifier.h in order to avoid the madness of
modifying a header used globally (and that triggers an almost full tree
rebuild every time it is touched) with information that is of interest only
to code that includes the rfkill.h header.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Cc: Ivo van Doorn <IvDoorn@gmail.com>
---
 include/linux/rfkill.h |    7 +++++
 net/rfkill/rfkill.c    |   70 +++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 74 insertions(+), 3 deletions(-)

diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index c0cab7d..98667be 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -117,4 +117,11 @@ static inline char *rfkill_get_led_name(struct rfkill *rfkill)
 #endif
 }
 
+/* rfkill notification chain */
+#define RFKILL_STATE_CHANGED		0x0001	/* state of a normal rfkill
+						   switch has changed */
+
+int register_rfkill_notifier(struct notifier_block *nb);
+int unregister_rfkill_notifier(struct notifier_block *nb);
+
 #endif /* RFKILL_H */
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index f11220b..251defe 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -46,6 +46,49 @@ MODULE_PARM_DESC(default_state,
 
 static enum rfkill_state rfkill_states[RFKILL_TYPE_MAX];
 
+static BLOCKING_NOTIFIER_HEAD(rfkill_notifier_list);
+
+
+/**
+ * register_rfkill_notifier - Add notifier to rfkill notifier chain
+ * @nb: pointer to the new entry to add to the chain
+ *
+ * See blocking_notifier_chain_register() for return value and further
+ * observations.
+ *
+ * Adds a notifier to the rfkill notifier chain.  The chain will be
+ * called with a pointer to the relevant rfkill structure as a parameter,
+ * refer to include/linux/rfkill.h for the possible events.
+ *
+ * Notifiers added to this chain are to always return NOTIFY_DONE.  This
+ * chain is a blocking notifier chain: notifiers can sleep.
+ *
+ * Calls to this chain may have been done through a workqueue.  One must
+ * one must assume unordered assynchronous behaviour, there is no way to
+ * know if actions related to the event that generated the notification
+ * have been carried out already.
+ */
+int register_rfkill_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_register(&rfkill_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(register_rfkill_notifier);
+
+/**
+ * unregister_rfkill_notifier - remove notifier from rfkill notifier chain
+ * @nb: pointer to the entry to remove from the chain
+ *
+ * See blocking_notifier_chain_unregister() for return value and further
+ * observations.
+ *
+ * Removes a notifier from the rfkill notifier chain.
+ */
+int unregister_rfkill_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_unregister(&rfkill_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_rfkill_notifier);
+
 
 static void rfkill_led_trigger(struct rfkill *rfkill,
 			       enum rfkill_state state)
@@ -62,14 +105,25 @@ static void rfkill_led_trigger(struct rfkill *rfkill,
 #endif /* CONFIG_RFKILL_LEDS */
 }
 
+static void notify_rfkill_state_change(struct rfkill *rfkill)
+{
+	blocking_notifier_call_chain(&rfkill_notifier_list,
+			RFKILL_STATE_CHANGED,
+			rfkill);
+}
+
 static void update_rfkill_state(struct rfkill *rfkill)
 {
-	enum rfkill_state newstate;
+	enum rfkill_state newstate, oldstate;
 
 	if (rfkill->get_state) {
 		mutex_lock(&rfkill->mutex);
-		if (!rfkill->get_state(rfkill->data, &newstate))
+		if (!rfkill->get_state(rfkill->data, &newstate)) {
+			oldstate = rfkill->state;
 			rfkill->state = newstate;
+			if (oldstate != newstate)
+				notify_rfkill_state_change(rfkill);
+		}
 		mutex_unlock(&rfkill->mutex);
 	}
 }
@@ -93,8 +147,10 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
 			rfkill->state = state;
 	}
 
-	if (force || rfkill->state != oldstate)
+	if (force || rfkill->state != oldstate) {
 		rfkill_led_trigger(rfkill, rfkill->state);
+		notify_rfkill_state_change(rfkill);
+	}
 
 	return retval;
 }
@@ -139,8 +195,16 @@ EXPORT_SYMBOL(rfkill_switch_all);
  */
 int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state)
 {
+	enum rfkill_state oldstate;
+
 	mutex_lock(&rfkill->mutex);
+
+	oldstate = rfkill->state;
 	rfkill->state = state;
+
+	if (state != oldstate)
+		notify_rfkill_state_change(rfkill);
+
 	mutex_unlock(&rfkill->mutex);
 
 	return 0;
-- 
1.5.5.1

--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[RFC] rfkill class rework, Henrique de Moraes Holschuh..., (Sun May 18, 2:47 pm)
[PATCH 08/15] rfkill: add read-write rfkill switch support, Henrique de Moraes Holschuh..., (Sun May 18, 2:47 pm)
[PATCH 15/15] rfkill: document rw rfkill switches and clarif..., Henrique de Moraes Holschuh..., (Sun May 18, 2:48 pm)
Re: [PATCH 15/15] rfkill: document rw rfkill switches and cl..., Henrique de Moraes Holschuh..., (Tue May 20, 11:54 am)
Re: [PATCH 15/15] rfkill: document rw rfkill switches and cl..., Henrique de Moraes Holschuh..., (Tue May 20, 9:44 pm)
[PATCH 15/15] rfkill: document rw rfkill switches and clarif..., Henrique de Moraes Holschuh..., (Wed May 28, 8:45 pm)
Re: [PATCH 15/15] rfkill: document rw rfkill switches and cl..., Henrique de Moraes Holschuh..., (Thu May 29, 12:26 pm)
Re: [PATCH 15/15] rfkill: document rw rfkill switches and cl..., Henrique de Moraes Holschuh..., (Thu May 29, 1:22 pm)
Re: [PATCH 15/15] rfkill: document rw rfkill switches and cl..., Henrique de Moraes Holschuh..., (Tue Jun 3, 11:11 pm)
Re: [PATCH 15/15] rfkill: document rw rfkill switches and cl..., Henrique de Moraes Holschuh..., (Thu May 29, 1:46 pm)
Re: [PATCH 15/15] rfkill: document rw rfkill switches and cl..., Henrique de Moraes Holschuh..., (Thu May 29, 5:16 pm)
[PATCH] Input: rename SW_RADIO to SW_RFKILL_ALL (v2), Henrique de Moraes Holschuh..., (Thu May 29, 5:25 pm)
Re: [PATCH 15/15] rfkill: document rw rfkill switches and cl..., Henrique de Moraes Holschuh..., (Mon May 19, 6:04 pm)
[PATCH 14/15] rfkill: do not allow userspace to override ALL..., Henrique de Moraes Holschuh..., (Sun May 18, 2:48 pm)
Re: [PATCH 14/15] rfkill: do not allow userspace to override..., Henrique de Moraes Holschuh..., (Thu May 22, 4:51 pm)
Re: [PATCH 14/15] rfkill: do not allow userspace to override..., Henrique de Moraes Holschuh..., (Tue May 27, 10:08 am)
Re: [PATCH 14/15] rfkill: do not allow userspace to override..., Henrique de Moraes Holschuh..., (Tue May 27, 1:41 pm)
[PATCH 11/15] rfkill: add notifier chains support, Henrique de Moraes Holschuh..., (Sun May 18, 2:48 pm)
Re: [PATCH 11/15] rfkill: add notifier chains support, Ivo van Doorn, (Tue May 20, 6:09 am)
Re: [PATCH 11/15] rfkill: add notifier chains support, Thomas Renninger, (Mon May 19, 4:44 am)
Re: [PATCH 11/15] rfkill: add notifier chains support, Henrique de Moraes Holschuh..., (Mon May 19, 9:10 am)
[PATCH 10/15] rfkill: rework suspend and resume handlers, Henrique de Moraes Holschuh..., (Sun May 18, 2:48 pm)
[PATCH 09/15] rfkill: add the WWAN radio type, Henrique de Moraes Holschuh..., (Sun May 18, 2:47 pm)
Re: [PATCH 09/15] rfkill: add the WWAN radio type, Ivo van Doorn, (Tue May 20, 6:08 am)
Re: [PATCH 09/15] rfkill: add the WWAN radio type, Henrique de Moraes Holschuh..., (Tue May 20, 9:12 pm)
Re: [PATCH 09/15] rfkill: add the WWAN radio type, Inaky Perez-Gonzalez, (Tue May 20, 11:35 pm)
Re: [PATCH 09/15] rfkill: add the WWAN radio type, Henrique de Moraes Holschuh..., (Tue May 20, 11:42 pm)
Re: [PATCH 09/15] rfkill: add the WWAN radio type, Inaky Perez-Gonzalez, (Wed May 21, 2:48 am)
Re: [PATCH 09/15] rfkill: add the WWAN radio type, Henrique de Moraes Holschuh..., (Wed May 21, 10:07 am)
[PATCH 13/15] rfkill: add uevent notifications, Henrique de Moraes Holschuh..., (Sun May 18, 2:48 pm)
Re: [PATCH 13/15] rfkill: add uevent notifications, Ivo van Doorn, (Tue May 20, 6:09 am)
[PATCH 12/15] rfkill: add type string helper, Henrique de Moraes Holschuh..., (Sun May 18, 2:48 pm)
Re: [PATCH 12/15] rfkill: add type string helper, Ivo van Doorn, (Tue May 20, 6:09 am)
[PATCH 07/15] rfkill: add parameter to disable radios by def..., Henrique de Moraes Holschuh..., (Sun May 18, 2:47 pm)
[PATCH 06/15] rfkill: handle SW_RFKILL_ALL events, Henrique de Moraes Holschuh..., (Sun May 18, 2:47 pm)
Re: [PATCH 06/15] rfkill: handle SW_RFKILL_ALL events, Ivo van Doorn, (Tue May 20, 6:08 am)
[PATCH 01/15] ACPI: thinkpad-acpi: fix initialization error ..., Henrique de Moraes Holschuh..., (Sun May 18, 2:47 pm)
[PATCH 05/15] rfkill: fix minor typo in kernel doc, Henrique de Moraes Holschuh..., (Sun May 18, 2:47 pm)
Re: [PATCH 05/15] rfkill: fix minor typo in kernel doc, Ivo van Doorn, (Tue May 20, 6:08 am)
[PATCH 04/15] rfkill: clarify meaning of rfkill states, Henrique de Moraes Holschuh..., (Sun May 18, 2:47 pm)
[PATCH 03/15] Input: rename SW_RADIO to SW_RFKILL_ALL (v2), Henrique de Moraes Holschuh..., (Sun May 18, 2:47 pm)
[PATCH 02/15] ACPI: thinkpad-acpi: fix LED handling on older..., Henrique de Moraes Holschuh..., (Sun May 18, 2:47 pm)