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
-----BEGIN PGP SIGNATURE-----
iHUEABYKAB0WIQSNN83d4NIlKPjon7a1SFbKvhIjKwUCY1a/wQAKCRC1SFbKvhIj
K+BZAP0TKVuXLDU4gBWcLGW+37LBNYn7AdufpkIshrE/6vgj4gEAnc1pMW26miW5
HyWKxNTdcbXz2p/DHXpr6Ef1fh7yBwM=
=bTl5
-----END PGP SIGNATURE-----
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
This commit is contained in:
commit
1deac35b2d
4 changed files with 62 additions and 32 deletions
|
|
@ -232,34 +232,45 @@ static const enum counter_function quad8_count_functions_list[] = {
|
|||
COUNTER_FUNCTION_QUADRATURE_X4,
|
||||
};
|
||||
|
||||
static int quad8_function_get(const struct quad8 *const priv, const size_t id,
|
||||
enum counter_function *const function)
|
||||
{
|
||||
if (!priv->quadrature_mode[id]) {
|
||||
*function = COUNTER_FUNCTION_PULSE_DIRECTION;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (priv->quadrature_scale[id]) {
|
||||
case 0:
|
||||
*function = COUNTER_FUNCTION_QUADRATURE_X1_A;
|
||||
return 0;
|
||||
case 1:
|
||||
*function = COUNTER_FUNCTION_QUADRATURE_X2_A;
|
||||
return 0;
|
||||
case 2:
|
||||
*function = COUNTER_FUNCTION_QUADRATURE_X4;
|
||||
return 0;
|
||||
default:
|
||||
/* should never reach this path */
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int quad8_function_read(struct counter_device *counter,
|
||||
struct counter_count *count,
|
||||
enum counter_function *function)
|
||||
{
|
||||
struct quad8 *const priv = counter_priv(counter);
|
||||
const int id = count->id;
|
||||
unsigned long irqflags;
|
||||
int retval;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, irqflags);
|
||||
|
||||
if (priv->quadrature_mode[id])
|
||||
switch (priv->quadrature_scale[id]) {
|
||||
case 0:
|
||||
*function = COUNTER_FUNCTION_QUADRATURE_X1_A;
|
||||
break;
|
||||
case 1:
|
||||
*function = COUNTER_FUNCTION_QUADRATURE_X2_A;
|
||||
break;
|
||||
case 2:
|
||||
*function = COUNTER_FUNCTION_QUADRATURE_X4;
|
||||
break;
|
||||
}
|
||||
else
|
||||
*function = COUNTER_FUNCTION_PULSE_DIRECTION;
|
||||
retval = quad8_function_get(priv, count->id, function);
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, irqflags);
|
||||
|
||||
return 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int quad8_function_write(struct counter_device *counter,
|
||||
|
|
@ -359,6 +370,7 @@ static int quad8_action_read(struct counter_device *counter,
|
|||
enum counter_synapse_action *action)
|
||||
{
|
||||
struct quad8 *const priv = counter_priv(counter);
|
||||
unsigned long irqflags;
|
||||
int err;
|
||||
enum counter_function function;
|
||||
const size_t signal_a_id = count->synapses[0].signal->id;
|
||||
|
|
@ -374,9 +386,21 @@ static int quad8_action_read(struct counter_device *counter,
|
|||
return 0;
|
||||
}
|
||||
|
||||
err = quad8_function_read(counter, count, &function);
|
||||
if (err)
|
||||
spin_lock_irqsave(&priv->lock, irqflags);
|
||||
|
||||
/* Get Count function and direction atomically */
|
||||
err = quad8_function_get(priv, count->id, &function);
|
||||
if (err) {
|
||||
spin_unlock_irqrestore(&priv->lock, irqflags);
|
||||
return err;
|
||||
}
|
||||
err = quad8_direction_read(counter, count, &direction);
|
||||
if (err) {
|
||||
spin_unlock_irqrestore(&priv->lock, irqflags);
|
||||
return err;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, irqflags);
|
||||
|
||||
/* Default action mode */
|
||||
*action = COUNTER_SYNAPSE_ACTION_NONE;
|
||||
|
|
@ -389,10 +413,6 @@ static int quad8_action_read(struct counter_device *counter,
|
|||
return 0;
|
||||
case COUNTER_FUNCTION_QUADRATURE_X1_A:
|
||||
if (synapse->signal->id == signal_a_id) {
|
||||
err = quad8_direction_read(counter, count, &direction);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (direction == COUNTER_COUNT_DIRECTION_FORWARD)
|
||||
*action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
|
||||
else
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ struct mchp_tc_data {
|
|||
int qdec_mode;
|
||||
int num_channels;
|
||||
int channel[2];
|
||||
bool trig_inverted;
|
||||
};
|
||||
|
||||
static const enum counter_function mchp_tc_count_functions[] = {
|
||||
|
|
@ -153,7 +152,7 @@ static int mchp_tc_count_signal_read(struct counter_device *counter,
|
|||
|
||||
regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], SR), &sr);
|
||||
|
||||
if (priv->trig_inverted)
|
||||
if (signal->id == 1)
|
||||
sigstatus = (sr & ATMEL_TC_MTIOB);
|
||||
else
|
||||
sigstatus = (sr & ATMEL_TC_MTIOA);
|
||||
|
|
@ -171,6 +170,17 @@ static int mchp_tc_count_action_read(struct counter_device *counter,
|
|||
struct mchp_tc_data *const priv = counter_priv(counter);
|
||||
u32 cmr;
|
||||
|
||||
if (priv->qdec_mode) {
|
||||
*action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Only TIOA signal is evaluated in non-QDEC mode */
|
||||
if (synapse->signal->id != 0) {
|
||||
*action = COUNTER_SYNAPSE_ACTION_NONE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], CMR), &cmr);
|
||||
|
||||
switch (cmr & ATMEL_TC_ETRGEDG) {
|
||||
|
|
@ -199,8 +209,8 @@ static int mchp_tc_count_action_write(struct counter_device *counter,
|
|||
struct mchp_tc_data *const priv = counter_priv(counter);
|
||||
u32 edge = ATMEL_TC_ETRGEDG_NONE;
|
||||
|
||||
/* QDEC mode is rising edge only */
|
||||
if (priv->qdec_mode)
|
||||
/* QDEC mode is rising edge only; only TIOA handled in non-QDEC mode */
|
||||
if (priv->qdec_mode || synapse->signal->id != 0)
|
||||
return -EINVAL;
|
||||
|
||||
switch (action) {
|
||||
|
|
|
|||
|
|
@ -377,7 +377,8 @@ static const enum counter_signal_polarity ecap_cnt_pol_avail[] = {
|
|||
COUNTER_SIGNAL_POLARITY_NEGATIVE,
|
||||
};
|
||||
|
||||
static DEFINE_COUNTER_ARRAY_POLARITY(ecap_cnt_pol_array, ecap_cnt_pol_avail, ECAP_NB_CEVT);
|
||||
static DEFINE_COUNTER_AVAILABLE(ecap_cnt_pol_available, ecap_cnt_pol_avail);
|
||||
static DEFINE_COUNTER_ARRAY_POLARITY(ecap_cnt_pol_array, ecap_cnt_pol_available, ECAP_NB_CEVT);
|
||||
|
||||
static struct counter_comp ecap_cnt_signal_ext[] = {
|
||||
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)
|
|||
int ret;
|
||||
|
||||
counter_dev = devm_counter_alloc(dev, sizeof(*ecap_dev));
|
||||
if (IS_ERR(counter_dev))
|
||||
return PTR_ERR(counter_dev);
|
||||
if (!counter_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
counter_dev->name = ECAP_DRV_NAME;
|
||||
counter_dev->parent = dev;
|
||||
|
|
|
|||
|
|
@ -542,11 +542,10 @@ struct counter_array {
|
|||
#define DEFINE_COUNTER_ARRAY_CAPTURE(_name, _length) \
|
||||
DEFINE_COUNTER_ARRAY_U64(_name, _length)
|
||||
|
||||
#define DEFINE_COUNTER_ARRAY_POLARITY(_name, _enums, _length) \
|
||||
DEFINE_COUNTER_AVAILABLE(_name##_available, _enums); \
|
||||
#define DEFINE_COUNTER_ARRAY_POLARITY(_name, _available, _length) \
|
||||
struct counter_array _name = { \
|
||||
.type = COUNTER_COMP_SIGNAL_POLARITY, \
|
||||
.avail = &(_name##_available), \
|
||||
.avail = &(_available), \
|
||||
.length = (_length), \
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue