Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: trigger: free trigger resource correctly

These stand-alone trigger drivers were using iio_trigger_put()
where they should have been using iio_trigger_free(). The
iio_trigger_put() adds a module_put which is bad since they
never did a module_get.

In the sysfs driver, module_get/put's are used as triggers are
added & removed. This extra module_put() occurs on an error path
in the probe routine (probably rare).

In the bfin-timer & interrupt trigger drivers, the module resources
are not explicitly managed, so it's doing a put on something that
was never get'd. It occurs on the probe error path and on the
remove path (not so rare).

Tested with the sysfs trigger driver.
The bfin & interrupt drivers were build tested & inspected only.

Signed-off-by: Alison Schofield <amsfield22@gmail.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>

authored by

Alison Schofield and committed by
Jonathan Cameron
10e840df 2c99f1a0

+7 -7
+4 -4
drivers/iio/trigger/iio-trig-interrupt.c
··· 58 58 trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL); 59 59 if (!trig_info) { 60 60 ret = -ENOMEM; 61 - goto error_put_trigger; 61 + goto error_free_trigger; 62 62 } 63 63 iio_trigger_set_drvdata(trig, trig_info); 64 64 trig_info->irq = irq; ··· 83 83 free_irq(irq, trig); 84 84 error_free_trig_info: 85 85 kfree(trig_info); 86 - error_put_trigger: 87 - iio_trigger_put(trig); 86 + error_free_trigger: 87 + iio_trigger_free(trig); 88 88 error_ret: 89 89 return ret; 90 90 } ··· 99 99 iio_trigger_unregister(trig); 100 100 free_irq(trig_info->irq, trig); 101 101 kfree(trig_info); 102 - iio_trigger_put(trig); 102 + iio_trigger_free(trig); 103 103 104 104 return 0; 105 105 }
+1 -1
drivers/iio/trigger/iio-trig-sysfs.c
··· 174 174 return 0; 175 175 176 176 out2: 177 - iio_trigger_put(t->trig); 177 + iio_trigger_free(t->trig); 178 178 free_t: 179 179 kfree(t); 180 180 out1:
+2 -2
drivers/staging/iio/trigger/iio-trig-bfin-timer.c
··· 260 260 out1: 261 261 iio_trigger_unregister(st->trig); 262 262 out: 263 - iio_trigger_put(st->trig); 263 + iio_trigger_free(st->trig); 264 264 return ret; 265 265 } 266 266 ··· 273 273 peripheral_free(st->t->pin); 274 274 free_irq(st->irq, st); 275 275 iio_trigger_unregister(st->trig); 276 - iio_trigger_put(st->trig); 276 + iio_trigger_free(st->trig); 277 277 278 278 return 0; 279 279 }