/*
* Pass event through all open handles. This function is called with
- * dev->event_lock held and interrupts disabled. Because of that we
- * do not need to use rcu_read_lock() here although we are using RCU
- * to access handle list. Note that because of that write-side uses
- * synchronize_sched() instead of synchronize_ru().
+ * dev->event_lock held and interrupts disabled.
*/
static void input_pass_event(struct input_dev *dev,
unsigned int type, unsigned int code, int value)
{
- struct input_handle *handle = rcu_dereference(dev->grab);
+ struct input_handle *handle;
+
+ rcu_read_lock();
+ handle = rcu_dereference(dev->grab);
if (handle)
handle->handler->event(handle, type, code, value);
else
if (handle->open)
handle->handler->event(handle,
type, code, value);
+ rcu_read_unlock();
}
/*
if (value >= 0)
disposition = INPUT_PASS_TO_ALL;
break;
+
+ case EV_PWR:
+ disposition = INPUT_PASS_TO_ALL;
+ break;
}
if (type != EV_SYN)
if (is_event_supported(type, dev->evbit, EV_MAX)) {
spin_lock_irqsave(&dev->event_lock, flags);
+ rcu_read_lock();
grab = rcu_dereference(dev->grab);
if (!grab || grab == handle)
input_handle_event(dev, type, code, value);
+ rcu_read_unlock();
spin_unlock_irqrestore(&dev->event_lock, flags);
}
}
rcu_assign_pointer(dev->grab, handle);
- /*
- * Not using synchronize_rcu() because read-side is protected
- * by a spinlock with interrupts off instead of rcu_read_lock().
- */
- synchronize_sched();
+ synchronize_rcu();
out:
mutex_unlock(&dev->mutex);
if (dev->grab == handle) {
rcu_assign_pointer(dev->grab, NULL);
/* Make sure input_pass_event() notices that grab is gone */
- synchronize_sched();
+ synchronize_rcu();
list_for_each_entry(handle, &dev->h_list, d_node)
if (handle->open && handle->handler->start)
* Make sure we are not delivering any more events
* through this handle
*/
- synchronize_sched();
+ synchronize_rcu();
}
}
if (!--handle->open) {
/*
- * synchronize_sched() makes sure that input_pass_event()
+ * synchronize_rcu() makes sure that input_pass_event()
* completed and that no more input events are delivered
* through this handle
*/
- synchronize_sched();
+ synchronize_rcu();
}
mutex_unlock(&dev->mutex);
#define MATCH_BIT(bit, max) \
- for (i = 0; i < NBITS(max); i++) \
+ for (i = 0; i < BITS_TO_LONGS(max); i++) \
if ((id->bit[i] & dev->bit[i]) != id->bit[i]) \
break; \
- if (i != NBITS(max)) \
+ if (i != BITS_TO_LONGS(max)) \
continue;
static const struct input_device_id *input_match_device(const struct input_device_id *id,
{
int i;
- for (i = NBITS(max) - 1; i > 0; i--)
+ for (i = BITS_TO_LONGS(max) - 1; i > 0; i--)
if (bitmap[i])
break;
len += snprintf(buf, max(size, 0), "%c", name);
for (i = min_bit; i < max_bit; i++)
- if (bm[LONG(i)] & BIT(i))
+ if (bm[BIT_WORD(i)] & BIT_MASK(i))
len += snprintf(buf + len, max(size - len, 0), "%X,", i);
return len;
}
int i;
int len = 0;
- for (i = NBITS(max) - 1; i > 0; i--)
+ for (i = BITS_TO_LONGS(max) - 1; i > 0; i--)
if (bitmap[i])
break;
__set_bit(code, dev->ffbit);
break;
+ case EV_PWR:
+ /* do nothing */
+ break;
+
default:
printk(KERN_ERR
"input_set_capability: unknown type %u (code %u)\n",
return error;
list_add_tail_rcu(&handle->d_node, &dev->h_list);
mutex_unlock(&dev->mutex);
- /*
- * We don't use synchronize_rcu() here because we rely
- * on dev->event_lock to protect read-side critical
- * section in input_pass_event().
- */
- synchronize_sched();
+ synchronize_rcu();
/*
* Since we are supposed to be called from ->connect()
mutex_lock(&dev->mutex);
list_del_rcu(&handle->d_node);
mutex_unlock(&dev->mutex);
- synchronize_sched();
+ synchronize_rcu();
}
EXPORT_SYMBOL(input_unregister_handle);