Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aac307f9 authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman
Browse files

staging: comedi: comedi_pci: introduce comedi_pci_detach()



Introduce a generic (*detach) function for comedi PCI drivers to handle
the boilerplate code needed to detach a PCI driver.

This function works similar to comedi_legacy_detach() where it will:

  * free the dev->irq if it has been requested
  * iounmap the dev->mmio addres if it has been ioremap'ed

The helper then calls comedi_pci_disable() to release the regions and
disable the PCI device.

Use the new helper directly for the (*detach) in the following cases:

  * where comedi_pci_disable() is used directly for the (*detach)
  * where the detach function is just boilerplate

Use the new helper in the (*detach) of the simpler PCI drivers. Call
the helper after disabling interrupts (reset) and before any additional
cleanup (kfree) to avoid any race conditions with the interrupt handler.

Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 081b6ee6
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
 */

#include <linux/pci.h>
#include <linux/interrupt.h>

#include "comedidev.h"

@@ -72,6 +73,29 @@ void comedi_pci_disable(struct comedi_device *dev)
}
EXPORT_SYMBOL_GPL(comedi_pci_disable);

/**
 * comedi_pci_detach() - A generic (*detach) function for PCI drivers.
 * @dev: comedi_device struct
 */
void comedi_pci_detach(struct comedi_device *dev)
{
	struct pci_dev *pcidev = comedi_to_pci_dev(dev);

	if (!pcidev || !dev->ioenabled)
		return;

	if (dev->irq) {
		free_irq(dev->irq, dev);
		dev->irq = 0;
	}
	if (dev->mmio) {
		iounmap(dev->mmio);
		dev->mmio = NULL;
	}
	comedi_pci_disable(dev);
}
EXPORT_SYMBOL_GPL(comedi_pci_detach);

/**
 * comedi_pci_auto_config() - Configure/probe a comedi PCI driver.
 * @pcidev: pci_dev struct
+5 −0
Original line number Diff line number Diff line
@@ -509,6 +509,7 @@ struct pci_dev *comedi_to_pci_dev(struct comedi_device *);

int comedi_pci_enable(struct comedi_device *);
void comedi_pci_disable(struct comedi_device *);
void comedi_pci_detach(struct comedi_device *);

int comedi_pci_auto_config(struct pci_dev *, struct comedi_driver *,
			   unsigned long context);
@@ -553,6 +554,10 @@ static inline void comedi_pci_disable(struct comedi_device *dev)
{
}

static inline void comedi_pci_detach(struct comedi_device *dev)
{
}

#endif /* CONFIG_COMEDI_PCI_DRIVERS */

#ifdef CONFIG_COMEDI_PCMCIA_DRIVERS
+1 −8
Original line number Diff line number Diff line
@@ -246,18 +246,11 @@ static int pci_8255_auto_attach(struct comedi_device *dev,
	return 0;
}

static void pci_8255_detach(struct comedi_device *dev)
{
	if (dev->mmio)
		iounmap(dev->mmio);
	comedi_pci_disable(dev);
}

static struct comedi_driver pci_8255_driver = {
	.driver_name	= "8255_pci",
	.module		= THIS_MODULE,
	.auto_attach	= pci_8255_auto_attach,
	.detach		= pci_8255_detach,
	.detach		= comedi_pci_detach,
};

static int pci_8255_pci_probe(struct pci_dev *dev,
+3 −9
Original line number Diff line number Diff line
@@ -268,13 +268,7 @@ static int addi_auto_attach(struct comedi_device *dev,

static void i_ADDI_Detach(struct comedi_device *dev)
{
	struct addi_private *devpriv = dev->private;

	if (devpriv) {
	if (dev->iobase)
		i_ADDI_Reset(dev);
		if (dev->irq)
			free_irq(dev->irq, dev);
	}
	comedi_pci_disable(dev);
	comedi_pci_detach(dev);
}
+1 −3
Original line number Diff line number Diff line
@@ -343,9 +343,7 @@ static void apci1032_detach(struct comedi_device *dev)
{
	if (dev->iobase)
		apci1032_reset(dev);
	if (dev->irq)
		free_irq(dev->irq, dev);
	comedi_pci_disable(dev);
	comedi_pci_detach(dev);
}

static struct comedi_driver apci1032_driver = {
Loading