Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b05681b9 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab
Browse files

[media] rc-main: Fix device de-registration logic



rc unregister logic were deadly broken, preventing some drivers to
be removed. Among the broken things, rc_dev_uevent() is being called
during device_del(), causing a data filling on an area that it is
not ready anymore.

Also, some drivers have a stop callback defined, that needs to be called
before data removal, as it stops data polling.

Acked-by: default avatarJarod Wilson <jarod@redhat.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent eaceba65
Loading
Loading
Loading
Loading
+19 −10
Original line number Diff line number Diff line
@@ -928,10 +928,6 @@ static ssize_t store_protocols(struct device *device,

static void rc_dev_release(struct device *device)
{
	struct rc_dev *dev = to_rc_dev(device);

	kfree(dev);
	module_put(THIS_MODULE);
}

#define ADD_HOTPLUG_VAR(fmt, val...)					\
@@ -945,6 +941,9 @@ static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
{
	struct rc_dev *dev = to_rc_dev(device);

	if (!dev || !dev->input_dev)
		return -ENODEV;

	if (dev->rc_map.name)
		ADD_HOTPLUG_VAR("NAME=%s", dev->rc_map.name);
	if (dev->driver_name)
@@ -1013,10 +1012,16 @@ EXPORT_SYMBOL_GPL(rc_allocate_device);

void rc_free_device(struct rc_dev *dev)
{
	if (dev) {
	if (!dev)
		return;

	if (dev->input_dev)
		input_free_device(dev->input_dev);

	put_device(&dev->dev);
	}

	kfree(dev);
	module_put(THIS_MODULE);
}
EXPORT_SYMBOL_GPL(rc_free_device);

@@ -1143,14 +1148,18 @@ void rc_unregister_device(struct rc_dev *dev)
	if (dev->driver_type == RC_DRIVER_IR_RAW)
		ir_raw_event_unregister(dev);

	/* Freeing the table should also call the stop callback */
	ir_free_table(&dev->rc_map);
	IR_dprintk(1, "Freed keycode table\n");

	input_unregister_device(dev->input_dev);
	dev->input_dev = NULL;

	ir_free_table(&dev->rc_map);
	IR_dprintk(1, "Freed keycode table\n");
	device_del(&dev->dev);

	device_unregister(&dev->dev);
	rc_free_device(dev);
}

EXPORT_SYMBOL_GPL(rc_unregister_device);

/*