staging: gasket: interrupt: allow device driver to manage interrupts
Add interrupt type DEVICE_MANAGED, indicating that the device driver
manages interrupt setup and handling. Future non-PCI wire interrupts
will use this type, calling gasket_handle_interrupt(), which is now made
non-static, to call into the gasket framework in order to update sysfs
files for interrupt counts and other framework interfaces.
Change-Id: Ie0be3d950ed2706f7ada848c19ddf7017e9623b2
Signed-off-by: Todd Poynor <toddpoynor@google.com>
diff --git a/drivers/staging/gasket/gasket_core.h b/drivers/staging/gasket/gasket_core.h
index 56805d3..ef7cf16 100644
--- a/drivers/staging/gasket/gasket_core.h
+++ b/drivers/staging/gasket/gasket_core.h
@@ -56,6 +56,7 @@
/* Type of the interrupt supported by the device. */
enum gasket_interrupt_type {
PCI_MSIX = 0,
+ DEVICE_MANAGED = 1, /* Managed externally in device driver */
};
/*
diff --git a/drivers/staging/gasket/gasket_interrupt.c b/drivers/staging/gasket/gasket_interrupt.c
index 9d0ad2c..915146c 100644
--- a/drivers/staging/gasket/gasket_interrupt.c
+++ b/drivers/staging/gasket/gasket_interrupt.c
@@ -93,6 +93,9 @@
dev_dbg(gasket_dev->dev, "Running interrupt setup\n");
+ if (interrupt_data->type == DEVICE_MANAGED)
+ return; /* device driver handles setup */
+
/* Setup the MSIX table. */
for (i = 0; i < interrupt_data->num_interrupts; i++) {
@@ -145,7 +148,7 @@
}
}
-static void
+void
gasket_handle_interrupt(struct gasket_interrupt_data *interrupt_data,
int interrupt_index)
{
@@ -340,7 +343,6 @@
interrupt_data->interrupts = driver_desc->interrupts;
interrupt_data->interrupt_bar_index = driver_desc->interrupt_bar_index;
interrupt_data->pack_width = driver_desc->interrupt_pack_width;
- interrupt_data->num_configured = 0;
interrupt_data->eventfd_ctxs = kcalloc(driver_desc->num_interrupts,
sizeof(struct eventfd_ctx *),
@@ -369,6 +371,11 @@
force_msix_interrupt_unmasking(gasket_dev);
break;
+ case DEVICE_MANAGED: /* Device driver manages IRQ init */
+ interrupt_data->num_configured = interrupt_data->num_interrupts;
+ ret = 0;
+ break;
+
default:
ret = -EINVAL;
}
@@ -426,6 +433,10 @@
force_msix_interrupt_unmasking(gasket_dev);
break;
+ case DEVICE_MANAGED: /* Device driver manages IRQ reinit */
+ ret = 0;
+ break;
+
default:
ret = -EINVAL;
}
@@ -471,6 +482,9 @@
gasket_interrupt_msix_cleanup(interrupt_data);
break;
+ case DEVICE_MANAGED: /* Device driver manages IRQ cleanup */
+ break;
+
default:
break;
}
diff --git a/drivers/staging/gasket/gasket_interrupt.h b/drivers/staging/gasket/gasket_interrupt.h
index 85526a1..b17b723 100644
--- a/drivers/staging/gasket/gasket_interrupt.h
+++ b/drivers/staging/gasket/gasket_interrupt.h
@@ -45,6 +45,11 @@
*/
int gasket_interrupt_reinit(struct gasket_dev *gasket_dev);
+/* Handle gasket interrupt processing, called from an external handler. */
+void
+gasket_handle_interrupt(struct gasket_interrupt_data *interrupt_data,
+ int interrupt_index);
+
/*
* Reset the counts stored in the interrupt subsystem.
* @gasket_dev: The Gasket information structure for this device.