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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi all,

This is take #3 of the "add pci_{request,free}_irq" patch.
The following changes have been made since last proposal:
- add IRQF_SHARED systematically to the flags parameter. This is safe
  even for MSI as seen here: http://lkml.org/lkml/2006/10/4/21
- remove IRQF_SHARED from tg3 and e1000
- s/ARCH_VALIDATE_PCI_IRQ/ARCH_VALIDATE_IRQ/ in
  include/linux/interrupts.h, as the irq line may be tweaked outside
  the pci subsystem in an arch specific way.

I'll send a follow-up patch showing the implied modifications for the
following drivers: aic7xxx, aic79xx, tg3 and e1000.

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

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index a544997..50b49ef 100644
 drivers/pci/pci.c         |   42 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/interrupt.h |    7 +++++++
 include/linux/pci.h       |    6 ++++++
 3 files changed, 55 insertions(+)

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 | IRQF_SHARED,
+			   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_IRQ
+static inline int is_irq_valid(unsigned int irq)
+{
+	return irq ? 1 : 0;
+}
+#endif /* ARCH_VALIDATE_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 [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux