diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-11-04 16:21:47 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-11-04 16:21:47 +0100 |
commit | 5c904c66ed4e86c31ac7c033b64274cebed04e0e (patch) | |
tree | 769d366c5e61ffa45d5d8a99c61ae9d5ea39a0a0 /drivers/counter/ti-eqep.c | |
parent | Merge tag 'staging-5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git... (diff) | |
parent | comedi: dt9812: fix DMA buffers on stack (diff) | |
download | linux-5c904c66ed4e86c31ac7c033b64274cebed04e0e.tar.xz linux-5c904c66ed4e86c31ac7c033b64274cebed04e0e.zip |
Merge tag 'char-misc-5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH:
"Here is the big set of char and misc and other tiny driver subsystem
updates for 5.16-rc1.
Loads of things in here, all of which have been in linux-next for a
while with no reported problems (except for one called out below.)
Included are:
- habanana labs driver updates, including dma_buf usage, reviewed and
acked by the dma_buf maintainers
- iio driver update (going through this tree not staging as they
really do not belong going through that tree anymore)
- counter driver updates
- hwmon driver updates that the counter drivers needed, acked by the
hwmon maintainer
- xillybus driver updates
- binder driver updates
- extcon driver updates
- dma_buf module namespaces added (will cause a build error in arm64
for allmodconfig, but that change is on its way through the drm
tree)
- lkdtm driver updates
- pvpanic driver updates
- phy driver updates
- virt acrn and nitr_enclaves driver updates
- smaller char and misc driver updates"
* tag 'char-misc-5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (386 commits)
comedi: dt9812: fix DMA buffers on stack
comedi: ni_usb6501: fix NULL-deref in command paths
arm64: errata: Enable TRBE workaround for write to out-of-range address
arm64: errata: Enable workaround for TRBE overwrite in FILL mode
coresight: trbe: Work around write to out of range
coresight: trbe: Make sure we have enough space
coresight: trbe: Add a helper to determine the minimum buffer size
coresight: trbe: Workaround TRBE errata overwrite in FILL mode
coresight: trbe: Add infrastructure for Errata handling
coresight: trbe: Allow driver to choose a different alignment
coresight: trbe: Decouple buffer base from the hardware base
coresight: trbe: Add a helper to pad a given buffer area
coresight: trbe: Add a helper to calculate the trace generated
coresight: trbe: Defer the probe on offline CPUs
coresight: trbe: Fix incorrect access of the sink specific data
coresight: etm4x: Add ETM PID for Kryo-5XX
coresight: trbe: Prohibit trace before disabling TRBE
coresight: trbe: End the AUX handle on truncation
coresight: trbe: Do not truncate buffer on IRQ
coresight: trbe: Fix handling of spurious interrupts
...
Diffstat (limited to 'drivers/counter/ti-eqep.c')
-rw-r--r-- | drivers/counter/ti-eqep.c | 180 |
1 files changed, 98 insertions, 82 deletions
diff --git a/drivers/counter/ti-eqep.c b/drivers/counter/ti-eqep.c index 94fe58bb3eab..09817c953f9a 100644 --- a/drivers/counter/ti-eqep.c +++ b/drivers/counter/ti-eqep.c @@ -13,6 +13,7 @@ #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/regmap.h> +#include <linux/types.h> /* 32-bit registers */ #define QPOSCNT 0x0 @@ -73,19 +74,13 @@ enum { }; /* Position Counter Input Modes */ -enum { +enum ti_eqep_count_func { TI_EQEP_COUNT_FUNC_QUAD_COUNT, TI_EQEP_COUNT_FUNC_DIR_COUNT, TI_EQEP_COUNT_FUNC_UP_COUNT, TI_EQEP_COUNT_FUNC_DOWN_COUNT, }; -enum { - TI_EQEP_SYNAPSE_ACTION_BOTH_EDGES, - TI_EQEP_SYNAPSE_ACTION_RISING_EDGE, - TI_EQEP_SYNAPSE_ACTION_NONE, -}; - struct ti_eqep_cnt { struct counter_device counter; struct regmap *regmap32; @@ -93,7 +88,7 @@ struct ti_eqep_cnt { }; static int ti_eqep_count_read(struct counter_device *counter, - struct counter_count *count, unsigned long *val) + struct counter_count *count, u64 *val) { struct ti_eqep_cnt *priv = counter->priv; u32 cnt; @@ -105,7 +100,7 @@ static int ti_eqep_count_read(struct counter_device *counter, } static int ti_eqep_count_write(struct counter_device *counter, - struct counter_count *count, unsigned long val) + struct counter_count *count, u64 val) { struct ti_eqep_cnt *priv = counter->priv; u32 max; @@ -117,64 +112,100 @@ static int ti_eqep_count_write(struct counter_device *counter, return regmap_write(priv->regmap32, QPOSCNT, val); } -static int ti_eqep_function_get(struct counter_device *counter, - struct counter_count *count, size_t *function) +static int ti_eqep_function_read(struct counter_device *counter, + struct counter_count *count, + enum counter_function *function) { struct ti_eqep_cnt *priv = counter->priv; u32 qdecctl; regmap_read(priv->regmap16, QDECCTL, &qdecctl); - *function = (qdecctl & QDECCTL_QSRC) >> QDECCTL_QSRC_SHIFT; + + switch ((qdecctl & QDECCTL_QSRC) >> QDECCTL_QSRC_SHIFT) { + case TI_EQEP_COUNT_FUNC_QUAD_COUNT: + *function = COUNTER_FUNCTION_QUADRATURE_X4; + break; + case TI_EQEP_COUNT_FUNC_DIR_COUNT: + *function = COUNTER_FUNCTION_PULSE_DIRECTION; + break; + case TI_EQEP_COUNT_FUNC_UP_COUNT: + *function = COUNTER_FUNCTION_INCREASE; + break; + case TI_EQEP_COUNT_FUNC_DOWN_COUNT: + *function = COUNTER_FUNCTION_DECREASE; + break; + } return 0; } -static int ti_eqep_function_set(struct counter_device *counter, - struct counter_count *count, size_t function) +static int ti_eqep_function_write(struct counter_device *counter, + struct counter_count *count, + enum counter_function function) { struct ti_eqep_cnt *priv = counter->priv; + enum ti_eqep_count_func qsrc; + + switch (function) { + case COUNTER_FUNCTION_QUADRATURE_X4: + qsrc = TI_EQEP_COUNT_FUNC_QUAD_COUNT; + break; + case COUNTER_FUNCTION_PULSE_DIRECTION: + qsrc = TI_EQEP_COUNT_FUNC_DIR_COUNT; + break; + case COUNTER_FUNCTION_INCREASE: + qsrc = TI_EQEP_COUNT_FUNC_UP_COUNT; + break; + case COUNTER_FUNCTION_DECREASE: + qsrc = TI_EQEP_COUNT_FUNC_DOWN_COUNT; + break; + default: + /* should never reach this path */ + return -EINVAL; + } return regmap_write_bits(priv->regmap16, QDECCTL, QDECCTL_QSRC, - function << QDECCTL_QSRC_SHIFT); + qsrc << QDECCTL_QSRC_SHIFT); } -static int ti_eqep_action_get(struct counter_device *counter, - struct counter_count *count, - struct counter_synapse *synapse, size_t *action) +static int ti_eqep_action_read(struct counter_device *counter, + struct counter_count *count, + struct counter_synapse *synapse, + enum counter_synapse_action *action) { struct ti_eqep_cnt *priv = counter->priv; - size_t function; + enum counter_function function; u32 qdecctl; int err; - err = ti_eqep_function_get(counter, count, &function); + err = ti_eqep_function_read(counter, count, &function); if (err) return err; switch (function) { - case TI_EQEP_COUNT_FUNC_QUAD_COUNT: + case COUNTER_FUNCTION_QUADRATURE_X4: /* In quadrature mode, the rising and falling edge of both * QEPA and QEPB trigger QCLK. */ - *action = TI_EQEP_SYNAPSE_ACTION_BOTH_EDGES; + *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; return 0; - case TI_EQEP_COUNT_FUNC_DIR_COUNT: + case COUNTER_FUNCTION_PULSE_DIRECTION: /* In direction-count mode only rising edge of QEPA is counted * and QEPB gives direction. */ switch (synapse->signal->id) { case TI_EQEP_SIGNAL_QEPA: - *action = TI_EQEP_SYNAPSE_ACTION_RISING_EDGE; + *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE; return 0; case TI_EQEP_SIGNAL_QEPB: - *action = TI_EQEP_SYNAPSE_ACTION_NONE; + *action = COUNTER_SYNAPSE_ACTION_NONE; return 0; default: /* should never reach this path */ return -EINVAL; } - case TI_EQEP_COUNT_FUNC_UP_COUNT: - case TI_EQEP_COUNT_FUNC_DOWN_COUNT: + case COUNTER_FUNCTION_INCREASE: + case COUNTER_FUNCTION_DECREASE: /* In up/down-count modes only QEPA is counted and QEPB is not * used. */ @@ -185,12 +216,12 @@ static int ti_eqep_action_get(struct counter_device *counter, return err; if (qdecctl & QDECCTL_XCR) - *action = TI_EQEP_SYNAPSE_ACTION_BOTH_EDGES; + *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; else - *action = TI_EQEP_SYNAPSE_ACTION_RISING_EDGE; + *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE; return 0; case TI_EQEP_SIGNAL_QEPB: - *action = TI_EQEP_SYNAPSE_ACTION_NONE; + *action = COUNTER_SYNAPSE_ACTION_NONE; return 0; default: /* should never reach this path */ @@ -205,82 +236,67 @@ static int ti_eqep_action_get(struct counter_device *counter, static const struct counter_ops ti_eqep_counter_ops = { .count_read = ti_eqep_count_read, .count_write = ti_eqep_count_write, - .function_get = ti_eqep_function_get, - .function_set = ti_eqep_function_set, - .action_get = ti_eqep_action_get, + .function_read = ti_eqep_function_read, + .function_write = ti_eqep_function_write, + .action_read = ti_eqep_action_read, }; -static ssize_t ti_eqep_position_ceiling_read(struct counter_device *counter, - struct counter_count *count, - void *ext_priv, char *buf) +static int ti_eqep_position_ceiling_read(struct counter_device *counter, + struct counter_count *count, + u64 *ceiling) { struct ti_eqep_cnt *priv = counter->priv; u32 qposmax; regmap_read(priv->regmap32, QPOSMAX, &qposmax); - return sprintf(buf, "%u\n", qposmax); + *ceiling = qposmax; + + return 0; } -static ssize_t ti_eqep_position_ceiling_write(struct counter_device *counter, - struct counter_count *count, - void *ext_priv, const char *buf, - size_t len) +static int ti_eqep_position_ceiling_write(struct counter_device *counter, + struct counter_count *count, + u64 ceiling) { struct ti_eqep_cnt *priv = counter->priv; - int err; - u32 res; - err = kstrtouint(buf, 0, &res); - if (err < 0) - return err; + if (ceiling != (u32)ceiling) + return -ERANGE; - regmap_write(priv->regmap32, QPOSMAX, res); + regmap_write(priv->regmap32, QPOSMAX, ceiling); - return len; + return 0; } -static ssize_t ti_eqep_position_enable_read(struct counter_device *counter, - struct counter_count *count, - void *ext_priv, char *buf) +static int ti_eqep_position_enable_read(struct counter_device *counter, + struct counter_count *count, u8 *enable) { struct ti_eqep_cnt *priv = counter->priv; u32 qepctl; regmap_read(priv->regmap16, QEPCTL, &qepctl); - return sprintf(buf, "%u\n", !!(qepctl & QEPCTL_PHEN)); + *enable = !!(qepctl & QEPCTL_PHEN); + + return 0; } -static ssize_t ti_eqep_position_enable_write(struct counter_device *counter, - struct counter_count *count, - void *ext_priv, const char *buf, - size_t len) +static int ti_eqep_position_enable_write(struct counter_device *counter, + struct counter_count *count, u8 enable) { struct ti_eqep_cnt *priv = counter->priv; - int err; - bool res; - - err = kstrtobool(buf, &res); - if (err < 0) - return err; - regmap_write_bits(priv->regmap16, QEPCTL, QEPCTL_PHEN, res ? -1 : 0); + regmap_write_bits(priv->regmap16, QEPCTL, QEPCTL_PHEN, enable ? -1 : 0); - return len; + return 0; } -static struct counter_count_ext ti_eqep_position_ext[] = { - { - .name = "ceiling", - .read = ti_eqep_position_ceiling_read, - .write = ti_eqep_position_ceiling_write, - }, - { - .name = "enable", - .read = ti_eqep_position_enable_read, - .write = ti_eqep_position_enable_write, - }, +static struct counter_comp ti_eqep_position_ext[] = { + COUNTER_COMP_CEILING(ti_eqep_position_ceiling_read, + ti_eqep_position_ceiling_write), + COUNTER_COMP_ENABLE(ti_eqep_position_enable_read, + ti_eqep_position_enable_write), }; static struct counter_signal ti_eqep_signals[] = { @@ -295,16 +311,16 @@ static struct counter_signal ti_eqep_signals[] = { }; static const enum counter_function ti_eqep_position_functions[] = { - [TI_EQEP_COUNT_FUNC_QUAD_COUNT] = COUNTER_FUNCTION_QUADRATURE_X4, - [TI_EQEP_COUNT_FUNC_DIR_COUNT] = COUNTER_FUNCTION_PULSE_DIRECTION, - [TI_EQEP_COUNT_FUNC_UP_COUNT] = COUNTER_FUNCTION_INCREASE, - [TI_EQEP_COUNT_FUNC_DOWN_COUNT] = COUNTER_FUNCTION_DECREASE, + COUNTER_FUNCTION_QUADRATURE_X4, + COUNTER_FUNCTION_PULSE_DIRECTION, + COUNTER_FUNCTION_INCREASE, + COUNTER_FUNCTION_DECREASE, }; static const enum counter_synapse_action ti_eqep_position_synapse_actions[] = { - [TI_EQEP_SYNAPSE_ACTION_BOTH_EDGES] = COUNTER_SYNAPSE_ACTION_BOTH_EDGES, - [TI_EQEP_SYNAPSE_ACTION_RISING_EDGE] = COUNTER_SYNAPSE_ACTION_RISING_EDGE, - [TI_EQEP_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE, + COUNTER_SYNAPSE_ACTION_BOTH_EDGES, + COUNTER_SYNAPSE_ACTION_RISING_EDGE, + COUNTER_SYNAPSE_ACTION_NONE, }; static struct counter_synapse ti_eqep_position_synapses[] = { |