2 Oct 2006 22:00
[RFC PATCH] pci_request_irq (was [-mm patch] aic7xxx: check irq validity)
Frederik Deweerdt <deweerdt <at> free.fr>
2006-10-02 20:00:48 GMT
2006-10-02 20:00:48 GMT
Hi all,
I've tried to summarize the different proposals made by Jeff Garzik,
Matthew Wilcox and Arjan van de Ven in the "[-mm patch] aic7xxx: check
irq validity" thread. I've also added:
- some kerneldoc
- renamed valid_irq to is_irq_valid()
- added pci_release_irq().
I'll send a follow-up patch showing the implied modifications for the
following - semi-randomly chosen :) - drivers: aic7xxx, aic79xx, tg3
and drm.
Regards,
Frederik
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index a544997..ae20a3a 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
<at> <at> -15,6 +15,7 <at> <at> #include <linux/init.h>
#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"
<at> <at> -810,6 +811,49 <at> <at> err_out:
}
/**
+ * pci_request_irq - Reserve an IRQ for a PCI device
+ * <at> pdev: The PCI device whose irq is to be reserved
+ * handler: The interrupt handler function,
+ * pci_get_drvdata(pdev) shall be passed as an argument to that function
+ * <at> flags: The flags to be passed to request_irq()
+ * <at> 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.
+ */
+int pci_request_irq(struct pci_dev *pdev,
+ irqreturn_t (*handler)(int, void *, struct pt_regs *),
+ unsigned long flags, const char *name)
+{
+ int rc;
+ const char *actual_name = name;
+
+ rc = is_irq_valid(pdev->irq);
+ if (!rc) {
+ dev_printk(KERN_ERR, &pdev->dev, "invalid irq #%d\n", pdev->irq);
+ return -EINVAL;
+ }
+
+ if (!actual_name)
+ actual_name = pci_name(pdev);
+
+ return request_irq(pdev->irq, handler, flags | IRQF_SHARED,
+ actual_name, pci_get_drvdata(pdev));
+}
+EXPORT_SYMBOL(pci_request_irq);
+
+/**
+ * pci_free_irq - releases the interrupt line reserved to the PCI
+ * device pointed by <at> pdev
+ * <at> pdev: the PCI device whose interrupt is to be freed
+ */
+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
* <at> dev: the PCI device to enable
*
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 1f97e3d..c320b50 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
<at> <at> -75,6 +75,13 <at> <at> 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 *),
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 5bc4659..5e0f07a 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
<at> <at> -52,6 +52,7 <at> <at> #include <linux/list.h>
#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 {
<at> <at> -531,6 +532,11 <at> <at> 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-scsi" in
the body of a message to majordomo <at> vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
RSS Feed