]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.19
authorSasha Levin <sashal@kernel.org>
Sat, 1 Oct 2022 22:03:37 +0000 (18:03 -0400)
committerSasha Levin <sashal@kernel.org>
Sat, 1 Oct 2022 22:03:37 +0000 (18:03 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.19/counter-104-quad-8-fix-skipped-irq-lines-during-even.patch [new file with mode: 0644]
queue-5.19/counter-104-quad-8-implement-and-utilize-register-st.patch [new file with mode: 0644]
queue-5.19/counter-104-quad-8-utilize-iomap-interface.patch [new file with mode: 0644]
queue-5.19/perf-record-fix-cpu-mask-bit-setting-for-mixed-mmaps.patch [new file with mode: 0644]
queue-5.19/riscv-make-t-head-erratas-depend-on-mmu.patch [new file with mode: 0644]
queue-5.19/series [new file with mode: 0644]
queue-5.19/tools-perf-fix-out-of-bound-access-to-cpu-mask-array.patch [new file with mode: 0644]

diff --git a/queue-5.19/counter-104-quad-8-fix-skipped-irq-lines-during-even.patch b/queue-5.19/counter-104-quad-8-fix-skipped-irq-lines-during-even.patch
new file mode 100644 (file)
index 0000000..1ab7094
--- /dev/null
@@ -0,0 +1,54 @@
+From 0065390921085a7d416a5333356bf6264a309d76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Sep 2022 07:20:56 -0400
+Subject: counter: 104-quad-8: Fix skipped IRQ lines during events
+ configuration
+
+From: William Breathitt Gray <william.gray@linaro.org>
+
+[ Upstream commit 2bc54aaa65d2126ae629919175708a28ce7ef06e ]
+
+IRQ trigger configuration is skipped if it has already been set before;
+however, the IRQ line still needs to be OR'd to irq_enabled because
+irq_enabled is reset for every events_configure call. This patch moves
+the irq_enabled OR operation update to before the irq_trigger check so
+that IRQ line enablement is not skipped.
+
+Fixes: c95cc0d95702 ("counter: 104-quad-8: Fix persistent enabled events bug")
+Cc: stable <stable@kernel.org>
+Link: https://lore.kernel.org/r/20220815122301.2750-1-william.gray@linaro.org/
+Signed-off-by: William Breathitt Gray <william.gray@linaro.org>
+Link: https://lore.kernel.org/r/179eed11eaf225dbd908993b510df0c8f67b1230.1663844776.git.william.gray@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/counter/104-quad-8.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
+index 62c2b7ac4339..4407203e0c9b 100644
+--- a/drivers/counter/104-quad-8.c
++++ b/drivers/counter/104-quad-8.c
+@@ -449,6 +449,9 @@ static int quad8_events_configure(struct counter_device *counter)
+                       return -EINVAL;
+               }
++              /* Enable IRQ line */
++              irq_enabled |= BIT(event_node->channel);
++
+               /* Skip configuration if it is the same as previously set */
+               if (priv->irq_trigger[event_node->channel] == next_irq_trigger)
+                       continue;
+@@ -462,9 +465,6 @@ static int quad8_events_configure(struct counter_device *counter)
+                         priv->irq_trigger[event_node->channel] << 3;
+               iowrite8(QUAD8_CTR_IOR | ior_cfg,
+                        &priv->reg->channel[event_node->channel].control);
+-
+-              /* Enable IRQ line */
+-              irq_enabled |= BIT(event_node->channel);
+       }
+       iowrite8(irq_enabled, &priv->reg->index_interrupt);
+-- 
+2.35.1
+
diff --git a/queue-5.19/counter-104-quad-8-implement-and-utilize-register-st.patch b/queue-5.19/counter-104-quad-8-implement-and-utilize-register-st.patch
new file mode 100644 (file)
index 0000000..7315878
--- /dev/null
@@ -0,0 +1,504 @@
+From 5ea881f1eafbc400c3fd912ad3f5e0e6e3713e03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 12:07:14 -0400
+Subject: counter: 104-quad-8: Implement and utilize register structures
+
+From: William Breathitt Gray <william.gray@linaro.org>
+
+[ Upstream commit daae1ee572d1f99daddef26afe6c6fc7aeea741d ]
+
+Reduce magic numbers and improve code readability by implementing and
+utilizing named register data structures.
+
+Link: https://lore.kernel.org/r/20220707171709.36010-1-william.gray@linaro.org/
+Cc: Syed Nayyar Waris <syednwaris@gmail.com>
+Tested-by: Fred Eckert <Frede@cmslaser.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: William Breathitt Gray <william.gray@linaro.org>
+Link: https://lore.kernel.org/r/285fdc7c03892251f50bdbf2c28c19998243a6a3.1657813472.git.william.gray@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 2bc54aaa65d2 ("counter: 104-quad-8: Fix skipped IRQ lines during events configuration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/counter/104-quad-8.c | 166 ++++++++++++++++++++---------------
+ 1 file changed, 93 insertions(+), 73 deletions(-)
+
+diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
+index 43dde9abfdcf..62c2b7ac4339 100644
+--- a/drivers/counter/104-quad-8.c
++++ b/drivers/counter/104-quad-8.c
+@@ -33,6 +33,36 @@ MODULE_PARM_DESC(irq, "ACCES 104-QUAD-8 interrupt line numbers");
+ #define QUAD8_NUM_COUNTERS 8
++/**
++ * struct channel_reg - channel register structure
++ * @data:     Count data
++ * @control:  Channel flags and control
++ */
++struct channel_reg {
++      u8 data;
++      u8 control;
++};
++
++/**
++ * struct quad8_reg - device register structure
++ * @channel:          quadrature counter data and control
++ * @interrupt_status: channel interrupt status
++ * @channel_oper:     enable/reset counters and interrupt functions
++ * @index_interrupt:  enable channel interrupts
++ * @reserved:         reserved for Factory Use
++ * @index_input_levels:       index signal logical input level
++ * @cable_status:     differential encoder cable status
++ */
++struct quad8_reg {
++      struct channel_reg channel[QUAD8_NUM_COUNTERS];
++      u8 interrupt_status;
++      u8 channel_oper;
++      u8 index_interrupt;
++      u8 reserved[3];
++      u8 index_input_levels;
++      u8 cable_status;
++};
++
+ /**
+  * struct quad8 - device private data structure
+  * @lock:             lock to prevent clobbering device states during R/W ops
+@@ -48,7 +78,7 @@ MODULE_PARM_DESC(irq, "ACCES 104-QUAD-8 interrupt line numbers");
+  * @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 device
++ * @reg:              I/O address offset for the device registers
+  */
+ struct quad8 {
+       spinlock_t lock;
+@@ -63,14 +93,9 @@ struct quad8 {
+       unsigned int synchronous_mode[QUAD8_NUM_COUNTERS];
+       unsigned int index_polarity[QUAD8_NUM_COUNTERS];
+       unsigned int cable_fault_enable;
+-      void __iomem *base;
++      struct quad8_reg __iomem *reg;
+ };
+-#define QUAD8_REG_INTERRUPT_STATUS 0x10
+-#define QUAD8_REG_CHAN_OP 0x11
+-#define QUAD8_REG_INDEX_INTERRUPT 0x12
+-#define QUAD8_REG_INDEX_INPUT_LEVELS 0x16
+-#define QUAD8_DIFF_ENCODER_CABLE_STATUS 0x17
+ /* Borrow Toggle flip-flop */
+ #define QUAD8_FLAG_BT BIT(0)
+ /* Carry Toggle flip-flop */
+@@ -118,8 +143,7 @@ static int quad8_signal_read(struct counter_device *counter,
+       if (signal->id < 16)
+               return -EINVAL;
+-      state = ioread8(priv->base + QUAD8_REG_INDEX_INPUT_LEVELS) &
+-              BIT(signal->id - 16);
++      state = ioread8(&priv->reg->index_input_levels) & BIT(signal->id - 16);
+       *level = (state) ? COUNTER_SIGNAL_LEVEL_HIGH : COUNTER_SIGNAL_LEVEL_LOW;
+@@ -130,14 +154,14 @@ static int quad8_count_read(struct counter_device *counter,
+                           struct counter_count *count, u64 *val)
+ {
+       struct quad8 *const priv = counter_priv(counter);
+-      void __iomem *const base_offset = priv->base + 2 * count->id;
++      struct channel_reg __iomem *const chan = priv->reg->channel + count->id;
+       unsigned int flags;
+       unsigned int borrow;
+       unsigned int carry;
+       unsigned long irqflags;
+       int i;
+-      flags = ioread8(base_offset + 1);
++      flags = ioread8(&chan->control);
+       borrow = flags & QUAD8_FLAG_BT;
+       carry = !!(flags & QUAD8_FLAG_CT);
+@@ -148,10 +172,10 @@ static int quad8_count_read(struct counter_device *counter,
+       /* Reset Byte Pointer; transfer Counter to Output Latch */
+       iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_CNTR_OUT,
+-               base_offset + 1);
++               &chan->control);
+       for (i = 0; i < 3; i++)
+-              *val |= (unsigned long)ioread8(base_offset) << (8 * i);
++              *val |= (unsigned long)ioread8(&chan->data) << (8 * i);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -162,7 +186,7 @@ static int quad8_count_write(struct counter_device *counter,
+                            struct counter_count *count, u64 val)
+ {
+       struct quad8 *const priv = counter_priv(counter);
+-      void __iomem *const base_offset = priv->base + 2 * count->id;
++      struct channel_reg __iomem *const chan = priv->reg->channel + count->id;
+       unsigned long irqflags;
+       int i;
+@@ -173,27 +197,27 @@ static int quad8_count_write(struct counter_device *counter,
+       spin_lock_irqsave(&priv->lock, irqflags);
+       /* Reset Byte Pointer */
+-      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, &chan->control);
+       /* Counter can only be set via Preset Register */
+       for (i = 0; i < 3; i++)
+-              iowrite8(val >> (8 * i), base_offset);
++              iowrite8(val >> (8 * i), &chan->data);
+       /* Transfer Preset Register to Counter */
+-      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_PRESET_CNTR, base_offset + 1);
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_PRESET_CNTR, &chan->control);
+       /* Reset Byte Pointer */
+-      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, &chan->control);
+       /* Set Preset Register back to original value */
+       val = priv->preset[count->id];
+       for (i = 0; i < 3; i++)
+-              iowrite8(val >> (8 * i), base_offset);
++              iowrite8(val >> (8 * i), &chan->data);
+       /* Reset Borrow, Carry, Compare, and Sign flags */
+-      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_FLAGS, base_offset + 1);
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_FLAGS, &chan->control);
+       /* Reset Error flag */
+-      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, base_offset + 1);
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, &chan->control);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -246,7 +270,7 @@ static int quad8_function_write(struct counter_device *counter,
+       unsigned int *const quadrature_mode = priv->quadrature_mode + id;
+       unsigned int *const scale = priv->quadrature_scale + id;
+       unsigned int *const synchronous_mode = priv->synchronous_mode + id;
+-      void __iomem *const base_offset = priv->base + 2 * id + 1;
++      u8 __iomem *const control = &priv->reg->channel[id].control;
+       unsigned long irqflags;
+       unsigned int mode_cfg;
+       unsigned int idr_cfg;
+@@ -266,7 +290,7 @@ static int quad8_function_write(struct counter_device *counter,
+               if (*synchronous_mode) {
+                       *synchronous_mode = 0;
+                       /* Disable synchronous function mode */
+-                      iowrite8(QUAD8_CTR_IDR | idr_cfg, base_offset);
++                      iowrite8(QUAD8_CTR_IDR | idr_cfg, control);
+               }
+       } else {
+               *quadrature_mode = 1;
+@@ -292,7 +316,7 @@ static int quad8_function_write(struct counter_device *counter,
+       }
+       /* Load mode configuration to Counter Mode Register */
+-      iowrite8(QUAD8_CTR_CMR | mode_cfg, base_offset);
++      iowrite8(QUAD8_CTR_CMR | mode_cfg, control);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -305,7 +329,7 @@ static int quad8_direction_read(struct counter_device *counter,
+ {
+       const struct quad8 *const priv = counter_priv(counter);
+       unsigned int ud_flag;
+-      void __iomem *const flag_addr = priv->base + 2 * count->id + 1;
++      u8 __iomem *const flag_addr = &priv->reg->channel[count->id].control;
+       /* U/D flag: nonzero = up, zero = down */
+       ud_flag = ioread8(flag_addr) & QUAD8_FLAG_UD;
+@@ -402,7 +426,6 @@ static int quad8_events_configure(struct counter_device *counter)
+       struct counter_event_node *event_node;
+       unsigned int next_irq_trigger;
+       unsigned long ior_cfg;
+-      void __iomem *base_offset;
+       spin_lock_irqsave(&priv->lock, irqflags);
+@@ -437,14 +460,14 @@ static int quad8_events_configure(struct counter_device *counter)
+               ior_cfg = priv->ab_enable[event_node->channel] |
+                         priv->preset_enable[event_node->channel] << 1 |
+                         priv->irq_trigger[event_node->channel] << 3;
+-              base_offset = priv->base + 2 * event_node->channel + 1;
+-              iowrite8(QUAD8_CTR_IOR | ior_cfg, base_offset);
++              iowrite8(QUAD8_CTR_IOR | ior_cfg,
++                       &priv->reg->channel[event_node->channel].control);
+               /* Enable IRQ line */
+               irq_enabled |= BIT(event_node->channel);
+       }
+-      iowrite8(irq_enabled, priv->base + QUAD8_REG_INDEX_INTERRUPT);
++      iowrite8(irq_enabled, &priv->reg->index_interrupt);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -508,7 +531,7 @@ static int quad8_index_polarity_set(struct counter_device *counter,
+ {
+       struct quad8 *const priv = counter_priv(counter);
+       const size_t channel_id = signal->id - 16;
+-      void __iomem *const base_offset = priv->base + 2 * channel_id + 1;
++      u8 __iomem *const control = &priv->reg->channel[channel_id].control;
+       unsigned long irqflags;
+       unsigned int idr_cfg = index_polarity << 1;
+@@ -519,7 +542,7 @@ static int quad8_index_polarity_set(struct counter_device *counter,
+       priv->index_polarity[channel_id] = index_polarity;
+       /* Load Index Control configuration to Index Control Register */
+-      iowrite8(QUAD8_CTR_IDR | idr_cfg, base_offset);
++      iowrite8(QUAD8_CTR_IDR | idr_cfg, control);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -549,7 +572,7 @@ static int quad8_synchronous_mode_set(struct counter_device *counter,
+ {
+       struct quad8 *const priv = counter_priv(counter);
+       const size_t channel_id = signal->id - 16;
+-      void __iomem *const base_offset = priv->base + 2 * channel_id + 1;
++      u8 __iomem *const control = &priv->reg->channel[channel_id].control;
+       unsigned long irqflags;
+       unsigned int idr_cfg = synchronous_mode;
+@@ -566,7 +589,7 @@ static int quad8_synchronous_mode_set(struct counter_device *counter,
+       priv->synchronous_mode[channel_id] = synchronous_mode;
+       /* Load Index Control configuration to Index Control Register */
+-      iowrite8(QUAD8_CTR_IDR | idr_cfg, base_offset);
++      iowrite8(QUAD8_CTR_IDR | idr_cfg, control);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -614,7 +637,7 @@ static int quad8_count_mode_write(struct counter_device *counter,
+       struct quad8 *const priv = counter_priv(counter);
+       unsigned int count_mode;
+       unsigned int mode_cfg;
+-      void __iomem *const base_offset = priv->base + 2 * count->id + 1;
++      u8 __iomem *const control = &priv->reg->channel[count->id].control;
+       unsigned long irqflags;
+       /* Map Generic Counter count mode to 104-QUAD-8 count mode */
+@@ -648,7 +671,7 @@ static int quad8_count_mode_write(struct counter_device *counter,
+               mode_cfg |= (priv->quadrature_scale[count->id] + 1) << 3;
+       /* Load mode configuration to Counter Mode Register */
+-      iowrite8(QUAD8_CTR_CMR | mode_cfg, base_offset);
++      iowrite8(QUAD8_CTR_CMR | mode_cfg, control);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -669,7 +692,7 @@ static int quad8_count_enable_write(struct counter_device *counter,
+                                   struct counter_count *count, u8 enable)
+ {
+       struct quad8 *const priv = counter_priv(counter);
+-      void __iomem *const base_offset = priv->base + 2 * count->id;
++      u8 __iomem *const control = &priv->reg->channel[count->id].control;
+       unsigned long irqflags;
+       unsigned int ior_cfg;
+@@ -681,7 +704,7 @@ static int quad8_count_enable_write(struct counter_device *counter,
+                 priv->irq_trigger[count->id] << 3;
+       /* Load I/O control configuration */
+-      iowrite8(QUAD8_CTR_IOR | ior_cfg, base_offset + 1);
++      iowrite8(QUAD8_CTR_IOR | ior_cfg, control);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -697,9 +720,9 @@ static int quad8_error_noise_get(struct counter_device *counter,
+                                struct counter_count *count, u32 *noise_error)
+ {
+       const struct quad8 *const priv = counter_priv(counter);
+-      void __iomem *const base_offset = priv->base + 2 * count->id + 1;
++      u8 __iomem *const flag_addr = &priv->reg->channel[count->id].control;
+-      *noise_error = !!(ioread8(base_offset) & QUAD8_FLAG_E);
++      *noise_error = !!(ioread8(flag_addr) & QUAD8_FLAG_E);
+       return 0;
+ }
+@@ -717,17 +740,17 @@ static int quad8_count_preset_read(struct counter_device *counter,
+ static void quad8_preset_register_set(struct quad8 *const priv, const int id,
+                                     const unsigned int preset)
+ {
+-      void __iomem *const base_offset = priv->base + 2 * id;
++      struct channel_reg __iomem *const chan = priv->reg->channel + id;
+       int i;
+       priv->preset[id] = preset;
+       /* Reset Byte Pointer */
+-      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, &chan->control);
+       /* Set Preset Register */
+       for (i = 0; i < 3; i++)
+-              iowrite8(preset >> (8 * i), base_offset);
++              iowrite8(preset >> (8 * i), &chan->data);
+ }
+ static int quad8_count_preset_write(struct counter_device *counter,
+@@ -816,7 +839,7 @@ static int quad8_count_preset_enable_write(struct counter_device *counter,
+                                          u8 preset_enable)
+ {
+       struct quad8 *const priv = counter_priv(counter);
+-      void __iomem *const base_offset = priv->base + 2 * count->id + 1;
++      u8 __iomem *const control = &priv->reg->channel[count->id].control;
+       unsigned long irqflags;
+       unsigned int ior_cfg;
+@@ -831,7 +854,7 @@ static int quad8_count_preset_enable_write(struct counter_device *counter,
+                 priv->irq_trigger[count->id] << 3;
+       /* Load I/O control configuration to Input / Output Control Register */
+-      iowrite8(QUAD8_CTR_IOR | ior_cfg, base_offset);
++      iowrite8(QUAD8_CTR_IOR | ior_cfg, control);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -858,7 +881,7 @@ static int quad8_signal_cable_fault_read(struct counter_device *counter,
+       }
+       /* Logic 0 = cable fault */
+-      status = ioread8(priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS);
++      status = ioread8(&priv->reg->cable_status);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -899,8 +922,7 @@ static int quad8_signal_cable_fault_enable_write(struct counter_device *counter,
+       /* Enable is active low in Differential Encoder Cable Status register */
+       cable_fault_enable = ~priv->cable_fault_enable;
+-      iowrite8(cable_fault_enable,
+-               priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS);
++      iowrite8(cable_fault_enable, &priv->reg->cable_status);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -924,7 +946,7 @@ static int quad8_signal_fck_prescaler_write(struct counter_device *counter,
+ {
+       struct quad8 *const priv = counter_priv(counter);
+       const size_t channel_id = signal->id / 2;
+-      void __iomem *const base_offset = priv->base + 2 * channel_id;
++      struct channel_reg __iomem *const chan = priv->reg->channel + channel_id;
+       unsigned long irqflags;
+       spin_lock_irqsave(&priv->lock, irqflags);
+@@ -932,12 +954,12 @@ static int quad8_signal_fck_prescaler_write(struct counter_device *counter,
+       priv->fck_prescaler[channel_id] = prescaler;
+       /* Reset Byte Pointer */
+-      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, &chan->control);
+       /* Set filter clock factor */
+-      iowrite8(prescaler, base_offset);
++      iowrite8(prescaler, &chan->data);
+       iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_PRESET_PSC,
+-               base_offset + 1);
++               &chan->control);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -1085,12 +1107,11 @@ static irqreturn_t quad8_irq_handler(int irq, void *private)
+ {
+       struct counter_device *counter = private;
+       struct quad8 *const priv = counter_priv(counter);
+-      void __iomem *const base = priv->base;
+       unsigned long irq_status;
+       unsigned long channel;
+       u8 event;
+-      irq_status = ioread8(base + QUAD8_REG_INTERRUPT_STATUS);
++      irq_status = ioread8(&priv->reg->interrupt_status);
+       if (!irq_status)
+               return IRQ_NONE;
+@@ -1119,36 +1140,36 @@ static irqreturn_t quad8_irq_handler(int irq, void *private)
+       }
+       /* Clear pending interrupts on device */
+-      iowrite8(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC, base + QUAD8_REG_CHAN_OP);
++      iowrite8(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC, &priv->reg->channel_oper);
+       return IRQ_HANDLED;
+ }
+-static void quad8_init_counter(void __iomem *const base_offset)
++static void quad8_init_counter(struct channel_reg __iomem *const chan)
+ {
+       unsigned long i;
+       /* Reset Byte Pointer */
+-      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, &chan->control);
+       /* Reset filter clock factor */
+-      iowrite8(0, base_offset);
++      iowrite8(0, &chan->data);
+       iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_PRESET_PSC,
+-               base_offset + 1);
++               &chan->control);
+       /* Reset Byte Pointer */
+-      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, &chan->control);
+       /* Reset Preset Register */
+       for (i = 0; i < 3; i++)
+-              iowrite8(0x00, base_offset);
++              iowrite8(0x00, &chan->data);
+       /* Reset Borrow, Carry, Compare, and Sign flags */
+-      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_FLAGS, base_offset + 1);
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_FLAGS, &chan->control);
+       /* Reset Error flag */
+-      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, base_offset + 1);
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, &chan->control);
+       /* Binary encoding; Normal count; non-quadrature mode */
+-      iowrite8(QUAD8_CTR_CMR, base_offset + 1);
++      iowrite8(QUAD8_CTR_CMR, &chan->control);
+       /* Disable A and B inputs; preset on index; FLG1 as Carry */
+-      iowrite8(QUAD8_CTR_IOR, base_offset + 1);
++      iowrite8(QUAD8_CTR_IOR, &chan->control);
+       /* Disable index function; negative index polarity */
+-      iowrite8(QUAD8_CTR_IDR, base_offset + 1);
++      iowrite8(QUAD8_CTR_IDR, &chan->control);
+ }
+ static int quad8_probe(struct device *dev, unsigned int id)
+@@ -1169,8 +1190,8 @@ static int quad8_probe(struct device *dev, unsigned int id)
+               return -ENOMEM;
+       priv = counter_priv(counter);
+-      priv->base = devm_ioport_map(dev, base[id], QUAD8_EXTENT);
+-      if (!priv->base)
++      priv->reg = devm_ioport_map(dev, base[id], QUAD8_EXTENT);
++      if (!priv->reg)
+               return -ENOMEM;
+       /* Initialize Counter device and driver data */
+@@ -1185,17 +1206,16 @@ static int quad8_probe(struct device *dev, unsigned int id)
+       spin_lock_init(&priv->lock);
+       /* Reset Index/Interrupt Register */
+-      iowrite8(0x00, priv->base + QUAD8_REG_INDEX_INTERRUPT);
++      iowrite8(0x00, &priv->reg->index_interrupt);
+       /* Reset all counters and disable interrupt function */
+-      iowrite8(QUAD8_CHAN_OP_RESET_COUNTERS, priv->base + QUAD8_REG_CHAN_OP);
++      iowrite8(QUAD8_CHAN_OP_RESET_COUNTERS, &priv->reg->channel_oper);
+       /* Set initial configuration for all counters */
+       for (i = 0; i < QUAD8_NUM_COUNTERS; i++)
+-              quad8_init_counter(priv->base + 2 * i);
++              quad8_init_counter(priv->reg->channel + i);
+       /* Disable Differential Encoder Cable Status for all channels */
+-      iowrite8(0xFF, priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS);
++      iowrite8(0xFF, &priv->reg->cable_status);
+       /* Enable all counters and enable interrupt function */
+-      iowrite8(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC,
+-               priv->base + QUAD8_REG_CHAN_OP);
++      iowrite8(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC, &priv->reg->channel_oper);
+       err = devm_request_irq(&counter->dev, irq[id], quad8_irq_handler,
+                              IRQF_SHARED, counter->name, counter);
+-- 
+2.35.1
+
diff --git a/queue-5.19/counter-104-quad-8-utilize-iomap-interface.patch b/queue-5.19/counter-104-quad-8-utilize-iomap-interface.patch
new file mode 100644 (file)
index 0000000..56f6598
--- /dev/null
@@ -0,0 +1,487 @@
+From 25ebedbb5ed2470217a480bf5fe7f16ccf1867ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 12:07:13 -0400
+Subject: counter: 104-quad-8: Utilize iomap interface
+
+From: William Breathitt Gray <william.gray@linaro.org>
+
+[ Upstream commit b6e9cded90d46b1066a1ca260d8b5ecf67787aba ]
+
+This driver doesn't need to access I/O ports directly via inb()/outb()
+and friends. This patch abstracts such access by calling ioport_map()
+to enable the use of more typical ioread8()/iowrite8() I/O memory
+accessor calls.
+
+Link: https://lore.kernel.org/r/861c003318dce3d2bef4061711643bb04f5ec14f.1652201921.git.william.gray@linaro.org
+Cc: Syed Nayyar Waris <syednwaris@gmail.com>
+Suggested-by: David Laight <David.Laight@ACULAB.COM>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: William Breathitt Gray <william.gray@linaro.org>
+Link: https://lore.kernel.org/r/e971b897cacfac4cb2eca478f5533d2875f5cadd.1657813472.git.william.gray@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 2bc54aaa65d2 ("counter: 104-quad-8: Fix skipped IRQ lines during events configuration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/counter/104-quad-8.c | 169 ++++++++++++++++++-----------------
+ 1 file changed, 89 insertions(+), 80 deletions(-)
+
+diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
+index a17e51d65aca..43dde9abfdcf 100644
+--- a/drivers/counter/104-quad-8.c
++++ b/drivers/counter/104-quad-8.c
+@@ -63,7 +63,7 @@ struct quad8 {
+       unsigned int synchronous_mode[QUAD8_NUM_COUNTERS];
+       unsigned int index_polarity[QUAD8_NUM_COUNTERS];
+       unsigned int cable_fault_enable;
+-      unsigned int base;
++      void __iomem *base;
+ };
+ #define QUAD8_REG_INTERRUPT_STATUS 0x10
+@@ -118,8 +118,8 @@ static int quad8_signal_read(struct counter_device *counter,
+       if (signal->id < 16)
+               return -EINVAL;
+-      state = inb(priv->base + QUAD8_REG_INDEX_INPUT_LEVELS)
+-              & BIT(signal->id - 16);
++      state = ioread8(priv->base + QUAD8_REG_INDEX_INPUT_LEVELS) &
++              BIT(signal->id - 16);
+       *level = (state) ? COUNTER_SIGNAL_LEVEL_HIGH : COUNTER_SIGNAL_LEVEL_LOW;
+@@ -130,14 +130,14 @@ static int quad8_count_read(struct counter_device *counter,
+                           struct counter_count *count, u64 *val)
+ {
+       struct quad8 *const priv = counter_priv(counter);
+-      const int base_offset = priv->base + 2 * count->id;
++      void __iomem *const base_offset = priv->base + 2 * count->id;
+       unsigned int flags;
+       unsigned int borrow;
+       unsigned int carry;
+       unsigned long irqflags;
+       int i;
+-      flags = inb(base_offset + 1);
++      flags = ioread8(base_offset + 1);
+       borrow = flags & QUAD8_FLAG_BT;
+       carry = !!(flags & QUAD8_FLAG_CT);
+@@ -147,11 +147,11 @@ static int quad8_count_read(struct counter_device *counter,
+       spin_lock_irqsave(&priv->lock, irqflags);
+       /* Reset Byte Pointer; transfer Counter to Output Latch */
+-      outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_CNTR_OUT,
+-           base_offset + 1);
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_CNTR_OUT,
++               base_offset + 1);
+       for (i = 0; i < 3; i++)
+-              *val |= (unsigned long)inb(base_offset) << (8 * i);
++              *val |= (unsigned long)ioread8(base_offset) << (8 * i);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -162,7 +162,7 @@ static int quad8_count_write(struct counter_device *counter,
+                            struct counter_count *count, u64 val)
+ {
+       struct quad8 *const priv = counter_priv(counter);
+-      const int base_offset = priv->base + 2 * count->id;
++      void __iomem *const base_offset = priv->base + 2 * count->id;
+       unsigned long irqflags;
+       int i;
+@@ -173,27 +173,27 @@ static int quad8_count_write(struct counter_device *counter,
+       spin_lock_irqsave(&priv->lock, irqflags);
+       /* Reset Byte Pointer */
+-      outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
++      iowrite8(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);
++              iowrite8(val >> (8 * i), base_offset);
+       /* Transfer Preset Register to Counter */
+-      outb(QUAD8_CTR_RLD | QUAD8_RLD_PRESET_CNTR, base_offset + 1);
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_PRESET_CNTR, base_offset + 1);
+       /* Reset Byte Pointer */
+-      outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
+       /* Set Preset Register back to original value */
+       val = priv->preset[count->id];
+       for (i = 0; i < 3; i++)
+-              outb(val >> (8 * i), base_offset);
++              iowrite8(val >> (8 * i), base_offset);
+       /* Reset Borrow, Carry, Compare, and Sign flags */
+-      outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_FLAGS, base_offset + 1);
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_FLAGS, base_offset + 1);
+       /* Reset Error flag */
+-      outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, base_offset + 1);
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, base_offset + 1);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -246,7 +246,7 @@ static int quad8_function_write(struct counter_device *counter,
+       unsigned int *const quadrature_mode = priv->quadrature_mode + id;
+       unsigned int *const scale = priv->quadrature_scale + id;
+       unsigned int *const synchronous_mode = priv->synchronous_mode + id;
+-      const int base_offset = priv->base + 2 * id + 1;
++      void __iomem *const base_offset = priv->base + 2 * id + 1;
+       unsigned long irqflags;
+       unsigned int mode_cfg;
+       unsigned int idr_cfg;
+@@ -266,7 +266,7 @@ static int quad8_function_write(struct counter_device *counter,
+               if (*synchronous_mode) {
+                       *synchronous_mode = 0;
+                       /* Disable synchronous function mode */
+-                      outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
++                      iowrite8(QUAD8_CTR_IDR | idr_cfg, base_offset);
+               }
+       } else {
+               *quadrature_mode = 1;
+@@ -292,7 +292,7 @@ static int quad8_function_write(struct counter_device *counter,
+       }
+       /* Load mode configuration to Counter Mode Register */
+-      outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
++      iowrite8(QUAD8_CTR_CMR | mode_cfg, base_offset);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -305,10 +305,10 @@ static int quad8_direction_read(struct counter_device *counter,
+ {
+       const struct quad8 *const priv = counter_priv(counter);
+       unsigned int ud_flag;
+-      const unsigned int flag_addr = priv->base + 2 * count->id + 1;
++      void __iomem *const flag_addr = priv->base + 2 * count->id + 1;
+       /* U/D flag: nonzero = up, zero = down */
+-      ud_flag = inb(flag_addr) & QUAD8_FLAG_UD;
++      ud_flag = ioread8(flag_addr) & QUAD8_FLAG_UD;
+       *direction = (ud_flag) ? COUNTER_COUNT_DIRECTION_FORWARD :
+               COUNTER_COUNT_DIRECTION_BACKWARD;
+@@ -402,7 +402,7 @@ static int quad8_events_configure(struct counter_device *counter)
+       struct counter_event_node *event_node;
+       unsigned int next_irq_trigger;
+       unsigned long ior_cfg;
+-      unsigned long base_offset;
++      void __iomem *base_offset;
+       spin_lock_irqsave(&priv->lock, irqflags);
+@@ -438,13 +438,13 @@ static int quad8_events_configure(struct counter_device *counter)
+                         priv->preset_enable[event_node->channel] << 1 |
+                         priv->irq_trigger[event_node->channel] << 3;
+               base_offset = priv->base + 2 * event_node->channel + 1;
+-              outb(QUAD8_CTR_IOR | ior_cfg, base_offset);
++              iowrite8(QUAD8_CTR_IOR | ior_cfg, base_offset);
+               /* Enable IRQ line */
+               irq_enabled |= BIT(event_node->channel);
+       }
+-      outb(irq_enabled, priv->base + QUAD8_REG_INDEX_INTERRUPT);
++      iowrite8(irq_enabled, priv->base + QUAD8_REG_INDEX_INTERRUPT);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -508,7 +508,7 @@ static int quad8_index_polarity_set(struct counter_device *counter,
+ {
+       struct quad8 *const priv = counter_priv(counter);
+       const size_t channel_id = signal->id - 16;
+-      const int base_offset = priv->base + 2 * channel_id + 1;
++      void __iomem *const base_offset = priv->base + 2 * channel_id + 1;
+       unsigned long irqflags;
+       unsigned int idr_cfg = index_polarity << 1;
+@@ -519,7 +519,7 @@ static int quad8_index_polarity_set(struct counter_device *counter,
+       priv->index_polarity[channel_id] = index_polarity;
+       /* Load Index Control configuration to Index Control Register */
+-      outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
++      iowrite8(QUAD8_CTR_IDR | idr_cfg, base_offset);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -549,7 +549,7 @@ static int quad8_synchronous_mode_set(struct counter_device *counter,
+ {
+       struct quad8 *const priv = counter_priv(counter);
+       const size_t channel_id = signal->id - 16;
+-      const int base_offset = priv->base + 2 * channel_id + 1;
++      void __iomem *const base_offset = priv->base + 2 * channel_id + 1;
+       unsigned long irqflags;
+       unsigned int idr_cfg = synchronous_mode;
+@@ -566,7 +566,7 @@ static int quad8_synchronous_mode_set(struct counter_device *counter,
+       priv->synchronous_mode[channel_id] = synchronous_mode;
+       /* Load Index Control configuration to Index Control Register */
+-      outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
++      iowrite8(QUAD8_CTR_IDR | idr_cfg, base_offset);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -614,7 +614,7 @@ static int quad8_count_mode_write(struct counter_device *counter,
+       struct quad8 *const priv = counter_priv(counter);
+       unsigned int count_mode;
+       unsigned int mode_cfg;
+-      const int base_offset = priv->base + 2 * count->id + 1;
++      void __iomem *const base_offset = priv->base + 2 * count->id + 1;
+       unsigned long irqflags;
+       /* Map Generic Counter count mode to 104-QUAD-8 count mode */
+@@ -648,7 +648,7 @@ static int quad8_count_mode_write(struct counter_device *counter,
+               mode_cfg |= (priv->quadrature_scale[count->id] + 1) << 3;
+       /* Load mode configuration to Counter Mode Register */
+-      outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
++      iowrite8(QUAD8_CTR_CMR | mode_cfg, base_offset);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -669,7 +669,7 @@ static int quad8_count_enable_write(struct counter_device *counter,
+                                   struct counter_count *count, u8 enable)
+ {
+       struct quad8 *const priv = counter_priv(counter);
+-      const int base_offset = priv->base + 2 * count->id;
++      void __iomem *const base_offset = priv->base + 2 * count->id;
+       unsigned long irqflags;
+       unsigned int ior_cfg;
+@@ -681,7 +681,7 @@ static int quad8_count_enable_write(struct counter_device *counter,
+                 priv->irq_trigger[count->id] << 3;
+       /* Load I/O control configuration */
+-      outb(QUAD8_CTR_IOR | ior_cfg, base_offset + 1);
++      iowrite8(QUAD8_CTR_IOR | ior_cfg, base_offset + 1);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -697,9 +697,9 @@ static int quad8_error_noise_get(struct counter_device *counter,
+                                struct counter_count *count, u32 *noise_error)
+ {
+       const struct quad8 *const priv = counter_priv(counter);
+-      const int base_offset = priv->base + 2 * count->id + 1;
++      void __iomem *const base_offset = priv->base + 2 * count->id + 1;
+-      *noise_error = !!(inb(base_offset) & QUAD8_FLAG_E);
++      *noise_error = !!(ioread8(base_offset) & QUAD8_FLAG_E);
+       return 0;
+ }
+@@ -717,17 +717,17 @@ static int quad8_count_preset_read(struct counter_device *counter,
+ 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;
++      void __iomem *const base_offset = priv->base + 2 * id;
+       int i;
+       priv->preset[id] = preset;
+       /* Reset Byte Pointer */
+-      outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
++      iowrite8(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);
++              iowrite8(preset >> (8 * i), base_offset);
+ }
+ static int quad8_count_preset_write(struct counter_device *counter,
+@@ -816,7 +816,7 @@ static int quad8_count_preset_enable_write(struct counter_device *counter,
+                                          u8 preset_enable)
+ {
+       struct quad8 *const priv = counter_priv(counter);
+-      const int base_offset = priv->base + 2 * count->id + 1;
++      void __iomem *const base_offset = priv->base + 2 * count->id + 1;
+       unsigned long irqflags;
+       unsigned int ior_cfg;
+@@ -831,7 +831,7 @@ static int quad8_count_preset_enable_write(struct counter_device *counter,
+                 priv->irq_trigger[count->id] << 3;
+       /* Load I/O control configuration to Input / Output Control Register */
+-      outb(QUAD8_CTR_IOR | ior_cfg, base_offset);
++      iowrite8(QUAD8_CTR_IOR | ior_cfg, base_offset);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -858,7 +858,7 @@ static int quad8_signal_cable_fault_read(struct counter_device *counter,
+       }
+       /* Logic 0 = cable fault */
+-      status = inb(priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS);
++      status = ioread8(priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -899,7 +899,8 @@ static int quad8_signal_cable_fault_enable_write(struct counter_device *counter,
+       /* Enable is active low in Differential Encoder Cable Status register */
+       cable_fault_enable = ~priv->cable_fault_enable;
+-      outb(cable_fault_enable, priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS);
++      iowrite8(cable_fault_enable,
++               priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -923,7 +924,7 @@ static int quad8_signal_fck_prescaler_write(struct counter_device *counter,
+ {
+       struct quad8 *const priv = counter_priv(counter);
+       const size_t channel_id = signal->id / 2;
+-      const int base_offset = priv->base + 2 * channel_id;
++      void __iomem *const base_offset = priv->base + 2 * channel_id;
+       unsigned long irqflags;
+       spin_lock_irqsave(&priv->lock, irqflags);
+@@ -931,12 +932,12 @@ static int quad8_signal_fck_prescaler_write(struct counter_device *counter,
+       priv->fck_prescaler[channel_id] = prescaler;
+       /* Reset Byte Pointer */
+-      outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
+       /* Set filter clock factor */
+-      outb(prescaler, base_offset);
+-      outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_PRESET_PSC,
+-           base_offset + 1);
++      iowrite8(prescaler, base_offset);
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_PRESET_PSC,
++               base_offset + 1);
+       spin_unlock_irqrestore(&priv->lock, irqflags);
+@@ -1084,12 +1085,12 @@ static irqreturn_t quad8_irq_handler(int irq, void *private)
+ {
+       struct counter_device *counter = private;
+       struct quad8 *const priv = counter_priv(counter);
+-      const unsigned long base = priv->base;
++      void __iomem *const base = priv->base;
+       unsigned long irq_status;
+       unsigned long channel;
+       u8 event;
+-      irq_status = inb(base + QUAD8_REG_INTERRUPT_STATUS);
++      irq_status = ioread8(base + QUAD8_REG_INTERRUPT_STATUS);
+       if (!irq_status)
+               return IRQ_NONE;
+@@ -1118,17 +1119,43 @@ static irqreturn_t quad8_irq_handler(int irq, void *private)
+       }
+       /* Clear pending interrupts on device */
+-      outb(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC, base + QUAD8_REG_CHAN_OP);
++      iowrite8(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC, base + QUAD8_REG_CHAN_OP);
+       return IRQ_HANDLED;
+ }
++static void quad8_init_counter(void __iomem *const base_offset)
++{
++      unsigned long i;
++
++      /* Reset Byte Pointer */
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
++      /* Reset filter clock factor */
++      iowrite8(0, base_offset);
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_PRESET_PSC,
++               base_offset + 1);
++      /* Reset Byte Pointer */
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
++      /* Reset Preset Register */
++      for (i = 0; i < 3; i++)
++              iowrite8(0x00, base_offset);
++      /* Reset Borrow, Carry, Compare, and Sign flags */
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_FLAGS, base_offset + 1);
++      /* Reset Error flag */
++      iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, base_offset + 1);
++      /* Binary encoding; Normal count; non-quadrature mode */
++      iowrite8(QUAD8_CTR_CMR, base_offset + 1);
++      /* Disable A and B inputs; preset on index; FLG1 as Carry */
++      iowrite8(QUAD8_CTR_IOR, base_offset + 1);
++      /* Disable index function; negative index polarity */
++      iowrite8(QUAD8_CTR_IDR, base_offset + 1);
++}
++
+ static int quad8_probe(struct device *dev, unsigned int id)
+ {
+       struct counter_device *counter;
+       struct quad8 *priv;
+-      int i, j;
+-      unsigned int base_offset;
++      unsigned long i;
+       int err;
+       if (!devm_request_region(dev, base[id], QUAD8_EXTENT, dev_name(dev))) {
+@@ -1142,6 +1169,10 @@ static int quad8_probe(struct device *dev, unsigned int id)
+               return -ENOMEM;
+       priv = counter_priv(counter);
++      priv->base = devm_ioport_map(dev, base[id], QUAD8_EXTENT);
++      if (!priv->base)
++              return -ENOMEM;
++
+       /* Initialize Counter device and driver data */
+       counter->name = dev_name(dev);
+       counter->parent = dev;
+@@ -1150,43 +1181,21 @@ static int quad8_probe(struct device *dev, unsigned int id)
+       counter->num_counts = ARRAY_SIZE(quad8_counts);
+       counter->signals = quad8_signals;
+       counter->num_signals = ARRAY_SIZE(quad8_signals);
+-      priv->base = base[id];
+       spin_lock_init(&priv->lock);
+       /* Reset Index/Interrupt Register */
+-      outb(0x00, base[id] + QUAD8_REG_INDEX_INTERRUPT);
++      iowrite8(0x00, priv->base + QUAD8_REG_INDEX_INTERRUPT);
+       /* Reset all counters and disable interrupt function */
+-      outb(QUAD8_CHAN_OP_RESET_COUNTERS, base[id] + QUAD8_REG_CHAN_OP);
++      iowrite8(QUAD8_CHAN_OP_RESET_COUNTERS, priv->base + QUAD8_REG_CHAN_OP);
+       /* Set initial configuration for all counters */
+-      for (i = 0; i < QUAD8_NUM_COUNTERS; i++) {
+-              base_offset = base[id] + 2 * i;
+-              /* Reset Byte Pointer */
+-              outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
+-              /* Reset filter clock factor */
+-              outb(0, base_offset);
+-              outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_PRESET_PSC,
+-                   base_offset + 1);
+-              /* Reset Byte Pointer */
+-              outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
+-              /* Reset Preset Register */
+-              for (j = 0; j < 3; j++)
+-                      outb(0x00, 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);
+-              /* Binary encoding; Normal count; non-quadrature mode */
+-              outb(QUAD8_CTR_CMR, base_offset + 1);
+-              /* Disable A and B inputs; preset on index; FLG1 as Carry */
+-              outb(QUAD8_CTR_IOR, base_offset + 1);
+-              /* Disable index function; negative index polarity */
+-              outb(QUAD8_CTR_IDR, base_offset + 1);
+-      }
++      for (i = 0; i < QUAD8_NUM_COUNTERS; i++)
++              quad8_init_counter(priv->base + 2 * i);
+       /* Disable Differential Encoder Cable Status for all channels */
+-      outb(0xFF, base[id] + QUAD8_DIFF_ENCODER_CABLE_STATUS);
++      iowrite8(0xFF, priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS);
+       /* Enable all counters and enable interrupt function */
+-      outb(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC, base[id] + QUAD8_REG_CHAN_OP);
++      iowrite8(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC,
++               priv->base + QUAD8_REG_CHAN_OP);
+       err = devm_request_irq(&counter->dev, irq[id], quad8_irq_handler,
+                              IRQF_SHARED, counter->name, counter);
+-- 
+2.35.1
+
diff --git a/queue-5.19/perf-record-fix-cpu-mask-bit-setting-for-mixed-mmaps.patch b/queue-5.19/perf-record-fix-cpu-mask-bit-setting-for-mixed-mmaps.patch
new file mode 100644 (file)
index 0000000..599923f
--- /dev/null
@@ -0,0 +1,60 @@
+From 57224444030ba3d24e26a125231d5b7c56fb0bd8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Sep 2022 15:26:11 +0300
+Subject: perf record: Fix cpu mask bit setting for mixed mmaps
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+[ Upstream commit ca76d7d2812b46124291f99c9b50aaf63a936f23 ]
+
+With mixed per-thread and (system-wide) per-cpu maps, the "any cpu" value
+ -1 must be skipped when setting CPU mask bits.
+
+Prior to commit cbd7bfc7fd99acdd ("tools/perf: Fix out of bound access
+to cpu mask array") the invalid setting went unnoticed, but since then
+it causes perf record to fail with an error.
+
+Example:
+
+ Before:
+
+   $ perf record -e intel_pt// --per-thread uname
+   Failed to initialize parallel data streaming masks
+
+ After:
+
+   $ perf record -e intel_pt// --per-thread uname
+   Linux
+   [ perf record: Woken up 1 times to write data ]
+   [ perf record: Captured and wrote 0.068 MB perf.data ]
+
+Fixes: ae4f8ae16a078964 ("libperf evlist: Allow mixing per-thread and per-cpu mmaps")
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20220915122612.81738-2-adrian.hunter@intel.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-record.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
+index 708880a1c83c..7fbc85c1da81 100644
+--- a/tools/perf/builtin-record.c
++++ b/tools/perf/builtin-record.c
+@@ -3344,6 +3344,8 @@ static int record__mmap_cpu_mask_init(struct mmap_cpu_mask *mask, struct perf_cp
+               return 0;
+       perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
++              if (cpu.cpu == -1)
++                      continue;
+               /* Return ENODEV is input cpu is greater than max cpu */
+               if ((unsigned long)cpu.cpu > mask->nbits)
+                       return -ENODEV;
+-- 
+2.35.1
+
diff --git a/queue-5.19/riscv-make-t-head-erratas-depend-on-mmu.patch b/queue-5.19/riscv-make-t-head-erratas-depend-on-mmu.patch
new file mode 100644 (file)
index 0000000..33cb804
--- /dev/null
@@ -0,0 +1,42 @@
+From c516c7a2f5d290f4c3e3b9a527a25309a5cbe793 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Sep 2022 17:49:32 +0200
+Subject: riscv: make t-head erratas depend on MMU
+
+From: Heiko Stuebner <heiko@sntech.de>
+
+[ Upstream commit 2a2018c3ac84c2dc7cfbad117ce9339ea0914622 ]
+
+Both basic extensions of SVPBMT and ZICBOM depend on CONFIG_MMU.
+Make the T-Head errata implementations of the similar functionality
+also depend on it to prevent build errors.
+
+Fixes: a35707c3d850 ("riscv: add memory-type errata for T-Head")
+Fixes: d20ec7529236 ("riscv: implement cache-management errata for T-Head SoCs")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Reviewed-by: Guo Ren <guoren@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20220907154932.2858518-1-heiko@sntech.de
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/Kconfig.erratas | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/riscv/Kconfig.erratas b/arch/riscv/Kconfig.erratas
+index 457ac72c9b36..e59a770b4432 100644
+--- a/arch/riscv/Kconfig.erratas
++++ b/arch/riscv/Kconfig.erratas
+@@ -46,7 +46,7 @@ config ERRATA_THEAD
+ config ERRATA_THEAD_PBMT
+       bool "Apply T-Head memory type errata"
+-      depends on ERRATA_THEAD && 64BIT
++      depends on ERRATA_THEAD && 64BIT && MMU
+       select RISCV_ALTERNATIVE_EARLY
+       default y
+       help
+-- 
+2.35.1
+
diff --git a/queue-5.19/series b/queue-5.19/series
new file mode 100644 (file)
index 0000000..6ecf583
--- /dev/null
@@ -0,0 +1,6 @@
+riscv-make-t-head-erratas-depend-on-mmu.patch
+tools-perf-fix-out-of-bound-access-to-cpu-mask-array.patch
+perf-record-fix-cpu-mask-bit-setting-for-mixed-mmaps.patch
+counter-104-quad-8-utilize-iomap-interface.patch
+counter-104-quad-8-implement-and-utilize-register-st.patch
+counter-104-quad-8-fix-skipped-irq-lines-during-even.patch
diff --git a/queue-5.19/tools-perf-fix-out-of-bound-access-to-cpu-mask-array.patch b/queue-5.19/tools-perf-fix-out-of-bound-access-to-cpu-mask-array.patch
new file mode 100644 (file)
index 0000000..1b41f7f
--- /dev/null
@@ -0,0 +1,139 @@
+From 02f569478c767d5365ece100794c29dca8e76eb5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Sep 2022 19:49:29 +0530
+Subject: tools/perf: Fix out of bound access to cpu mask array
+
+From: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+
+[ Upstream commit cbd7bfc7fd99acdde58ec2b0bce990158fba1654 ]
+
+The cpu mask init code in "record__mmap_cpu_mask_init" function access
+"bits" array part of "struct mmap_cpu_mask".  The size of this array is
+the value from cpu__max_cpu().cpu.  This array is used to contain the
+cpumask value for each cpu. While setting bit for each cpu, it calls
+"set_bit" function which access index in "bits" array.
+
+If we provide a command line option to -C which is greater than the
+number of CPU's present in the system, the set_bit could access an array
+member which is out-of the array size. This is because currently, there
+is no boundary check for the CPU. This will result in seg fault:
+
+<<>>
+  ./perf record -C 12341234 ls
+  Perf can support 2048 CPUs. Consider raising MAX_NR_CPUS
+  Segmentation fault (core dumped)
+<<>>
+
+Debugging with gdb, points to function flow as below:
+
+<<>>
+  set_bit
+  record__mmap_cpu_mask_init
+  record__init_thread_default_masks
+  record__init_thread_masks
+  cmd_record
+<<>>
+
+Fix this by adding boundary check for the array.
+
+After the patch:
+
+<<>>
+./perf record -C 12341234 ls
+  Perf can support 2048 CPUs. Consider raising MAX_NR_CPUS
+  Failed to initialize parallel data streaming masks
+<<>>
+
+With this fix, if -C is given a non-exsiting CPU, perf
+record will fail with:
+
+<<>>
+  ./perf record -C 50 ls
+  Failed to initialize parallel data streaming masks
+<<>>
+
+Reported-by: Nageswara R Sastry <rnsastry@linux.ibm.com>
+Signed-off-by: Athira Jajeev <atrajeev@linux.vnet.ibm.com>
+Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Tested-by: Nageswara R Sastry <rnsastry@linux.ibm.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kajol Jain <kjain@linux.ibm.com>
+Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
+Cc: Michael Ellerman <mpe@ellerman.id.au>
+Cc: linuxppc-dev@lists.ozlabs.org
+Link: https://lore.kernel.org/r/20220905141929.7171-2-atrajeev@linux.vnet.ibm.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: ca76d7d2812b ("perf record: Fix cpu mask bit setting for mixed mmaps")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-record.c | 26 ++++++++++++++++++++------
+ 1 file changed, 20 insertions(+), 6 deletions(-)
+
+diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
+index 68c878b4e5e4..708880a1c83c 100644
+--- a/tools/perf/builtin-record.c
++++ b/tools/perf/builtin-record.c
+@@ -3335,16 +3335,22 @@ static struct option __record_options[] = {
+ struct option *record_options = __record_options;
+-static void record__mmap_cpu_mask_init(struct mmap_cpu_mask *mask, struct perf_cpu_map *cpus)
++static int record__mmap_cpu_mask_init(struct mmap_cpu_mask *mask, struct perf_cpu_map *cpus)
+ {
+       struct perf_cpu cpu;
+       int idx;
+       if (cpu_map__is_dummy(cpus))
+-              return;
++              return 0;
+-      perf_cpu_map__for_each_cpu(cpu, idx, cpus)
++      perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
++              /* Return ENODEV is input cpu is greater than max cpu */
++              if ((unsigned long)cpu.cpu > mask->nbits)
++                      return -ENODEV;
+               set_bit(cpu.cpu, mask->bits);
++      }
++
++      return 0;
+ }
+ static int record__mmap_cpu_mask_init_spec(struct mmap_cpu_mask *mask, const char *mask_spec)
+@@ -3356,7 +3362,9 @@ static int record__mmap_cpu_mask_init_spec(struct mmap_cpu_mask *mask, const cha
+               return -ENOMEM;
+       bitmap_zero(mask->bits, mask->nbits);
+-      record__mmap_cpu_mask_init(mask, cpus);
++      if (record__mmap_cpu_mask_init(mask, cpus))
++              return -ENODEV;
++
+       perf_cpu_map__put(cpus);
+       return 0;
+@@ -3438,7 +3446,12 @@ static int record__init_thread_masks_spec(struct record *rec, struct perf_cpu_ma
+               pr_err("Failed to allocate CPUs mask\n");
+               return ret;
+       }
+-      record__mmap_cpu_mask_init(&cpus_mask, cpus);
++
++      ret = record__mmap_cpu_mask_init(&cpus_mask, cpus);
++      if (ret) {
++              pr_err("Failed to init cpu mask\n");
++              goto out_free_cpu_mask;
++      }
+       ret = record__thread_mask_alloc(&full_mask, cpu__max_cpu().cpu);
+       if (ret) {
+@@ -3679,7 +3692,8 @@ static int record__init_thread_default_masks(struct record *rec, struct perf_cpu
+       if (ret)
+               return ret;
+-      record__mmap_cpu_mask_init(&rec->thread_masks->maps, cpus);
++      if (record__mmap_cpu_mask_init(&rec->thread_masks->maps, cpus))
++              return -ENODEV;
+       rec->nr_threads = 1;
+-- 
+2.35.1
+