diff --git a/gasket_core.h b/gasket_core.h index 56805d3..ef7cf16 100644 --- a/gasket_core.h +++ b/gasket_core.h @@ -56,6 +56,7 @@ enum gasket_interrupt_packing { /* 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/gasket_interrupt.c b/gasket_interrupt.c index 9d0ad2c..915146c 100644 --- a/gasket_interrupt.c +++ b/gasket_interrupt.c @@ -93,6 +93,9 @@ static void gasket_interrupt_setup(struct gasket_dev *gasket_dev) 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 gasket_interrupt_setup(struct gasket_dev *gasket_dev) } } -static void +void gasket_handle_interrupt(struct gasket_interrupt_data *interrupt_data, int interrupt_index) { @@ -340,7 +343,6 @@ int gasket_interrupt_init(struct gasket_dev *gasket_dev) 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 @@ int gasket_interrupt_init(struct gasket_dev *gasket_dev) 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 @@ int gasket_interrupt_reinit(struct gasket_dev *gasket_dev) 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 @@ void gasket_interrupt_cleanup(struct gasket_dev *gasket_dev) gasket_interrupt_msix_cleanup(interrupt_data); break; + case DEVICE_MANAGED: /* Device driver manages IRQ cleanup */ + break; + default: break; } diff --git a/gasket_interrupt.h b/gasket_interrupt.h index 85526a1..b17b723 100644 --- a/gasket_interrupt.h +++ b/gasket_interrupt.h @@ -45,6 +45,11 @@ void gasket_interrupt_cleanup(struct gasket_dev *gasket_dev); */ 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.