Skip to content

Commit

Permalink
staging: comedi: cb_das16_cs: convert to auto attach
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
H Hartley Sweeten authored and Greg Kroah-Hartman committed Jan 31, 2013
1 parent 1f021e1 commit 2bdaef1
Showing 1 changed file with 49 additions and 66 deletions.
115 changes: 49 additions & 66 deletions drivers/staging/comedi/drivers/cb_das16_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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[] = {
Expand All @@ -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>");
Expand Down

0 comments on commit 2bdaef1

Please sign in to comment.