Commit f8a27dfa authored by Chris Packham's avatar Chris Packham Committed by Greg Kroah-Hartman
Browse files

uio: use threaded interrupts



Split the existing uio_interrupt into a hardirq handler and a thread
function. The hardirq handler deals with the interrupt source in
hardware, the thread function notifies userspace that there is an event
to be handled.

Signed-off-by: default avatarChris Packham <chris.packham@alliedtelesis.co.nz>
Link: https://lore.kernel.org/r/20240408234050.2056374-3-chris.packham@alliedtelesis.co.nz


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 90fa0280
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
@@ -442,18 +442,27 @@ EXPORT_SYMBOL_GPL(uio_event_notify);
 * @irq: IRQ number, can be UIO_IRQ_CYCLIC for cyclic timer
 * @dev_id: Pointer to the devices uio_device structure
 */
static irqreturn_t uio_interrupt(int irq, void *dev_id)
static irqreturn_t uio_interrupt_handler(int irq, void *dev_id)
{
	struct uio_device *idev = (struct uio_device *)dev_id;
	irqreturn_t ret;

	ret = idev->info->handler(irq, idev->info);
	if (ret == IRQ_HANDLED)
		uio_event_notify(idev->info);
		ret = IRQ_WAKE_THREAD;

	return ret;
}

static irqreturn_t uio_interrupt_thread(int irq, void *dev_id)
{
	struct uio_device *idev = (struct uio_device *)dev_id;

	uio_event_notify(idev->info);

	return IRQ_HANDLED;
}

struct uio_listener {
	struct uio_device *dev;
	s32 event_count;
@@ -1024,7 +1033,7 @@ int __uio_register_device(struct module *owner,
		 * FDs at the time of unregister and therefore may not be
		 * freed until they are released.
		 */
		ret = request_irq(info->irq, uio_interrupt,
		ret = request_threaded_irq(info->irq, uio_interrupt_handler, uio_interrupt_thread,
					   info->irq_flags, info->name, idev);
		if (ret) {
			info->uio_dev = NULL;