aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/input.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/input.c')
-rw-r--r--drivers/input/input.c37
1 files changed, 35 insertions, 2 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 2266ecbfbc01..5c16001959cc 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -1658,6 +1658,38 @@ void input_unregister_handler(struct input_handler *handler)
1658EXPORT_SYMBOL(input_unregister_handler); 1658EXPORT_SYMBOL(input_unregister_handler);
1659 1659
1660/** 1660/**
1661 * input_handler_for_each_handle - handle iterator
1662 * @handler: input handler to iterate
1663 * @data: data for the callback
1664 * @fn: function to be called for each handle
1665 *
1666 * Iterate over @bus's list of devices, and call @fn for each, passing
1667 * it @data and stop when @fn returns a non-zero value. The function is
1668 * using RCU to traverse the list and therefore may be usind in atonic
1669 * contexts. The @fn callback is invoked from RCU critical section and
1670 * thus must not sleep.
1671 */
1672int input_handler_for_each_handle(struct input_handler *handler, void *data,
1673 int (*fn)(struct input_handle *, void *))
1674{
1675 struct input_handle *handle;
1676 int retval = 0;
1677
1678 rcu_read_lock();
1679
1680 list_for_each_entry_rcu(handle, &handler->h_list, h_node) {
1681 retval = fn(handle, data);
1682 if (retval)
1683 break;
1684 }
1685
1686 rcu_read_unlock();
1687
1688 return retval;
1689}
1690EXPORT_SYMBOL(input_handler_for_each_handle);
1691
1692/**
1661 * input_register_handle - register a new input handle 1693 * input_register_handle - register a new input handle
1662 * @handle: handle to register 1694 * @handle: handle to register
1663 * 1695 *
@@ -1690,7 +1722,7 @@ int input_register_handle(struct input_handle *handle)
1690 * we can't be racing with input_unregister_handle() 1722 * we can't be racing with input_unregister_handle()
1691 * and so separate lock is not needed here. 1723 * and so separate lock is not needed here.
1692 */ 1724 */
1693 list_add_tail(&handle->h_node, &handler->h_list); 1725 list_add_tail_rcu(&handle->h_node, &handler->h_list);
1694 1726
1695 if (handler->start) 1727 if (handler->start)
1696 handler->start(handle); 1728 handler->start(handle);
@@ -1713,7 +1745,7 @@ void input_unregister_handle(struct input_handle *handle)
1713{ 1745{
1714 struct input_dev *dev = handle->dev; 1746 struct input_dev *dev = handle->dev;
1715 1747
1716 list_del_init(&handle->h_node); 1748 list_del_rcu(&handle->h_node);
1717 1749
1718 /* 1750 /*
1719 * Take dev->mutex to prevent race with input_release_device(). 1751 * Take dev->mutex to prevent race with input_release_device().
@@ -1721,6 +1753,7 @@ void input_unregister_handle(struct input_handle *handle)
1721 mutex_lock(&dev->mutex); 1753 mutex_lock(&dev->mutex);
1722 list_del_rcu(&handle->d_node); 1754 list_del_rcu(&handle->d_node);
1723 mutex_unlock(&dev->mutex); 1755 mutex_unlock(&dev->mutex);
1756
1724 synchronize_rcu(); 1757 synchronize_rcu();
1725} 1758}
1726EXPORT_SYMBOL(input_unregister_handle); 1759EXPORT_SYMBOL(input_unregister_handle);