pcmcia: insert PCMCIA device resources into resource tree
authorDominik Brodowski <linux@dominikbrodowski.net>
Sun, 25 Jul 2010 11:10:22 +0000 (13:10 +0200)
committerDominik Brodowski <linux@dominikbrodowski.net>
Tue, 3 Aug 2010 07:04:19 +0000 (09:04 +0200)
Insert PCMCIA device resources into the resource tree. However, this is
currently only implemented for sockets which do not statically map the
resources.

Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
drivers/pcmcia/cs_internal.h
drivers/pcmcia/ds.c
drivers/pcmcia/pcmcia_resource.c
drivers/pcmcia/rsrc_iodyn.c
drivers/pcmcia/rsrc_mgr.c
drivers/pcmcia/rsrc_nonstatic.c

index 37d38b5..da055dc 100644 (file)
@@ -62,7 +62,8 @@ struct pccard_resource_ops {
                                         unsigned int attr,
                                         unsigned int *base,
                                         unsigned int num,
-                                        unsigned int align);
+                                        unsigned int align,
+                                        struct resource **parent);
        struct resource* (*find_mem)    (unsigned long base, unsigned long num,
                                         unsigned long align, int low,
                                         struct pcmcia_socket *s);
index 028c973..55570d9 100644 (file)
@@ -553,11 +553,11 @@ static struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s,
                p_dev->function_config = c;
                kref_init(&c->ref);
                for (i = 0; i < MAX_IO_WIN; i++) {
-                       c->io[i].name = dev_name(&p_dev->dev);
+                       c->io[i].name = p_dev->devname;
                        c->io[i].flags = IORESOURCE_IO;
                }
                for (i = 0; i< MAX_WIN; i++) {
-                       c->mem[i].name = dev_name(&p_dev->dev);
+                       c->mem[i].name = p_dev->devname;
                        c->mem[i].flags = IORESOURCE_MEM;
                }
        }
index 01f8e56..d48437f 100644 (file)
@@ -56,6 +56,33 @@ struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,
 }
 
 
+static void release_io_space(struct pcmcia_socket *s, struct resource *res)
+{
+       resource_size_t num = resource_size(res);
+       int i;
+
+       dev_dbg(&s->dev, "release_io_space for %pR\n", res);
+
+       for (i = 0; i < MAX_IO_WIN; i++) {
+               if (!s->io[i].res)
+                       continue;
+               if ((s->io[i].res->start <= res->start) &&
+                   (s->io[i].res->end >= res->end)) {
+                       s->io[i].InUse -= num;
+                       if (res->parent)
+                               release_resource(res);
+                       res->start = res->end = 0;
+                       res->flags = IORESOURCE_IO;
+                       /* Free the window if no one else is using it */
+                       if (s->io[i].InUse == 0) {
+                               release_resource(s->io[i].res);
+                               kfree(s->io[i].res);
+                               s->io[i].res = NULL;
+                       }
+               }
+       }
+} /* release_io_space */
+
 /** alloc_io_space
  *
  * Special stuff for managing IO windows, because they are scarce
@@ -87,43 +114,28 @@ static int alloc_io_space(struct pcmcia_socket *s, struct resource *res,
                align = 0;
        }
 
-       ret = s->resource_ops->find_io(s, res->flags, &base, num, align);
+       ret = s->resource_ops->find_io(s, res->flags, &base, num, align,
+                               &res->parent);
        if (ret) {
-               dev_dbg(&s->dev, "alloc_io_space request returned %d", ret);
+               dev_dbg(&s->dev, "alloc_io_space request failed (%d)\n", ret);
                return -EINVAL;
        }
 
        res->start = base;
        res->end = res->start + num - 1;
-       dev_dbg(&s->dev, "alloc_io_space request returned %pR, %d\n", res, ret);
-       return 0;
-} /* alloc_io_space */
 
-
-static void release_io_space(struct pcmcia_socket *s, struct resource *res)
-{
-       resource_size_t num = resource_size(res);
-       int i;
-
-       dev_dbg(&s->dev, "release_io_space for %pR\n", res);
-
-       for (i = 0; i < MAX_IO_WIN; i++) {
-               if (!s->io[i].res)
-                       continue;
-               if ((s->io[i].res->start <= res->start) &&
-                   (s->io[i].res->end >= res->end)) {
-                       s->io[i].InUse -= num;
-                       res->start = res->end = 0;
-                       res->flags = IORESOURCE_IO;
-                       /* Free the window if no one else is using it */
-                       if (s->io[i].InUse == 0) {
-                               release_resource(s->io[i].res);
-                               kfree(s->io[i].res);
-                               s->io[i].res = NULL;
-                       }
+       if (res->parent) {
+               ret = request_resource(res->parent, res);
+               if (ret) {
+                       dev_warn(&s->dev,
+                               "request_resource %pR failed: %d\n", res, ret);
+                       res->parent = NULL;
+                       release_io_space(s, res);
                }
        }
-} /* release_io_space */
+       dev_dbg(&s->dev, "alloc_io_space request result %d: %pR\n", ret, res);
+       return ret;
+} /* alloc_io_space */
 
 
 /**
@@ -401,6 +413,7 @@ int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res)
 
        /* Release system memory */
        if (win->res) {
+               release_resource(res);
                release_resource(win->res);
                kfree(win->res);
                win->res = NULL;
@@ -853,6 +866,11 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
        res->end = req->Base + req->Size - 1;
        res->flags &= ~IORESOURCE_BITS;
        res->flags |= (req->Attributes & WIN_FLAGS_MAP) | (win->map << 2);
+       res->flags |= IORESOURCE_MEM;
+       res->parent = win->res;
+       if (win->res)
+               request_resource(&iomem_resource, res);
+
        dev_dbg(&s->dev, "request_window results in %pR\n", res);
 
        mutex_unlock(&s->ops_mutex);
index 3b1dce2..8510c35 100644 (file)
@@ -87,7 +87,7 @@ static struct resource *__iodyn_find_io_region(struct pcmcia_socket *s,
 
 static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr,
                        unsigned int *base, unsigned int num,
-                       unsigned int align)
+                       unsigned int align, struct resource **parent)
 {
        int i, ret = 0;
 
@@ -128,6 +128,7 @@ static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr,
                                ((res->flags & ~IORESOURCE_BITS) |
                                        (attr & IORESOURCE_BITS));
                        s->io[i].InUse = num;
+                       *parent = res;
                        return 0;
                }
 
@@ -139,6 +140,7 @@ static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr,
                                continue;
                        *base = try;
                        s->io[i].InUse += num;
+                       *parent = res;
                        return 0;
                }
 
@@ -151,6 +153,7 @@ static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr,
                                continue;
                        *base = try;
                        s->io[i].InUse += num;
+                       *parent = res;
                        return 0;
                }
        }
index b433a79..4e80421 100644 (file)
@@ -47,11 +47,12 @@ struct resource *pcmcia_make_resource(unsigned long start, unsigned long end,
 
 static int static_find_io(struct pcmcia_socket *s, unsigned int attr,
                        unsigned int *base, unsigned int num,
-                       unsigned int align)
+                       unsigned int align, struct resource **parent)
 {
        if (!s->io_offset)
                return -EINVAL;
        *base = s->io_offset | (*base & 0x0fff);
+       *parent = NULL;
 
        return 0;
 }
index c17a17d..96f348b 100644 (file)
@@ -718,7 +718,7 @@ static struct resource *__nonstatic_find_io_region(struct pcmcia_socket *s,
 
 static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
                        unsigned int *base, unsigned int num,
-                       unsigned int align)
+                       unsigned int align, struct resource **parent)
 {
        int i, ret = 0;
 
@@ -760,6 +760,7 @@ static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
                                ((res->flags & ~IORESOURCE_BITS) |
                                        (attr & IORESOURCE_BITS));
                        s->io[i].InUse = num;
+                       *parent = res;
                        return 0;
                }
 
@@ -775,6 +776,7 @@ static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
                                        continue;
                                *base = try;
                                s->io[i].InUse += num;
+                               *parent = res;
                                return 0;
                        }
                }
@@ -793,6 +795,7 @@ static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
                                        continue;
                                *base = try;
                                s->io[i].InUse += num;
+                               *parent = res;
                                return 0;
                        }
                }