pcmcia: introduce autoconfiguration feature
[linux-2.6.git] / drivers / isdn / hisax / sedlbauer_cs.c
index 7778385..b69eccf 100644 (file)
@@ -46,8 +46,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
 #include <pcmcia/ds.h>
@@ -87,32 +85,8 @@ static void sedlbauer_release(struct pcmcia_device *link);
 
 static void sedlbauer_detach(struct pcmcia_device *p_dev) __devexit;
 
-/*
-   You'll also need to prototype all the functions that will actually
-   be used to talk to your device.  See 'memory_cs' for a good example
-   of a fully self-sufficient driver; the other drivers rely more or
-   less on other parts of the kernel.
-*/
-
-/*
-   A driver needs to provide a dev_node_t structure for each device
-   on a card.  In some cases, there is only one device per card (for
-   example, ethernet cards, modems).  In other cases, there may be
-   many actual or logical devices (SCSI adapters, memory cards with
-   multiple partitions).  The dev_node_t structures need to be kept
-   in a linked list starting at the 'dev' field of a struct pcmcia_device
-   structure.  We allocate them in the card's private data structure,
-   because they generally shouldn't be allocated dynamically.
-
-   In this case, we also provide a flag to indicate if a device is
-   "stopped" due to a power management event, or card ejection.  The
-   device IO routines can use a flag like this to throttle IO to a
-   card that is not ready to accept it.
-*/
-   
 typedef struct local_info_t {
        struct pcmcia_device    *p_dev;
-    dev_node_t         node;
     int                        stop;
     int                        cardnr;
 } local_info_t;
@@ -154,12 +128,8 @@ static int __devinit sedlbauer_probe(struct pcmcia_device *link)
     /* from old sedl_cs 
     */
     /* The io structure describes IO port mapping */
-    link->io.NumPorts1 = 8;
-    link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-    link->io.IOAddrLines = 3;
-
-    link->conf.Attributes = 0;
-    link->conf.IntType = INT_MEMORY_AND_IO;
+    link->resource[0]->end = 8;
+    link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
 
     return sedlbauer_config(link);
 } /* sedlbauer_attach */
@@ -194,84 +164,31 @@ static void __devexit sedlbauer_detach(struct pcmcia_device *link)
 static int sedlbauer_config_check(struct pcmcia_device *p_dev,
                                  cistpl_cftable_entry_t *cfg,
                                  cistpl_cftable_entry_t *dflt,
-                                 unsigned int vcc,
                                  void *priv_data)
 {
-       win_req_t *req = priv_data;
-
        if (cfg->index == 0)
                return -ENODEV;
 
-       /* Does this card need audio output? */
-       if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
-               p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
-               p_dev->conf.Status = CCSR_AUDIO_ENA;
-       }
-
-       /* Use power settings for Vcc and Vpp if present */
-       /*  Note that the CIS values need to be rescaled */
-       if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
-               if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000)
-                       return -ENODEV;
-       } else if (dflt->vcc.present & (1<<CISTPL_POWER_VNOM)) {
-               if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM]/10000)
-                       return -ENODEV;
-       }
-
-       if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
-               p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
-       else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
-               p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
-
-       p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
-
        /* IO window settings */
-       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+       p_dev->resource[0]->end = p_dev->resource[1]->end = 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.BasePort1 = io->win[0].base;
-               p_dev->io.NumPorts1 = io->win[0].len;
+               p_dev->resource[0]->start = io->win[0].base;
+               p_dev->resource[0]->end = io->win[0].len;
+               p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+               p_dev->resource[0]->flags |=
+                                       pcmcia_io_cfg_data_width(io->flags);
                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;
+                       p_dev->resource[1]->flags = p_dev->resource[0]->flags;
+                       p_dev->resource[1]->start = io->win[1].base;
+                       p_dev->resource[1]->end = io->win[1].len;
                }
                /* This reserves IO space but doesn't actually enable it */
-               if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+               p_dev->io_lines = 3;
+               if (pcmcia_request_io(p_dev) != 0)
                        return -ENODEV;
        }
 
-       /*
-         Now set up a common memory window, if needed.  There is room
-         in the struct pcmcia_device structure for one memory window handle,
-         but if the base addresses need to be saved, or if multiple
-         windows are needed, the info should go in the private data
-         structure for this device.
-
-         Note that the memory window base is a physical address, and
-         needs to be mapped to virtual space with ioremap() before it
-         is used.
-       */
-       if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
-               cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
-               memreq_t map;
-               req->Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
-               req->Attributes |= WIN_ENABLE;
-               req->Base = mem->win[0].host_addr;
-               req->Size = mem->win[0].len;
-               req->AccessSpeed = 0;
-               if (pcmcia_request_window(p_dev, req, &p_dev->win) != 0)
-                       return -ENODEV;
-               map.Page = 0;
-               map.CardOffset = mem->win[0].card_addr;
-               if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0)
-                       return -ENODEV;
-       }
        return 0;
 }
 
@@ -279,16 +196,13 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev,
 
 static int __devinit sedlbauer_config(struct pcmcia_device *link)
 {
-    local_info_t *dev = link->priv;
-    win_req_t *req;
     int ret;
     IsdnCard_t  icard;
 
     dev_dbg(&link->dev, "sedlbauer_config(0x%p)\n", link);
 
-    req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
-    if (!req)
-           return -ENOMEM;
+    link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_CHECK_VCC |
+           CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO;
 
     /*
       In this loop, we scan the CIS for configuration table entries,
@@ -302,7 +216,7 @@ static int __devinit sedlbauer_config(struct pcmcia_device *link)
       these things without consulting the CIS, and most client drivers
       will only use the CIS to fill in implementation-defined details.
     */
-    ret = pcmcia_loop_config(link, sedlbauer_config_check, req);
+    ret = pcmcia_loop_config(link, sedlbauer_config_check, NULL);
     if (ret)
            goto failed;
 
@@ -311,46 +225,32 @@ static int __devinit sedlbauer_config(struct pcmcia_device *link)
        the I/O windows and the interrupt mapping, and putting the
        card and host interface into "Memory and IO" mode.
     */
-    ret = pcmcia_request_configuration(link, &link->conf);
+    ret = pcmcia_enable_device(link);
     if (ret)
            goto failed;
 
-    /*
-      At this point, the dev_node_t structure(s) need to be
-      initialized and arranged in a linked list at link->dev.
-    */
-    sprintf(dev->node.dev_name, "sedlbauer");
-    dev->node.major = dev->node.minor = 0;
-    link->dev_node = &dev->node;
-
     /* Finally, report what we've done */
-    printk(KERN_INFO "%s: index 0x%02x:",
-          dev->node.dev_name, link->conf.ConfigIndex);
-    if (link->conf.Vpp)
-       printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
-    if (link->conf.Attributes & CONF_ENABLE_IRQ)
-       printk(", irq %d", link->irq);
-    if (link->io.NumPorts1)
-       printk(", io 0x%04x-0x%04x", link->io.BasePort1,
-              link->io.BasePort1+link->io.NumPorts1-1);
-    if (link->io.NumPorts2)
-       printk(" & 0x%04x-0x%04x", link->io.BasePort2,
-              link->io.BasePort2+link->io.NumPorts2-1);
-    if (link->win)
-       printk(", mem 0x%06lx-0x%06lx", req->Base,
-              req->Base+req->Size-1);
+    dev_info(&link->dev, "index 0x%02x:",
+          link->config_index);
+    if (link->vpp)
+       printk(", Vpp %d.%d", link->vpp/10, link->vpp%10);
+    printk(", irq %d", link->irq);
+    if (link->resource[0])
+       printk(" & %pR", link->resource[0]);
+    if (link->resource[1])
+       printk(" & %pR", link->resource[1]);
     printk("\n");
 
     icard.para[0] = link->irq;
-    icard.para[1] = link->io.BasePort1;
+    icard.para[1] = link->resource[0]->start;
     icard.protocol = protocol;
     icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA;
     
     ret = hisax_init_pcmcia(link, 
                            &(((local_info_t *)link->priv)->stop), &icard);
     if (ret < 0) {
-       printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n",
-               ret, link->io.BasePort1);
+       printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d with %pR\n",
+               ret, link->resource[0]);
        sedlbauer_release(link);
        return -ENODEV;
     } else