summaryrefslogtreecommitdiff
path: root/drivers/iio/trigger
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio/trigger')
-rw-r--r--drivers/iio/trigger/iio-trig-hrtimer.c4
-rw-r--r--drivers/iio/trigger/iio-trig-interrupt.c2
-rw-r--r--drivers/iio/trigger/stm32-lptimer-trigger.c77
-rw-r--r--drivers/iio/trigger/stm32-timer-trigger.c109
4 files changed, 129 insertions, 63 deletions
diff --git a/drivers/iio/trigger/iio-trig-hrtimer.c b/drivers/iio/trigger/iio-trig-hrtimer.c
index 716c795d08fb..82c72baccb62 100644
--- a/drivers/iio/trigger/iio-trig-hrtimer.c
+++ b/drivers/iio/trigger/iio-trig-hrtimer.c
@@ -145,8 +145,8 @@ static struct iio_sw_trigger *iio_trig_hrtimer_probe(const char *name)
trig_info->swt.trigger->ops = &iio_hrtimer_trigger_ops;
trig_info->swt.trigger->dev.groups = iio_hrtimer_attr_groups;
- hrtimer_init(&trig_info->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_HARD);
- trig_info->timer.function = iio_hrtimer_trig_handler;
+ hrtimer_setup(&trig_info->timer, iio_hrtimer_trig_handler, CLOCK_MONOTONIC,
+ HRTIMER_MODE_REL_HARD);
trig_info->sampling_frequency[0] = HRTIMER_DEFAULT_SAMPLING_FREQUENCY;
trig_info->period = NSEC_PER_SEC / trig_info->sampling_frequency[0];
diff --git a/drivers/iio/trigger/iio-trig-interrupt.c b/drivers/iio/trigger/iio-trig-interrupt.c
index dec256bfbd73..21c6b6292a72 100644
--- a/drivers/iio/trigger/iio-trig-interrupt.c
+++ b/drivers/iio/trigger/iio-trig-interrupt.c
@@ -96,7 +96,7 @@ static void iio_interrupt_trigger_remove(struct platform_device *pdev)
static struct platform_driver iio_interrupt_trigger_driver = {
.probe = iio_interrupt_trigger_probe,
- .remove_new = iio_interrupt_trigger_remove,
+ .remove = iio_interrupt_trigger_remove,
.driver = {
.name = "iio_interrupt_trigger",
},
diff --git a/drivers/iio/trigger/stm32-lptimer-trigger.c b/drivers/iio/trigger/stm32-lptimer-trigger.c
index f1e18913236a..2505ace440b4 100644
--- a/drivers/iio/trigger/stm32-lptimer-trigger.c
+++ b/drivers/iio/trigger/stm32-lptimer-trigger.c
@@ -16,16 +16,43 @@
#include <linux/platform_device.h>
#include <linux/property.h>
-/* List Low-Power Timer triggers */
-static const char * const stm32_lptim_triggers[] = {
- LPTIM1_OUT,
- LPTIM2_OUT,
- LPTIM3_OUT,
+/* Maximum triggers + one trailing null entry to indicate the end of array */
+#define MAX_TRIGGERS 3
+
+struct stm32_lptim_cfg {
+ const char * const (*triggers)[MAX_TRIGGERS];
+ unsigned int nb_triggers;
+};
+
+/* List Low-Power Timer triggers for H7, MP13, MP15 */
+static const char * const stm32_lptim_triggers[][MAX_TRIGGERS] = {
+ { LPTIM1_OUT,},
+ { LPTIM2_OUT,},
+ { LPTIM3_OUT,},
+};
+
+/* List Low-Power Timer triggers for STM32MP25 */
+static const char * const stm32mp25_lptim_triggers[][MAX_TRIGGERS] = {
+ { LPTIM1_CH1, LPTIM1_CH2, },
+ { LPTIM2_CH1, LPTIM2_CH2, },
+ { LPTIM3_CH1,},
+ { LPTIM4_CH1,},
+ { LPTIM5_OUT,},
+};
+
+static const struct stm32_lptim_cfg stm32mp15_lptim_cfg = {
+ .triggers = stm32_lptim_triggers,
+ .nb_triggers = ARRAY_SIZE(stm32_lptim_triggers),
+};
+
+static const struct stm32_lptim_cfg stm32mp25_lptim_cfg = {
+ .triggers = stm32mp25_lptim_triggers,
+ .nb_triggers = ARRAY_SIZE(stm32mp25_lptim_triggers),
};
struct stm32_lptim_trigger {
struct device *dev;
- const char *trg;
+ const char * const *triggers;
};
static int stm32_lptim_validate_device(struct iio_trigger *trig,
@@ -56,22 +83,33 @@ EXPORT_SYMBOL(is_stm32_lptim_trigger);
static int stm32_lptim_setup_trig(struct stm32_lptim_trigger *priv)
{
- struct iio_trigger *trig;
+ const char * const *cur = priv->triggers;
+ int ret;
- trig = devm_iio_trigger_alloc(priv->dev, "%s", priv->trg);
- if (!trig)
- return -ENOMEM;
+ while (cur && *cur) {
+ struct iio_trigger *trig;
- trig->dev.parent = priv->dev->parent;
- trig->ops = &stm32_lptim_trigger_ops;
- iio_trigger_set_drvdata(trig, priv);
+ trig = devm_iio_trigger_alloc(priv->dev, "%s", *cur);
+ if (!trig)
+ return -ENOMEM;
- return devm_iio_trigger_register(priv->dev, trig);
+ trig->dev.parent = priv->dev->parent;
+ trig->ops = &stm32_lptim_trigger_ops;
+ iio_trigger_set_drvdata(trig, priv);
+
+ ret = devm_iio_trigger_register(priv->dev, trig);
+ if (ret)
+ return ret;
+ cur++;
+ }
+
+ return 0;
}
static int stm32_lptim_trigger_probe(struct platform_device *pdev)
{
struct stm32_lptim_trigger *priv;
+ struct stm32_lptim_cfg const *lptim_cfg;
u32 index;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
@@ -81,18 +119,21 @@ static int stm32_lptim_trigger_probe(struct platform_device *pdev)
if (device_property_read_u32(&pdev->dev, "reg", &index))
return -EINVAL;
- if (index >= ARRAY_SIZE(stm32_lptim_triggers))
+ lptim_cfg = device_get_match_data(&pdev->dev);
+
+ if (index >= lptim_cfg->nb_triggers)
return -EINVAL;
priv->dev = &pdev->dev;
- priv->trg = stm32_lptim_triggers[index];
+ priv->triggers = lptim_cfg->triggers[index];
return stm32_lptim_setup_trig(priv);
}
static const struct of_device_id stm32_lptim_trig_of_match[] = {
- { .compatible = "st,stm32-lptimer-trigger", },
- {},
+ { .compatible = "st,stm32-lptimer-trigger", .data = &stm32mp15_lptim_cfg },
+ { .compatible = "st,stm32mp25-lptimer-trigger", .data = &stm32mp25_lptim_cfg},
+ { }
};
MODULE_DEVICE_TABLE(of, stm32_lptim_trig_of_match);
diff --git a/drivers/iio/trigger/stm32-timer-trigger.c b/drivers/iio/trigger/stm32-timer-trigger.c
index d76444030a28..925b864facca 100644
--- a/drivers/iio/trigger/stm32-timer-trigger.c
+++ b/drivers/iio/trigger/stm32-timer-trigger.c
@@ -38,6 +38,9 @@ static const void *triggers_table[][MAX_TRIGGERS] = {
{ TIM15_TRGO,},
{ TIM16_OC1,},
{ TIM17_OC1,},
+ { }, /* timer 18 */
+ { }, /* timer 19 */
+ { TIM20_TRGO, TIM20_TRGO2, TIM20_OC1, TIM20_OC2, TIM20_OC3, },
};
/* List the triggers accepted by each timer */
@@ -119,7 +122,7 @@ static int stm32_timer_start(struct stm32_timer_trigger *priv,
unsigned int frequency)
{
unsigned long long prd, div;
- int prescaler = 0;
+ int prescaler = 0, ret;
u32 ccer;
/* Period and prescaler values depends of clock rate */
@@ -150,15 +153,17 @@ static int stm32_timer_start(struct stm32_timer_trigger *priv,
if (ccer & TIM_CCER_CCXE)
return -EBUSY;
- mutex_lock(&priv->lock);
+ guard(mutex)(&priv->lock);
if (!priv->enabled) {
priv->enabled = true;
- clk_enable(priv->clk);
+ ret = clk_enable(priv->clk);
+ if (ret)
+ return ret;
}
regmap_write(priv->regmap, TIM_PSC, prescaler);
regmap_write(priv->regmap, TIM_ARR, prd - 1);
- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, TIM_CR1_ARPE);
+ regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE);
/* Force master mode to update mode */
if (stm32_timer_is_trgo2_name(trig->name))
@@ -169,11 +174,10 @@ static int stm32_timer_start(struct stm32_timer_trigger *priv,
0x2 << TIM_CR2_MMS_SHIFT);
/* Make sure that registers are updated */
- regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG);
+ regmap_set_bits(priv->regmap, TIM_EGR, TIM_EGR_UG);
/* Enable controller */
- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, TIM_CR1_CEN);
- mutex_unlock(&priv->lock);
+ regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN);
return 0;
}
@@ -189,19 +193,19 @@ static void stm32_timer_stop(struct stm32_timer_trigger *priv,
mutex_lock(&priv->lock);
/* Stop timer */
- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0);
- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0);
+ regmap_clear_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE);
+ regmap_clear_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN);
regmap_write(priv->regmap, TIM_PSC, 0);
regmap_write(priv->regmap, TIM_ARR, 0);
/* Force disable master mode */
if (stm32_timer_is_trgo2_name(trig->name))
- regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2, 0);
+ regmap_clear_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2);
else
- regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS, 0);
+ regmap_clear_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS);
/* Make sure that registers are updated */
- regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG);
+ regmap_set_bits(priv->regmap, TIM_EGR, TIM_EGR_UG);
if (priv->enabled) {
priv->enabled = false;
@@ -307,7 +311,7 @@ static ssize_t stm32_tt_store_master_mode(struct device *dev,
struct stm32_timer_trigger *priv = dev_get_drvdata(dev);
struct iio_trigger *trig = to_iio_trigger(dev);
u32 mask, shift, master_mode_max;
- int i;
+ int i, ret;
if (stm32_timer_is_trgo2_name(trig->name)) {
mask = TIM_CR2_MMS2;
@@ -322,15 +326,16 @@ static ssize_t stm32_tt_store_master_mode(struct device *dev,
for (i = 0; i <= master_mode_max; i++) {
if (!strncmp(master_mode_table[i], buf,
strlen(master_mode_table[i]))) {
- mutex_lock(&priv->lock);
+ guard(mutex)(&priv->lock);
if (!priv->enabled) {
/* Clock should be enabled first */
priv->enabled = true;
- clk_enable(priv->clk);
+ ret = clk_enable(priv->clk);
+ if (ret)
+ return ret;
}
regmap_update_bits(priv->regmap, TIM_CR2, mask,
i << shift);
- mutex_unlock(&priv->lock);
return len;
}
}
@@ -482,6 +487,7 @@ static int stm32_counter_write_raw(struct iio_dev *indio_dev,
int val, int val2, long mask)
{
struct stm32_timer_trigger *priv = iio_priv(indio_dev);
+ int ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
@@ -491,28 +497,29 @@ static int stm32_counter_write_raw(struct iio_dev *indio_dev,
/* fixed scale */
return -EINVAL;
- case IIO_CHAN_INFO_ENABLE:
- mutex_lock(&priv->lock);
+ case IIO_CHAN_INFO_ENABLE: {
+ guard(mutex)(&priv->lock);
if (val) {
if (!priv->enabled) {
priv->enabled = true;
- clk_enable(priv->clk);
+ ret = clk_enable(priv->clk);
+ if (ret)
+ return ret;
}
- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN,
- TIM_CR1_CEN);
+ regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN);
} else {
- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN,
- 0);
+ regmap_clear_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN);
if (priv->enabled) {
priv->enabled = false;
clk_disable(priv->clk);
}
}
- mutex_unlock(&priv->lock);
+
return 0;
}
-
- return -EINVAL;
+ default:
+ return -EINVAL;
+ }
}
static int stm32_counter_validate_trigger(struct iio_dev *indio_dev,
@@ -555,7 +562,7 @@ static int stm32_set_trigger_mode(struct iio_dev *indio_dev,
{
struct stm32_timer_trigger *priv = iio_priv(indio_dev);
- regmap_update_bits(priv->regmap, TIM_SMCR, TIM_SMCR_SMS, TIM_SMCR_SMS);
+ regmap_set_bits(priv->regmap, TIM_SMCR, TIM_SMCR_SMS);
return 0;
}
@@ -604,6 +611,7 @@ static int stm32_set_enable_mode(struct iio_dev *indio_dev,
{
struct stm32_timer_trigger *priv = iio_priv(indio_dev);
int sms = stm32_enable_mode2sms(mode);
+ int ret;
if (sms < 0)
return sms;
@@ -611,12 +619,15 @@ static int stm32_set_enable_mode(struct iio_dev *indio_dev,
* Triggered mode sets CEN bit automatically by hardware. So, first
* enable counter clock, so it can use it. Keeps it in sync with CEN.
*/
- mutex_lock(&priv->lock);
- if (sms == 6 && !priv->enabled) {
- clk_enable(priv->clk);
- priv->enabled = true;
+ scoped_guard(mutex, &priv->lock) {
+ if (sms == 6 && !priv->enabled) {
+ ret = clk_enable(priv->clk);
+ if (ret)
+ return ret;
+
+ priv->enabled = true;
+ }
}
- mutex_unlock(&priv->lock);
regmap_update_bits(priv->regmap, TIM_SMCR, TIM_SMCR_SMS, sms);
@@ -683,7 +694,7 @@ static ssize_t stm32_count_set_preset(struct iio_dev *indio_dev,
return ret;
/* TIMx_ARR register shouldn't be buffered (ARPE=0) */
- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0);
+ regmap_clear_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE);
regmap_write(priv->regmap, TIM_ARR, preset);
return len;
@@ -700,7 +711,7 @@ static const struct iio_chan_spec_ext_info stm32_trigger_count_info[] = {
IIO_ENUM_AVAILABLE("enable_mode", IIO_SHARED_BY_TYPE, &stm32_enable_mode_enum),
IIO_ENUM("trigger_mode", IIO_SEPARATE, &stm32_trigger_mode_enum),
IIO_ENUM_AVAILABLE("trigger_mode", IIO_SHARED_BY_TYPE, &stm32_trigger_mode_enum),
- {}
+ { }
};
static const struct iio_chan_spec stm32_trigger_channel = {
@@ -757,9 +768,9 @@ static void stm32_timer_detect_trgo2(struct stm32_timer_trigger *priv)
* Master mode selection 2 bits can only be written and read back when
* timer supports it.
*/
- regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2, TIM_CR2_MMS2);
+ regmap_set_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2);
regmap_read(priv->regmap, TIM_CR2, &val);
- regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2, 0);
+ regmap_clear_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2);
priv->has_trgo2 = !!val;
}
@@ -783,7 +794,7 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev)
return -EINVAL;
/* Create an IIO device only if we have triggers to be validated */
- if (*cfg->valids_table[index])
+ if (cfg->valids_table && *cfg->valids_table[index])
priv = stm32_setup_counter_device(dev);
else
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -796,7 +807,8 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev)
priv->clk = ddata->clk;
priv->max_arr = ddata->max_arr;
priv->triggers = triggers_table[index];
- priv->valids = cfg->valids_table[index];
+ if (cfg->valids_table && *cfg->valids_table[index])
+ priv->valids = cfg->valids_table[index];
stm32_timer_detect_trgo2(priv);
mutex_init(&priv->lock);
@@ -820,7 +832,7 @@ static void stm32_timer_trigger_remove(struct platform_device *pdev)
/* Check if nobody else use the timer, then disable it */
regmap_read(priv->regmap, TIM_CCER, &val);
if (!(val & TIM_CCER_CCXE))
- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0);
+ regmap_clear_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN);
if (priv->enabled)
clk_disable(priv->clk);
@@ -841,7 +853,7 @@ static int stm32_timer_trigger_suspend(struct device *dev)
regmap_read(priv->regmap, TIM_SMCR, &priv->bak.smcr);
/* Disable the timer */
- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0);
+ regmap_clear_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN);
clk_disable(priv->clk);
}
@@ -888,6 +900,16 @@ static const struct stm32_timer_trigger_cfg stm32h7_timer_trg_cfg = {
.num_valids_table = ARRAY_SIZE(stm32h7_valids_table),
};
+static const struct stm32_timer_trigger_cfg stm32mp25_timer_trg_cfg = {
+ /*
+ * valids_table not used: counter framework is now superseding the deprecated IIO
+ * counter interface (IIO_COUNT), so don't support it. num_valids_table is only
+ * kept here to register the IIO HW triggers. valids_table should be moved at some
+ * point to the stm32-timer-cnt driver instead.
+ */
+ .num_valids_table = ARRAY_SIZE(triggers_table),
+};
+
static const struct of_device_id stm32_trig_of_match[] = {
{
.compatible = "st,stm32-timer-trigger",
@@ -895,14 +917,17 @@ static const struct of_device_id stm32_trig_of_match[] = {
}, {
.compatible = "st,stm32h7-timer-trigger",
.data = (void *)&stm32h7_timer_trg_cfg,
+ }, {
+ .compatible = "st,stm32mp25-timer-trigger",
+ .data = (void *)&stm32mp25_timer_trg_cfg,
},
- { /* end node */ },
+ { }
};
MODULE_DEVICE_TABLE(of, stm32_trig_of_match);
static struct platform_driver stm32_timer_trigger_driver = {
.probe = stm32_timer_trigger_probe,
- .remove_new = stm32_timer_trigger_remove,
+ .remove = stm32_timer_trigger_remove,
.driver = {
.name = "stm32-timer-trigger",
.of_match_table = stm32_trig_of_match,