diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-07-24 13:03:02 -0400 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-08-03 03:04:16 -0400 |
commit | 0ca724d37af370dbf2d55dc4d6359ead558e5756 (patch) | |
tree | 994685118202d9bf54f11ec9b39a654f6fb4f21f /drivers/pcmcia | |
parent | b5cb259e7fac5536c4ddf350af6a3d6cc950e47e (diff) |
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>
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r-- | drivers/pcmcia/cs_internal.h | 1 | ||||
-rw-r--r-- | drivers/pcmcia/ds.c | 6 | ||||
-rw-r--r-- | drivers/pcmcia/pcmcia_resource.c | 70 |
3 files changed, 45 insertions, 32 deletions
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index 511ac753b9d9..37d38b5a1972 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h | |||
@@ -40,6 +40,7 @@ typedef struct config_t { | |||
40 | unsigned int CardValues; | 40 | unsigned int CardValues; |
41 | 41 | ||
42 | struct resource io[MAX_IO_WIN]; /* io ports */ | 42 | struct resource io[MAX_IO_WIN]; /* io ports */ |
43 | struct resource mem[MAX_WIN]; /* mem areas */ | ||
43 | 44 | ||
44 | struct { | 45 | struct { |
45 | u_int Attributes; | 46 | u_int Attributes; |
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 7ddd19a4033d..0bb780c3f263 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -556,9 +556,15 @@ static struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, | |||
556 | c->io[i].name = dev_name(&p_dev->dev); | 556 | c->io[i].name = dev_name(&p_dev->dev); |
557 | c->io[i].flags = IORESOURCE_IO; | 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 | for (i = 0; i < MAX_IO_WIN; i++) | 564 | for (i = 0; i < MAX_IO_WIN; i++) |
561 | p_dev->resource[i] = &p_dev->function_config->io[i]; | 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 | mutex_unlock(&s->ops_mutex); | 569 | mutex_unlock(&s->ops_mutex); |
564 | 570 | ||
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 975baaa8168b..01f8e56c8d2f 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c | |||
@@ -196,15 +196,17 @@ int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t wh, | |||
196 | unsigned int offset) | 196 | unsigned int offset) |
197 | { | 197 | { |
198 | struct pcmcia_socket *s = p_dev->socket; | 198 | struct pcmcia_socket *s = p_dev->socket; |
199 | struct resource *res = wh; | ||
200 | unsigned int w; | ||
199 | int ret; | 201 | int ret; |
200 | 202 | ||
201 | wh--; | 203 | w = ((res->flags & IORESOURCE_BITS & WIN_FLAGS_REQ) >> 2) - 1; |
202 | if (wh >= MAX_WIN) | 204 | if (w >= MAX_WIN) |
203 | return -EINVAL; | 205 | return -EINVAL; |
204 | 206 | ||
205 | mutex_lock(&s->ops_mutex); | 207 | mutex_lock(&s->ops_mutex); |
206 | s->win[wh].card_start = offset; | 208 | s->win[w].card_start = offset; |
207 | ret = s->ops->set_mem_map(s, &s->win[wh]); | 209 | ret = s->ops->set_mem_map(s, &s->win[w]); |
208 | if (ret) | 210 | if (ret) |
209 | dev_warn(&s->dev, "failed to set_mem_map\n"); | 211 | dev_warn(&s->dev, "failed to set_mem_map\n"); |
210 | mutex_unlock(&s->ops_mutex); | 212 | mutex_unlock(&s->ops_mutex); |
@@ -371,19 +373,22 @@ out: | |||
371 | } /* pcmcia_release_io */ | 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 | struct pcmcia_socket *s = p_dev->socket; | 378 | struct pcmcia_socket *s = p_dev->socket; |
377 | pccard_mem_map *win; | 379 | pccard_mem_map *win; |
380 | unsigned int w; | ||
378 | 381 | ||
379 | wh--; | 382 | dev_dbg(&p_dev->dev, "releasing window %pR\n", res); |
380 | if (wh >= MAX_WIN) | 383 | |
384 | w = ((res->flags & IORESOURCE_BITS & WIN_FLAGS_REQ) >> 2) - 1; | ||
385 | if (w >= MAX_WIN) | ||
381 | return -EINVAL; | 386 | return -EINVAL; |
382 | 387 | ||
383 | mutex_lock(&s->ops_mutex); | 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 | dev_dbg(&s->dev, "not releasing unknown window\n"); | 392 | dev_dbg(&s->dev, "not releasing unknown window\n"); |
388 | mutex_unlock(&s->ops_mutex); | 393 | mutex_unlock(&s->ops_mutex); |
389 | return -EINVAL; | 394 | return -EINVAL; |
@@ -392,7 +397,7 @@ int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh) | |||
392 | /* Shut down memory window */ | 397 | /* Shut down memory window */ |
393 | win->flags &= ~MAP_ACTIVE; | 398 | win->flags &= ~MAP_ACTIVE; |
394 | s->ops->set_mem_map(s, win); | 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 | /* Release system memory */ | 402 | /* Release system memory */ |
398 | if (win->res) { | 403 | if (win->res) { |
@@ -400,7 +405,7 @@ int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh) | |||
400 | kfree(win->res); | 405 | kfree(win->res); |
401 | win->res = NULL; | 406 | win->res = NULL; |
402 | } | 407 | } |
403 | p_dev->_win &= ~CLIENT_WIN_REQ(wh); | 408 | p_dev->_win &= ~CLIENT_WIN_REQ(w); |
404 | mutex_unlock(&s->ops_mutex); | 409 | mutex_unlock(&s->ops_mutex); |
405 | 410 | ||
406 | return 0; | 411 | return 0; |
@@ -775,23 +780,18 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
775 | struct pcmcia_socket *s = p_dev->socket; | 780 | struct pcmcia_socket *s = p_dev->socket; |
776 | pccard_mem_map *win; | 781 | pccard_mem_map *win; |
777 | u_long align; | 782 | u_long align; |
783 | struct resource *res; | ||
778 | int w; | 784 | int w; |
779 | 785 | ||
780 | if (!(s->state & SOCKET_PRESENT)) { | 786 | if (!(s->state & SOCKET_PRESENT)) { |
781 | dev_dbg(&s->dev, "No card present\n"); | 787 | dev_dbg(&s->dev, "No card present\n"); |
782 | return -ENODEV; | 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 | /* Window size defaults to smallest available */ | 791 | /* Window size defaults to smallest available */ |
790 | if (req->Size == 0) | 792 | if (req->Size == 0) |
791 | req->Size = s->map_size; | 793 | req->Size = s->map_size; |
792 | align = (((s->features & SS_CAP_MEM_ALIGN) || | 794 | align = (s->features & SS_CAP_MEM_ALIGN) ? req->Size : s->map_size; |
793 | (req->Attributes & WIN_STRICT_ALIGN)) ? | ||
794 | req->Size : s->map_size); | ||
795 | if (req->Size & (s->map_size-1)) { | 795 | if (req->Size & (s->map_size-1)) { |
796 | dev_dbg(&s->dev, "invalid map size\n"); | 796 | dev_dbg(&s->dev, "invalid map size\n"); |
797 | return -EINVAL; | 797 | return -EINVAL; |
@@ -805,20 +805,21 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
805 | align = 0; | 805 | align = 0; |
806 | 806 | ||
807 | /* Allocate system memory window */ | 807 | /* Allocate system memory window */ |
808 | mutex_lock(&s->ops_mutex); | ||
808 | for (w = 0; w < MAX_WIN; w++) | 809 | for (w = 0; w < MAX_WIN; w++) |
809 | if (!(s->state & SOCKET_WIN_REQ(w))) | 810 | if (!(s->state & SOCKET_WIN_REQ(w))) |
810 | break; | 811 | break; |
811 | if (w == MAX_WIN) { | 812 | if (w == MAX_WIN) { |
812 | dev_dbg(&s->dev, "all windows are used already\n"); | 813 | dev_dbg(&s->dev, "all windows are used already\n"); |
814 | mutex_unlock(&s->ops_mutex); | ||
813 | return -EINVAL; | 815 | return -EINVAL; |
814 | } | 816 | } |
815 | 817 | ||
816 | mutex_lock(&s->ops_mutex); | ||
817 | win = &s->win[w]; | 818 | win = &s->win[w]; |
818 | 819 | ||
819 | if (!(s->features & SS_CAP_STATIC_MAP)) { | 820 | if (!(s->features & SS_CAP_STATIC_MAP)) { |
820 | win->res = pcmcia_find_mem_region(req->Base, req->Size, align, | 821 | win->res = pcmcia_find_mem_region(req->Base, req->Size, align, |
821 | (req->Attributes & WIN_MAP_BELOW_1MB), s); | 822 | 0, s); |
822 | if (!win->res) { | 823 | if (!win->res) { |
823 | dev_dbg(&s->dev, "allocating mem region failed\n"); | 824 | dev_dbg(&s->dev, "allocating mem region failed\n"); |
824 | mutex_unlock(&s->ops_mutex); | 825 | mutex_unlock(&s->ops_mutex); |
@@ -829,16 +830,8 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
829 | 830 | ||
830 | /* Configure the socket controller */ | 831 | /* Configure the socket controller */ |
831 | win->map = w+1; | 832 | win->map = w+1; |
832 | win->flags = 0; | 833 | win->flags = req->Attributes; |
833 | win->speed = req->AccessSpeed; | 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 | win->card_start = 0; | 835 | win->card_start = 0; |
843 | 836 | ||
844 | if (s->ops->set_mem_map(s, win) != 0) { | 837 | if (s->ops->set_mem_map(s, win) != 0) { |
@@ -854,8 +847,16 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
854 | else | 847 | else |
855 | req->Base = win->res->start; | 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 | mutex_unlock(&s->ops_mutex); | 858 | mutex_unlock(&s->ops_mutex); |
858 | *wh = w + 1; | 859 | *wh = res; |
859 | 860 | ||
860 | return 0; | 861 | return 0; |
861 | } /* pcmcia_request_window */ | 862 | } /* pcmcia_request_window */ |
@@ -863,13 +864,18 @@ EXPORT_SYMBOL(pcmcia_request_window); | |||
863 | 864 | ||
864 | void pcmcia_disable_device(struct pcmcia_device *p_dev) | 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 | pcmcia_release_configuration(p_dev); | 874 | pcmcia_release_configuration(p_dev); |
867 | pcmcia_release_io(p_dev); | 875 | pcmcia_release_io(p_dev); |
868 | if (p_dev->_irq) { | 876 | if (p_dev->_irq) { |
869 | free_irq(p_dev->irq, p_dev->priv); | 877 | free_irq(p_dev->irq, p_dev->priv); |
870 | p_dev->_irq = 0; | 878 | p_dev->_irq = 0; |
871 | } | 879 | } |
872 | if (p_dev->win) | ||
873 | pcmcia_release_window(p_dev, p_dev->win); | ||
874 | } | 880 | } |
875 | EXPORT_SYMBOL(pcmcia_disable_device); | 881 | EXPORT_SYMBOL(pcmcia_disable_device); |