aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2010-07-25 07:10:22 -0400
committerDominik Brodowski <linux@dominikbrodowski.net>2010-08-03 03:04:19 -0400
commitad0c7be28bc7593da43f494f6d074767ea96ca59 (patch)
tree31db0dd8238bfb075e5d7b3adade482e24e5e352 /drivers/pcmcia
parent8f677ea07a2a934ac74ffa57db0f5617aec15ddf (diff)
pcmcia: insert PCMCIA device resources into resource tree
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>
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r--drivers/pcmcia/cs_internal.h3
-rw-r--r--drivers/pcmcia/ds.c4
-rw-r--r--drivers/pcmcia/pcmcia_resource.c74
-rw-r--r--drivers/pcmcia/rsrc_iodyn.c5
-rw-r--r--drivers/pcmcia/rsrc_mgr.c3
-rw-r--r--drivers/pcmcia/rsrc_nonstatic.c5
6 files changed, 60 insertions, 34 deletions
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index 37d38b5a1972..da055dc14d98 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -62,7 +62,8 @@ struct pccard_resource_ops {
62 unsigned int attr, 62 unsigned int attr,
63 unsigned int *base, 63 unsigned int *base,
64 unsigned int num, 64 unsigned int num,
65 unsigned int align); 65 unsigned int align,
66 struct resource **parent);
66 struct resource* (*find_mem) (unsigned long base, unsigned long num, 67 struct resource* (*find_mem) (unsigned long base, unsigned long num,
67 unsigned long align, int low, 68 unsigned long align, int low,
68 struct pcmcia_socket *s); 69 struct pcmcia_socket *s);
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 028c97353b92..55570d9e1e4c 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -553,11 +553,11 @@ static struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s,
553 p_dev->function_config = c; 553 p_dev->function_config = c;
554 kref_init(&c->ref); 554 kref_init(&c->ref);
555 for (i = 0; i < MAX_IO_WIN; i++) { 555 for (i = 0; i < MAX_IO_WIN; i++) {
556 c->io[i].name = dev_name(&p_dev->dev); 556 c->io[i].name = p_dev->devname;
557 c->io[i].flags = IORESOURCE_IO; 557 c->io[i].flags = IORESOURCE_IO;
558 } 558 }
559 for (i = 0; i< MAX_WIN; i++) { 559 for (i = 0; i< MAX_WIN; i++) {
560 c->mem[i].name = dev_name(&p_dev->dev); 560 c->mem[i].name = p_dev->devname;
561 c->mem[i].flags = IORESOURCE_MEM; 561 c->mem[i].flags = IORESOURCE_MEM;
562 } 562 }
563 } 563 }
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index 01f8e56c8d2f..d48437f83acf 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -56,6 +56,33 @@ struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,
56} 56}
57 57
58 58
59static void release_io_space(struct pcmcia_socket *s, struct resource *res)
60{
61 resource_size_t num = resource_size(res);
62 int i;
63
64 dev_dbg(&s->dev, "release_io_space for %pR\n", res);
65
66 for (i = 0; i < MAX_IO_WIN; i++) {
67 if (!s->io[i].res)
68 continue;
69 if ((s->io[i].res->start <= res->start) &&
70 (s->io[i].res->end >= res->end)) {
71 s->io[i].InUse -= num;
72 if (res->parent)
73 release_resource(res);
74 res->start = res->end = 0;
75 res->flags = IORESOURCE_IO;
76 /* Free the window if no one else is using it */
77 if (s->io[i].InUse == 0) {
78 release_resource(s->io[i].res);
79 kfree(s->io[i].res);
80 s->io[i].res = NULL;
81 }
82 }
83 }
84} /* release_io_space */
85
59/** alloc_io_space 86/** alloc_io_space
60 * 87 *
61 * Special stuff for managing IO windows, because they are scarce 88 * 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,
87 align = 0; 114 align = 0;
88 } 115 }
89 116
90 ret = s->resource_ops->find_io(s, res->flags, &base, num, align); 117 ret = s->resource_ops->find_io(s, res->flags, &base, num, align,
118 &res->parent);
91 if (ret) { 119 if (ret) {
92 dev_dbg(&s->dev, "alloc_io_space request returned %d", ret); 120 dev_dbg(&s->dev, "alloc_io_space request failed (%d)\n", ret);
93 return -EINVAL; 121 return -EINVAL;
94 } 122 }
95 123
96 res->start = base; 124 res->start = base;
97 res->end = res->start + num - 1; 125 res->end = res->start + num - 1;
98 dev_dbg(&s->dev, "alloc_io_space request returned %pR, %d\n", res, ret);
99 return 0;
100} /* alloc_io_space */
101 126
102 127 if (res->parent) {
103static void release_io_space(struct pcmcia_socket *s, struct resource *res) 128 ret = request_resource(res->parent, res);
104{ 129 if (ret) {
105 resource_size_t num = resource_size(res); 130 dev_warn(&s->dev,
106 int i; 131 "request_resource %pR failed: %d\n", res, ret);
107 132 res->parent = NULL;
108 dev_dbg(&s->dev, "release_io_space for %pR\n", res); 133 release_io_space(s, res);
109
110 for (i = 0; i < MAX_IO_WIN; i++) {
111 if (!s->io[i].res)
112 continue;
113 if ((s->io[i].res->start <= res->start) &&
114 (s->io[i].res->end >= res->end)) {
115 s->io[i].InUse -= num;
116 res->start = res->end = 0;
117 res->flags = IORESOURCE_IO;
118 /* Free the window if no one else is using it */
119 if (s->io[i].InUse == 0) {
120 release_resource(s->io[i].res);
121 kfree(s->io[i].res);
122 s->io[i].res = NULL;
123 }
124 } 134 }
125 } 135 }
126} /* release_io_space */ 136 dev_dbg(&s->dev, "alloc_io_space request result %d: %pR\n", ret, res);
137 return ret;
138} /* alloc_io_space */
127 139
128 140
129/** 141/**
@@ -401,6 +413,7 @@ int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res)
401 413
402 /* Release system memory */ 414 /* Release system memory */
403 if (win->res) { 415 if (win->res) {
416 release_resource(res);
404 release_resource(win->res); 417 release_resource(win->res);
405 kfree(win->res); 418 kfree(win->res);
406 win->res = NULL; 419 win->res = NULL;
@@ -853,6 +866,11 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
853 res->end = req->Base + req->Size - 1; 866 res->end = req->Base + req->Size - 1;
854 res->flags &= ~IORESOURCE_BITS; 867 res->flags &= ~IORESOURCE_BITS;
855 res->flags |= (req->Attributes & WIN_FLAGS_MAP) | (win->map << 2); 868 res->flags |= (req->Attributes & WIN_FLAGS_MAP) | (win->map << 2);
869 res->flags |= IORESOURCE_MEM;
870 res->parent = win->res;
871 if (win->res)
872 request_resource(&iomem_resource, res);
873
856 dev_dbg(&s->dev, "request_window results in %pR\n", res); 874 dev_dbg(&s->dev, "request_window results in %pR\n", res);
857 875
858 mutex_unlock(&s->ops_mutex); 876 mutex_unlock(&s->ops_mutex);
diff --git a/drivers/pcmcia/rsrc_iodyn.c b/drivers/pcmcia/rsrc_iodyn.c
index 3b1dce2df26a..8510c35d2952 100644
--- a/drivers/pcmcia/rsrc_iodyn.c
+++ b/drivers/pcmcia/rsrc_iodyn.c
@@ -87,7 +87,7 @@ static struct resource *__iodyn_find_io_region(struct pcmcia_socket *s,
87 87
88static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr, 88static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr,
89 unsigned int *base, unsigned int num, 89 unsigned int *base, unsigned int num,
90 unsigned int align) 90 unsigned int align, struct resource **parent)
91{ 91{
92 int i, ret = 0; 92 int i, ret = 0;
93 93
@@ -128,6 +128,7 @@ static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr,
128 ((res->flags & ~IORESOURCE_BITS) | 128 ((res->flags & ~IORESOURCE_BITS) |
129 (attr & IORESOURCE_BITS)); 129 (attr & IORESOURCE_BITS));
130 s->io[i].InUse = num; 130 s->io[i].InUse = num;
131 *parent = res;
131 return 0; 132 return 0;
132 } 133 }
133 134
@@ -139,6 +140,7 @@ static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr,
139 continue; 140 continue;
140 *base = try; 141 *base = try;
141 s->io[i].InUse += num; 142 s->io[i].InUse += num;
143 *parent = res;
142 return 0; 144 return 0;
143 } 145 }
144 146
@@ -151,6 +153,7 @@ static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr,
151 continue; 153 continue;
152 *base = try; 154 *base = try;
153 s->io[i].InUse += num; 155 s->io[i].InUse += num;
156 *parent = res;
154 return 0; 157 return 0;
155 } 158 }
156 } 159 }
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
index b433a7995651..4e80421fd908 100644
--- a/drivers/pcmcia/rsrc_mgr.c
+++ b/drivers/pcmcia/rsrc_mgr.c
@@ -47,11 +47,12 @@ struct resource *pcmcia_make_resource(unsigned long start, unsigned long end,
47 47
48static int static_find_io(struct pcmcia_socket *s, unsigned int attr, 48static int static_find_io(struct pcmcia_socket *s, unsigned int attr,
49 unsigned int *base, unsigned int num, 49 unsigned int *base, unsigned int num,
50 unsigned int align) 50 unsigned int align, struct resource **parent)
51{ 51{
52 if (!s->io_offset) 52 if (!s->io_offset)
53 return -EINVAL; 53 return -EINVAL;
54 *base = s->io_offset | (*base & 0x0fff); 54 *base = s->io_offset | (*base & 0x0fff);
55 *parent = NULL;
55 56
56 return 0; 57 return 0;
57} 58}
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index c17a17d9f9b5..96f348b35fde 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -718,7 +718,7 @@ static struct resource *__nonstatic_find_io_region(struct pcmcia_socket *s,
718 718
719static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr, 719static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
720 unsigned int *base, unsigned int num, 720 unsigned int *base, unsigned int num,
721 unsigned int align) 721 unsigned int align, struct resource **parent)
722{ 722{
723 int i, ret = 0; 723 int i, ret = 0;
724 724
@@ -760,6 +760,7 @@ static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
760 ((res->flags & ~IORESOURCE_BITS) | 760 ((res->flags & ~IORESOURCE_BITS) |
761 (attr & IORESOURCE_BITS)); 761 (attr & IORESOURCE_BITS));
762 s->io[i].InUse = num; 762 s->io[i].InUse = num;
763 *parent = res;
763 return 0; 764 return 0;
764 } 765 }
765 766
@@ -775,6 +776,7 @@ static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
775 continue; 776 continue;
776 *base = try; 777 *base = try;
777 s->io[i].InUse += num; 778 s->io[i].InUse += num;
779 *parent = res;
778 return 0; 780 return 0;
779 } 781 }
780 } 782 }
@@ -793,6 +795,7 @@ static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
793 continue; 795 continue;
794 *base = try; 796 *base = try;
795 s->io[i].InUse += num; 797 s->io[i].InUse += num;
798 *parent = res;
796 return 0; 799 return 0;
797 } 800 }
798 } 801 }