Skip to content

Commit 1deac35

Browse files
committed
Merge tag 'counter-fixes-for-6.1a' of git://git.kernel.org/pub/scm/linux/kernel/git/wbg/counter into char-misc-linus
William writes: "First set of Counter fixes for 6.1 cycle Typical driver fixes for races and bugs. This also includes a sparse warning fix for the recently introduced counter_array API: the macro DEFINE_COUNTER_ARRAY_POLARITY() is reduced to a simple structure definition rather than multiple data structure definitions. - 104-quad-8 * Fix race getting function mode and direction - microchip-tcb-capture * Handle Signal1 read and Synapse - ti-ecap-capture * fix IS_ERR() vs NULL check - counter * Reduce DEFINE_COUNTER_ARRAY_POLARITY() to defining counter_array" * tag 'counter-fixes-for-6.1a' of git://git.kernel.org/pub/scm/linux/kernel/git/wbg/counter: counter: 104-quad-8: Fix race getting function mode and direction counter: microchip-tcb-capture: Handle Signal1 read and Synapse counter: ti-ecap-capture: fix IS_ERR() vs NULL check counter: Reduce DEFINE_COUNTER_ARRAY_POLARITY() to defining counter_array
2 parents 6746eae + d501d37 commit 1deac35

File tree

4 files changed

+62
-32
lines changed

4 files changed

+62
-32
lines changed

drivers/counter/104-quad-8.c

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -232,34 +232,45 @@ static const enum counter_function quad8_count_functions_list[] = {
232232
COUNTER_FUNCTION_QUADRATURE_X4,
233233
};
234234

235+
static int quad8_function_get(const struct quad8 *const priv, const size_t id,
236+
enum counter_function *const function)
237+
{
238+
if (!priv->quadrature_mode[id]) {
239+
*function = COUNTER_FUNCTION_PULSE_DIRECTION;
240+
return 0;
241+
}
242+
243+
switch (priv->quadrature_scale[id]) {
244+
case 0:
245+
*function = COUNTER_FUNCTION_QUADRATURE_X1_A;
246+
return 0;
247+
case 1:
248+
*function = COUNTER_FUNCTION_QUADRATURE_X2_A;
249+
return 0;
250+
case 2:
251+
*function = COUNTER_FUNCTION_QUADRATURE_X4;
252+
return 0;
253+
default:
254+
/* should never reach this path */
255+
return -EINVAL;
256+
}
257+
}
258+
235259
static int quad8_function_read(struct counter_device *counter,
236260
struct counter_count *count,
237261
enum counter_function *function)
238262
{
239263
struct quad8 *const priv = counter_priv(counter);
240-
const int id = count->id;
241264
unsigned long irqflags;
265+
int retval;
242266

243267
spin_lock_irqsave(&priv->lock, irqflags);
244268

245-
if (priv->quadrature_mode[id])
246-
switch (priv->quadrature_scale[id]) {
247-
case 0:
248-
*function = COUNTER_FUNCTION_QUADRATURE_X1_A;
249-
break;
250-
case 1:
251-
*function = COUNTER_FUNCTION_QUADRATURE_X2_A;
252-
break;
253-
case 2:
254-
*function = COUNTER_FUNCTION_QUADRATURE_X4;
255-
break;
256-
}
257-
else
258-
*function = COUNTER_FUNCTION_PULSE_DIRECTION;
269+
retval = quad8_function_get(priv, count->id, function);
259270

260271
spin_unlock_irqrestore(&priv->lock, irqflags);
261272

262-
return 0;
273+
return retval;
263274
}
264275

265276
static int quad8_function_write(struct counter_device *counter,
@@ -359,6 +370,7 @@ static int quad8_action_read(struct counter_device *counter,
359370
enum counter_synapse_action *action)
360371
{
361372
struct quad8 *const priv = counter_priv(counter);
373+
unsigned long irqflags;
362374
int err;
363375
enum counter_function function;
364376
const size_t signal_a_id = count->synapses[0].signal->id;
@@ -374,9 +386,21 @@ static int quad8_action_read(struct counter_device *counter,
374386
return 0;
375387
}
376388

377-
err = quad8_function_read(counter, count, &function);
378-
if (err)
389+
spin_lock_irqsave(&priv->lock, irqflags);
390+
391+
/* Get Count function and direction atomically */
392+
err = quad8_function_get(priv, count->id, &function);
393+
if (err) {
394+
spin_unlock_irqrestore(&priv->lock, irqflags);
395+
return err;
396+
}
397+
err = quad8_direction_read(counter, count, &direction);
398+
if (err) {
399+
spin_unlock_irqrestore(&priv->lock, irqflags);
379400
return err;
401+
}
402+
403+
spin_unlock_irqrestore(&priv->lock, irqflags);
380404

381405
/* Default action mode */
382406
*action = COUNTER_SYNAPSE_ACTION_NONE;
@@ -389,10 +413,6 @@ static int quad8_action_read(struct counter_device *counter,
389413
return 0;
390414
case COUNTER_FUNCTION_QUADRATURE_X1_A:
391415
if (synapse->signal->id == signal_a_id) {
392-
err = quad8_direction_read(counter, count, &direction);
393-
if (err)
394-
return err;
395-
396416
if (direction == COUNTER_COUNT_DIRECTION_FORWARD)
397417
*action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
398418
else

drivers/counter/microchip-tcb-capture.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ struct mchp_tc_data {
2828
int qdec_mode;
2929
int num_channels;
3030
int channel[2];
31-
bool trig_inverted;
3231
};
3332

3433
static const enum counter_function mchp_tc_count_functions[] = {
@@ -153,7 +152,7 @@ static int mchp_tc_count_signal_read(struct counter_device *counter,
153152

154153
regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], SR), &sr);
155154

156-
if (priv->trig_inverted)
155+
if (signal->id == 1)
157156
sigstatus = (sr & ATMEL_TC_MTIOB);
158157
else
159158
sigstatus = (sr & ATMEL_TC_MTIOA);
@@ -171,6 +170,17 @@ static int mchp_tc_count_action_read(struct counter_device *counter,
171170
struct mchp_tc_data *const priv = counter_priv(counter);
172171
u32 cmr;
173172

173+
if (priv->qdec_mode) {
174+
*action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
175+
return 0;
176+
}
177+
178+
/* Only TIOA signal is evaluated in non-QDEC mode */
179+
if (synapse->signal->id != 0) {
180+
*action = COUNTER_SYNAPSE_ACTION_NONE;
181+
return 0;
182+
}
183+
174184
regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], CMR), &cmr);
175185

176186
switch (cmr & ATMEL_TC_ETRGEDG) {
@@ -199,8 +209,8 @@ static int mchp_tc_count_action_write(struct counter_device *counter,
199209
struct mchp_tc_data *const priv = counter_priv(counter);
200210
u32 edge = ATMEL_TC_ETRGEDG_NONE;
201211

202-
/* QDEC mode is rising edge only */
203-
if (priv->qdec_mode)
212+
/* QDEC mode is rising edge only; only TIOA handled in non-QDEC mode */
213+
if (priv->qdec_mode || synapse->signal->id != 0)
204214
return -EINVAL;
205215

206216
switch (action) {

drivers/counter/ti-ecap-capture.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,8 @@ static const enum counter_signal_polarity ecap_cnt_pol_avail[] = {
377377
COUNTER_SIGNAL_POLARITY_NEGATIVE,
378378
};
379379

380-
static DEFINE_COUNTER_ARRAY_POLARITY(ecap_cnt_pol_array, ecap_cnt_pol_avail, ECAP_NB_CEVT);
380+
static DEFINE_COUNTER_AVAILABLE(ecap_cnt_pol_available, ecap_cnt_pol_avail);
381+
static DEFINE_COUNTER_ARRAY_POLARITY(ecap_cnt_pol_array, ecap_cnt_pol_available, ECAP_NB_CEVT);
381382

382383
static struct counter_comp ecap_cnt_signal_ext[] = {
383384
COUNTER_COMP_ARRAY_POLARITY(ecap_cnt_pol_read, ecap_cnt_pol_write, ecap_cnt_pol_array),
@@ -479,8 +480,8 @@ static int ecap_cnt_probe(struct platform_device *pdev)
479480
int ret;
480481

481482
counter_dev = devm_counter_alloc(dev, sizeof(*ecap_dev));
482-
if (IS_ERR(counter_dev))
483-
return PTR_ERR(counter_dev);
483+
if (!counter_dev)
484+
return -ENOMEM;
484485

485486
counter_dev->name = ECAP_DRV_NAME;
486487
counter_dev->parent = dev;

include/linux/counter.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -542,11 +542,10 @@ struct counter_array {
542542
#define DEFINE_COUNTER_ARRAY_CAPTURE(_name, _length) \
543543
DEFINE_COUNTER_ARRAY_U64(_name, _length)
544544

545-
#define DEFINE_COUNTER_ARRAY_POLARITY(_name, _enums, _length) \
546-
DEFINE_COUNTER_AVAILABLE(_name##_available, _enums); \
545+
#define DEFINE_COUNTER_ARRAY_POLARITY(_name, _available, _length) \
547546
struct counter_array _name = { \
548547
.type = COUNTER_COMP_SIGNAL_POLARITY, \
549-
.avail = &(_name##_available), \
548+
.avail = &(_available), \
550549
.length = (_length), \
551550
}
552551

0 commit comments

Comments
 (0)