Commit 62af1652 authored by Todd Poynor's avatar Todd Poynor Committed by Greg Kroah-Hartman

staging: gasket: interrupt: refactor PCI MSIX-specific handler code

Split interrupt handler into PCI MSIX-specific and generic functions,
for adding non-MSIX handlers in the future.  Move MSIX init code
together,, out of generic init path.
Signed-off-by: default avatarTodd Poynor <toddpoynor@google.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 97fead8c
...@@ -157,9 +157,22 @@ static void gasket_interrupt_setup(struct gasket_dev *gasket_dev) ...@@ -157,9 +157,22 @@ static void gasket_interrupt_setup(struct gasket_dev *gasket_dev)
} }
} }
static irqreturn_t gasket_msix_interrupt_handler(int irq, void *dev_id) static void
gasket_handle_interrupt(struct gasket_interrupt_data *interrupt_data,
int interrupt_index)
{ {
struct eventfd_ctx *ctx; struct eventfd_ctx *ctx;
trace_gasket_interrupt_event(interrupt_data->name, interrupt_index);
ctx = interrupt_data->eventfd_ctxs[interrupt_index];
if (ctx)
eventfd_signal(ctx, 1);
++(interrupt_data->interrupt_counts[interrupt_index]);
}
static irqreturn_t gasket_msix_interrupt_handler(int irq, void *dev_id)
{
struct gasket_interrupt_data *interrupt_data = dev_id; struct gasket_interrupt_data *interrupt_data = dev_id;
int interrupt = -1; int interrupt = -1;
int i; int i;
...@@ -175,14 +188,7 @@ static irqreturn_t gasket_msix_interrupt_handler(int irq, void *dev_id) ...@@ -175,14 +188,7 @@ static irqreturn_t gasket_msix_interrupt_handler(int irq, void *dev_id)
pr_err("Received unknown irq %d\n", irq); pr_err("Received unknown irq %d\n", irq);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
trace_gasket_interrupt_event(interrupt_data->name, interrupt); gasket_handle_interrupt(interrupt_data, interrupt);
ctx = interrupt_data->eventfd_ctxs[interrupt];
if (ctx)
eventfd_signal(ctx, 1);
++(interrupt_data->interrupt_counts[interrupt]);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -192,6 +198,12 @@ gasket_interrupt_msix_init(struct gasket_interrupt_data *interrupt_data) ...@@ -192,6 +198,12 @@ gasket_interrupt_msix_init(struct gasket_interrupt_data *interrupt_data)
int ret = 1; int ret = 1;
int i; int i;
interrupt_data->msix_entries =
kcalloc(interrupt_data->num_interrupts,
sizeof(struct msix_entry), GFP_KERNEL);
if (!interrupt_data->msix_entries)
return -ENOMEM;
for (i = 0; i < interrupt_data->num_interrupts; i++) { for (i = 0; i < interrupt_data->num_interrupts; i++) {
interrupt_data->msix_entries[i].entry = i; interrupt_data->msix_entries[i].entry = i;
interrupt_data->msix_entries[i].vector = 0; interrupt_data->msix_entries[i].vector = 0;
...@@ -343,20 +355,10 @@ int gasket_interrupt_init(struct gasket_dev *gasket_dev, const char *name, ...@@ -343,20 +355,10 @@ int gasket_interrupt_init(struct gasket_dev *gasket_dev, const char *name,
interrupt_data->num_configured = 0; interrupt_data->num_configured = 0;
interrupt_data->wire_interrupt_offsets = wire_int_offsets; interrupt_data->wire_interrupt_offsets = wire_int_offsets;
/* Allocate all dynamic structures. */
interrupt_data->msix_entries = kcalloc(num_interrupts,
sizeof(struct msix_entry),
GFP_KERNEL);
if (!interrupt_data->msix_entries) {
kfree(interrupt_data);
return -ENOMEM;
}
interrupt_data->eventfd_ctxs = kcalloc(num_interrupts, interrupt_data->eventfd_ctxs = kcalloc(num_interrupts,
sizeof(struct eventfd_ctx *), sizeof(struct eventfd_ctx *),
GFP_KERNEL); GFP_KERNEL);
if (!interrupt_data->eventfd_ctxs) { if (!interrupt_data->eventfd_ctxs) {
kfree(interrupt_data->msix_entries);
kfree(interrupt_data); kfree(interrupt_data);
return -ENOMEM; return -ENOMEM;
} }
...@@ -366,7 +368,6 @@ int gasket_interrupt_init(struct gasket_dev *gasket_dev, const char *name, ...@@ -366,7 +368,6 @@ int gasket_interrupt_init(struct gasket_dev *gasket_dev, const char *name,
GFP_KERNEL); GFP_KERNEL);
if (!interrupt_data->interrupt_counts) { if (!interrupt_data->interrupt_counts) {
kfree(interrupt_data->eventfd_ctxs); kfree(interrupt_data->eventfd_ctxs);
kfree(interrupt_data->msix_entries);
kfree(interrupt_data); kfree(interrupt_data);
return -ENOMEM; return -ENOMEM;
} }
...@@ -417,6 +418,7 @@ gasket_interrupt_msix_cleanup(struct gasket_interrupt_data *interrupt_data) ...@@ -417,6 +418,7 @@ gasket_interrupt_msix_cleanup(struct gasket_interrupt_data *interrupt_data)
if (interrupt_data->msix_configured) if (interrupt_data->msix_configured)
pci_disable_msix(interrupt_data->pci_dev); pci_disable_msix(interrupt_data->pci_dev);
interrupt_data->msix_configured = 0; interrupt_data->msix_configured = 0;
kfree(interrupt_data->msix_entries);
} }
int gasket_interrupt_reinit(struct gasket_dev *gasket_dev) int gasket_interrupt_reinit(struct gasket_dev *gasket_dev)
...@@ -448,10 +450,11 @@ int gasket_interrupt_reinit(struct gasket_dev *gasket_dev) ...@@ -448,10 +450,11 @@ int gasket_interrupt_reinit(struct gasket_dev *gasket_dev)
} }
if (ret) { if (ret) {
/* Failing to setup MSIx will cause the device /* Failing to setup interrupts will cause the device
* to report GASKET_STATUS_LAMED, but is not fatal. * to report GASKET_STATUS_LAMED, but is not fatal.
*/ */
dev_warn(gasket_dev->dev, "Couldn't init msix: %d\n", ret); dev_warn(gasket_dev->dev, "Couldn't reinit interrupts: %d\n",
ret);
return 0; return 0;
} }
...@@ -497,7 +500,6 @@ void gasket_interrupt_cleanup(struct gasket_dev *gasket_dev) ...@@ -497,7 +500,6 @@ void gasket_interrupt_cleanup(struct gasket_dev *gasket_dev)
kfree(interrupt_data->interrupt_counts); kfree(interrupt_data->interrupt_counts);
kfree(interrupt_data->eventfd_ctxs); kfree(interrupt_data->eventfd_ctxs);
kfree(interrupt_data->msix_entries);
kfree(interrupt_data); kfree(interrupt_data);
gasket_dev->interrupt_data = NULL; gasket_dev->interrupt_data = NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment