[RFC PATCH] add pci_{request,free}_irq take #2

From: Frederik Deweerdt
Date: Tue Oct 03 2006 - 18:08:34 EST


Hi all,

This is take #2 of the "add pci_{request,free}_irq" patch.
The following changes have been made since last proposal:
- fix broken kerneldoc (Randy Dunlap)
- change warning message (Alan Cox)
- taken into account the various comments made by Matthew Wilcox
- remove the IRQF_SHARED flag from the request_irq() call: not all
drivers (eg. tg3) set it (Arjan van de Ven suggested dropping it
before the call, but this may not suit the different usage patterns,
tg3 in particular)

I'll send a follow-up patch showing the implied modifications for the
following - semi-randomly chosen :) - drivers: aic7xxx, aic79xx, tg3
and e1000 (Dropped the drm one, which was NACKed by the maintainer).

Please note that I'm not submitting the driver changes, they're there
only for illustration purposes. I'll CC the appropriate maintainers
when/if an API is agreed upon.

Regards,
Frederik

PS: trimmed the CC list a bit, this must be noise to linux-scsi
PPS: used quilt to manage patches, I should have done it long ago :)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index a544997..50b49ef 100644
Index: 2.6.18-mm3/drivers/pci/pci.c
===================================================================
--- 2.6.18-mm3.orig/drivers/pci/pci.c
+++ 2.6.18-mm3/drivers/pci/pci.c
@@ -15,6 +15,7 @@
#include <linux/pci.h>
#include <linux/module.h>
#include <linux/spinlock.h>
+#include <linux/interrupt.h>
#include <linux/string.h>
#include <asm/dma.h> /* isa_dma_bridge_buggy */
#include "pci.h"
@@ -810,6 +811,47 @@ err_out:
}

/**
+ * pci_request_irq - Reserve an IRQ for a PCI device
+ * @pdev: The PCI device whose irq is to be reserved
+ * @handler: The interrupt handler function,
+ * @flags: The flags to be passed to request_irq()
+ * @name: The name of the device to be associated with the irq
+ *
+ * Returns 0 on success, or a negative value on error. A warning
+ * message is also printed on failure.
+ * pci_get_drvdata(pdev) shall be passed as an argument to the @handler
+ * function
+ */
+int pci_request_irq(struct pci_dev *pdev,
+ irqreturn_t(*handler) (int, void *, struct pt_regs *),
+ unsigned long flags, const char *name)
+{
+ if (!is_irq_valid(pdev->irq)) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "No usable irq line was found (got #%d)\n",
+ pdev->irq);
+ return -EINVAL;
+ }
+
+ return request_irq(pdev->irq, handler, flags,
+ name ? name : pdev->driver->name,
+ pci_get_drvdata(pdev));
+}
+EXPORT_SYMBOL(pci_request_irq);
+
+/**
+ * pci_free_irq - Free an IRQ for a PCI device
+ *
+ * @pdev: the PCI device whose interrupt is to be freed
+ * pci_get_drvdata(pdev) is used as the device identifier
+ */
+void pci_free_irq(struct pci_dev *pdev)
+{
+ free_irq(pdev->irq, pci_get_drvdata(pdev));
+}
+EXPORT_SYMBOL(pci_free_irq);
+
+/**
* pci_set_master - enables bus-mastering for device dev
* @dev: the PCI device to enable
*
Index: 2.6.18-mm3/include/linux/interrupt.h
===================================================================
--- 2.6.18-mm3.orig/include/linux/interrupt.h
+++ 2.6.18-mm3/include/linux/interrupt.h
@@ -75,6 +75,13 @@ struct irqaction {
struct proc_dir_entry *dir;
};

+#ifndef ARCH_VALIDATE_PCI_IRQ
+static inline int is_irq_valid(unsigned int irq)
+{
+ return irq ? 1 : 0;
+}
+#endif /* ARCH_VALIDATE_PCI_IRQ */
+
extern irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs);
extern int request_irq(unsigned int,
irqreturn_t (*handler)(int, void *, struct pt_regs *),
Index: 2.6.18-mm3/include/linux/pci.h
===================================================================
--- 2.6.18-mm3.orig/include/linux/pci.h
+++ 2.6.18-mm3/include/linux/pci.h
@@ -52,6 +52,7 @@
#include <linux/compiler.h>
#include <linux/errno.h>
#include <linux/device.h>
+#include <linux/interrupt.h>

/* File state for mmap()s on /proc/bus/pci/X/Y */
enum pci_mmap_state {
@@ -532,6 +533,11 @@ void pci_release_regions(struct pci_dev
int __must_check pci_request_region(struct pci_dev *, int, const char *);
void pci_release_region(struct pci_dev *, int);

+int __must_check pci_request_irq(struct pci_dev *pdev,
+ irqreturn_t (*handler)(int, void *, struct pt_regs *),
+ unsigned long flags, const char *name);
+void pci_free_irq(struct pci_dev *pdev);
+
/* drivers/pci/bus.c */
int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
struct resource *res, resource_size_t size,
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/