summaryrefslogtreecommitdiff
path: root/drivers/counter
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/counter')
-rw-r--r--drivers/counter/104-quad-8.c13
-rw-r--r--drivers/counter/Kconfig10
-rw-r--r--drivers/counter/Makefile1
-rw-r--r--drivers/counter/ftm-quaddec.c2
-rw-r--r--drivers/counter/intel-qep.c544
-rw-r--r--drivers/counter/interrupt-cnt.c8
-rw-r--r--drivers/counter/microchip-tcb-capture.c4
-rw-r--r--drivers/counter/stm32-lptimer-cnt.c4
-rw-r--r--drivers/counter/stm32-timer-cnt.c4
9 files changed, 572 insertions, 18 deletions
diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
index 9691f8612be8..09a9a77cce06 100644
--- a/drivers/counter/104-quad-8.c
+++ b/drivers/counter/104-quad-8.c
@@ -21,7 +21,7 @@
static unsigned int base[max_num_isa_dev(QUAD8_EXTENT)];
static unsigned int num_quad8;
-module_param_array(base, uint, &num_quad8, 0);
+module_param_hw_array(base, uint, ioport, &num_quad8, 0);
MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
#define QUAD8_NUM_COUNTERS 8
@@ -193,7 +193,7 @@ enum quad8_count_function {
QUAD8_COUNT_FUNCTION_QUADRATURE_X4
};
-static enum counter_count_function quad8_count_functions_list[] = {
+static const enum counter_count_function quad8_count_functions_list[] = {
[QUAD8_COUNT_FUNCTION_PULSE_DIRECTION] = COUNTER_COUNT_FUNCTION_PULSE_DIRECTION,
[QUAD8_COUNT_FUNCTION_QUADRATURE_X1] = COUNTER_COUNT_FUNCTION_QUADRATURE_X1_A,
[QUAD8_COUNT_FUNCTION_QUADRATURE_X2] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A,
@@ -305,12 +305,12 @@ enum quad8_synapse_action {
QUAD8_SYNAPSE_ACTION_BOTH_EDGES
};
-static enum counter_synapse_action quad8_index_actions_list[] = {
+static const enum counter_synapse_action quad8_index_actions_list[] = {
[QUAD8_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE,
[QUAD8_SYNAPSE_ACTION_RISING_EDGE] = COUNTER_SYNAPSE_ACTION_RISING_EDGE
};
-static enum counter_synapse_action quad8_synapse_actions_list[] = {
+static const enum counter_synapse_action quad8_synapse_actions_list[] = {
[QUAD8_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE,
[QUAD8_SYNAPSE_ACTION_RISING_EDGE] = COUNTER_SYNAPSE_ACTION_RISING_EDGE,
[QUAD8_SYNAPSE_ACTION_FALLING_EDGE] = COUNTER_SYNAPSE_ACTION_FALLING_EDGE,
@@ -632,8 +632,8 @@ static ssize_t quad8_count_preset_read(struct counter_device *counter,
return sprintf(buf, "%u\n", priv->preset[count->id]);
}
-static void quad8_preset_register_set(struct quad8 *priv, int id,
- unsigned int preset)
+static void quad8_preset_register_set(struct quad8 *const priv, const int id,
+ const unsigned int preset)
{
const unsigned int base_offset = priv->base + 2 * id;
int i;
@@ -1082,7 +1082,6 @@ 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 Counter device */
return devm_counter_register(dev, &priv->counter);
}
diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig
index 5328705aa09c..d5d2540b30c2 100644
--- a/drivers/counter/Kconfig
+++ b/drivers/counter/Kconfig
@@ -91,4 +91,14 @@ config MICROCHIP_TCB_CAPTURE
To compile this driver as a module, choose M here: the
module will be called microchip-tcb-capture.
+config INTEL_QEP
+ tristate "Intel Quadrature Encoder Peripheral driver"
+ depends on PCI
+ help
+ Select this option to enable the Intel Quadrature Encoder Peripheral
+ driver.
+
+ To compile this driver as a module, choose M here: the module
+ will be called intel-qep.
+
endif # COUNTER
diff --git a/drivers/counter/Makefile b/drivers/counter/Makefile
index cb646ed2f039..19742e6f5e3e 100644
--- a/drivers/counter/Makefile
+++ b/drivers/counter/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_STM32_LPTIMER_CNT) += stm32-lptimer-cnt.o
obj-$(CONFIG_TI_EQEP) += ti-eqep.o
obj-$(CONFIG_FTM_QUADDEC) += ftm-quaddec.o
obj-$(CONFIG_MICROCHIP_TCB_CAPTURE) += microchip-tcb-capture.o
+obj-$(CONFIG_INTEL_QEP) += intel-qep.o
diff --git a/drivers/counter/ftm-quaddec.c b/drivers/counter/ftm-quaddec.c
index c2b3fdfd8b77..9371532406ca 100644
--- a/drivers/counter/ftm-quaddec.c
+++ b/drivers/counter/ftm-quaddec.c
@@ -162,7 +162,7 @@ enum ftm_quaddec_synapse_action {
FTM_QUADDEC_SYNAPSE_ACTION_BOTH_EDGES,
};
-static enum counter_synapse_action ftm_quaddec_synapse_actions[] = {
+static const enum counter_synapse_action ftm_quaddec_synapse_actions[] = {
[FTM_QUADDEC_SYNAPSE_ACTION_BOTH_EDGES] =
COUNTER_SYNAPSE_ACTION_BOTH_EDGES
};
diff --git a/drivers/counter/intel-qep.c b/drivers/counter/intel-qep.c
new file mode 100644
index 000000000000..8d7ae28fbd67
--- /dev/null
+++ b/drivers/counter/intel-qep.c
@@ -0,0 +1,544 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Intel Quadrature Encoder Peripheral driver
+ *
+ * Copyright (C) 2019-2021 Intel Corporation
+ *
+ * Author: Felipe Balbi (Intel)
+ * Author: Jarkko Nikula <jarkko.nikula@linux.intel.com>
+ * Author: Raymond Tan <raymond.tan@intel.com>
+ */
+#include <linux/bitops.h>
+#include <linux/counter.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/pci.h>
+#include <linux/pm_runtime.h>
+
+#define INTEL_QEPCON 0x00
+#define INTEL_QEPFLT 0x04
+#define INTEL_QEPCOUNT 0x08
+#define INTEL_QEPMAX 0x0c
+#define INTEL_QEPWDT 0x10
+#define INTEL_QEPCAPDIV 0x14
+#define INTEL_QEPCNTR 0x18
+#define INTEL_QEPCAPBUF 0x1c
+#define INTEL_QEPINT_STAT 0x20
+#define INTEL_QEPINT_MASK 0x24
+
+/* QEPCON */
+#define INTEL_QEPCON_EN BIT(0)
+#define INTEL_QEPCON_FLT_EN BIT(1)
+#define INTEL_QEPCON_EDGE_A BIT(2)
+#define INTEL_QEPCON_EDGE_B BIT(3)
+#define INTEL_QEPCON_EDGE_INDX BIT(4)
+#define INTEL_QEPCON_SWPAB BIT(5)
+#define INTEL_QEPCON_OP_MODE BIT(6)
+#define INTEL_QEPCON_PH_ERR BIT(7)
+#define INTEL_QEPCON_COUNT_RST_MODE BIT(8)
+#define INTEL_QEPCON_INDX_GATING_MASK GENMASK(10, 9)
+#define INTEL_QEPCON_INDX_GATING(n) (((n) & 3) << 9)
+#define INTEL_QEPCON_INDX_PAL_PBL INTEL_QEPCON_INDX_GATING(0)
+#define INTEL_QEPCON_INDX_PAL_PBH INTEL_QEPCON_INDX_GATING(1)
+#define INTEL_QEPCON_INDX_PAH_PBL INTEL_QEPCON_INDX_GATING(2)
+#define INTEL_QEPCON_INDX_PAH_PBH INTEL_QEPCON_INDX_GATING(3)
+#define INTEL_QEPCON_CAP_MODE BIT(11)
+#define INTEL_QEPCON_FIFO_THRE_MASK GENMASK(14, 12)
+#define INTEL_QEPCON_FIFO_THRE(n) ((((n) - 1) & 7) << 12)
+#define INTEL_QEPCON_FIFO_EMPTY BIT(15)
+
+/* QEPFLT */
+#define INTEL_QEPFLT_MAX_COUNT(n) ((n) & 0x1fffff)
+
+/* QEPINT */
+#define INTEL_QEPINT_FIFOCRIT BIT(5)
+#define INTEL_QEPINT_FIFOENTRY BIT(4)
+#define INTEL_QEPINT_QEPDIR BIT(3)
+#define INTEL_QEPINT_QEPRST_UP BIT(2)
+#define INTEL_QEPINT_QEPRST_DOWN BIT(1)
+#define INTEL_QEPINT_WDT BIT(0)
+
+#define INTEL_QEPINT_MASK_ALL GENMASK(5, 0)
+
+#define INTEL_QEP_CLK_PERIOD_NS 10
+
+#define INTEL_QEP_COUNTER_EXT_RW(_name) \
+{ \
+ .name = #_name, \
+ .read = _name##_read, \
+ .write = _name##_write, \
+}
+
+struct intel_qep {
+ struct counter_device counter;
+ struct mutex lock;
+ struct device *dev;
+ void __iomem *regs;
+ bool enabled;
+ /* Context save registers */
+ u32 qepcon;
+ u32 qepflt;
+ u32 qepmax;
+};
+
+static inline u32 intel_qep_readl(struct intel_qep *qep, u32 offset)
+{
+ return readl(qep->regs + offset);
+}
+
+static inline void intel_qep_writel(struct intel_qep *qep,
+ u32 offset, u32 value)
+{
+ writel(value, qep->regs + offset);
+}
+
+static void intel_qep_init(struct intel_qep *qep)
+{
+ u32 reg;
+
+ reg = intel_qep_readl(qep, INTEL_QEPCON);
+ reg &= ~INTEL_QEPCON_EN;
+ intel_qep_writel(qep, INTEL_QEPCON, reg);
+ qep->enabled = false;
+ /*
+ * Make sure peripheral is disabled by flushing the write with
+ * a dummy read
+ */
+ reg = intel_qep_readl(qep, INTEL_QEPCON);
+
+ reg &= ~(INTEL_QEPCON_OP_MODE | INTEL_QEPCON_FLT_EN);
+ reg |= INTEL_QEPCON_EDGE_A | INTEL_QEPCON_EDGE_B |
+ INTEL_QEPCON_EDGE_INDX | INTEL_QEPCON_COUNT_RST_MODE;
+ intel_qep_writel(qep, INTEL_QEPCON, reg);
+ intel_qep_writel(qep, INTEL_QEPINT_MASK, INTEL_QEPINT_MASK_ALL);
+}
+
+static int intel_qep_count_read(struct counter_device *counter,
+ struct counter_count *count,
+ unsigned long *val)
+{
+ struct intel_qep *const qep = counter->priv;
+
+ pm_runtime_get_sync(qep->dev);
+ *val = intel_qep_readl(qep, INTEL_QEPCOUNT);
+ pm_runtime_put(qep->dev);
+
+ return 0;
+}
+
+static const enum counter_count_function intel_qep_count_functions[] = {
+ COUNTER_COUNT_FUNCTION_QUADRATURE_X4,
+};
+
+static int intel_qep_function_get(struct counter_device *counter,
+ struct counter_count *count,
+ size_t *function)
+{
+ *function = 0;
+
+ return 0;
+}
+
+static const enum counter_synapse_action intel_qep_synapse_actions[] = {
+ COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
+};
+
+static int intel_qep_action_get(struct counter_device *counter,
+ struct counter_count *count,
+ struct counter_synapse *synapse,
+ size_t *action)
+{
+ *action = 0;
+ return 0;
+}
+
+static const struct counter_ops intel_qep_counter_ops = {
+ .count_read = intel_qep_count_read,
+ .function_get = intel_qep_function_get,
+ .action_get = intel_qep_action_get,
+};
+
+#define INTEL_QEP_SIGNAL(_id, _name) { \
+ .id = (_id), \
+ .name = (_name), \
+}
+
+static struct counter_signal intel_qep_signals[] = {
+ INTEL_QEP_SIGNAL(0, "Phase A"),
+ INTEL_QEP_SIGNAL(1, "Phase B"),
+ INTEL_QEP_SIGNAL(2, "Index"),
+};
+
+#define INTEL_QEP_SYNAPSE(_signal_id) { \
+ .actions_list = intel_qep_synapse_actions, \
+ .num_actions = ARRAY_SIZE(intel_qep_synapse_actions), \
+ .signal = &intel_qep_signals[(_signal_id)], \
+}
+
+static struct counter_synapse intel_qep_count_synapses[] = {
+ INTEL_QEP_SYNAPSE(0),
+ INTEL_QEP_SYNAPSE(1),
+ INTEL_QEP_SYNAPSE(2),
+};
+
+static ssize_t ceiling_read(struct counter_device *counter,
+ struct counter_count *count,
+ void *priv, char *buf)
+{
+ struct intel_qep *qep = counter->priv;
+ u32 reg;
+
+ pm_runtime_get_sync(qep->dev);
+ reg = intel_qep_readl(qep, INTEL_QEPMAX);
+ pm_runtime_put(qep->dev);
+
+ return sysfs_emit(buf, "%u\n", reg);
+}
+
+static ssize_t ceiling_write(struct counter_device *counter,
+ struct counter_count *count,
+ void *priv, const char *buf, size_t len)
+{
+ struct intel_qep *qep = counter->priv;
+ u32 max;
+ int ret;
+
+ ret = kstrtou32(buf, 0, &max);
+ if (ret < 0)
+ return ret;
+
+ mutex_lock(&qep->lock);
+ if (qep->enabled) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ pm_runtime_get_sync(qep->dev);
+ intel_qep_writel(qep, INTEL_QEPMAX, max);
+ pm_runtime_put(qep->dev);
+ ret = len;
+
+out:
+ mutex_unlock(&qep->lock);
+ return ret;
+}
+
+static ssize_t enable_read(struct counter_device *counter,
+ struct counter_count *count,
+ void *priv, char *buf)
+{
+ struct intel_qep *qep = counter->priv;
+
+ return sysfs_emit(buf, "%u\n", qep->enabled);
+}
+
+static ssize_t enable_write(struct counter_device *counter,
+ struct counter_count *count,
+ void *priv, const char *buf, size_t len)
+{
+ struct intel_qep *qep = counter->priv;
+ u32 reg;
+ bool val, changed;
+ int ret;
+
+ ret = kstrtobool(buf, &val);
+ if (ret)
+ return ret;
+
+ mutex_lock(&qep->lock);
+ changed = val ^ qep->enabled;
+ if (!changed)
+ goto out;
+
+ pm_runtime_get_sync(qep->dev);
+ reg = intel_qep_readl(qep, INTEL_QEPCON);
+ if (val) {
+ /* Enable peripheral and keep runtime PM always on */
+ reg |= INTEL_QEPCON_EN;
+ pm_runtime_get_noresume(qep->dev);
+ } else {
+ /* Let runtime PM be idle and disable peripheral */
+ pm_runtime_put_noidle(qep->dev);
+ reg &= ~INTEL_QEPCON_EN;
+ }
+ intel_qep_writel(qep, INTEL_QEPCON, reg);
+ pm_runtime_put(qep->dev);
+ qep->enabled = val;
+
+out:
+ mutex_unlock(&qep->lock);
+ return len;
+}
+
+static ssize_t spike_filter_ns_read(struct counter_device *counter,
+ struct counter_count *count,
+ void *priv, char *buf)
+{
+ struct intel_qep *qep = counter->priv;
+ u32 reg;
+
+ pm_runtime_get_sync(qep->dev);
+ reg = intel_qep_readl(qep, INTEL_QEPCON);
+ if (!(reg & INTEL_QEPCON_FLT_EN)) {
+ pm_runtime_put(qep->dev);
+ return sysfs_emit(buf, "0\n");
+ }
+ reg = INTEL_QEPFLT_MAX_COUNT(intel_qep_readl(qep, INTEL_QEPFLT));
+ pm_runtime_put(qep->dev);
+
+ return sysfs_emit(buf, "%u\n", (reg + 2) * INTEL_QEP_CLK_PERIOD_NS);
+}
+
+static ssize_t spike_filter_ns_write(struct counter_device *counter,
+ struct counter_count *count,
+ void *priv, const char *buf, size_t len)
+{
+ struct intel_qep *qep = counter->priv;
+ u32 reg, length;
+ bool enable;
+ int ret;
+
+ ret = kstrtou32(buf, 0, &length);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * Spike filter length is (MAX_COUNT + 2) clock periods.
+ * Disable filter when userspace writes 0, enable for valid
+ * nanoseconds values and error out otherwise.
+ */
+ length /= INTEL_QEP_CLK_PERIOD_NS;
+ if (length == 0) {
+ enable = false;
+ length = 0;
+ } else if (length >= 2) {
+ enable = true;
+ length -= 2;
+ } else {
+ return -EINVAL;
+ }
+
+ if (length > INTEL_QEPFLT_MAX_COUNT(length))
+ return -EINVAL;
+
+ mutex_lock(&qep->lock);
+ if (qep->enabled) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ pm_runtime_get_sync(qep->dev);
+ reg = intel_qep_readl(qep, INTEL_QEPCON);
+ if (enable)
+ reg |= INTEL_QEPCON_FLT_EN;
+ else
+ reg &= ~INTEL_QEPCON_FLT_EN;
+ intel_qep_writel(qep, INTEL_QEPFLT, length);
+ intel_qep_writel(qep, INTEL_QEPCON, reg);
+ pm_runtime_put(qep->dev);
+ ret = len;
+
+out:
+ mutex_unlock(&qep->lock);
+ return ret;
+}
+
+static ssize_t preset_enable_read(struct counter_device *counter,
+ struct counter_count *count,
+ void *priv, char *buf)
+{
+ struct intel_qep *qep = counter->priv;
+ u32 reg;
+
+ pm_runtime_get_sync(qep->dev);
+ reg = intel_qep_readl(qep, INTEL_QEPCON);
+ pm_runtime_put(qep->dev);
+ return sysfs_emit(buf, "%u\n", !(reg & INTEL_QEPCON_COUNT_RST_MODE));
+}
+
+static ssize_t preset_enable_write(struct counter_device *counter,
+ struct counter_count *count,
+ void *priv, const char *buf, size_t len)
+{
+ struct intel_qep *qep = counter->priv;
+ u32 reg;
+ bool val;
+ int ret;
+
+ ret = kstrtobool(buf, &val);
+ if (ret)
+ return ret;
+
+ mutex_lock(&qep->lock);
+ if (qep->enabled) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ pm_runtime_get_sync(qep->dev);
+ reg = intel_qep_readl(qep, INTEL_QEPCON);
+ if (val)
+ reg &= ~INTEL_QEPCON_COUNT_RST_MODE;
+ else
+ reg |= INTEL_QEPCON_COUNT_RST_MODE;
+
+ intel_qep_writel(qep, INTEL_QEPCON, reg);
+ pm_runtime_put(qep->dev);
+ ret = len;
+
+out:
+ mutex_unlock(&qep->lock);
+
+ return ret;
+}
+
+static const struct counter_count_ext intel_qep_count_ext[] = {
+ INTEL_QEP_COUNTER_EXT_RW(ceiling),
+ INTEL_QEP_COUNTER_EXT_RW(enable),
+ INTEL_QEP_COUNTER_EXT_RW(spike_filter_ns),
+ INTEL_QEP_COUNTER_EXT_RW(preset_enable)
+};
+
+static struct counter_count intel_qep_counter_count[] = {
+ {
+ .id = 0,
+ .name = "Channel 1 Count",
+ .functions_list = intel_qep_count_functions,
+ .num_functions = ARRAY_SIZE(intel_qep_count_functions),
+ .synapses = intel_qep_count_synapses,
+ .num_synapses = ARRAY_SIZE(intel_qep_count_synapses),
+ .ext = intel_qep_count_ext,
+ .num_ext = ARRAY_SIZE(intel_qep_count_ext),
+ },
+};
+
+static int intel_qep_probe(struct pci_dev *pci, const struct pci_device_id *id)
+{
+ struct intel_qep *qep;
+ struct device *dev = &pci->dev;
+ void __iomem *regs;
+ int ret;
+
+ qep = devm_kzalloc(dev, sizeof(*qep), GFP_KERNEL);
+ if (!qep)
+ return -ENOMEM;
+
+ ret = pcim_enable_device(pci);
+ if (ret)
+ return ret;
+
+ pci_set_master(pci);
+
+ ret = pcim_iomap_regions(pci, BIT(0), pci_name(pci));
+ if (ret)
+ return ret;
+
+ regs = pcim_iomap_table(pci)[0];
+ if (!regs)
+ return -ENOMEM;
+
+ qep->dev = dev;
+ qep->regs = regs;
+ mutex_init(&qep->lock);
+
+ intel_qep_init(qep);
+ pci_set_drvdata(pci, qep);
+
+ qep->counter.name = pci_name(pci);
+ qep->counter.parent = dev;
+ qep->counter.ops = &intel_qep_counter_ops;
+ qep->counter.counts = intel_qep_counter_count;
+ qep->counter.num_counts = ARRAY_SIZE(intel_qep_counter_count);
+ qep->counter.signals = intel_qep_signals;
+ qep->counter.num_signals = ARRAY_SIZE(intel_qep_signals);
+ qep->counter.priv = qep;
+ qep->enabled = false;
+
+ pm_runtime_put(dev);
+ pm_runtime_allow(dev);
+
+ return devm_counter_register(&pci->dev, &qep->counter);
+}
+
+static void intel_qep_remove(struct pci_dev *pci)
+{
+ struct intel_qep *qep = pci_get_drvdata(pci);
+ struct device *dev = &pci->dev;
+
+ pm_runtime_forbid(dev);
+ if (!qep->enabled)
+ pm_runtime_get(dev);
+
+ intel_qep_writel(qep, INTEL_QEPCON, 0);
+}
+
+static int __maybe_unused intel_qep_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct intel_qep *qep = pci_get_drvdata(pdev);
+
+ qep->qepcon = intel_qep_readl(qep, INTEL_QEPCON);
+ qep->qepflt = intel_qep_readl(qep, INTEL_QEPFLT);
+ qep->qepmax = intel_qep_readl(qep, INTEL_QEPMAX);
+
+ return 0;
+}
+
+static int __maybe_unused intel_qep_resume(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct intel_qep *qep = pci_get_drvdata(pdev);
+
+ /*
+ * Make sure peripheral is disabled when restoring registers and
+ * control register bits that are writable only when the peripheral
+ * is disabled
+ */
+ intel_qep_writel(qep, INTEL_QEPCON, 0);
+ intel_qep_readl(qep, INTEL_QEPCON);
+
+ intel_qep_writel(qep, INTEL_QEPFLT, qep->qepflt);
+ intel_qep_writel(qep, INTEL_QEPMAX, qep->qepmax);
+ intel_qep_writel(qep, INTEL_QEPINT_MASK, INTEL_QEPINT_MASK_ALL);
+
+ /* Restore all other control register bits except enable status */
+ intel_qep_writel(qep, INTEL_QEPCON, qep->qepcon & ~INTEL_QEPCON_EN);
+ intel_qep_readl(qep, INTEL_QEPCON);
+
+ /* Restore enable status */
+ intel_qep_writel(qep, INTEL_QEPCON, qep->qepcon);
+
+ return 0;
+}
+
+static UNIVERSAL_DEV_PM_OPS(intel_qep_pm_ops,
+ intel_qep_suspend, intel_qep_resume, NULL);
+
+static const struct pci_device_id intel_qep_id_table[] = {
+ /* EHL */
+ { PCI_VDEVICE(INTEL, 0x4bc3), },
+ { PCI_VDEVICE(INTEL, 0x4b81), },
+ { PCI_VDEVICE(INTEL, 0x4b82), },
+ { PCI_VDEVICE(INTEL, 0x4b83), },
+ { } /* Terminating Entry */
+};
+MODULE_DEVICE_TABLE(pci, intel_qep_id_table);
+
+static struct pci_driver intel_qep_driver = {
+ .name = "intel-qep",
+ .id_table = intel_qep_id_table,
+ .probe = intel_qep_probe,
+ .remove = intel_qep_remove,
+ .driver = {
+ .pm = &intel_qep_pm_ops,
+ }
+};
+
+module_pci_driver(intel_qep_driver);
+
+MODULE_AUTHOR("Felipe Balbi (Intel)");
+MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@linux.intel.com>");
+MODULE_AUTHOR("Raymond Tan <raymond.tan@intel.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Intel Quadrature Encoder Peripheral driver");
diff --git a/drivers/counter/interrupt-cnt.c b/drivers/counter/interrupt-cnt.c
index a99ee7996977..5df7cd13d4c7 100644
--- a/drivers/counter/interrupt-cnt.c
+++ b/drivers/counter/interrupt-cnt.c
@@ -77,7 +77,7 @@ static const struct counter_count_ext interrupt_cnt_ext[] = {
},
};
-static enum counter_synapse_action interrupt_cnt_synapse_actionss[] = {
+static const enum counter_synapse_action interrupt_cnt_synapse_actions[] = {
COUNTER_SYNAPSE_ACTION_RISING_EDGE,
};
@@ -112,7 +112,7 @@ static int interrupt_cnt_write(struct counter_device *counter,
return 0;
}
-static enum counter_count_function interrupt_cnt_functions[] = {
+static const enum counter_count_function interrupt_cnt_functions[] = {
COUNTER_COUNT_FUNCTION_INCREASE,
};
@@ -194,8 +194,8 @@ static int interrupt_cnt_probe(struct platform_device *pdev)
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.actions_list = interrupt_cnt_synapse_actions;
+ priv->synapses.num_actions = ARRAY_SIZE(interrupt_cnt_synapse_actions);
priv->synapses.signal = &priv->signals;
priv->cnts.name = "Channel 0 Count";
diff --git a/drivers/counter/microchip-tcb-capture.c b/drivers/counter/microchip-tcb-capture.c
index 710acc0a3704..51b8af80f98b 100644
--- a/drivers/counter/microchip-tcb-capture.c
+++ b/drivers/counter/microchip-tcb-capture.c
@@ -37,7 +37,7 @@ enum mchp_tc_count_function {
MCHP_TC_FUNCTION_QUADRATURE,
};
-static enum counter_count_function mchp_tc_count_functions[] = {
+static const enum counter_count_function mchp_tc_count_functions[] = {
[MCHP_TC_FUNCTION_INCREASE] = COUNTER_COUNT_FUNCTION_INCREASE,
[MCHP_TC_FUNCTION_QUADRATURE] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4,
};
@@ -49,7 +49,7 @@ enum mchp_tc_synapse_action {
MCHP_TC_SYNAPSE_ACTION_BOTH_EDGE
};
-static enum counter_synapse_action mchp_tc_synapse_actions[] = {
+static const enum counter_synapse_action mchp_tc_synapse_actions[] = {
[MCHP_TC_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE,
[MCHP_TC_SYNAPSE_ACTION_RISING_EDGE] = COUNTER_SYNAPSE_ACTION_RISING_EDGE,
[MCHP_TC_SYNAPSE_ACTION_FALLING_EDGE] = COUNTER_SYNAPSE_ACTION_FALLING_EDGE,
diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c
index 937439635d53..c19d998df5ba 100644
--- a/drivers/counter/stm32-lptimer-cnt.c
+++ b/drivers/counter/stm32-lptimer-cnt.c
@@ -134,7 +134,7 @@ enum stm32_lptim_cnt_function {
STM32_LPTIM_ENCODER_BOTH_EDGE,
};
-static enum counter_count_function stm32_lptim_cnt_functions[] = {
+static const enum counter_count_function stm32_lptim_cnt_functions[] = {
[STM32_LPTIM_COUNTER_INCREASE] = COUNTER_COUNT_FUNCTION_INCREASE,
[STM32_LPTIM_ENCODER_BOTH_EDGE] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4,
};
@@ -146,7 +146,7 @@ enum stm32_lptim_synapse_action {
STM32_LPTIM_SYNAPSE_ACTION_NONE,
};
-static enum counter_synapse_action stm32_lptim_cnt_synapse_actions[] = {
+static const enum counter_synapse_action stm32_lptim_cnt_synapse_actions[] = {
/* Index must match with stm32_lptim_cnt_polarity[] (priv->polarity) */
[STM32_LPTIM_SYNAPSE_ACTION_RISING_EDGE] = COUNTER_SYNAPSE_ACTION_RISING_EDGE,
[STM32_LPTIM_SYNAPSE_ACTION_FALLING_EDGE] = COUNTER_SYNAPSE_ACTION_FALLING_EDGE,
diff --git a/drivers/counter/stm32-timer-cnt.c b/drivers/counter/stm32-timer-cnt.c
index 75bc401fdd18..603b30ada839 100644
--- a/drivers/counter/stm32-timer-cnt.c
+++ b/drivers/counter/stm32-timer-cnt.c
@@ -50,7 +50,7 @@ enum stm32_count_function {
STM32_COUNT_ENCODER_MODE_3,
};
-static enum counter_count_function stm32_count_functions[] = {
+static const enum counter_count_function stm32_count_functions[] = {
[STM32_COUNT_SLAVE_MODE_DISABLED] = COUNTER_COUNT_FUNCTION_INCREASE,
[STM32_COUNT_ENCODER_MODE_1] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A,
[STM32_COUNT_ENCODER_MODE_2] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_B,
@@ -267,7 +267,7 @@ enum stm32_synapse_action {
STM32_SYNAPSE_ACTION_BOTH_EDGES
};
-static enum counter_synapse_action stm32_synapse_actions[] = {
+static const enum counter_synapse_action stm32_synapse_actions[] = {
[STM32_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE,
[STM32_SYNAPSE_ACTION_BOTH_EDGES] = COUNTER_SYNAPSE_ACTION_BOTH_EDGES
};