aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/comedi/drivers/das08_cs.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2009-12-06 17:00:33 +0000
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-12-06 17:00:33 +0000
commit3d14b5beba35250c548d3851a2b84fce742d8311 (patch)
tree065e3d93c3fcbc5ee4c44fa78662393cddbdf6de /drivers/staging/comedi/drivers/das08_cs.c
parentMerge branch 'devel-stable' into devel (diff)
parentFix soc_common PCMCIA configuration (diff)
downloadlinux-dev-3d14b5beba35250c548d3851a2b84fce742d8311.tar.xz
linux-dev-3d14b5beba35250c548d3851a2b84fce742d8311.zip
Merge branch 'sa1100' into devel
Diffstat (limited to 'drivers/staging/comedi/drivers/das08_cs.c')
-rw-r--r--drivers/staging/comedi/drivers/das08_cs.c203
1 files changed, 55 insertions, 148 deletions
diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c
index 9cab21eaaa18..9b945e5fdd32 100644
--- a/drivers/staging/comedi/drivers/das08_cs.c
+++ b/drivers/staging/comedi/drivers/das08_cs.c
@@ -110,25 +110,6 @@ static int das08_cs_attach(struct comedi_device *dev,
======================================================================*/
-/*
- All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
- you do not define PCMCIA_DEBUG at all, all the debug code will be
- left out. If you compile with PCMCIA_DEBUG=0, the debug code will
- be present but disabled -- but it can then be enabled for specific
- modules at load time with a 'pc_debug=#' option to insmod.
-*/
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static const char *version =
- "das08.c pcmcia code (Frank Hess), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
-
-/*====================================================================*/
static void das08_pcmcia_config(struct pcmcia_device *link);
static void das08_pcmcia_release(struct pcmcia_device *link);
static int das08_pcmcia_suspend(struct pcmcia_device *p_dev);
@@ -181,7 +162,7 @@ static int das08_pcmcia_attach(struct pcmcia_device *link)
{
struct local_info_t *local;
- DEBUG(0, "das08_pcmcia_attach()\n");
+ dev_dbg(&link->dev, "das08_pcmcia_attach()\n");
/* Allocate space for private device-specific data */
local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
@@ -192,7 +173,6 @@ static int das08_pcmcia_attach(struct pcmcia_device *link)
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->irq.Handler = NULL;
/*
@@ -224,7 +204,7 @@ static int das08_pcmcia_attach(struct pcmcia_device *link)
static void das08_pcmcia_detach(struct pcmcia_device *link)
{
- DEBUG(0, "das08_pcmcia_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "das08_pcmcia_detach\n");
if (link->dev_node) {
((struct local_info_t *)link->priv)->stop = 1;
@@ -237,6 +217,44 @@ static void das08_pcmcia_detach(struct pcmcia_device *link)
} /* das08_pcmcia_detach */
+
+static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ if (cfg->index == 0)
+ return -ENODEV;
+
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
+ p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ p_dev->io.BasePort1 = io->win[0].base;
+ p_dev->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ p_dev->io.Attributes2 = p_dev->io.Attributes1;
+ p_dev->io.BasePort2 = io->win[1].base;
+ p_dev->io.NumPorts2 = io->win[1].len;
+ }
+ /* This reserves IO space but doesn't actually enable it */
+ return pcmcia_request_io(p_dev, &p_dev->io);
+ }
+ return 0;
+}
+
+
/*======================================================================
das08_pcmcia_config() is scheduled to run after a CARD_INSERTION event
@@ -248,128 +266,20 @@ static void das08_pcmcia_detach(struct pcmcia_device *link)
static void das08_pcmcia_config(struct pcmcia_device *link)
{
struct local_info_t *dev = link->priv;
- tuple_t tuple;
- cisparse_t parse;
- int last_fn, last_ret;
- u_char buf[64];
- cistpl_cftable_entry_t dflt = { 0 };
-
- DEBUG(0, "das08_pcmcia_config(0x%p)\n", link);
-
- /*
- This reads the card's CONFIG tuple to find its configuration
- registers.
- */
- tuple.DesiredTuple = CISTPL_CONFIG;
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
- last_fn = GetFirstTuple;
-
- last_ret = pcmcia_get_first_tuple(link, &tuple);
- if (last_ret)
- goto cs_failed;
-
- last_fn = GetTupleData;
-
- last_ret = pcmcia_get_tuple_data(link, &tuple);
- if (last_ret)
- goto cs_failed;
-
- last_fn = ParseTuple;
-
- last_ret = pcmcia_parse_tuple(&tuple, &parse);
- if (last_ret)
- goto cs_failed;
-
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
-
- /*
- In this loop, we scan the CIS for configuration table entries,
- each of which describes a valid card configuration, including
- voltage, IO window, memory window, and interrupt settings.
-
- We make no assumptions about the card to be configured: we use
- just the information available in the CIS. In an ideal world,
- this would work for any PCMCIA card, but it requires a complete
- and accurate CIS. In practice, a driver usually "knows" most of
- these things without consulting the CIS, and most client drivers
- will only use the CIS to fill in implementation-defined details.
- */
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- last_fn = GetFirstTuple;
-
- last_ret = pcmcia_get_first_tuple(link, &tuple);
- if (last_ret)
- goto cs_failed;
-
- while (1) {
- cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
-
- last_ret = pcmcia_get_tuple_data(link, &tuple);
- if (last_ret)
- goto next_entry;
-
- last_ret = pcmcia_parse_tuple(&tuple, &parse);
- if (last_ret)
- goto next_entry;
-
- if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
- dflt = *cfg;
- if (cfg->index == 0)
- goto next_entry;
- link->conf.ConfigIndex = cfg->index;
-
- /* Does this card need audio output? */
-/* if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
- link->conf.Attributes |= CONF_ENABLE_SPKR;
- link->conf.Status = CCSR_AUDIO_ENA;
- }
-*/
- /* Do we need to allocate an interrupt? */
- if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
- link->conf.Attributes |= CONF_ENABLE_IRQ;
-
- /* IO window settings */
- link->io.NumPorts1 = link->io.NumPorts2 = 0;
- if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
- cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- if (!(io->flags & CISTPL_IO_8BIT))
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
- if (!(io->flags & CISTPL_IO_16BIT))
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
- link->io.BasePort1 = io->win[0].base;
- link->io.NumPorts1 = io->win[0].len;
- if (io->nwin > 1) {
- link->io.Attributes2 = link->io.Attributes1;
- link->io.BasePort2 = io->win[1].base;
- link->io.NumPorts2 = io->win[1].len;
- }
- /* This reserves IO space but doesn't actually enable it */
- if (pcmcia_request_io(link, &link->io) != 0)
- goto next_entry;
- }
-
- /* If we got this far, we're cool! */
- break;
+ int ret;
-next_entry:
- last_fn = GetNextTuple;
+ dev_dbg(&link->dev, "das08_pcmcia_config\n");
- last_ret = pcmcia_get_next_tuple(link, &tuple);
- if (last_ret)
- goto cs_failed;
+ ret = pcmcia_loop_config(link, das08_pcmcia_config_loop, NULL);
+ if (ret) {
+ dev_warn(&link->dev, "no configuration found\n");
+ goto failed;
}
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
- last_fn = RequestIRQ;
- last_ret = pcmcia_request_irq(link, &link->irq);
- if (last_ret)
- goto cs_failed;
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret)
+ goto failed;
}
/*
@@ -377,10 +287,9 @@ next_entry:
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
- last_fn = RequestConfiguration;
- last_ret = pcmcia_request_configuration(link, &link->conf);
- if (last_ret)
- goto cs_failed;
+ ret = pcmcia_request_configuration(link, &link->conf);
+ if (ret)
+ goto failed;
/*
At this point, the dev_node_t structure(s) need to be
@@ -405,8 +314,7 @@ next_entry:
return;
-cs_failed:
- cs_error(link, last_fn, last_ret);
+failed:
das08_pcmcia_release(link);
} /* das08_pcmcia_config */
@@ -421,7 +329,7 @@ cs_failed:
static void das08_pcmcia_release(struct pcmcia_device *link)
{
- DEBUG(0, "das08_pcmcia_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "das08_pcmcia_release\n");
pcmcia_disable_device(link);
} /* das08_pcmcia_release */
@@ -477,14 +385,13 @@ struct pcmcia_driver das08_cs_driver = {
static int __init init_das08_pcmcia_cs(void)
{
- DEBUG(0, "%s\n", version);
pcmcia_register_driver(&das08_cs_driver);
return 0;
}
static void __exit exit_das08_pcmcia_cs(void)
{
- DEBUG(0, "das08_pcmcia_cs: unloading\n");
+ pr_debug("das08_pcmcia_cs: unloading\n");
pcmcia_unregister_driver(&das08_cs_driver);
}