aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/pcmcia_resource.c
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/pcmcia_resource.c
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/pcmcia_resource.c')
-rw-r--r--drivers/pcmcia/pcmcia_resource.c74
1 files changed, 46 insertions, 28 deletions
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);