Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[firefly-linux-kernel-4.4.55.git] / drivers / staging / comedi / drivers / cb_das16_cs.c
index 93731de1f2b1b1317682c5a04bf6ccba93485efe..f874fff445236bc627615dd82af30f059ae881b0 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,46 +382,45 @@ 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_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;
-
-       dev->board_ptr = das16cs_probe(dev, link);
-       if (!dev->board_ptr)
-               return -EIO;
-       thisboard = comedi_board(dev);
-
-       dev->board_name = thisboard->name;
+       board = das16cs_find_boardinfo(dev, link);
+       if (!board)
+               return -ENODEV;
+       dev->board_ptr = board;
+       dev->board_name = board->name;
 
+       link->config_flags |= CONF_AUTO_SET_IO | CONF_ENABLE_IRQ;
+       ret = comedi_pcmcia_enable(dev, NULL);
+       if (ret)
+               return ret;
        dev->iobase = link->resource[0]->start;
 
-       ret = request_irq(link->irq, das16cs_interrupt,
-                         IRQF_SHARED, "cb_das16_cs", dev);
-       if (ret < 0)
+       link->priv = dev;
+       ret = pcmcia_request_irq(link, das16cs_interrupt);
+       if (ret)
                return ret;
        dev->irq = link->irq;
 
@@ -450,10 +448,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;
@@ -479,58 +477,16 @@ static int das16cs_attach(struct comedi_device *dev,
        return 0;
 }
 
-static void das16cs_detach(struct comedi_device *dev)
-{
-       if (dev->irq)
-               free_irq(dev->irq, dev);
-}
-
 static struct comedi_driver driver_das16cs = {
        .driver_name    = "cb_das16_cs",
        .module         = THIS_MODULE,
-       .attach         = das16cs_attach,
-       .detach         = das16cs_detach,
+       .auto_attach    = das16cs_auto_attach,
+       .detach         = comedi_pcmcia_disable,
 };
 
-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,35 +499,11 @@ 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,
 };
-
-static int __init das16cs_init(void)
-{
-       int ret;
-
-       ret = comedi_driver_register(&driver_das16cs);
-       if (ret < 0)
-               return ret;
-
-       ret = pcmcia_register_driver(&das16cs_driver);
-       if (ret < 0) {
-               comedi_driver_unregister(&driver_das16cs);
-               return ret;
-       }
-
-       return 0;
-}
-module_init(das16cs_init);
-
-static void __exit das16cs_exit(void)
-{
-       pcmcia_unregister_driver(&das16cs_driver);
-       comedi_driver_unregister(&driver_das16cs);
-}
-module_exit(das16cs_exit);
+module_comedi_pcmcia_driver(driver_das16cs, das16cs_driver);
 
 MODULE_AUTHOR("David A. Schleef <ds@schleef.org>");
 MODULE_DESCRIPTION("Comedi driver for Computer Boards PC-CARD DAS16/16");