aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/pcmcia_resource.c
diff options
context:
space:
mode:
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);