VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
author: Greg Kroah-Hartman <gregkh@linuxfoundation.org> 2021-03-26 12:09:47 +0100 committer: Greg Kroah-Hartman <gregkh@linuxfoundation.org> 2021-03-26 12:09:47 +0100 commit: 9c15db92a8e56bcde0f58064ac1adc28c0579b51 parent: d010995736cb581de55e99268d66937085b45ea0
Commit Summary:
Merge tag 'iio-for-5.13a' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next
Diffstat:
5 files changed, 302 insertions, 697 deletions
diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
index 78766b6ec271..9691f8612be8 100644
--- a/drivers/counter/104-quad-8.c
+++ b/drivers/counter/104-quad-8.c
@@ -9,8 +9,6 @@
 #include <linux/counter.h>
 #include <linux/device.h>
 #include <linux/errno.h>
-#include <linux/iio/iio.h>
-#include <linux/iio/types.h>
 #include <linux/io.h>
 #include <linux/ioport.h>
 #include <linux/isa.h>
@@ -29,7 +27,7 @@ MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
 #define QUAD8_NUM_COUNTERS 8
 
 /**
- * struct quad8_iio - IIO device private data structure
+ * struct quad8 - device private data structure
  * @counter:		instance of the counter_device
  * @fck_prescaler:	array of filter clock prescaler configurations
  * @preset:		array of preset values
@@ -41,9 +39,9 @@ MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
  * @synchronous_mode:	array of index function synchronous mode configurations
  * @index_polarity:	array of index function polarity configurations
  * @cable_fault_enable:	differential encoder cable status enable configurations
- * @base:		base port address of the IIO device
+ * @base:		base port address of the device
  */
-struct quad8_iio {
+struct quad8 {
 	struct mutex lock;
 	struct counter_device counter;
 	unsigned int fck_prescaler[QUAD8_NUM_COUNTERS];
@@ -98,532 +96,10 @@ struct quad8_iio {
 #define QUAD8_CMR_QUADRATURE_X2 0x10
 #define QUAD8_CMR_QUADRATURE_X4 0x18
 
-
-static int quad8_read_raw(struct iio_dev *indio_dev,
-	struct iio_chan_spec const *chan, int *val, int *val2, long mask)
-{
-	struct quad8_iio *const priv = iio_priv(indio_dev);
-	const int base_offset = priv->base + 2 * chan->channel;
-	unsigned int flags;
-	unsigned int borrow;
-	unsigned int carry;
-	int i;
-
-	switch (mask) {
-	case IIO_CHAN_INFO_RAW:
-		if (chan->type == IIO_INDEX) {
-			*val = !!(inb(priv->base + QUAD8_REG_INDEX_INPUT_LEVELS)
-				& BIT(chan->channel));
-			return IIO_VAL_INT;
-		}
-
-		flags = inb(base_offset + 1);
-		borrow = flags & QUAD8_FLAG_BT;
-		carry = !!(flags & QUAD8_FLAG_CT);
-
-		/* Borrow XOR Carry effectively doubles count range */
-		*val = (borrow ^ carry) << 24;
-
-		mutex_lock(&priv->lock);
-
-		/* Reset Byte Pointer; transfer Counter to Output Latch */
-		outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_CNTR_OUT,
-		     base_offset + 1);
-
-		for (i = 0; i < 3; i++)
-			*val |= (unsigned int)inb(base_offset) << (8 * i);
-
-		mutex_unlock(&priv->lock);
-
-		return IIO_VAL_INT;
-	case IIO_CHAN_INFO_ENABLE:
-		*val = priv->ab_enable[chan->channel];
-		return IIO_VAL_INT;
-	case IIO_CHAN_INFO_SCALE:
-		*val = 1;
-		*val2 = priv->quadrature_scale[chan->channel];
-		return IIO_VAL_FRACTIONAL_LOG2;
-	}
-
-	return -EINVAL;
-}
-
-static int quad8_write_raw(struct iio_dev *indio_dev,
-	struct iio_chan_spec const *chan, int val, int val2, long mask)
-{
-	struct quad8_iio *const priv = iio_priv(indio_dev);
-	const int base_offset = priv->base + 2 * chan->channel;
-	int i;
-	unsigned int ior_cfg;
-
-	switch (mask) {
-	case IIO_CHAN_INFO_RAW:
-		if (chan->type == IIO_INDEX)
-			return -EINVAL;
-
-		/* Only 24-bit values are supported */
-		if ((unsigned int)val > 0xFFFFFF)
-			return -EINVAL;
-
-		mutex_lock(&priv->lock);
-
-		/* Reset Byte Pointer */
-		outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
-
-		/* Counter can only be set via Preset Register */
-		for (i = 0; i < 3; i++)
-			outb(val >> (8 * i), base_offset);
-
-		/* Transfer Preset Register to Counter */
-		outb(QUAD8_CTR_RLD | QUAD8_RLD_PRESET_CNTR, base_offset + 1);
-
-		/* Reset Byte Pointer */
-		outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
-
-		/* Set Preset Register back to original value */
-		val = priv->preset[chan->channel];
-		for (i = 0; i < 3; i++)
-			outb(val >> (8 * i), base_offset);
-
-		/* Reset Borrow, Carry, Compare, and Sign flags */
-		outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_FLAGS, base_offset + 1);
-		/* Reset Error flag */
-		outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, base_offset + 1);
-
-		mutex_unlock(&priv->lock);
-
-		return 0;
-	case IIO_CHAN_INFO_ENABLE:
-		/* only boolean values accepted */
-		if (val < 0 || val > 1)
-			return -EINVAL;
-
-		mutex_lock(&priv->lock);
-
-		priv->ab_enable[chan->channel] = val;
-
-		ior_cfg = val | priv->preset_enable[chan->channel] << 1;
-
-		/* Load I/O control configuration */
-		outb(QUAD8_CTR_IOR | ior_cfg, base_offset + 1);
-
-		mutex_unlock(&priv->lock);
-
-		return 0;
-	case IIO_CHAN_INFO_SCALE:
-		mutex_lock(&priv->lock);
-
-		/* Quadrature scaling only available in quadrature mode */
-		if (!priv->quadrature_mode[chan->channel] &&
-				(val2 || val != 1)) {
-			mutex_unlock(&priv->lock);
-			return -EINVAL;
-		}
-
-		/* Only three gain states (1, 0.5, 0.25) */
-		if (val == 1 && !val2)
-			priv->quadrature_scale[chan->channel] = 0;
-		else if (!val)
-			switch (val2) {
-			case 500000:
-				priv->quadrature_scale[chan->channel] = 1;
-				break;
-			case 250000:
-				priv->quadrature_scale[chan->channel] = 2;
-				break;
-			default:
-				mutex_unlock(&priv->lock);
-				return -EINVAL;
-			}
-		else {
-			mutex_unlock(&priv->lock);
-			return -EINVAL;
-		}
-
-		mutex_unlock(&priv->lock);
-		return 0;
-	}
-
-	return -EINVAL;
-}
-
-static const struct iio_info quad8_info = {
-	.read_raw = quad8_read_raw,
-	.write_raw = quad8_write_raw
-};
-
-static ssize_t quad8_read_preset(struct iio_dev *indio_dev, uintptr_t private,
-	const struct iio_chan_spec *chan, char *buf)
-{
-	const struct quad8_iio *const priv = iio_priv(indio_dev);
-
-	return snprintf(buf, PAGE_SIZE, "%u\n", priv->preset[chan->channel]);
-}
-
-static ssize_t quad8_write_preset(struct iio_dev *indio_dev, uintptr_t private,
-	const struct iio_chan_spec *chan, const char *buf, size_t len)
-{
-	struct quad8_iio *const priv = iio_priv(indio_dev);
-	const int base_offset = priv->base + 2 * chan->channel;
-	unsigned int preset;
-	int ret;
-	int i;
-
-	ret = kstrtouint(buf, 0, &preset);
-	if (ret)
-		return ret;
-
-	/* Only 24-bit values are supported */
-	if (preset > 0xFFFFFF)
-		return -EINVAL;
-
-	mutex_lock(&priv->lock);
-
-	priv->preset[chan->channel] = preset;
-
-	/* Reset Byte Pointer */
-	outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
-
-	/* Set Preset Register */
-	for (i = 0; i < 3; i++)
-		outb(preset >> (8 * i), base_offset);
-
-	mutex_unlock(&priv->lock);
-
-	return len;
-}
-
-static ssize_t quad8_read_set_to_preset_on_index(struct iio_dev *indio_dev,
-	uintptr_t private, const struct iio_chan_spec *chan, char *buf)
-{
-	const struct quad8_iio *const priv = iio_priv(indio_dev);
-
-	return snprintf(buf, PAGE_SIZE, "%u\n",
-		!priv->preset_enable[chan->channel]);
-}
-
-static ssize_t quad8_write_set_to_preset_on_index(struct iio_dev *indio_dev,
-	uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
-	size_t len)
-{
-	struct quad8_iio *const priv = iio_priv(indio_dev);
-	const int base_offset = priv->base + 2 * chan->channel + 1;
-	bool preset_enable;
-	int ret;
-	unsigned int ior_cfg;
-
-	ret = kstrtobool(buf, &preset_enable);
-	if (ret)
-		return ret;
-
-	/* Preset enable is active low in Input/Output Control register */
-	preset_enable = !preset_enable;
-
-	mutex_lock(&priv->lock);
-
-	priv->preset_enable[chan->channel] = preset_enable;
-
-	ior_cfg = priv->ab_enable[chan->channel] |
-		(unsigned int)preset_enable << 1;
-
-	/* Load I/O control configuration to Input / Output Control Register */
-	outb(QUAD8_CTR_IOR | ior_cfg, base_offset);
-
-	mutex_unlock(&priv->lock);
-
-	return len;
-}
-
-static const char *const quad8_noise_error_states[] = {
-	"No excessive noise is present at the count inputs",
-	"Excessive noise is present at the count inputs"
-};
-
-static int quad8_get_noise_error(struct iio_dev *indio_dev,
-	const struct iio_chan_spec *chan)
-{
-	struct quad8_iio *const priv = iio_priv(indio_dev);
-	const int base_offset = priv->base + 2 * chan->channel + 1;
-
-	return !!(inb(base_offset) & QUAD8_FLAG_E);
-}
-
-static const struct iio_enum quad8_noise_error_enum = {
-	.items = quad8_noise_error_states,
-	.num_items = ARRAY_SIZE(quad8_noise_error_states),
-	.get = quad8_get_noise_error
-};
-
-static const char *const quad8_count_direction_states[] = {
-	"down",
-	"up"
-};
-
-static int quad8_get_count_direction(struct iio_dev *indio_dev,
-	const struct iio_chan_spec *chan)
-{
-	struct quad8_iio *const priv = iio_priv(indio_dev);
-	const int base_offset = priv->base + 2 * chan->channel + 1;
-
-	return !!(inb(base_offset) & QUAD8_FLAG_UD);
-}
-
-static const struct iio_enum quad8_count_direction_enum = {
-	.items = quad8_count_direction_states,
-	.num_items = ARRAY_SIZE(quad8_count_direction_states),
-	.get = quad8_get_count_direction
-};
-
-static const char *const quad8_count_modes[] = {
-	"normal",
-	"range limit",
-	"non-recycle",
-	"modulo-n"
-};
-
-static int quad8_set_count_mode(struct iio_dev *indio_dev,
-	const struct iio_chan_spec *chan, unsigned int cnt_mode)
-{
-	struct quad8_iio *const priv = iio_priv(indio_dev);
-	unsigned int mode_cfg = cnt_mode << 1;
-	const int base_offset = priv->base + 2 * chan->channel + 1;
-
-	mutex_lock(&priv->lock);
-
-	priv->count_mode[chan->channel] = cnt_mode;
-
-	/* Add quadrature mode configuration */
-	if (priv->quadrature_mode[chan->channel])
-		mode_cfg |= (priv->quadrature_scale[chan->channel] + 1) << 3;
-
-	/* Load mode configuration to Counter Mode Register */
-	outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
-
-	mutex_unlock(&priv->lock);
-
-	return 0;
-}
-
-static int quad8_get_count_mode(struct iio_dev *indio_dev,
-	const struct iio_chan_spec *chan)
-{
-	const struct quad8_iio *const priv = iio_priv(indio_dev);
-
-	return priv->count_mode[chan->channel];
-}
-
-static const struct iio_enum quad8_count_mode_enum = {
-	.items = quad8_count_modes,
-	.num_items = ARRAY_SIZE(quad8_count_modes),
-	.set = quad8_set_count_mode,
-	.get = quad8_get_count_mode
-};
-
-static const char *const quad8_synchronous_modes[] = {
-	"non-synchronous",
-	"synchronous"
-};
-
-static int quad8_set_synchronous_mode(struct iio_dev *indio_dev,
-	const struct iio_chan_spec *chan, unsigned int synchronous_mode)
-{
-	struct quad8_iio *const priv = iio_priv(indio_dev);
-	const int base_offset = priv->base + 2 * chan->channel + 1;
-	unsigned int idr_cfg = synchronous_mode;
-
-	mutex_lock(&priv->lock);
-
-	idr_cfg |= priv->index_polarity[chan->channel] << 1;
-
-	/* Index function must be non-synchronous in non-quadrature mode */
-	if (synchronous_mode && !priv->quadrature_mode[chan->channel]) {
-		mutex_unlock(&priv->lock);
-		return -EINVAL;
-	}
-
-	priv->synchronous_mode[chan->channel] = synchronous_mode;
-
-	/* Load Index Control configuration to Index Control Register */
-	outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
-
-	mutex_unlock(&priv->lock);
-
-	return 0;
-}
-
-static int quad8_get_synchronous_mode(struct iio_dev *indio_dev,
-	const struct iio_chan_spec *chan)
-{
-	const struct quad8_iio *const priv = iio_priv(indio_dev);
-
-	return priv->synchronous_mode[chan->channel];
-}
-
-static const struct iio_enum quad8_synchronous_mode_enum = {
-	.items = quad8_synchronous_modes,
-	.num_items = ARRAY_SIZE(quad8_synchronous_modes),
-	.set = quad8_set_synchronous_mode,
-	.get = quad8_get_synchronous_mode
-};
-
-static const char *const quad8_quadrature_modes[] = {
-	"non-quadrature",
-	"quadrature"
-};
-
-static int quad8_set_quadrature_mode(struct iio_dev *indio_dev,
-	const struct iio_chan_spec *chan, unsigned int quadrature_mode)
-{
-	struct quad8_iio *const priv = iio_priv(indio_dev);
-	const int base_offset = priv->base + 2 * chan->channel + 1;
-	unsigned int mode_cfg;
-
-	mutex_lock(&priv->lock);
-
-	mode_cfg = priv->count_mode[chan->channel] << 1;
-
-	if (quadrature_mode)
-		mode_cfg |= (priv->quadrature_scale[chan->channel] + 1) << 3;
-	else {
-		/* Quadrature scaling only available in quadrature mode */
-		priv->quadrature_scale[chan->channel] = 0;
-
-		/* Synchronous function not supported in non-quadrature mode */
-		if (priv->synchronous_mode[chan->channel])
-			quad8_set_synchronous_mode(indio_dev, chan, 0);
-	}
-
-	priv->quadrature_mode[chan->channel] = quadrature_mode;
-
-	/* Load mode configuration to Counter Mode Register */
-	outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
-
-	mutex_unlock(&priv->lock);
-
-	return 0;
-}
-
-static int quad8_get_quadrature_mode(struct iio_dev *indio_dev,
-	const struct iio_chan_spec *chan)
-{
-	const struct quad8_iio *const priv = iio_priv(indio_dev);
-
-	return priv->quadrature_mode[chan->channel];
-}
-
-static const struct iio_enum quad8_quadrature_mode_enum = {
-	.items = quad8_quadrature_modes,
-	.num_items = ARRAY_SIZE(quad8_quadrature_modes),
-	.set = quad8_set_quadrature_mode,
-	.get = quad8_get_quadrature_mode
-};
-
-static const char *const quad8_index_polarity_modes[] = {
-	"negative",
-	"positive"
-};
-
-static int quad8_set_index_polarity(struct iio_dev *indio_dev,
-	const struct iio_chan_spec *chan, unsigned int index_polarity)
-{
-	struct quad8_iio *const priv = iio_priv(indio_dev);
-	const int base_offset = priv->base + 2 * chan->channel + 1;
-	unsigned int idr_cfg = index_polarity << 1;
-
-	mutex_lock(&priv->lock);
-
-	idr_cfg |= priv->synchronous_mode[chan->channel];
-
-	priv->index_polarity[chan->channel] = index_polarity;
-
-	/* Load Index Control configuration to Index Control Register */
-	outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
-
-	mutex_unlock(&priv->lock);
-
-	return 0;
-}
-
-static int quad8_get_index_polarity(struct iio_dev *indio_dev,
-	const struct iio_chan_spec *chan)
-{
-	const struct quad8_iio *const priv = iio_priv(indio_dev);
-
-	return priv->index_polarity[chan->channel];
-}
-
-static const struct iio_enum quad8_index_polarity_enum = {
-	.items = quad8_index_polarity_modes,
-	.num_items = ARRAY_SIZE(quad8_index_polarity_modes),
-	.set = quad8_set_index_polarity,
-	.get = quad8_get_index_polarity
-};
-
-static const struct iio_chan_spec_ext_info quad8_count_ext_info[] = {
-	{
-		.name = "preset",
-		.shared = IIO_SEPARATE,
-		.read = quad8_read_preset,
-		.write = quad8_write_preset
-	},
-	{
-		.name = "set_to_preset_on_index",
-		.shared = IIO_SEPARATE,
-		.read = quad8_read_set_to_preset_on_index,
-		.write = quad8_write_set_to_preset_on_index
-	},
-	IIO_ENUM("noise_error", IIO_SEPARATE, &quad8_noise_error_enum),
-	IIO_ENUM_AVAILABLE("noise_error", &quad8_noise_error_enum),
-	IIO_ENUM("count_direction", IIO_SEPARATE, &quad8_count_direction_enum),
-	IIO_ENUM_AVAILABLE("count_direction", &quad8_count_direction_enum),
-	IIO_ENUM("count_mode", IIO_SEPARATE, &quad8_count_mode_enum),
-	IIO_ENUM_AVAILABLE("count_mode", &quad8_count_mode_enum),
-	IIO_ENUM("quadrature_mode", IIO_SEPARATE, &quad8_quadrature_mode_enum),
-	IIO_ENUM_AVAILABLE("quadrature_mode", &quad8_quadrature_mode_enum),
-	{}
-};
-
-static const struct iio_chan_spec_ext_info quad8_index_ext_info[] = {
-	IIO_ENUM("synchronous_mode", IIO_SEPARATE,
-		&quad8_synchronous_mode_enum),
-	IIO_ENUM_AVAILABLE("synchronous_mode", &quad8_synchronous_mode_enum),
-	IIO_ENUM("index_polarity", IIO_SEPARATE, &quad8_index_polarity_enum),
-	IIO_ENUM_AVAILABLE("index_polarity", &quad8_index_polarity_enum),
-	{}
-};
-
-#define QUAD8_COUNT_CHAN(_chan) {					\
-	.type = IIO_COUNT,						\
-	.channel = (_chan),						\
-	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |			\
-		BIT(IIO_CHAN_INFO_ENABLE) | BIT(IIO_CHAN_INFO_SCALE),	\
-	.ext_info = quad8_count_ext_info,				\
-	.indexed = 1							\
-}
-
-#define QUAD8_INDEX_CHAN(_chan) {			\
-	.type = IIO_INDEX,				\
-	.channel = (_chan),				\
-	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),	\
-	.ext_info = quad8_index_ext_info,		\
-	.indexed = 1					\
-}
-
-static const struct iio_chan_spec quad8_channels[] = {
-	QUAD8_COUNT_CHAN(0), QUAD8_INDEX_CHAN(0),
-	QUAD8_COUNT_CHAN(1), QUAD8_INDEX_CHAN(1),
-	QUAD8_COUNT_CHAN(2), QUAD8_INDEX_CHAN(2),
-	QUAD8_COUNT_CHAN(3), QUAD8_INDEX_CHAN(3),
-	QUAD8_COUNT_CHAN(4), QUAD8_INDEX_CHAN(4),
-	QUAD8_COUNT_CHAN(5), QUAD8_INDEX_CHAN(5),
-	QUAD8_COUNT_CHAN(6), QUAD8_INDEX_CHAN(6),
-	QUAD8_COUNT_CHAN(7), QUAD8_INDEX_CHAN(7)
-};
-
 static int quad8_signal_read(struct counter_device *counter,
 	struct counter_signal *signal, enum counter_signal_value *val)
 {
-	const struct quad8_iio *const priv = counter->priv;
+	const struct quad8 *const priv = counter->priv;
 	unsigned int state;
 
 	/* Only Index signal levels can be read */
@@ -641,7 +117,7 @@ static int quad8_signal_read(struct counter_device *counter,
 static int quad8_count_read(struct counter_device *counter,
 	struct counter_count *count, unsigned long *val)
 {
-	struct quad8_iio *const priv = counter->priv;
+	struct quad8 *const priv = counter->priv;
 	const int base_offset = priv->base + 2 * count->id;
 	unsigned int flags;
 	unsigned int borrow;
@@ -672,7 +148,7 @@ static int quad8_count_read(struct counter_device *counter,
 static int quad8_count_write(struct counter_device *counter,
 	struct counter_count *count, unsigned long val)
 {
-	struct quad8_iio *const priv = counter->priv;
+	struct quad8 *const priv = counter->priv;
 	const int base_offset = priv->base + 2 * count->id;
 	int i;
 
@@ -727,7 +203,7 @@ static enum counter_count_function quad8_count_functions_list[] = {
 static int quad8_function_get(struct counter_device *counter,
 	struct counter_count *count, size_t *function)
 {
-	struct quad8_iio *const priv = counter->priv;
+	struct quad8 *const priv = counter->priv;
 	const int id = count->id;
 
 	mutex_lock(&priv->lock);
@@ -755,7 +231,7 @@ static int quad8_function_get(struct counter_device *counter,
 static int quad8_function_set(struct counter_device *counter,
 	struct counter_count *count, size_t function)
 {
-	struct quad8_iio *const priv = counter->priv;
+	struct quad8 *const priv = counter->priv;
 	const int id = count->id;
 	unsigned int *const quadrature_mode = priv->quadrature_mode + id;
 	unsigned int *const scale = priv->quadrature_scale + id;
@@ -811,7 +287,7 @@ static int quad8_function_set(struct counter_device *counter,
 static void quad8_direction_get(struct counter_device *counter,
 	struct counter_count *count, enum counter_count_direction *direction)
 {
-	const struct quad8_iio *const priv = counter->priv;
+	const struct quad8 *const priv = counter->priv;
 	unsigned int ud_flag;
 	const unsigned int flag_addr = priv->base + 2 * count->id + 1;
 
@@ -845,7 +321,7 @@ static int quad8_action_get(struct counter_device *counter,
 	struct counter_count *count, struct counter_synapse *synapse,
 	size_t *action)
 {
-	struct quad8_iio *const priv = counter->priv;
+	struct quad8 *const priv = counter->priv;
 	int err;
 	size_t function = 0;
 	const size_t signal_a_id = count->synapses[0].signal->id;
@@ -905,10 +381,15 @@ static const struct counter_ops quad8_ops = {
 	.action_get = quad8_action_get
 };
 
+static const char *const quad8_index_polarity_modes[] = {
+	"negative",
+	"positive"
+};
+
 static int quad8_index_polarity_get(struct counter_device *counter,
 	struct counter_signal *signal, size_t *index_polarity)
 {
-	const struct quad8_iio *const priv = counter->priv;
+	const struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id - 16;
 
 	*index_polarity = priv->index_polarity[channel_id];
@@ -919,7 +400,7 @@ static int quad8_index_polarity_get(struct counter_device *counter,
 static int quad8_index_polarity_set(struct counter_device *counter,
 	struct counter_signal *signal, size_t index_polarity)
 {
-	struct quad8_iio *const priv = counter->priv;
+	struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id - 16;
 	const int base_offset = priv->base + 2 * channel_id + 1;
 	unsigned int idr_cfg = index_polarity << 1;
@@ -945,10 +426,15 @@ static struct counter_signal_enum_ext quad8_index_pol_enum = {
 	.set = quad8_index_polarity_set
 };
 
+static const char *const quad8_synchronous_modes[] = {
+	"non-synchronous",
+	"synchronous"
+};
+
 static int quad8_synchronous_mode_get(struct counter_device *counter,
 	struct counter_signal *signal, size_t *synchronous_mode)
 {
-	const struct quad8_iio *const priv = counter->priv;
+	const struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id - 16;
 
 	*synchronous_mode = priv->synchronous_mode[channel_id];
@@ -959,7 +445,7 @@ static int quad8_synchronous_mode_get(struct counter_device *counter,
 static int quad8_synchronous_mode_set(struct counter_device *counter,
 	struct counter_signal *signal, size_t synchronous_mode)
 {
-	struct quad8_iio *const priv = counter->priv;
+	struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id - 16;
 	const int base_offset = priv->base + 2 * channel_id + 1;
 	unsigned int idr_cfg = synchronous_mode;
@@ -1001,7 +487,7 @@ static ssize_t quad8_count_floor_read(struct counter_device *counter,
 static int quad8_count_mode_get(struct counter_device *counter,
 	struct counter_count *count, size_t *cnt_mode)
 {
-	const struct quad8_iio *const priv = counter->priv;
+	const struct quad8 *const priv = counter->priv;
 
 	/* Map 104-QUAD-8 count mode to Generic Counter count mode */
 	switch (priv->count_mode[count->id]) {
@@ -1025,7 +511,7 @@ static int quad8_count_mode_get(struct counter_device *counter,
 static int quad8_count_mode_set(struct counter_device *counter,
 	struct counter_count *count, size_t cnt_mode)
 {
-	struct quad8_iio *const priv = counter->priv;
+	struct quad8 *const priv = counter->priv;
 	unsigned int mode_cfg;
 	const int base_offset = priv->base + 2 * count->id + 1;
 
@@ -1084,7 +570,7 @@ static ssize_t quad8_count_direction_read(struct counter_device *counter,
 static ssize_t quad8_count_enable_read(struct counter_device *counter,
 	struct counter_count *count, void *private, char *buf)
 {
-	const struct quad8_iio *const priv = counter->priv;
+	const struct quad8 *const priv = counter->priv;
 
 	return sprintf(buf, "%u\n", priv->ab_enable[count->id]);
 }
@@ -1092,7 +578,7 @@ static ssize_t quad8_count_enable_read(struct counter_device *counter,
 static ssize_t quad8_count_enable_write(struct counter_device *counter,
 	struct counter_count *count, void *private, const char *buf, size_t len)
 {
-	struct quad8_iio *const priv = counter->priv;
+	struct quad8 *const priv = counter->priv;
 	const int base_offset = priv->base + 2 * count->id;
 	int err;
 	bool ab_enable;
@@ -1116,10 +602,15 @@ static ssize_t quad8_count_enable_write(struct counter_device *counter,
 	return len;
 }
 
+static const char *const quad8_noise_error_states[] = {
+	"No excessive noise is present at the count inputs",
+	"Excessive noise is present at the count inputs"
+};
+
 static int quad8_error_noise_get(struct counter_device *counter,
 	struct counter_count *count, size_t *noise_error)
 {
-	const struct quad8_iio *const priv = counter->priv;
+	const struct quad8 *const priv = counter->priv;
 	const int base_offset = priv->base + 2 * count->id + 1;
 
 	*noise_error = !!(inb(base_offset) & QUAD8_FLAG_E);
@@ -1136,18 +627,18 @@ static struct counter_count_enum_ext quad8_error_noise_enum = {
 static ssize_t quad8_count_preset_read(struct counter_device *counter,
 	struct counter_count *count, void *private, char *buf)
 {
-	const struct quad8_iio *const priv = counter->priv;
+	const struct quad8 *const priv = counter->priv;
 
 	return sprintf(buf, "%u\n", priv->preset[count->id]);
 }
 
-static void quad8_preset_register_set(struct quad8_iio *quad8iio, int id,
-		unsigned int preset)
+static void quad8_preset_register_set(struct quad8 *priv, int id,
+				      unsigned int preset)
 {
-	const unsigned int base_offset = quad8iio->base + 2 * id;
+	const unsigned int base_offset = priv->base + 2 * id;
 	int i;
 
-	quad8iio->preset[id] = preset;
+	priv->preset[id] = preset;
 
 	/* Reset Byte Pointer */
 	outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
@@ -1160,7 +651,7 @@ static void quad8_preset_register_set(struct quad8_iio *quad8iio, int id,
 static ssize_t quad8_count_preset_write(struct counter_device *counter,
 	struct counter_count *count, void *private, const char *buf, size_t len)
 {
-	struct quad8_iio *const priv = counter->priv;
+	struct quad8 *const priv = counter->priv;
 	unsigned int preset;
 	int ret;
 
@@ -1184,7 +675,7 @@ static ssize_t quad8_count_preset_write(struct counter_device *counter,
 static ssize_t quad8_count_ceiling_read(struct counter_device *counter,
 	struct counter_count *count, void *private, char *buf)
 {
-	struct quad8_iio *const priv = counter->priv;
+	struct quad8 *const priv = counter->priv;
 
 	mutex_lock(&priv->lock);
 
@@ -1205,7 +696,7 @@ static ssize_t quad8_count_ceiling_read(struct counter_device *counter,
 static ssize_t quad8_count_ceiling_write(struct counter_device *counter,
 	struct counter_count *count, void *private, const char *buf, size_t len)
 {
-	struct quad8_iio *const priv = counter->priv;
+	struct quad8 *const priv = counter->priv;
 	unsigned int ceiling;
 	int ret;
 
@@ -1235,7 +726,7 @@ static ssize_t quad8_count_ceiling_write(struct counter_device *counter,
 static ssize_t quad8_count_preset_enable_read(struct counter_device *counter,
 	struct counter_count *count, void *private, char *buf)
 {
-	const struct quad8_iio *const priv = counter->priv;
+	const struct quad8 *const priv = counter->priv;
 
 	return sprintf(buf, "%u\n", !priv->preset_enable[count->id]);
 }
@@ -1243,7 +734,7 @@ static ssize_t quad8_count_preset_enable_read(struct counter_device *counter,
 static ssize_t quad8_count_preset_enable_write(struct counter_device *counter,
 	struct counter_count *count, void *private, const char *buf, size_t len)
 {
-	struct quad8_iio *const priv = counter->priv;
+	struct quad8 *const priv = counter->priv;
 	const int base_offset = priv->base + 2 * count->id + 1;
 	bool preset_enable;
 	int ret;
@@ -1274,7 +765,7 @@ static ssize_t quad8_signal_cable_fault_read(struct counter_device *counter,
 					     struct counter_signal *signal,
 					     void *private, char *buf)
 {
-	struct quad8_iio *const priv = counter->priv;
+	struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id / 2;
 	bool disabled;
 	unsigned int status;
@@ -1304,7 +795,7 @@ static ssize_t quad8_signal_cable_fault_enable_read(
 	struct counter_device *counter, struct counter_signal *signal,
 	void *private, char *buf)
 {
-	const struct quad8_iio *const priv = counter->priv;
+	const struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id / 2;
 	const unsigned int enb = !!(priv->cable_fault_enable & BIT(channel_id));
 
@@ -1315,7 +806,7 @@ static ssize_t quad8_signal_cable_fault_enable_write(
 	struct counter_device *counter, struct counter_signal *signal,
 	void *private, const char *buf, size_t len)
 {
-	struct quad8_iio *const priv = counter->priv;
+	struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id / 2;
 	bool enable;
 	int ret;
@@ -1345,7 +836,7 @@ static ssize_t quad8_signal_cable_fault_enable_write(
 static ssize_t quad8_signal_fck_prescaler_read(struct counter_device *counter,
 	struct counter_signal *signal, void *private, char *buf)
 {
-	const struct quad8_iio *const priv = counter->priv;
+	const struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id / 2;
 
 	return sprintf(buf, "%u\n", priv->fck_prescaler[channel_id]);
@@ -1355,7 +846,7 @@ static ssize_t quad8_signal_fck_prescaler_write(struct counter_device *counter,
 	struct counter_signal *signal, void *private, const char *buf,
 	size_t len)
 {
-	struct quad8_iio *const priv = counter->priv;
+	struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id / 2;
 	const int base_offset = priv->base + 2 * channel_id;
 	u8 prescaler;
@@ -1531,11 +1022,9 @@ static struct counter_count quad8_counts[] = {
 
 static int quad8_probe(struct device *dev, unsigned int id)
 {
-	struct iio_dev *indio_dev;
-	struct quad8_iio *quad8iio;
+	struct quad8 *priv;
 	int i, j;
 	unsigned int base_offset;
-	int err;
 
 	if (!devm_request_region(dev, base[id], QUAD8_EXTENT, dev_name(dev))) {
 		dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
@@ -1543,32 +1032,23 @@ static int quad8_probe(struct device *dev, unsigned int id)
 		return -EBUSY;
 	}
 
-	/* Allocate IIO device; this also allocates driver data structure */
-	indio_dev = devm_iio_device_alloc(dev, sizeof(*quad8iio));
-	if (!indio_dev)
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
 		return -ENOMEM;
 
-	/* Initialize IIO device */
-	indio_dev->info = &quad8_info;
-	indio_dev->modes = INDIO_DIRECT_MODE;
-	indio_dev->num_channels = ARRAY_SIZE(quad8_channels);
-	indio_dev->channels = quad8_channels;
-	indio_dev->name = dev_name(dev);
-
 	/* Initialize Counter device and driver data */
-	quad8iio = iio_priv(indio_dev);
-	quad8iio->counter.name = dev_name(dev);
-	quad8iio->counter.parent = dev;
-	quad8iio->counter.ops = &quad8_ops;
-	quad8iio->counter.counts = quad8_counts;
-	quad8iio->counter.num_counts = ARRAY_SIZE(quad8_counts);
-	quad8iio->counter.signals = quad8_signals;
-	quad8iio->counter.num_signals = ARRAY_SIZE(quad8_signals);
-	quad8iio->counter.priv = quad8iio;
-	quad8iio->base = base[id];
+	priv->counter.name = dev_name(dev);
+	priv->counter.parent = dev;
+	priv->counter.ops = &quad8_ops;
+	priv->counter.counts = quad8_counts;
+	priv->counter.num_counts = ARRAY_SIZE(quad8_counts);
+	priv->counter.signals = quad8_signals;
+	priv->counter.num_signals = ARRAY_SIZE(quad8_signals);
+	priv->counter.priv = priv;
+	priv->base = base[id];
 
 	/* Initialize mutex */
-	mutex_init(&quad8iio->lock);
+	mutex_init(&priv->lock);
 
 	/* Reset all counters and disable interrupt function */
 	outb(QUAD8_CHAN_OP_RESET_COUNTERS, base[id] + QUAD8_REG_CHAN_OP);
@@ -1602,13 +1082,8 @@ static int quad8_probe(struct device *dev, unsigned int id)
 	/* Enable all counters */
 	outb(QUAD8_CHAN_OP_ENABLE_COUNTERS, base[id] + QUAD8_REG_CHAN_OP);
 
-	/* Register IIO device */
-	err = devm_iio_device_register(dev, indio_dev);
-	if (err)
-		return err;
-
 	/* Register Counter device */
-	return devm_counter_register(dev, &quad8iio->counter);
+	return devm_counter_register(dev, &priv->counter);
 }
 
 static struct isa_driver quad8_driver = {
@@ -1621,5 +1096,5 @@ static struct isa_driver quad8_driver = {
 module_isa_driver(quad8_driver, num_quad8);
 
 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
-MODULE_DESCRIPTION("ACCES 104-QUAD-8 IIO driver");
+MODULE_DESCRIPTION("ACCES 104-QUAD-8 driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig
index 2de53ab0dd25..5328705aa09c 100644
--- a/drivers/counter/Kconfig
+++ b/drivers/counter/Kconfig
@@ -14,7 +14,7 @@ if COUNTER
 
 config 104_QUAD_8
 	tristate "ACCES 104-QUAD-8 driver"
-	depends on PC104 && X86 && IIO
+	depends on PC104 && X86
 	select ISA_BUS_API
 	help
 	  Say yes here to build support for the ACCES 104-QUAD-8 quadrature
@@ -29,6 +29,16 @@ config 104_QUAD_8
 	  The base port addresses for the devices may be configured via the base
 	  array module parameter.
 
+config INTERRUPT_CNT
+	tristate "Interrupt counter driver"
+	depends on GPIOLIB
+	help
+	  Select this option to enable interrupt counter driver. Any interrupt
+	  source can be used by this driver as the event source.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called interrupt-cnt.
+
 config STM32_TIMER_CNT
 	tristate "STM32 Timer encoder counter driver"
 	depends on MFD_STM32_TIMERS || COMPILE_TEST
@@ -41,7 +51,7 @@ config STM32_TIMER_CNT
 
 config STM32_LPTIMER_CNT
 	tristate "STM32 LP Timer encoder counter driver"
-	depends on (MFD_STM32_LPTIMER || COMPILE_TEST) && IIO
+	depends on MFD_STM32_LPTIMER || COMPILE_TEST
 	help
 	  Select this option to enable STM32 Low-Power Timer quadrature encoder
 	  and counter driver.
diff --git a/drivers/counter/Makefile b/drivers/counter/Makefile
index 0a393f71e481..cb646ed2f039 100644
--- a/drivers/counter/Makefile
+++ b/drivers/counter/Makefile
@@ -6,6 +6,7 @@
 obj-$(CONFIG_COUNTER) += counter.o
 
 obj-$(CONFIG_104_QUAD_8)	+= 104-quad-8.o
+obj-$(CONFIG_INTERRUPT_CNT)		+= interrupt-cnt.o
 obj-$(CONFIG_STM32_TIMER_CNT)	+= stm32-timer-cnt.o
 obj-$(CONFIG_STM32_LPTIMER_CNT)	+= stm32-lptimer-cnt.o
 obj-$(CONFIG_TI_EQEP)		+= ti-eqep.o
diff --git a/drivers/counter/interrupt-cnt.c b/drivers/counter/interrupt-cnt.c
new file mode 100644
index 000000000000..a99ee7996977
--- /dev/null
+++ b/drivers/counter/interrupt-cnt.c
@@ -0,0 +1,244 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
+ */
+
+#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/platform_device.h>
+
+#define INTERRUPT_CNT_NAME "interrupt-cnt"
+
+struct interrupt_cnt_priv {
+	atomic_t count;
+	struct counter_device counter;
+	struct gpio_desc *gpio;
+	int irq;
+	bool enabled;
+	struct counter_signal signals;
+	struct counter_synapse synapses;
+	struct counter_count cnts;
+};
+
+static irqreturn_t interrupt_cnt_isr(int irq, void *dev_id)
+{
+	struct interrupt_cnt_priv *priv = dev_id;
+
+	atomic_inc(&priv->count);
+
+	return IRQ_HANDLED;
+}
+
+static ssize_t interrupt_cnt_enable_read(struct counter_device *counter,
+					 struct counter_count *count,
+					 void *private, char *buf)
+{
+	struct interrupt_cnt_priv *priv = counter->priv;
+
+	return sysfs_emit(buf, "%d\n", priv->enabled);
+}
+
+static ssize_t interrupt_cnt_enable_write(struct counter_device *counter,
+					  struct counter_count *count,
+					  void *private, const char *buf,
+					  size_t len)
+{
+	struct interrupt_cnt_priv *priv = counter->priv;
+	bool enable;
+	ssize_t ret;
+
+	ret = kstrtobool(buf, &enable);
+	if (ret)
+		return ret;
+
+	if (priv->enabled == enable)
+		return len;
+
+	if (enable) {
+		priv->enabled = true;
+		enable_irq(priv->irq);
+	} else {
+		disable_irq(priv->irq);
+		priv->enabled = false;
+	}
+
+	return len;
+}
+
+static const struct counter_count_ext interrupt_cnt_ext[] = {
+	{
+		.name = "enable",
+		.read = interrupt_cnt_enable_read,
+		.write = interrupt_cnt_enable_write,
+	},
+};
+
+static enum counter_synapse_action interrupt_cnt_synapse_actionss[] = {
+	COUNTER_SYNAPSE_ACTION_RISING_EDGE,
+};
+
+static int interrupt_cnt_action_get(struct counter_device *counter,
+				    struct counter_count *count,
+				    struct counter_synapse *synapse,
+				    size_t *action)
+{
+	*action = 0;
+
+	return 0;
+}
+
+static int interrupt_cnt_read(struct counter_device *counter,
+			      struct counter_count *count, unsigned long *val)
+{
+	struct interrupt_cnt_priv *priv = counter->priv;
+
+	*val = atomic_read(&priv->count);
+
+	return 0;
+}
+
+static int interrupt_cnt_write(struct counter_device *counter,
+			       struct counter_count *count,
+			       const unsigned long val)
+{
+	struct interrupt_cnt_priv *priv = counter->priv;
+
+	atomic_set(&priv->count, val);
+
+	return 0;
+}
+
+static enum counter_count_function interrupt_cnt_functions[] = {
+	COUNTER_COUNT_FUNCTION_INCREASE,
+};
+
+static int interrupt_cnt_function_get(struct counter_device *counter,
+				      struct counter_count *count,
+				      size_t *function)
+{
+	*function = 0;
+
+	return 0;
+}
+
+static int interrupt_cnt_signal_read(struct counter_device *counter,
+				     struct counter_signal *signal,
+				     enum counter_signal_value *val)
+{
+	struct interrupt_cnt_priv *priv = counter->priv;
+	int ret;
+
+	if (!priv->gpio)
+		return -EINVAL;
+
+	ret = gpiod_get_value(priv->gpio);
+	if (ret < 0)
+		return ret;
+
+	*val = ret ? COUNTER_SIGNAL_HIGH : COUNTER_SIGNAL_LOW;
+
+	return 0;
+}
+
+static const struct counter_ops interrupt_cnt_ops = {
+	.action_get = interrupt_cnt_action_get,
+	.count_read = interrupt_cnt_read,
+	.count_write = interrupt_cnt_write,
+	.function_get = interrupt_cnt_function_get,
+	.signal_read  = interrupt_cnt_signal_read,
+};
+
+static int interrupt_cnt_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct interrupt_cnt_priv *priv;
+	int ret;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->irq = platform_get_irq_optional(pdev,  0);
+	if (priv->irq == -ENXIO)
+		priv->irq = 0;
+	else if (priv->irq < 0)
+		return dev_err_probe(dev, priv->irq, "failed to get IRQ\n");
+
+	priv->gpio = devm_gpiod_get_optional(dev, NULL, GPIOD_IN);
+	if (IS_ERR(priv->gpio))
+		return dev_err_probe(dev, PTR_ERR(priv->gpio), "failed to get GPIO\n");
+
+	if (!priv->irq && !priv->gpio) {
+		dev_err(dev, "IRQ and GPIO are not found. At least one source should be provided\n");
+		return -ENODEV;
+	}
+
+	if (!priv->irq) {
+		int irq = gpiod_to_irq(priv->gpio);
+
+		if (irq < 0)
+			return dev_err_probe(dev, irq, "failed to get IRQ from GPIO\n");
+
+		priv->irq = irq;
+	}
+
+	priv->signals.name = devm_kasprintf(dev, GFP_KERNEL, "IRQ %d",
+					    priv->irq);
+	if (!priv->signals.name)
+		return -ENOMEM;
+
+	priv->counter.signals = &priv->signals;
+	priv->counter.num_signals = 1;
+
+	priv->synapses.actions_list = interrupt_cnt_synapse_actionss;
+	priv->synapses.num_actions = ARRAY_SIZE(interrupt_cnt_synapse_actionss);
+	priv->synapses.signal = &priv->signals;
+
+	priv->cnts.name = "Channel 0 Count";
+	priv->cnts.functions_list = interrupt_cnt_functions;
+	priv->cnts.num_functions = ARRAY_SIZE(interrupt_cnt_functions);
+	priv->cnts.synapses = &priv->synapses;
+	priv->cnts.num_synapses = 1;
+	priv->cnts.ext = interrupt_cnt_ext;
+	priv->cnts.num_ext = ARRAY_SIZE(interrupt_cnt_ext);
+
+	priv->counter.priv = priv;
+	priv->counter.name = dev_name(dev);
+	priv->counter.parent = dev;
+	priv->counter.ops = &interrupt_cnt_ops;
+	priv->counter.counts = &priv->cnts;
+	priv->counter.num_counts = 1;
+
+	irq_set_status_flags(priv->irq, IRQ_NOAUTOEN);
+	ret = devm_request_irq(dev, priv->irq, interrupt_cnt_isr,
+			       IRQF_TRIGGER_RISING | IRQF_NO_THREAD,
+			       dev_name(dev), priv);
+	if (ret)
+		return ret;
+
+	return devm_counter_register(dev, &priv->counter);
+}
+
+static const struct of_device_id interrupt_cnt_of_match[] = {
+	{ .compatible = "interrupt-counter", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, interrupt_cnt_of_match);
+
+static struct platform_driver interrupt_cnt_driver = {
+	.probe = interrupt_cnt_probe,
+	.driver = {
+		.name = INTERRUPT_CNT_NAME,
+		.of_match_table = interrupt_cnt_of_match,
+	},
+};
+module_platform_driver(interrupt_cnt_driver);
+
+MODULE_ALIAS("platform:interrupt-counter");
+MODULE_AUTHOR("Oleksij Rempel <o.rempel@pengutronix.de>");
+MODULE_DESCRIPTION("Interrupt counter driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c
index fd6828e2d34f..937439635d53 100644
--- a/drivers/counter/stm32-lptimer-cnt.c
+++ b/drivers/counter/stm32-lptimer-cnt.c
@@ -12,8 +12,8 @@
 
 #include <linux/bitfield.h>
 #include <linux/counter.h>
-#include <linux/iio/iio.h>
 #include <linux/mfd/stm32-lptimer.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
@@ -107,249 +107,27 @@ static int stm32_lptim_setup(struct stm32_lptim_cnt *priv, int enable)
 	return regmap_update_bits(priv->regmap, STM32_LPTIM_CFGR, mask, val);
 }
 
-static int stm32_lptim_write_raw(struct iio_dev *indio_dev,
-				 struct iio_chan_spec const *chan,
-				 int val, int val2, long mask)
-{
-	struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
-	int ret;
-
-	switch (mask) {
-	case IIO_CHAN_INFO_ENABLE:
-		if (val < 0 || val > 1)
-			return -EINVAL;
-
-		/* Check nobody uses the timer, or already disabled/enabled */
-		ret = stm32_lptim_is_enabled(priv);
-		if ((ret < 0) || (!ret && !val))
-			return ret;
-		if (val && ret)
-			return -EBUSY;
-
-		ret = stm32_lptim_setup(priv, val);
-		if (ret)
-			return ret;
-		return stm32_lptim_set_enable_state(priv, val);
-
-	default:
-		return -EINVAL;
-	}
-}
-
-static int stm32_lptim_read_raw(struct iio_dev *indio_dev,
-				struct iio_chan_spec const *chan,
-				int *val, int *val2, long mask)
-{
-	struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
-	u32 dat;
-	int ret;
-
-	switch (mask) {
-	case IIO_CHAN_INFO_RAW:
-		ret = regmap_read(priv->regmap, STM32_LPTIM_CNT, &dat);
-		if (ret)
-			return ret;
-		*val = dat;
-		return IIO_VAL_INT;
-
-	case IIO_CHAN_INFO_ENABLE:
-		ret = stm32_lptim_is_enabled(priv);
-		if (ret < 0)
-			return ret;
-		*val = ret;
-		return IIO_VAL_INT;
-
-	case IIO_CHAN_INFO_SCALE:
-		/* Non-quadrature mode: scale = 1 */
-		*val = 1;
-		*val2 = 0;
-		if (priv->quadrature_mode) {
-			/*
-			 * Quadrature encoder mode:
-			 * - both edges, quarter cycle, scale is 0.25
-			 * - either rising/falling edge scale is 0.5
-			 */
-			if (priv->polarity > 1)
-				*val2 = 2;
-			else
-				*val2 = 1;
-		}
-		return IIO_VAL_FRACTIONAL_LOG2;
-
-	default:
-		return -EINVAL;
-	}
-}
-
-static const struct iio_info stm32_lptim_cnt_iio_info = {
-	.read_raw = stm32_lptim_read_raw,
-	.write_raw = stm32_lptim_write_raw,
-};
-
-static const char *const stm32_lptim_quadrature_modes[] = {
-	"non-quadrature",
-	"quadrature",
-};
-
-static int stm32_lptim_get_quadrature_mode(struct iio_dev *indio_dev,
-					   const struct iio_chan_spec *chan)
-{
-	struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
-
-	return priv->quadrature_mode;
-}
-
-static int stm32_lptim_set_quadrature_mode(struct iio_dev *indio_dev,
-					   const struct iio_chan_spec *chan,
-					   unsigned int type)
-{
-	struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
-
-	if (stm32_lptim_is_enabled(priv))
-		return -EBUSY;
-
-	priv->quadrature_mode = type;
-
-	return 0;
-}
-
-static const struct iio_enum stm32_lptim_quadrature_mode_en = {
-	.items = stm32_lptim_quadrature_modes,
-	.num_items = ARRAY_SIZE(stm32_lptim_quadrature_modes),
-	.get = stm32_lptim_get_quadrature_mode,
-	.set = stm32_lptim_set_quadrature_mode,
-};
-
-static const char * const stm32_lptim_cnt_polarity[] = {
-	"rising-edge", "falling-edge", "both-edges",
-};
-
-static int stm32_lptim_cnt_get_polarity(struct iio_dev *indio_dev,
-					const struct iio_chan_spec *chan)
-{
-	struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
-
-	return priv->polarity;
-}
-
-static int stm32_lptim_cnt_set_polarity(struct iio_dev *indio_dev,
-					const struct iio_chan_spec *chan,
-					unsigned int type)
-{
-	struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
-
-	if (stm32_lptim_is_enabled(priv))
-		return -EBUSY;
-
-	priv->polarity = type;
-
-	return 0;
-}
-
-static const struct iio_enum stm32_lptim_cnt_polarity_en = {
-	.items = stm32_lptim_cnt_polarity,
-	.num_items = ARRAY_SIZE(stm32_lptim_cnt_polarity),
-	.get = stm32_lptim_cnt_get_polarity,
-	.set = stm32_lptim_cnt_set_polarity,
-};
-
-static ssize_t stm32_lptim_cnt_get_ceiling(struct stm32_lptim_cnt *priv,
-					   char *buf)
-{
-	return snprintf(buf, PAGE_SIZE, "%u\n", priv->ceiling);
-}
-
-static ssize_t stm32_lptim_cnt_set_ceiling(struct stm32_lptim_cnt *priv,
-					   const char *buf, size_t len)
-{
-	int ret;
-
-	if (stm32_lptim_is_enabled(priv))
-		return -EBUSY;
-
-	ret = kstrtouint(buf, 0, &priv->ceiling);
-	if (ret)
-		return ret;
-
-	if (priv->ceiling > STM32_LPTIM_MAX_ARR)
-		return -EINVAL;
-
-	return len;
-}
-
-static ssize_t stm32_lptim_cnt_get_preset_iio(struct iio_dev *indio_dev,
-					      uintptr_t private,
-					      const struct iio_chan_spec *chan,
-					      char *buf)
-{
-	struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
-
-	return stm32_lptim_cnt_get_ceiling(priv, buf);
-}
-
-static ssize_t stm32_lptim_cnt_set_preset_iio(struct iio_dev *indio_dev,
-					      uintptr_t private,
-					      const struct iio_chan_spec *chan,
-					      const char *buf, size_t len)
-{
-	struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
-
-	return stm32_lptim_cnt_set_ceiling(priv, buf, len);
-}
-
-/* LP timer with encoder */
-static const struct iio_chan_spec_ext_info stm32_lptim_enc_ext_info[] = {
-	{
-		.name = "preset",
-		.shared = IIO_SEPARATE,
-		.read = stm32_lptim_cnt_get_preset_iio,
-		.write = stm32_lptim_cnt_set_preset_iio,
-	},
-	IIO_ENUM("polarity", IIO_SEPARATE, &stm32_lptim_cnt_polarity_en),
-	IIO_ENUM_AVAILABLE("polarity", &stm32_lptim_cnt_polarity_en),
-	IIO_ENUM("quadrature_mode", IIO_SEPARATE,
-		 &stm32_lptim_quadrature_mode_en),
-	IIO_ENUM_AVAILABLE("quadrature_mode", &stm32_lptim_quadrature_mode_en),
-	{}
-};
-
-static const struct iio_chan_spec stm32_lptim_enc_channels = {
-	.type = IIO_COUNT,
-	.channel = 0,
-	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
-			      BIT(IIO_CHAN_INFO_ENABLE) |
-			      BIT(IIO_CHAN_INFO_SCALE),
-	.ext_info = stm32_lptim_enc_ext_info,
-	.indexed = 1,
-};
-
-/* LP timer without encoder (counter only) */
-static const struct iio_chan_spec_ext_info stm32_lptim_cnt_ext_info[] = {
-	{
-		.name = "preset",
-		.shared = IIO_SEPARATE,
-		.read = stm32_lptim_cnt_get_preset_iio,
-		.write = stm32_lptim_cnt_set_preset_iio,
-	},
-	IIO_ENUM("polarity", IIO_SEPARATE, &stm32_lptim_cnt_polarity_en),
-	IIO_ENUM_AVAILABLE("polarity", &stm32_lptim_cnt_polarity_en),
-	{}
-};
-
-static const struct iio_chan_spec stm32_lptim_cnt_channels = {
-	.type = IIO_COUNT,
-	.channel = 0,
-	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
-			      BIT(IIO_CHAN_INFO_ENABLE) |
-			      BIT(IIO_CHAN_INFO_SCALE),
-	.ext_info = stm32_lptim_cnt_ext_info,
-	.indexed = 1,
-};
-
 /**
  * enum stm32_lptim_cnt_function - enumerates LPTimer counter & encoder modes
  * @STM32_LPTIM_COUNTER_INCREASE: up count on IN1 rising, falling or both edges
  * @STM32_LPTIM_ENCODER_BOTH_EDGE: count on both edges (IN1 & IN2 quadrature)
+ *
+ * In non-quadrature mode, device counts up on active edge.
+ * In quadrature mode, encoder counting scenarios are as follows:
+ * +---------+----------+--------------------+--------------------+
+ * | Active  | Level on |      IN1 signal    |     IN2 signal     |
+ * | edge    | opposite +----------+---------+----------+---------+
+ * |         | signal   |  Rising  | Falling |  Rising  | Falling |
+ * +---------+----------+----------+---------+----------+---------+
+ * | Rising  | High ->  |   Down   |    -    |   Up     |    -    |
+ * | edge    | Low  ->  |   Up     |    -    |   Down   |    -    |
+ * +---------+----------+----------+---------+----------+---------+
+ * | Falling | High ->  |    -     |   Up    |    -     |   Down  |
+ * | edge    | Low  ->  |    -     |   Down  |    -     |   Up    |
+ * +---------+----------+----------+---------+----------+---------+
+ * | Both    | High ->  |   Down   |   Up    |   Up     |   Down  |
+ * | edges   | Low  ->  |   Up     |   Down  |   Down   |   Up    |
+ * +---------+----------+----------+---------+----------+---------+
  */
 enum stm32_lptim_cnt_function {
 	STM32_LPTIM_COUNTER_INCREASE,
@@ -484,7 +262,7 @@ static ssize_t stm32_lptim_cnt_ceiling_read(struct counter_device *counter,
 {
 	struct stm32_lptim_cnt *const priv = counter->priv;
 
-	return stm32_lptim_cnt_get_ceiling(priv, buf);
+	return snprintf(buf, PAGE_SIZE, "%u\n", priv->ceiling);
 }
 
 static ssize_t stm32_lptim_cnt_ceiling_write(struct counter_device *counter,
@@ -493,8 +271,22 @@ static ssize_t stm32_lptim_cnt_ceiling_write(struct counter_device *counter,
 					     const char *buf, size_t len)
 {
 	struct stm32_lptim_cnt *const priv = counter->priv;
+	unsigned int ceiling;
+	int ret;
+
+	if (stm32_lptim_is_enabled(priv))
+		return -EBUSY;
+
+	ret = kstrtouint(buf, 0, &ceiling);
+	if (ret)
+		return ret;
+
+	if (ceiling > STM32_LPTIM_MAX_ARR)
+		return -EINVAL;
+
+	priv->ceiling = ceiling;
 
-	return stm32_lptim_cnt_set_ceiling(priv, buf, len);
+	return len;
 }
 
 static const struct counter_count_ext stm32_lptim_cnt_ext[] = {
@@ -630,32 +422,19 @@ static int stm32_lptim_cnt_probe(struct platform_device *pdev)
 {
 	struct stm32_lptimer *ddata = dev_get_drvdata(pdev->dev.parent);
 	struct stm32_lptim_cnt *priv;
-	struct iio_dev *indio_dev;
-	int ret;
 
 	if (IS_ERR_OR_NULL(ddata))
 		return -EINVAL;
 
-	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
-	if (!indio_dev)
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
 		return -ENOMEM;
 
-	priv = iio_priv(indio_dev);
 	priv->dev = &pdev->dev;
 	priv->regmap = ddata->regmap;
 	priv->clk = ddata->clk;
 	priv->ceiling = STM32_LPTIM_MAX_ARR;
 
-	/* Initialize IIO device */
-	indio_dev->name = dev_name(&pdev->dev);
-	indio_dev->dev.of_node = pdev->dev.of_node;
-	indio_dev->info = &stm32_lptim_cnt_iio_info;
-	if (ddata->has_encoder)
-		indio_dev->channels = &stm32_lptim_enc_channels;
-	else
-		indio_dev->channels = &stm32_lptim_cnt_channels;
-	indio_dev->num_channels = 1;
-
 	/* Initialize Counter device */
 	priv->counter.name = dev_name(&pdev->dev);
 	priv->counter.parent = &pdev->dev;
@@ -673,10 +452,6 @@ static int stm32_lptim_cnt_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, priv);
 
-	ret = devm_iio_device_register(&pdev->dev, indio_dev);
-	if (ret)
-		return ret;
-
 	return devm_counter_register(&pdev->dev, &priv->counter);
 }