[PATCH 42/43] rc-core: move remaining keytable functions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Move some more keytable related functionality over to rc-keytable.c which
allows more implementational details to be obscured away.

Signed-off-by: David Härdeman <david@xxxxxxxxxxx>
---
 drivers/media/rc/rc-core-priv.h |   11 +-
 drivers/media/rc/rc-keytable.c  |  213 +++++++++++++++++++++++++++++++++------
 drivers/media/rc/rc-main.c      |  132 +-----------------------
 include/media/rc-core.h         |   44 --------
 4 files changed, 193 insertions(+), 207 deletions(-)

diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
index 376030e..3f056e3 100644
--- a/drivers/media/rc/rc-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -156,13 +156,10 @@ void ir_raw_init(void);
 /*
  * Methods from rc-keytable.c to be used internally
  */
-void rc_keytable_keyup(struct rc_keytable *kt);
-void rc_keytable_repeat(struct rc_keytable *kt);
-void rc_keytable_keydown(struct rc_keytable *kt, enum rc_type protocol,
-			 u64 scancode, u8 toggle, bool autokeyup);
-struct rc_keytable *rc_keytable_create(struct rc_dev *dev, const char *name,
-				       const char *map_name);
-void rc_keytable_destroy(struct rc_keytable *kt);
+int rc_keytable_add(struct rc_dev *dev, const char *name, const char *map_name);
+int rc_keytable_remove(struct rc_dev *dev, unsigned i);
+int rc_keytable_get_name(struct rc_dev *dev, unsigned i,
+			 char *buf, size_t bufsize);
 
 /* Only to be used by rc-core and ir-lirc-codec */
 void rc_init_ir_rx(struct rc_dev *dev, struct rc_ir_rx *rx);
diff --git a/drivers/media/rc/rc-keytable.c b/drivers/media/rc/rc-keytable.c
index d0777cb..027a703 100644
--- a/drivers/media/rc/rc-keytable.c
+++ b/drivers/media/rc/rc-keytable.c
@@ -29,6 +29,50 @@
 /* FIXME: RC_KEYPRESS_TIMEOUT should be protocol specific */
 #define RC_KEYPRESS_TIMEOUT 250
 
+/**
+ * struct rc_scan - rcu-friendly scancode<->keycode table
+ * @len:        number of elements in the table array
+ * @table:      array of struct rc_map_table elements
+ */
+struct rc_scan {
+	unsigned len;
+	struct rc_map_table table[];
+};
+
+/**
+ * struct rc_keytable - represents one keytable for a rc_dev device
+ * @node:               used to iterate over all keytables for a rc_dev device
+ * @dev:                the rc_dev device this keytable belongs to
+ * @idev:               the input_dev device which belongs to this keytable
+ * @name:               the user-friendly name of this keytable
+ * @scan_mutex:         protects @scan against concurrent writers
+ * @scan:               the current scancode<->keycode table
+ * @key_lock:           protects the key state
+ * @key_pressed:        whether a key is currently pressed or not
+ * @last_keycode:       keycode of the last keypress
+ * @last_protocol:      protocol of the last keypress
+ * @last_scancode:      scancode of the last keypress
+ * @last_toggle:        toggle of the last keypress
+ * @timer_keyup:        responsible for the auto-release of keys
+ * @keyup_jiffies:      when the key should be auto-released
+ */
+struct rc_keytable {
+	struct list_head		node;
+	struct rc_dev			*dev;
+	struct input_dev		*idev;
+	char				name[RC_KEYTABLE_NAME_SIZE];
+	struct mutex			scan_mutex;
+	struct rc_scan __rcu		*scan;
+	spinlock_t			key_lock;
+	bool				key_pressed;
+	u32				last_keycode;
+	enum rc_type			last_protocol;
+	u64				last_scancode;
+	u8				last_toggle;
+	struct timer_list		timer_keyup;
+	unsigned long			keyup_jiffies;
+};
+
 /* Used to keep track of known keymaps */
 static LIST_HEAD(rc_map_list);
 static DEFINE_SPINLOCK(rc_map_lock);
@@ -557,19 +601,26 @@ static void rc_do_keyup(struct rc_keytable *kt, bool sync)
 
 /**
  * rc_keyup() - signals the release of a keypress
- * @kt:		the struct rc_keytable descriptor of the keytable
+ * @dev:        the struct rc_dev descriptor of the device
  *
  * This routine is used to signal that a key has been released on the
  * remote control.
  */
-void rc_keytable_keyup(struct rc_keytable *kt)
+void rc_keyup(struct rc_dev *dev)
 {
+	struct rc_keytable *kt;
 	unsigned long flags;
 
-	spin_lock_irqsave(&kt->key_lock, flags);
-	rc_do_keyup(kt, true);
-	spin_unlock_irqrestore(&kt->key_lock, flags);
+	rcu_read_lock();
+	list_for_each_entry_rcu(kt, &dev->keytable_list, node) {
+		spin_lock_irqsave(&kt->key_lock, flags);
+		rc_do_keyup(kt, true);
+		spin_unlock_irqrestore(&kt->key_lock, flags);
+	}
+	rcu_read_unlock();
 }
+EXPORT_SYMBOL_GPL(rc_keyup);
+
 
 /**
  * rc_timer_keyup() - generates a keyup event after a timeout
@@ -601,22 +652,32 @@ static void rc_timer_keyup(unsigned long cookie)
 
 /**
  * rc_repeat() - signals that a key is still pressed
- * @kt:		the struct rc_keytable descriptor of the keytable
+ * @dev:        the struct rc_dev descriptor of the device
  *
- * This routine is used when a repeat message which does not include the
- * necessary bits to reproduce the scancode has been received.
+ * This routine is used by when a repeat message which does
+ * not include the necessary bits to reproduce the scancode has been
+ * received.
  */
-void rc_keytable_repeat(struct rc_keytable *kt)
+void rc_repeat(struct rc_dev *dev)
 {
+	struct rc_keytable *kt;
 	unsigned long flags;
 
-	spin_lock_irqsave(&kt->key_lock, flags);
-	if (kt->key_pressed) {
-		kt->keyup_jiffies = jiffies + msecs_to_jiffies(RC_KEYPRESS_TIMEOUT);
-		mod_timer(&kt->timer_keyup, kt->keyup_jiffies);
+	rcu_read_lock();
+	list_for_each_entry_rcu(kt, &dev->keytable_list, node) {
+		spin_lock_irqsave(&kt->key_lock, flags);
+		if (kt->key_pressed) {
+			kt->keyup_jiffies = jiffies +
+					msecs_to_jiffies(RC_KEYPRESS_TIMEOUT);
+			mod_timer(&kt->timer_keyup, kt->keyup_jiffies);
+		}
+		spin_unlock_irqrestore(&kt->key_lock, flags);
 	}
-	spin_unlock_irqrestore(&kt->key_lock, flags);
+	rcu_read_unlock();
+
+	rc_event(dev, RC_KEY, RC_KEY_REPEAT, 1);
 }
+EXPORT_SYMBOL_GPL(rc_repeat);
 
 /**
  * rc_keytable_keydown() - generates input event for a key press
@@ -629,8 +690,8 @@ void rc_keytable_repeat(struct rc_keytable *kt)
  *
  * This routine is used to signal that a keypress has been detected.
  */
-void rc_keytable_keydown(struct rc_keytable *kt, enum rc_type protocol,
-			 u64 scancode, u8 toggle, bool autoup)
+static void rc_keytable_keydown(struct rc_keytable *kt, enum rc_type protocol,
+				u64 scancode, u8 toggle, bool autoup)
 {
 	struct rc_scan *scan;
 	unsigned index;
@@ -677,6 +738,35 @@ void rc_keytable_keydown(struct rc_keytable *kt, enum rc_type protocol,
 }
 
 /**
+ * rc_do_keydown() - generates input event for a key press
+ * @dev:        the struct rc_dev descriptor of the device
+ * @protocol:   the protocol for the keypress
+ * @scancode:   the scancode for the keypress
+ * @toggle:     the toggle value (protocol dependent, if the protocol doesn't
+ *              support toggle values, this should be set to zero)
+ * @autoup:     should an automatic keyup event be generated in the future
+ *
+ * This routine is used to signal that a key has been pressed on the
+ * remote control.
+ */
+void rc_do_keydown(struct rc_dev *dev, enum rc_type protocol,
+		   u64 scancode, u8 toggle, bool autoup)
+{
+	struct rc_keytable *kt;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(kt, &dev->keytable_list, node)
+		rc_keytable_keydown(kt, protocol, scancode, toggle, autoup);
+	rcu_read_unlock();
+
+	rc_event(dev, RC_KEY, RC_KEY_PROTOCOL, protocol);
+	rc_event(dev, RC_KEY, RC_KEY_SCANCODE, scancode);
+	rc_event(dev, RC_KEY, RC_KEY_TOGGLE, toggle);
+}
+EXPORT_SYMBOL_GPL(rc_do_keydown);
+
+
+/**
  * rc_input_open() - called on the initial use of the input device
  * @idev:	the struct input_dev corresponding to the given keytable
  * @return:	zero on success, otherwise a negative error code
@@ -755,31 +845,67 @@ static int rc_keytable_init(struct rc_keytable *kt,
 }
 
 /**
- * rc_keytable_create() - creates a new keytable
+ * rc_keytable_get_name() - get the name of a keytable
+ * @dev:
+ * @dev:	the struct rc_dev device the keytable belongs to
+ * @i:		the index of the keytable
+ * @buf:	the buffer to write the name to
+ * @bufsize:	the size of the buffer
+ * @return:	zero on success or negative error code
+ *
+ * This function is used to get the userfriendly name of a keytable.
+ */
+int rc_keytable_get_name(struct rc_dev *dev, unsigned i,
+			 char *buf, size_t bufsize)
+{
+	struct rc_keytable *kt;
+
+	rcu_read_lock();
+	kt = rcu_dereference(dev->keytables[i]);
+	if (kt) {
+		buf[0] = '\0';
+		strncat(buf, kt->name, bufsize);
+	}
+	rcu_read_unlock();
+
+	return kt ? 0 : -EINVAL;
+}
+
+
+/**
+ * rc_keytable_add() - creates a new keytable
  * @dev:	the struct rc_dev device this keytable should belong to
  * @name:	the userfriendly name of this keymap
  * @map_name:	the name of the keymap to autoload
- * @return:	a new struct rc_keytable pointer or NULL on error
+ * @return:	the index of the new rc_keytable or a negative error number
  *
  * This function creates a new keytable (essentially the combination of a
  * keytable and an input device along with some state (whether a key
  * is currently pressed or not, etc).
  */
-struct rc_keytable *rc_keytable_create(struct rc_dev *dev,
-				       const char *name,
-				       const char *map_name)
+int rc_keytable_add(struct rc_dev *dev, const char *name, const char *map_name)
 {
 	struct rc_keytable *kt;
+	unsigned i;
 	struct input_dev *idev = NULL;
 	int error;
 
+	for (i = 0; i < ARRAY_SIZE(dev->keytables); i++)
+		if (!dev->keytables[i])
+			break;
+
+	if (i >= ARRAY_SIZE(dev->keytables))
+		return -ENFILE;
+
 	kt = kzalloc(sizeof(*kt), GFP_KERNEL);
 	if (!kt)
-		return NULL;
+		return -ENOMEM;
 
 	idev = input_allocate_device();
-	if (!idev)
-		goto out;
+	if (!idev) {
+		error = -ENOMEM;
+		goto out_kt;
+	}
 
 	kt->idev = idev;
 	kt->dev = dev;
@@ -795,7 +921,7 @@ struct rc_keytable *rc_keytable_create(struct rc_dev *dev,
 
 	error = rc_keytable_init(kt, rc_map_get(map_name));
 	if (error)
-		goto out;
+		goto out_idev;
 
 	idev->dev.parent = &dev->dev;
 	memcpy(&idev->id, &dev->input_id, sizeof(dev->input_id));
@@ -822,26 +948,49 @@ struct rc_keytable *rc_keytable_create(struct rc_dev *dev,
 
 	spin_lock_init(&kt->key_lock);
 	mutex_init(&kt->scan_mutex);
-	return kt;
+
+	rcu_assign_pointer(dev->keytables[i], kt);
+	list_add_rcu(&kt->node, &dev->keytable_list);
+	synchronize_rcu();
+	rc_event(dev, RC_CORE, RC_CORE_KT_ADDED, i);
+
+	return i;
 
 out_table:
 	kfree(kt->scan);
-out:
+out_idev:
 	input_free_device(idev);
+out_kt:
 	kfree(kt);
-	return NULL;
+	return error;
 }
 
 /**
- * rc_keytable_destroy() - destroys a keytable
- * @dev:	the struct rc_keytable to destroy
+ * rc_keytable_remove() - removes a keytable
+ * @dev:	the struct rc_dev device the keytable belongs to
+ * @i:		the index of the keytable
+ * @return:	zero on success or negative error number
  *
- * This function destroys an existing keytable.
+ * This function removes an existing keytable.
  */
-void rc_keytable_destroy(struct rc_keytable *kt)
+int rc_keytable_remove(struct rc_dev *dev, unsigned i)
 {
+	struct rc_keytable *kt;
+
+	kt = dev->keytables[i];
+	rcu_assign_pointer(dev->keytables[i], NULL);
+	if (kt)
+		list_del_rcu(&kt->node);
+	synchronize_rcu();
+
+	if (!kt)
+		return -EINVAL;
+
+	rc_event(dev, RC_CORE, RC_CORE_KT_REMOVED, i);
 	del_timer_sync(&kt->timer_keyup);
 	input_unregister_device(kt->idev);
 	kfree(kt->scan);
 	kfree(kt);
+
+	return 0;
 }
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index b16dbf4..e2aa7b1 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -101,73 +101,6 @@ void rc_event(struct rc_dev *dev, u16 type, u16 code, u64 val)
 }
 EXPORT_SYMBOL_GPL(rc_event);
 
-/**
- * rc_keyup() - signals the release of a keypress
- * @dev:	the struct rc_dev descriptor of the device
- *
- * This routine is used to signal that a key has been released on the
- * remote control.
- */
-void rc_keyup(struct rc_dev *dev)
-{
-	struct rc_keytable *kt;
-
-	rcu_read_lock();
-	list_for_each_entry_rcu(kt, &dev->keytable_list, node)
-		rc_keytable_keyup(kt);
-	rcu_read_unlock();
-}
-EXPORT_SYMBOL_GPL(rc_keyup);
-
-/**
- * rc_repeat() - signals that a key is still pressed
- * @dev:	the struct rc_dev descriptor of the device
- *
- * This routine is used by IR decoders when a repeat message which does
- * not include the necessary bits to reproduce the scancode has been
- * received.
- */
-void rc_repeat(struct rc_dev *dev)
-{
-	struct rc_keytable *kt;
-
-	rcu_read_lock();
-	list_for_each_entry_rcu(kt, &dev->keytable_list, node)
-		rc_keytable_repeat(kt);
-	rcu_read_unlock();
-
-	rc_event(dev, RC_KEY, RC_KEY_REPEAT, 1);
-}
-EXPORT_SYMBOL_GPL(rc_repeat);
-
-/**
- * rc_do_keydown() - generates input event for a key press
- * @dev:	the struct rc_dev descriptor of the device
- * @protocol:	the protocol for the keypress
- * @scancode:   the scancode for the keypress
- * @toggle:     the toggle value (protocol dependent, if the protocol doesn't
- *              support toggle values, this should be set to zero)
- * @autoup:	should an automatic keyup event be generated in the future
- *
- * This routine is used to signal that a key has been pressed on the
- * remote control.
- */
-void rc_do_keydown(struct rc_dev *dev, enum rc_type protocol,
-		   u64 scancode, u8 toggle, bool autoup)
-{
-	struct rc_keytable *kt;
-
-	rcu_read_lock();
-	list_for_each_entry_rcu(kt, &dev->keytable_list, node)
-		rc_keytable_keydown(kt, protocol, scancode, toggle, autoup);
-	rcu_read_unlock();
-
-	rc_event(dev, RC_KEY, RC_KEY_PROTOCOL, protocol);
-	rc_event(dev, RC_KEY, RC_KEY_SCANCODE, scancode);
-	rc_event(dev, RC_KEY, RC_KEY_TOGGLE, toggle);
-}
-EXPORT_SYMBOL_GPL(rc_do_keydown);
-
 /* class for /sys/class/rc */
 static char *rc_devnode(struct device *dev, umode_t *mode)
 {
@@ -493,48 +426,6 @@ void rc_free_device(struct rc_dev *dev)
 }
 EXPORT_SYMBOL_GPL(rc_free_device);
 
-static int rc_add_keytable(struct rc_dev *dev, const char *name,
-			   const char *map_name)
-{
-	struct rc_keytable *kt;
-	unsigned i;
-
-	for (i = 0; i < ARRAY_SIZE(dev->keytables); i++)
-		if (!dev->keytables[i])
-			break;
-
-	if (i >= ARRAY_SIZE(dev->keytables))
-		return -ENFILE;
-
-	kt = rc_keytable_create(dev, name, map_name);
-	if (!kt)
-		return -ENOMEM;
-
-	rcu_assign_pointer(dev->keytables[i], kt);
-	list_add_rcu(&kt->node, &dev->keytable_list);
-	synchronize_rcu();
-	rc_event(dev, RC_CORE, RC_CORE_KT_ADDED, i);
-	return 0;
-}
-
-static int rc_remove_keytable(struct rc_dev *dev, unsigned i)
-{
-	struct rc_keytable *kt;
-
-	kt = dev->keytables[i];
-	rcu_assign_pointer(dev->keytables[i], NULL);
-	if (kt)
-		list_del_rcu(&kt->node);
-	synchronize_rcu();
-
-	if (!kt)
-		return -EINVAL;
-
-	rc_keytable_destroy(kt);
-	rc_event(dev, RC_CORE, RC_CORE_KT_REMOVED, i);
-	return 0;
-}
-
 static u64 rc_get_allowed_protocols(struct rc_dev *dev)
 {
 	return dev ? dev->allowed_protos : 0x0;
@@ -590,7 +481,7 @@ int rc_register_device(struct rc_dev *dev)
 	if (rc)
 		goto out_chardev;
 
-	rc = rc_add_keytable(dev, dev->map_name, dev->map_name);
+	rc = rc_keytable_add(dev, dev->map_name, dev->map_name);
 	if (rc < 0)
 		goto out_device;
 
@@ -628,7 +519,7 @@ void rc_unregister_device(struct rc_dev *dev)
 	mutex_lock(&dev->mutex);
 	dev->exist = false;
 	for (i = 0; i < ARRAY_SIZE(dev->keytables); i++)
-		rc_remove_keytable(dev, i);
+		rc_keytable_remove(dev, i);
 	mutex_unlock(&dev->mutex);
 
 	mutex_lock(&rc_dev_table_mutex);
@@ -923,7 +814,6 @@ static long rc_do_ioctl(struct rc_dev *dev, unsigned int cmd, unsigned long arg)
 	struct rc_ir_rx rx;
 	struct rc_ir_tx tx;
 	struct rc_keytable_ioctl ktio;
-	struct rc_keytable *kt;
 	int error;
 
 	switch (cmd) {
@@ -1000,7 +890,7 @@ static long rc_do_ioctl(struct rc_dev *dev, unsigned int cmd, unsigned long arg)
 		if (strlen(ktio.name) < 1)
 			return -EINVAL;
 
-		error = rc_add_keytable(dev, ktio.name, NULL);
+		error = rc_keytable_add(dev, ktio.name, NULL);
 		if (error < 0)
 			return error;
 		ktio.id = error;
@@ -1020,16 +910,10 @@ static long rc_do_ioctl(struct rc_dev *dev, unsigned int cmd, unsigned long arg)
 		if (ktio.flags)
 			return -EINVAL;
 
-		rcu_read_lock();
-		kt = rcu_dereference(dev->keytables[ktio.id]);
-		if (kt) {
-			ktio.name[0] = '\0';
-			strncat(ktio.name, kt->name, sizeof(ktio.name));
-		}
-		rcu_read_unlock();
-
-		if (!kt)
-			return -EINVAL;
+		error = rc_keytable_get_name(dev, ktio.id,
+					     ktio.name, sizeof(ktio.name));
+		if (error)
+			return error;
 
 		if (copy_to_user(p, &ktio, sizeof(ktio)))
 			return -EFAULT;
@@ -1046,7 +930,7 @@ static long rc_do_ioctl(struct rc_dev *dev, unsigned int cmd, unsigned long arg)
 		if (ktio.flags)
 			return -EINVAL;
 
-		return rc_remove_keytable(dev, ktio.id);
+		return rc_keytable_remove(dev, ktio.id);
 	}
 	return -EINVAL;
 }
diff --git a/include/media/rc-core.h b/include/media/rc-core.h
index 056275a..e311242 100644
--- a/include/media/rc-core.h
+++ b/include/media/rc-core.h
@@ -351,50 +351,6 @@ struct rc_dev {
 	int				(*set_ir_tx)(struct rc_dev *dev, struct rc_ir_tx *tx);
 };
 
-/**
- * struct rc_scan - rcu-friendly scancode<->keycode table
- * @len:	number of elements in the table array
- * @table:	array of struct rc_map_table elements
- */
-struct rc_scan {
-	unsigned len;
-	struct rc_map_table table[];
-};
-
-/**
- * struct rc_keytable - represents one keytable for a rc_dev device
- * @node:		used to iterate over all keytables for a rc_dev device
- * @dev:		the rc_dev device this keytable belongs to
- * @idev:		the input_dev device which belongs to this keytable
- * @name:		the user-friendly name of this keytable
- * @scan_mutex:		protects @scan against concurrent writers
- * @scan:		the current scancode<->keycode table
- * @key_lock:		protects the key state
- * @key_pressed:	whether a key is currently pressed or not
- * @last_keycode:	keycode of the last keypress
- * @last_protocol:	protocol of the last keypress
- * @last_scancode:	scancode of the last keypress
- * @last_toggle:	toggle of the last keypress
- * @timer_keyup:	responsible for the auto-release of keys
- * @keyup_jiffies:	when the key should be auto-released
- */
-struct rc_keytable {
-	struct list_head		node;
-	struct rc_dev			*dev;
-	struct input_dev		*idev;
-	char				name[RC_KEYTABLE_NAME_SIZE];
-	struct mutex			scan_mutex;
-	struct rc_scan __rcu		*scan;
-	spinlock_t			key_lock;
-	bool				key_pressed;
-	u32				last_keycode;
-	enum rc_type			last_protocol;
-	u64				last_scancode;
-	u8				last_toggle;
-	struct timer_list		timer_keyup;
-	unsigned long			keyup_jiffies;
-};
-
 #define to_rc_dev(d) container_of(d, struct rc_dev, dev)
 
 /*

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux