summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/counter.h56
1 files changed, 56 insertions, 0 deletions
diff --git a/include/linux/counter.h b/include/linux/counter.h
index 7c9f7e23953a..22b14a552b1d 100644
--- a/include/linux/counter.h
+++ b/include/linux/counter.h
@@ -6,9 +6,14 @@
#ifndef _COUNTER_H_
#define _COUNTER_H_
+#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/kernel.h>
+#include <linux/kfifo.h>
+#include <linux/mutex.h>
+#include <linux/spinlock_types.h>
#include <linux/types.h>
+#include <linux/wait.h>
#include <uapi/linux/counter.h>
struct counter_device;
@@ -200,6 +205,20 @@ struct counter_count {
};
/**
+ * struct counter_event_node - Counter Event node
+ * @l: list of current watching Counter events
+ * @event: event that triggers
+ * @channel: event channel
+ * @comp_list: list of components to watch when event triggers
+ */
+struct counter_event_node {
+ struct list_head l;
+ u8 event;
+ u8 channel;
+ struct list_head comp_list;
+};
+
+/**
* struct counter_ops - Callbacks from driver
* @signal_read: optional read callback for Signals. The read level of
* the respective Signal should be passed back via the
@@ -222,6 +241,13 @@ struct counter_count {
* @action_write: optional write callback for Synapse action modes. The
* action mode to write for the respective Synapse is
* passed in via the action parameter.
+ * @events_configure: optional write callback to configure events. The list of
+ * struct counter_event_node may be accessed via the
+ * events_list member of the counter parameter.
+ * @watch_validate: optional callback to validate a watch. The Counter
+ * component watch configuration is passed in via the watch
+ * parameter. A return value of 0 indicates a valid Counter
+ * component watch configuration.
*/
struct counter_ops {
int (*signal_read)(struct counter_device *counter,
@@ -245,6 +271,9 @@ struct counter_ops {
struct counter_count *count,
struct counter_synapse *synapse,
enum counter_synapse_action action);
+ int (*events_configure)(struct counter_device *counter);
+ int (*watch_validate)(struct counter_device *counter,
+ const struct counter_watch *watch);
};
/**
@@ -260,6 +289,16 @@ struct counter_ops {
* @num_ext: number of Counter device extensions specified in @ext
* @priv: optional private data supplied by driver
* @dev: internal device structure
+ * @chrdev: internal character device structure
+ * @events_list: list of current watching Counter events
+ * @events_list_lock: lock to protect Counter events list operations
+ * @next_events_list: list of next watching Counter events
+ * @n_events_list_lock: lock to protect Counter next events list operations
+ * @events: queue of detected Counter events
+ * @events_wait: wait queue to allow blocking reads of Counter events
+ * @events_lock: lock to protect Counter events queue read operations
+ * @chrdev_lock: lock to limit chrdev to a single open at a time
+ * @ops_exist_lock: lock to prevent use during removal
*/
struct counter_device {
const char *name;
@@ -278,12 +317,29 @@ struct counter_device {
void *priv;
struct device dev;
+ struct cdev chrdev;
+ struct list_head events_list;
+ spinlock_t events_list_lock;
+ struct list_head next_events_list;
+ struct mutex n_events_list_lock;
+ DECLARE_KFIFO_PTR(events, struct counter_event);
+ wait_queue_head_t events_wait;
+ struct mutex events_lock;
+ /*
+ * chrdev_lock is locked by counter_chrdev_open() and unlocked by
+ * counter_chrdev_release(), so a mutex is not possible here because
+ * chrdev_lock will invariably be held when returning to user space
+ */
+ atomic_t chrdev_lock;
+ struct mutex ops_exist_lock;
};
int counter_register(struct counter_device *const counter);
void counter_unregister(struct counter_device *const counter);
int devm_counter_register(struct device *dev,
struct counter_device *const counter);
+void counter_push_event(struct counter_device *const counter, const u8 event,
+ const u8 channel);
#define COUNTER_COMP_DEVICE_U8(_name, _read, _write) \
{ \