Commit 9e884bb1 authored by Uwe Kleine-König's avatar Uwe Kleine-König Committed by Greg Kroah-Hartman
Browse files

counter: 104-quad-8: Convert to new counter registration



This fixes device lifetime issues where it was possible to free a live
struct device.

Fixes: f1d8a071 ("counter: 104-quad-8: Add Generic Counter interface support")
Reviewed-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
Acked-by: default avatarWilliam Breathitt Gray <vilhelm.gray@gmail.com>
Signed-off-by: default avatarUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Link: https://lore.kernel.org/r/20211230150300.72196-16-u.kleine-koenig@pengutronix.de


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 98644726
Loading
Loading
Loading
Loading
+20 −15
Original line number Diff line number Diff line
@@ -52,7 +52,6 @@ MODULE_PARM_DESC(irq, "ACCES 104-QUAD-8 interrupt line numbers");
 */
struct quad8 {
	spinlock_t lock;
	struct counter_device counter;
	unsigned int fck_prescaler[QUAD8_NUM_COUNTERS];
	unsigned int preset[QUAD8_NUM_COUNTERS];
	unsigned int count_mode[QUAD8_NUM_COUNTERS];
@@ -1083,7 +1082,8 @@ static struct counter_count quad8_counts[] = {

static irqreturn_t quad8_irq_handler(int irq, void *private)
{
	struct quad8 *const priv = private;
	struct counter_device *counter = private;
	struct quad8 *const priv = counter_priv(counter);
	const unsigned long base = priv->base;
	unsigned long irq_status;
	unsigned long channel;
@@ -1114,7 +1114,7 @@ static irqreturn_t quad8_irq_handler(int irq, void *private)
			continue;
		}

		counter_push_event(&priv->counter, event, channel);
		counter_push_event(counter, event, channel);
	}

	/* Clear pending interrupts on device */
@@ -1125,6 +1125,7 @@ static irqreturn_t quad8_irq_handler(int irq, void *private)

static int quad8_probe(struct device *dev, unsigned int id)
{
	struct counter_device *counter;
	struct quad8 *priv;
	int i, j;
	unsigned int base_offset;
@@ -1136,19 +1137,19 @@ static int quad8_probe(struct device *dev, unsigned int id)
		return -EBUSY;
	}

	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
	counter = devm_counter_alloc(dev, sizeof(*priv));
	if (!counter)
		return -ENOMEM;
	priv = counter_priv(counter);

	/* Initialize Counter device and driver data */
	priv->counter.name = dev_name(dev);
	priv->counter.parent = dev;
	priv->counter.ops = &quad8_ops;
	priv->counter.counts = quad8_counts;
	priv->counter.num_counts = ARRAY_SIZE(quad8_counts);
	priv->counter.signals = quad8_signals;
	priv->counter.num_signals = ARRAY_SIZE(quad8_signals);
	priv->counter.priv = priv;
	counter->name = dev_name(dev);
	counter->parent = dev;
	counter->ops = &quad8_ops;
	counter->counts = quad8_counts;
	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);
@@ -1188,11 +1189,15 @@ static int quad8_probe(struct device *dev, unsigned int id)
	outb(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC, base[id] + QUAD8_REG_CHAN_OP);

	err = devm_request_irq(dev, irq[id], quad8_irq_handler, IRQF_SHARED,
			       priv->counter.name, priv);
			       counter->name, counter);
	if (err)
		return err;

	return devm_counter_register(dev, &priv->counter);
	err = devm_counter_add(dev, counter);
	if (err < 0)
		return dev_err_probe(dev, err, "Failed to add counter\n");

	return 0;
}

static struct isa_driver quad8_driver = {