Commit 0ca724d37af370dbf2d55dc4d6359ead558e5756
1 parent
b5cb259e7f
Exists in
master
and in
4 other branches
pcmcia: use struct resource for PCMCIA devices, part 2
Use struct resource * also for iomem resources. CC: linux-mtd@lists.infradead.org CC: netdev@vger.kernel.org CC: linux-wireless@vger.kernel.org CC: Jiri Kosina <jkosina@suse.cz> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Showing 10 changed files with 75 additions and 78 deletions Side-by-side Diff
drivers/char/pcmcia/ipwireless/main.c
... | ... | @@ -157,15 +157,12 @@ |
157 | 157 | return 0; |
158 | 158 | |
159 | 159 | exit3: |
160 | - pcmcia_release_window(p_dev, ipw->handle_attr_memory); | |
161 | 160 | exit2: |
162 | 161 | if (ipw->common_memory) { |
163 | 162 | release_mem_region(ipw->request_common_memory.Base, |
164 | 163 | ipw->request_common_memory.Size); |
165 | 164 | iounmap(ipw->common_memory); |
166 | - pcmcia_release_window(p_dev, ipw->handle_common_memory); | |
167 | - } else | |
168 | - pcmcia_release_window(p_dev, ipw->handle_common_memory); | |
165 | + } | |
169 | 166 | exit1: |
170 | 167 | release_resource(io_resource); |
171 | 168 | pcmcia_disable_device(p_dev); |
172 | 169 | |
... | ... | @@ -238,13 +235,12 @@ |
238 | 235 | release_mem_region(ipw->request_attr_memory.Base, |
239 | 236 | ipw->request_attr_memory.Size); |
240 | 237 | iounmap(ipw->attr_memory); |
241 | - pcmcia_release_window(link, ipw->handle_attr_memory); | |
238 | + | |
242 | 239 | } |
243 | 240 | if (ipw->common_memory) { |
244 | 241 | release_mem_region(ipw->request_common_memory.Base, |
245 | 242 | ipw->request_common_memory.Size); |
246 | 243 | iounmap(ipw->common_memory); |
247 | - pcmcia_release_window(link, ipw->handle_common_memory); | |
248 | 244 | } |
249 | 245 | pcmcia_disable_device(link); |
250 | 246 | return -1; |
... | ... | @@ -262,11 +258,6 @@ |
262 | 258 | ipw->request_attr_memory.Size); |
263 | 259 | iounmap(ipw->attr_memory); |
264 | 260 | } |
265 | - if (ipw->common_memory) | |
266 | - pcmcia_release_window(ipw->link, ipw->handle_common_memory); | |
267 | - if (ipw->attr_memory) | |
268 | - pcmcia_release_window(ipw->link, ipw->handle_attr_memory); | |
269 | - | |
270 | 261 | pcmcia_disable_device(ipw->link); |
271 | 262 | } |
272 | 263 |
drivers/mtd/maps/pcmciamtd.c
drivers/net/pcmcia/ibmtr_cs.c
drivers/net/wireless/b43/pcmcia.c
... | ... | @@ -76,8 +76,7 @@ |
76 | 76 | dev->conf.Attributes = CONF_ENABLE_IRQ; |
77 | 77 | dev->conf.IntType = INT_MEMORY_AND_IO; |
78 | 78 | |
79 | - win.Attributes = WIN_ADDR_SPACE_MEM | WIN_MEMORY_TYPE_CM | | |
80 | - WIN_ENABLE | WIN_DATA_WIDTH_16 | | |
79 | + win.Attributes = WIN_ENABLE | WIN_DATA_WIDTH_16 | | |
81 | 80 | WIN_USE_WAIT; |
82 | 81 | win.Base = 0; |
83 | 82 | win.Size = SSB_CORE_SIZE; |
drivers/net/wireless/ray_cs.c
... | ... | @@ -785,7 +785,6 @@ |
785 | 785 | { |
786 | 786 | struct net_device *dev = link->priv; |
787 | 787 | ray_dev_t *local = netdev_priv(dev); |
788 | - int i; | |
789 | 788 | |
790 | 789 | dev_dbg(&link->dev, "ray_release\n"); |
791 | 790 | |
... | ... | @@ -794,13 +793,6 @@ |
794 | 793 | iounmap(local->sram); |
795 | 794 | iounmap(local->rmem); |
796 | 795 | iounmap(local->amem); |
797 | - /* Do bother checking to see if these succeed or not */ | |
798 | - i = pcmcia_release_window(link, local->amem_handle); | |
799 | - if (i != 0) | |
800 | - dev_dbg(&link->dev, "ReleaseWindow(local->amem) ret = %x\n", i); | |
801 | - i = pcmcia_release_window(link, local->rmem_handle); | |
802 | - if (i != 0) | |
803 | - dev_dbg(&link->dev, "ReleaseWindow(local->rmem) ret = %x\n", i); | |
804 | 796 | pcmcia_disable_device(link); |
805 | 797 | |
806 | 798 | dev_dbg(&link->dev, "ray_release ending\n"); |
drivers/pcmcia/cs_internal.h
drivers/pcmcia/ds.c
... | ... | @@ -556,9 +556,15 @@ |
556 | 556 | c->io[i].name = dev_name(&p_dev->dev); |
557 | 557 | c->io[i].flags = IORESOURCE_IO; |
558 | 558 | } |
559 | + for (i = 0; i< MAX_WIN; i++) { | |
560 | + c->mem[i].name = dev_name(&p_dev->dev); | |
561 | + c->mem[i].flags = IORESOURCE_MEM; | |
562 | + } | |
559 | 563 | } |
560 | 564 | for (i = 0; i < MAX_IO_WIN; i++) |
561 | 565 | p_dev->resource[i] = &p_dev->function_config->io[i]; |
566 | + for (; i < (MAX_IO_WIN + MAX_WIN); i++) | |
567 | + p_dev->resource[i] = &p_dev->function_config->mem[i-MAX_IO_WIN]; | |
562 | 568 | |
563 | 569 | mutex_unlock(&s->ops_mutex); |
564 | 570 |
drivers/pcmcia/pcmcia_resource.c
... | ... | @@ -196,15 +196,17 @@ |
196 | 196 | unsigned int offset) |
197 | 197 | { |
198 | 198 | struct pcmcia_socket *s = p_dev->socket; |
199 | + struct resource *res = wh; | |
200 | + unsigned int w; | |
199 | 201 | int ret; |
200 | 202 | |
201 | - wh--; | |
202 | - if (wh >= MAX_WIN) | |
203 | + w = ((res->flags & IORESOURCE_BITS & WIN_FLAGS_REQ) >> 2) - 1; | |
204 | + if (w >= MAX_WIN) | |
203 | 205 | return -EINVAL; |
204 | 206 | |
205 | 207 | mutex_lock(&s->ops_mutex); |
206 | - s->win[wh].card_start = offset; | |
207 | - ret = s->ops->set_mem_map(s, &s->win[wh]); | |
208 | + s->win[w].card_start = offset; | |
209 | + ret = s->ops->set_mem_map(s, &s->win[w]); | |
208 | 210 | if (ret) |
209 | 211 | dev_warn(&s->dev, "failed to set_mem_map\n"); |
210 | 212 | mutex_unlock(&s->ops_mutex); |
211 | 213 | |
212 | 214 | |
213 | 215 | |
214 | 216 | |
... | ... | @@ -371,19 +373,22 @@ |
371 | 373 | } /* pcmcia_release_io */ |
372 | 374 | |
373 | 375 | |
374 | -int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh) | |
376 | +int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res) | |
375 | 377 | { |
376 | 378 | struct pcmcia_socket *s = p_dev->socket; |
377 | 379 | pccard_mem_map *win; |
380 | + unsigned int w; | |
378 | 381 | |
379 | - wh--; | |
380 | - if (wh >= MAX_WIN) | |
382 | + dev_dbg(&p_dev->dev, "releasing window %pR\n", res); | |
383 | + | |
384 | + w = ((res->flags & IORESOURCE_BITS & WIN_FLAGS_REQ) >> 2) - 1; | |
385 | + if (w >= MAX_WIN) | |
381 | 386 | return -EINVAL; |
382 | 387 | |
383 | 388 | mutex_lock(&s->ops_mutex); |
384 | - win = &s->win[wh]; | |
389 | + win = &s->win[w]; | |
385 | 390 | |
386 | - if (!(p_dev->_win & CLIENT_WIN_REQ(wh))) { | |
391 | + if (!(p_dev->_win & CLIENT_WIN_REQ(w))) { | |
387 | 392 | dev_dbg(&s->dev, "not releasing unknown window\n"); |
388 | 393 | mutex_unlock(&s->ops_mutex); |
389 | 394 | return -EINVAL; |
... | ... | @@ -392,7 +397,7 @@ |
392 | 397 | /* Shut down memory window */ |
393 | 398 | win->flags &= ~MAP_ACTIVE; |
394 | 399 | s->ops->set_mem_map(s, win); |
395 | - s->state &= ~SOCKET_WIN_REQ(wh); | |
400 | + s->state &= ~SOCKET_WIN_REQ(w); | |
396 | 401 | |
397 | 402 | /* Release system memory */ |
398 | 403 | if (win->res) { |
... | ... | @@ -400,7 +405,7 @@ |
400 | 405 | kfree(win->res); |
401 | 406 | win->res = NULL; |
402 | 407 | } |
403 | - p_dev->_win &= ~CLIENT_WIN_REQ(wh); | |
408 | + p_dev->_win &= ~CLIENT_WIN_REQ(w); | |
404 | 409 | mutex_unlock(&s->ops_mutex); |
405 | 410 | |
406 | 411 | return 0; |
407 | 412 | |
408 | 413 | |
... | ... | @@ -775,23 +780,18 @@ |
775 | 780 | struct pcmcia_socket *s = p_dev->socket; |
776 | 781 | pccard_mem_map *win; |
777 | 782 | u_long align; |
783 | + struct resource *res; | |
778 | 784 | int w; |
779 | 785 | |
780 | 786 | if (!(s->state & SOCKET_PRESENT)) { |
781 | 787 | dev_dbg(&s->dev, "No card present\n"); |
782 | 788 | return -ENODEV; |
783 | 789 | } |
784 | - if (req->Attributes & (WIN_PAGED | WIN_SHARED)) { | |
785 | - dev_dbg(&s->dev, "bad attribute setting for iomem region\n"); | |
786 | - return -EINVAL; | |
787 | - } | |
788 | 790 | |
789 | 791 | /* Window size defaults to smallest available */ |
790 | 792 | if (req->Size == 0) |
791 | 793 | req->Size = s->map_size; |
792 | - align = (((s->features & SS_CAP_MEM_ALIGN) || | |
793 | - (req->Attributes & WIN_STRICT_ALIGN)) ? | |
794 | - req->Size : s->map_size); | |
794 | + align = (s->features & SS_CAP_MEM_ALIGN) ? req->Size : s->map_size; | |
795 | 795 | if (req->Size & (s->map_size-1)) { |
796 | 796 | dev_dbg(&s->dev, "invalid map size\n"); |
797 | 797 | return -EINVAL; |
798 | 798 | |
799 | 799 | |
800 | 800 | |
... | ... | @@ -805,20 +805,21 @@ |
805 | 805 | align = 0; |
806 | 806 | |
807 | 807 | /* Allocate system memory window */ |
808 | + mutex_lock(&s->ops_mutex); | |
808 | 809 | for (w = 0; w < MAX_WIN; w++) |
809 | 810 | if (!(s->state & SOCKET_WIN_REQ(w))) |
810 | 811 | break; |
811 | 812 | if (w == MAX_WIN) { |
812 | 813 | dev_dbg(&s->dev, "all windows are used already\n"); |
814 | + mutex_unlock(&s->ops_mutex); | |
813 | 815 | return -EINVAL; |
814 | 816 | } |
815 | 817 | |
816 | - mutex_lock(&s->ops_mutex); | |
817 | 818 | win = &s->win[w]; |
818 | 819 | |
819 | 820 | if (!(s->features & SS_CAP_STATIC_MAP)) { |
820 | 821 | win->res = pcmcia_find_mem_region(req->Base, req->Size, align, |
821 | - (req->Attributes & WIN_MAP_BELOW_1MB), s); | |
822 | + 0, s); | |
822 | 823 | if (!win->res) { |
823 | 824 | dev_dbg(&s->dev, "allocating mem region failed\n"); |
824 | 825 | mutex_unlock(&s->ops_mutex); |
825 | 826 | |
... | ... | @@ -829,16 +830,8 @@ |
829 | 830 | |
830 | 831 | /* Configure the socket controller */ |
831 | 832 | win->map = w+1; |
832 | - win->flags = 0; | |
833 | + win->flags = req->Attributes; | |
833 | 834 | win->speed = req->AccessSpeed; |
834 | - if (req->Attributes & WIN_MEMORY_TYPE) | |
835 | - win->flags |= MAP_ATTRIB; | |
836 | - if (req->Attributes & WIN_ENABLE) | |
837 | - win->flags |= MAP_ACTIVE; | |
838 | - if (req->Attributes & WIN_DATA_WIDTH_16) | |
839 | - win->flags |= MAP_16BIT; | |
840 | - if (req->Attributes & WIN_USE_WAIT) | |
841 | - win->flags |= MAP_USE_WAIT; | |
842 | 835 | win->card_start = 0; |
843 | 836 | |
844 | 837 | if (s->ops->set_mem_map(s, win) != 0) { |
845 | 838 | |
... | ... | @@ -854,8 +847,16 @@ |
854 | 847 | else |
855 | 848 | req->Base = win->res->start; |
856 | 849 | |
850 | + /* convert to new-style resources */ | |
851 | + res = p_dev->resource[w + MAX_IO_WIN]; | |
852 | + res->start = req->Base; | |
853 | + res->end = req->Base + req->Size - 1; | |
854 | + res->flags &= ~IORESOURCE_BITS; | |
855 | + res->flags |= (req->Attributes & WIN_FLAGS_MAP) | (win->map << 2); | |
856 | + dev_dbg(&s->dev, "request_window results in %pR\n", res); | |
857 | + | |
857 | 858 | mutex_unlock(&s->ops_mutex); |
858 | - *wh = w + 1; | |
859 | + *wh = res; | |
859 | 860 | |
860 | 861 | return 0; |
861 | 862 | } /* pcmcia_request_window */ |
862 | 863 | |
... | ... | @@ -863,14 +864,19 @@ |
863 | 864 | |
864 | 865 | void pcmcia_disable_device(struct pcmcia_device *p_dev) |
865 | 866 | { |
867 | + int i; | |
868 | + for (i = 0; i < MAX_WIN; i++) { | |
869 | + struct resource *res = p_dev->resource[MAX_IO_WIN + i]; | |
870 | + if (res->flags & WIN_FLAGS_REQ) | |
871 | + pcmcia_release_window(p_dev, res); | |
872 | + } | |
873 | + | |
866 | 874 | pcmcia_release_configuration(p_dev); |
867 | 875 | pcmcia_release_io(p_dev); |
868 | 876 | if (p_dev->_irq) { |
869 | 877 | free_irq(p_dev->irq, p_dev->priv); |
870 | 878 | p_dev->_irq = 0; |
871 | 879 | } |
872 | - if (p_dev->win) | |
873 | - pcmcia_release_window(p_dev, p_dev->win); | |
874 | 880 | } |
875 | 881 | EXPORT_SYMBOL(pcmcia_disable_device); |
include/pcmcia/cs.h
... | ... | @@ -77,27 +77,20 @@ |
77 | 77 | } win_req_t; |
78 | 78 | |
79 | 79 | /* Attributes for RequestWindow */ |
80 | -#define WIN_ADDR_SPACE 0x0001 | |
81 | -#define WIN_ADDR_SPACE_MEM 0x0000 | |
82 | -#define WIN_ADDR_SPACE_IO 0x0001 | |
83 | -#define WIN_MEMORY_TYPE 0x0002 | |
84 | -#define WIN_MEMORY_TYPE_CM 0x0000 | |
85 | -#define WIN_MEMORY_TYPE_AM 0x0002 | |
86 | -#define WIN_ENABLE 0x0004 | |
87 | -#define WIN_DATA_WIDTH 0x0018 | |
88 | -#define WIN_DATA_WIDTH_8 0x0000 | |
89 | -#define WIN_DATA_WIDTH_16 0x0008 | |
90 | -#define WIN_DATA_WIDTH_32 0x0010 | |
91 | -#define WIN_PAGED 0x0020 | |
92 | -#define WIN_SHARED 0x0040 | |
93 | -#define WIN_FIRST_SHARED 0x0080 | |
94 | -#define WIN_USE_WAIT 0x0100 | |
95 | -#define WIN_STRICT_ALIGN 0x0200 | |
96 | -#define WIN_MAP_BELOW_1MB 0x0400 | |
97 | -#define WIN_PREFETCH 0x0800 | |
98 | -#define WIN_CACHEABLE 0x1000 | |
99 | -#define WIN_BAR_MASK 0xe000 | |
100 | -#define WIN_BAR_SHIFT 13 | |
80 | +#define WIN_MEMORY_TYPE_CM 0x00 /* default */ | |
81 | +#define WIN_MEMORY_TYPE_AM 0x20 /* MAP_ATTRIB */ | |
82 | +#define WIN_DATA_WIDTH_8 0x00 /* default */ | |
83 | +#define WIN_DATA_WIDTH_16 0x02 /* MAP_16BIT */ | |
84 | +#define WIN_ENABLE 0x01 /* MAP_ACTIVE */ | |
85 | +#define WIN_USE_WAIT 0x40 /* MAP_USE_WAIT */ | |
86 | + | |
87 | +#define WIN_FLAGS_MAP 0x63 /* MAP_ATTRIB | MAP_16BIT | MAP_ACTIVE | | |
88 | + MAP_USE_WAIT */ | |
89 | +#define WIN_FLAGS_REQ 0x1c /* mapping to socket->win[i]: | |
90 | + 0x04 -> 0 | |
91 | + 0x08 -> 1 | |
92 | + 0x0c -> 2 | |
93 | + 0x10 -> 3 */ | |
101 | 94 | |
102 | 95 | #endif /* _LINUX_CS_H */ |
include/pcmcia/ds.h
... | ... | @@ -36,7 +36,7 @@ |
36 | 36 | struct config_t; |
37 | 37 | struct net_device; |
38 | 38 | |
39 | -typedef unsigned long window_handle_t; | |
39 | +typedef struct resource *window_handle_t; | |
40 | 40 | |
41 | 41 | /* dynamic device IDs for PCMCIA device drivers. See |
42 | 42 | * Documentation/pcmcia/driver.txt for details. |
... | ... | @@ -63,6 +63,17 @@ |
63 | 63 | int pcmcia_register_driver(struct pcmcia_driver *driver); |
64 | 64 | void pcmcia_unregister_driver(struct pcmcia_driver *driver); |
65 | 65 | |
66 | +/* for struct resource * array embedded in struct pcmcia_device */ | |
67 | +enum { | |
68 | + PCMCIA_IOPORT_0, | |
69 | + PCMCIA_IOPORT_1, | |
70 | + PCMCIA_IOMEM_0, | |
71 | + PCMCIA_IOMEM_1, | |
72 | + PCMCIA_IOMEM_2, | |
73 | + PCMCIA_IOMEM_3, | |
74 | + PCMCIA_NUM_RESOURCES, | |
75 | +}; | |
76 | + | |
66 | 77 | struct pcmcia_device { |
67 | 78 | /* the socket and the device_no [for multifunction devices] |
68 | 79 | uniquely define a pcmcia_device */ |
... | ... | @@ -85,7 +96,7 @@ |
85 | 96 | |
86 | 97 | /* device setup */ |
87 | 98 | unsigned int irq; |
88 | - struct resource *resource[MAX_IO_WIN]; | |
99 | + struct resource *resource[PCMCIA_NUM_RESOURCES]; | |
89 | 100 | |
90 | 101 | unsigned int io_lines; /* number of I/O lines */ |
91 | 102 |