Lines Matching +full:interrupt +full:- +full:counter

1 // SPDX-License-Identifier: GPL-2.0
7 #include <linux/counter.h>
9 #include <linux/interrupt.h>
17 #define INTERRUPT_CNT_NAME "interrupt-cnt"
32 struct counter_device *counter = dev_id; in interrupt_cnt_isr() local
33 struct interrupt_cnt_priv *priv = counter_priv(counter); in interrupt_cnt_isr()
35 atomic_long_inc(&priv->count); in interrupt_cnt_isr()
37 counter_push_event(counter, COUNTER_EVENT_CHANGE_OF_STATE, 0); in interrupt_cnt_isr()
42 static int interrupt_cnt_enable_read(struct counter_device *counter, in interrupt_cnt_enable_read() argument
45 struct interrupt_cnt_priv *priv = counter_priv(counter); in interrupt_cnt_enable_read()
47 guard(mutex)(&priv->lock); in interrupt_cnt_enable_read()
49 *enable = priv->enabled; in interrupt_cnt_enable_read()
54 static int interrupt_cnt_enable_write(struct counter_device *counter, in interrupt_cnt_enable_write() argument
57 struct interrupt_cnt_priv *priv = counter_priv(counter); in interrupt_cnt_enable_write()
59 guard(mutex)(&priv->lock); in interrupt_cnt_enable_write()
61 if (priv->enabled == enable) in interrupt_cnt_enable_write()
65 priv->enabled = true; in interrupt_cnt_enable_write()
66 enable_irq(priv->irq); in interrupt_cnt_enable_write()
68 disable_irq(priv->irq); in interrupt_cnt_enable_write()
69 priv->enabled = false; in interrupt_cnt_enable_write()
84 static int interrupt_cnt_action_read(struct counter_device *counter, in interrupt_cnt_action_read() argument
94 static int interrupt_cnt_read(struct counter_device *counter, in interrupt_cnt_read() argument
97 struct interrupt_cnt_priv *priv = counter_priv(counter); in interrupt_cnt_read()
99 *val = atomic_long_read(&priv->count); in interrupt_cnt_read()
104 static int interrupt_cnt_write(struct counter_device *counter, in interrupt_cnt_write() argument
107 struct interrupt_cnt_priv *priv = counter_priv(counter); in interrupt_cnt_write()
109 if (val != (typeof(priv->count.counter))val) in interrupt_cnt_write()
110 return -ERANGE; in interrupt_cnt_write()
112 atomic_long_set(&priv->count, val); in interrupt_cnt_write()
121 static int interrupt_cnt_function_read(struct counter_device *counter, in interrupt_cnt_function_read() argument
130 static int interrupt_cnt_signal_read(struct counter_device *counter, in interrupt_cnt_signal_read() argument
134 struct interrupt_cnt_priv *priv = counter_priv(counter); in interrupt_cnt_signal_read()
137 if (!priv->gpio) in interrupt_cnt_signal_read()
138 return -EINVAL; in interrupt_cnt_signal_read()
140 ret = gpiod_get_value(priv->gpio); in interrupt_cnt_signal_read()
149 static int interrupt_cnt_watch_validate(struct counter_device *counter, in interrupt_cnt_watch_validate() argument
152 if (watch->channel != 0 || in interrupt_cnt_watch_validate()
153 watch->event != COUNTER_EVENT_CHANGE_OF_STATE) in interrupt_cnt_watch_validate()
154 return -EINVAL; in interrupt_cnt_watch_validate()
170 struct device *dev = &pdev->dev; in interrupt_cnt_probe()
171 struct counter_device *counter; in interrupt_cnt_probe() local
175 counter = devm_counter_alloc(dev, sizeof(*priv)); in interrupt_cnt_probe()
176 if (!counter) in interrupt_cnt_probe()
177 return -ENOMEM; in interrupt_cnt_probe()
178 priv = counter_priv(counter); in interrupt_cnt_probe()
180 priv->irq = platform_get_irq_optional(pdev, 0); in interrupt_cnt_probe()
181 if (priv->irq == -ENXIO) in interrupt_cnt_probe()
182 priv->irq = 0; in interrupt_cnt_probe()
183 else if (priv->irq < 0) in interrupt_cnt_probe()
184 return dev_err_probe(dev, priv->irq, "failed to get IRQ\n"); in interrupt_cnt_probe()
186 priv->gpio = devm_gpiod_get_optional(dev, NULL, GPIOD_IN); in interrupt_cnt_probe()
187 if (IS_ERR(priv->gpio)) in interrupt_cnt_probe()
188 return dev_err_probe(dev, PTR_ERR(priv->gpio), "failed to get GPIO\n"); in interrupt_cnt_probe()
190 if (!priv->irq && !priv->gpio) { in interrupt_cnt_probe()
192 return -ENODEV; in interrupt_cnt_probe()
195 if (!priv->irq) { in interrupt_cnt_probe()
196 int irq = gpiod_to_irq(priv->gpio); in interrupt_cnt_probe()
201 priv->irq = irq; in interrupt_cnt_probe()
204 priv->signals.name = devm_kasprintf(dev, GFP_KERNEL, "IRQ %d", in interrupt_cnt_probe()
205 priv->irq); in interrupt_cnt_probe()
206 if (!priv->signals.name) in interrupt_cnt_probe()
207 return -ENOMEM; in interrupt_cnt_probe()
209 counter->signals = &priv->signals; in interrupt_cnt_probe()
210 counter->num_signals = 1; in interrupt_cnt_probe()
212 priv->synapses.actions_list = interrupt_cnt_synapse_actions; in interrupt_cnt_probe()
213 priv->synapses.num_actions = ARRAY_SIZE(interrupt_cnt_synapse_actions); in interrupt_cnt_probe()
214 priv->synapses.signal = &priv->signals; in interrupt_cnt_probe()
216 priv->cnts.name = "Channel 0 Count"; in interrupt_cnt_probe()
217 priv->cnts.functions_list = interrupt_cnt_functions; in interrupt_cnt_probe()
218 priv->cnts.num_functions = ARRAY_SIZE(interrupt_cnt_functions); in interrupt_cnt_probe()
219 priv->cnts.synapses = &priv->synapses; in interrupt_cnt_probe()
220 priv->cnts.num_synapses = 1; in interrupt_cnt_probe()
221 priv->cnts.ext = interrupt_cnt_ext; in interrupt_cnt_probe()
222 priv->cnts.num_ext = ARRAY_SIZE(interrupt_cnt_ext); in interrupt_cnt_probe()
224 counter->name = dev_name(dev); in interrupt_cnt_probe()
225 counter->parent = dev; in interrupt_cnt_probe()
226 counter->ops = &interrupt_cnt_ops; in interrupt_cnt_probe()
227 counter->counts = &priv->cnts; in interrupt_cnt_probe()
228 counter->num_counts = 1; in interrupt_cnt_probe()
230 irq_set_status_flags(priv->irq, IRQ_NOAUTOEN); in interrupt_cnt_probe()
231 ret = devm_request_irq(dev, priv->irq, interrupt_cnt_isr, in interrupt_cnt_probe()
233 dev_name(dev), counter); in interrupt_cnt_probe()
237 mutex_init(&priv->lock); in interrupt_cnt_probe()
239 ret = devm_counter_add(dev, counter); in interrupt_cnt_probe()
241 return dev_err_probe(dev, ret, "Failed to add counter\n"); in interrupt_cnt_probe()
247 { .compatible = "interrupt-counter", },
261 MODULE_ALIAS("platform:interrupt-counter");
263 MODULE_DESCRIPTION("Interrupt counter driver");
265 MODULE_IMPORT_NS("COUNTER");