staging: comedi: cb_das16_cs: convert to auto attach
authorH Hartley Sweeten <hsweeten@visionengravers.com>
Wed, 30 Jan 2013 22:23:27 +0000 (15:23 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 31 Jan 2013 09:40:41 +0000 (10:40 +0100)
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@visionengravers.com>
Cc: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/comedi/drivers/cb_das16_cs.c

index e253fc0..efff059 100644 (file)
@@ -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@schleef.org>");