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

Commit 4f273959 authored by Tomas Winkler's avatar Tomas Winkler Committed by Linus Torvalds
Browse files

mei: nfc: fix deadlock on shutdown/suspend path



In function mei_nfc_host_exit mei_cl_remove_device cannot be called
under the device mutex as device removing flow invokes the device driver
remove handler that calls in turn to mei_cl_disable_device which
naturally acquires the device mutex.

Also remove mei_cl_bus_remove_devices which has the same issue, but is
never executed as currently the only device on the mei client bus is NFC
and a new device cannot be easily added till the bus revamp is
completed.

This fixes regression caused by commit be9b720a ("mei_phy: move all
nfc logic from mei driver to nfc")

Prior to this change the nfc driver remove handler called to no-op
disable function while actual nfc device was disabled directly from the
mei driver.

Reported-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Acked-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent c7e9ad7d
Loading
Loading
Loading
Loading
+0 −16
Original line number Diff line number Diff line
@@ -552,22 +552,6 @@ void mei_cl_bus_rx_event(struct mei_cl *cl)
	schedule_work(&device->event_work);
}

void mei_cl_bus_remove_devices(struct mei_device *dev)
{
	struct mei_cl *cl, *next;

	mutex_lock(&dev->device_lock);
	list_for_each_entry_safe(cl, next, &dev->device_list, device_link) {
		if (cl->device)
			mei_cl_remove_device(cl->device);

		list_del(&cl->device_link);
		mei_cl_unlink(cl);
		kfree(cl);
	}
	mutex_unlock(&dev->device_lock);
}

int __init mei_cl_bus_init(void)
{
	return bus_register(&mei_cl_bus_type);
+0 −2
Original line number Diff line number Diff line
@@ -333,8 +333,6 @@ void mei_stop(struct mei_device *dev)

	mei_nfc_host_exit(dev);

	mei_cl_bus_remove_devices(dev);

	mutex_lock(&dev->device_lock);

	mei_wd_stop(dev);
+2 −1
Original line number Diff line number Diff line
@@ -402,11 +402,12 @@ void mei_nfc_host_exit(struct mei_device *dev)

	cldev->priv_data = NULL;

	mutex_lock(&dev->device_lock);
	/* Need to remove the device here
	 * since mei_nfc_free will unlink the clients
	 */
	mei_cl_remove_device(cldev);

	mutex_lock(&dev->device_lock);
	mei_nfc_free(ndev);
	mutex_unlock(&dev->device_lock);
}