diff options
Diffstat (limited to 'drivers/counter')
-rw-r--r-- | drivers/counter/interrupt-cnt.c | 17 | ||||
-rw-r--r-- | drivers/counter/microchip-tcb-capture.c | 25 | ||||
-rw-r--r-- | drivers/counter/stm32-timer-cnt.c | 7 |
3 files changed, 42 insertions, 7 deletions
diff --git a/drivers/counter/interrupt-cnt.c b/drivers/counter/interrupt-cnt.c index 949598d51575..6c0c1d2d7027 100644 --- a/drivers/counter/interrupt-cnt.c +++ b/drivers/counter/interrupt-cnt.c @@ -3,22 +3,25 @@ * Copyright (c) 2021 Pengutronix, Oleksij Rempel <kernel@pengutronix.de> */ +#include <linux/cleanup.h> #include <linux/counter.h> #include <linux/gpio/consumer.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/mod_devicetable.h> #include <linux/module.h> +#include <linux/mutex.h> #include <linux/platform_device.h> #include <linux/types.h> #define INTERRUPT_CNT_NAME "interrupt-cnt" struct interrupt_cnt_priv { - atomic_t count; + atomic_long_t count; struct gpio_desc *gpio; int irq; bool enabled; + struct mutex lock; struct counter_signal signals; struct counter_synapse synapses; struct counter_count cnts; @@ -29,7 +32,7 @@ static irqreturn_t interrupt_cnt_isr(int irq, void *dev_id) struct counter_device *counter = dev_id; struct interrupt_cnt_priv *priv = counter_priv(counter); - atomic_inc(&priv->count); + atomic_long_inc(&priv->count); counter_push_event(counter, COUNTER_EVENT_CHANGE_OF_STATE, 0); @@ -41,6 +44,8 @@ static int interrupt_cnt_enable_read(struct counter_device *counter, { struct interrupt_cnt_priv *priv = counter_priv(counter); + guard(mutex)(&priv->lock); + *enable = priv->enabled; return 0; @@ -51,6 +56,8 @@ static int interrupt_cnt_enable_write(struct counter_device *counter, { struct interrupt_cnt_priv *priv = counter_priv(counter); + guard(mutex)(&priv->lock); + if (priv->enabled == enable) return 0; @@ -89,7 +96,7 @@ static int interrupt_cnt_read(struct counter_device *counter, { struct interrupt_cnt_priv *priv = counter_priv(counter); - *val = atomic_read(&priv->count); + *val = atomic_long_read(&priv->count); return 0; } @@ -102,7 +109,7 @@ static int interrupt_cnt_write(struct counter_device *counter, if (val != (typeof(priv->count.counter))val) return -ERANGE; - atomic_set(&priv->count, val); + atomic_long_set(&priv->count, val); return 0; } @@ -227,6 +234,8 @@ static int interrupt_cnt_probe(struct platform_device *pdev) if (ret) return ret; + mutex_init(&priv->lock); + ret = devm_counter_add(dev, counter); if (ret < 0) return dev_err_probe(dev, ret, "Failed to add counter\n"); diff --git a/drivers/counter/microchip-tcb-capture.c b/drivers/counter/microchip-tcb-capture.c index 1de3c50b9804..1a299d1f350b 100644 --- a/drivers/counter/microchip-tcb-capture.c +++ b/drivers/counter/microchip-tcb-capture.c @@ -337,6 +337,28 @@ static struct counter_comp mchp_tc_count_ext[] = { COUNTER_COMP_COMPARE(mchp_tc_count_compare_read, mchp_tc_count_compare_write), }; +static int mchp_tc_watch_validate(struct counter_device *counter, + const struct counter_watch *watch) +{ + if (watch->channel == COUNTER_MCHP_EVCHN_CV || watch->channel == COUNTER_MCHP_EVCHN_RA) + switch (watch->event) { + case COUNTER_EVENT_CHANGE_OF_STATE: + case COUNTER_EVENT_OVERFLOW: + case COUNTER_EVENT_CAPTURE: + return 0; + default: + return -EINVAL; + } + + if (watch->channel == COUNTER_MCHP_EVCHN_RB && watch->event == COUNTER_EVENT_CAPTURE) + return 0; + + if (watch->channel == COUNTER_MCHP_EVCHN_RC && watch->event == COUNTER_EVENT_THRESHOLD) + return 0; + + return -EINVAL; +} + static struct counter_count mchp_tc_counts[] = { { .id = 0, @@ -356,7 +378,8 @@ static const struct counter_ops mchp_tc_ops = { .function_read = mchp_tc_count_function_read, .function_write = mchp_tc_count_function_write, .action_read = mchp_tc_count_action_read, - .action_write = mchp_tc_count_action_write + .action_write = mchp_tc_count_action_write, + .watch_validate = mchp_tc_watch_validate, }; static const struct atmel_tcb_config tcb_rm9200_config = { diff --git a/drivers/counter/stm32-timer-cnt.c b/drivers/counter/stm32-timer-cnt.c index e75b69476a00..3d3384cbea87 100644 --- a/drivers/counter/stm32-timer-cnt.c +++ b/drivers/counter/stm32-timer-cnt.c @@ -669,12 +669,14 @@ static void stm32_timer_cnt_detect_channels(struct device *dev, dev_dbg(dev, "has %d cc channels\n", priv->nchannels); } -/* encoder supported on TIM1 TIM2 TIM3 TIM4 TIM5 TIM8 */ -#define STM32_TIM_ENCODER_SUPPORTED (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(7)) +/* encoder supported on TIM1 TIM2 TIM3 TIM4 TIM5 TIM8 TIM20 */ +#define STM32_TIM_ENCODER_SUPPORTED (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(7) | \ + BIT(19)) static const char * const stm32_timer_trigger_compat[] = { "st,stm32-timer-trigger", "st,stm32h7-timer-trigger", + "st,stm32mp25-timer-trigger", }; static int stm32_timer_cnt_probe_encoder(struct device *dev, @@ -846,6 +848,7 @@ static SIMPLE_DEV_PM_OPS(stm32_timer_cnt_pm_ops, stm32_timer_cnt_suspend, static const struct of_device_id stm32_timer_cnt_of_match[] = { { .compatible = "st,stm32-timer-counter", }, + { .compatible = "st,stm32mp25-timer-counter", }, {}, }; MODULE_DEVICE_TABLE(of, stm32_timer_cnt_of_match); |