[PATCH v2 05/10] staging: comedi: cb_das16_cs: convert to auto attach

H Hartley Sweeten hsweeten at visionengravers.com
Wed Jan 30 22:23:27 UTC 2013


Convert this pcmcia driver to the comedi auto attach mechanism.

This allows getting rid of the "hack" needed to pass the pcmcia_device
pointer from the pcmcia_driver to the comedi_driver.

Signed-off-by: H Hartley Sweeten <hsweeten at visionengravers.com>
Cc: Ian Abbott <abbotti at mev.co.uk>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/staging/comedi/drivers/cb_das16_cs.c | 115 ++++++++++++---------------
 1 file changed, 49 insertions(+), 66 deletions(-)

diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c
index e253fc0..efff059 100644
--- a/drivers/staging/comedi/drivers/cb_das16_cs.c
+++ b/drivers/staging/comedi/drivers/cb_das16_cs.c
@@ -40,9 +40,10 @@ Status: experimental
 
 #include <linux/interrupt.h>
 #include <linux/slab.h>
-#include "../comedidev.h"
 #include <linux/delay.h>
 
+#include "../comedidev.h"
+
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
 
@@ -89,8 +90,6 @@ struct das16cs_private {
 	unsigned short status2;
 };
 
-static struct pcmcia_device *cur_dev;
-
 static const struct comedi_lrange das16cs_ai_range = {
 	4, {
 		BIP_RANGE(10),
@@ -383,45 +382,62 @@ static int das16cs_dio_insn_config(struct comedi_device *dev,
 	return insn->n;
 }
 
-static const struct das16cs_board *das16cs_probe(struct comedi_device *dev,
-						 struct pcmcia_device *link)
+static const void *das16cs_find_boardinfo(struct comedi_device *dev,
+					  struct pcmcia_device *link)
 {
+	const struct das16cs_board *board;
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(das16cs_boards); i++) {
-		if (das16cs_boards[i].device_id == link->card_id)
-			return das16cs_boards + i;
+		board = &das16cs_boards[i];
+		if (board->device_id == link->card_id)
+			return board;
 	}
 
-	dev_dbg(dev->class_dev, "unknown board!\n");
-
 	return NULL;
 }
 
-static int das16cs_attach(struct comedi_device *dev,
-			  struct comedi_devconfig *it)
+static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev,
+				      void *priv_data)
+{
+	if (p_dev->config_index == 0)
+		return -EINVAL;
+
+	return pcmcia_request_io(p_dev);
+}
+
+static int das16cs_auto_attach(struct comedi_device *dev,
+			       unsigned long context)
 {
-	const struct das16cs_board *thisboard;
+	struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
+	const struct das16cs_board *board;
 	struct das16cs_private *devpriv;
-	struct pcmcia_device *link;
 	struct comedi_subdevice *s;
 	int ret;
 
-	link = cur_dev;		/* XXX hack */
-	if (!link)
-		return -EIO;
+	board = das16cs_find_boardinfo(dev, link);
+	if (!board)
+		return -ENODEV;
+	dev->board_ptr = board;
+	dev->board_name = board->name;
 
-	dev->board_ptr = das16cs_probe(dev, link);
-	if (!dev->board_ptr)
-		return -EIO;
-	thisboard = comedi_board(dev);
+	/* Do we need to allocate an interrupt? */
+	link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
 
-	dev->board_name = thisboard->name;
+	ret = pcmcia_loop_config(link, das16cs_pcmcia_config_loop, NULL);
+	if (ret)
+		return ret;
+
+	if (!link->irq)
+		return -EINVAL;
 
+	ret = pcmcia_enable_device(link);
+	if (ret)
+		return ret;
 	dev->iobase = link->resource[0]->start;
 
-	ret = request_irq(link->irq, das16cs_interrupt,
-			  IRQF_SHARED, "cb_das16_cs", dev);
+	ret = request_irq(link->irq, das16cs_interrupt, IRQF_SHARED,
+			  dev->board_name, dev);
 	if (ret < 0)
 		return ret;
 	dev->irq = link->irq;
@@ -450,10 +466,10 @@ static int das16cs_attach(struct comedi_device *dev,
 
 	s = &dev->subdevices[1];
 	/* analog output subdevice */
-	if (thisboard->n_ao_chans) {
+	if (board->n_ao_chans) {
 		s->type		= COMEDI_SUBD_AO;
 		s->subdev_flags	= SDF_WRITABLE;
-		s->n_chan	= thisboard->n_ao_chans;
+		s->n_chan	= board->n_ao_chans;
 		s->maxdata	= 0xffff;
 		s->range_table	= &range_bipolar10;
 		s->insn_write	= &das16cs_ao_winsn;
@@ -481,56 +497,24 @@ static int das16cs_attach(struct comedi_device *dev,
 
 static void das16cs_detach(struct comedi_device *dev)
 {
+	struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
+
 	if (dev->irq)
 		free_irq(dev->irq, dev);
+	if (dev->iobase)
+		pcmcia_disable_device(link);
 }
 
 static struct comedi_driver driver_das16cs = {
 	.driver_name	= "cb_das16_cs",
 	.module		= THIS_MODULE,
-	.attach		= das16cs_attach,
+	.auto_attach	= das16cs_auto_attach,
 	.detach		= das16cs_detach,
 };
 
-static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev,
-				void *priv_data)
-{
-	if (p_dev->config_index == 0)
-		return -EINVAL;
-
-	return pcmcia_request_io(p_dev);
-}
-
 static int das16cs_pcmcia_attach(struct pcmcia_device *link)
 {
-	int ret;
-
-	/* Do we need to allocate an interrupt? */
-	link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
-
-	ret = pcmcia_loop_config(link, das16cs_pcmcia_config_loop, NULL);
-	if (ret)
-		goto failed;
-
-	if (!link->irq)
-		goto failed;
-
-	ret = pcmcia_enable_device(link);
-	if (ret)
-		goto failed;
-
-	cur_dev = link;
-	return 0;
-
-failed:
-	pcmcia_disable_device(link);
-	return ret;
-}
-
-static void das16cs_pcmcia_detach(struct pcmcia_device *link)
-{
-	pcmcia_disable_device(link);
-	cur_dev = NULL;
+	return comedi_pcmcia_auto_config(link, &driver_das16cs);
 }
 
 static const struct pcmcia_device_id das16cs_id_table[] = {
@@ -543,11 +527,10 @@ MODULE_DEVICE_TABLE(pcmcia, das16cs_id_table);
 static struct pcmcia_driver das16cs_driver = {
 	.name		= "cb_das16_cs",
 	.owner		= THIS_MODULE,
-	.probe		= das16cs_pcmcia_attach,
-	.remove		= das16cs_pcmcia_detach,
 	.id_table	= das16cs_id_table,
+	.probe		= das16cs_pcmcia_attach,
+	.remove		= comedi_pcmcia_auto_unconfig,
 };
-
 module_comedi_pcmcia_driver(driver_das16cs, das16cs_driver);
 
 MODULE_AUTHOR("David A. Schleef <ds at schleef.org>");
-- 
1.8.1.1.293.gfe73786




More information about the devel mailing list