diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-07-28 04:59:06 -0400 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-09-29 11:20:21 -0400 |
commit | cdb138080b78146d1cdadba9f5dadbeb97445b91 (patch) | |
tree | fae26f709ed0f19648db79059234faf9fa028051 /drivers/pcmcia | |
parent | 899611ee7d373e5eeda08e9a8632684e1ebbbf00 (diff) |
pcmcia: do not use win_req_t when calling pcmcia_request_window()
Instead of win_req_t, drivers are now requested to fill out
struct pcmcia_device *p_dev->resource[2,3,4,5] for up to four iomem
ranges. After a call to pcmcia_request_window(), the windows found there
are reserved and may be used until pcmcia_release_window() is called.
CC: netdev@vger.kernel.org
CC: linux-wireless@vger.kernel.org
CC: linux-mtd@lists.infradead.org
CC: Jiri Kosina <jkosina@suse.cz>
CC: linux-scsi@vger.kernel.org
Tested-by: Wolfram Sang <w.sang@pengutronix.de>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r-- | drivers/pcmcia/pcmcia_resource.c | 60 |
1 files changed, 33 insertions, 27 deletions
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 9ba4dade69a4..bf16a1cf7399 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c | |||
@@ -204,11 +204,10 @@ int pcmcia_write_config_byte(struct pcmcia_device *p_dev, off_t where, u8 val) | |||
204 | EXPORT_SYMBOL(pcmcia_write_config_byte); | 204 | EXPORT_SYMBOL(pcmcia_write_config_byte); |
205 | 205 | ||
206 | 206 | ||
207 | int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t wh, | 207 | int pcmcia_map_mem_page(struct pcmcia_device *p_dev, struct resource *res, |
208 | unsigned int offset) | 208 | unsigned int offset) |
209 | { | 209 | { |
210 | struct pcmcia_socket *s = p_dev->socket; | 210 | struct pcmcia_socket *s = p_dev->socket; |
211 | struct resource *res = wh; | ||
212 | unsigned int w; | 211 | unsigned int w; |
213 | int ret; | 212 | int ret; |
214 | 213 | ||
@@ -386,7 +385,12 @@ out: | |||
386 | return ret; | 385 | return ret; |
387 | } /* pcmcia_release_io */ | 386 | } /* pcmcia_release_io */ |
388 | 387 | ||
389 | 388 | /** | |
389 | * pcmcia_release_window() - release reserved iomem for PCMCIA devices | ||
390 | * | ||
391 | * pcmcia_release_window() releases struct resource *res which was | ||
392 | * previously reserved by calling pcmcia_request_window(). | ||
393 | */ | ||
390 | int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res) | 394 | int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res) |
391 | { | 395 | { |
392 | struct pcmcia_socket *s = p_dev->socket; | 396 | struct pcmcia_socket *s = p_dev->socket; |
@@ -420,6 +424,8 @@ int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res) | |||
420 | kfree(win->res); | 424 | kfree(win->res); |
421 | win->res = NULL; | 425 | win->res = NULL; |
422 | } | 426 | } |
427 | res->start = res->end = 0; | ||
428 | res->flags = IORESOURCE_MEM; | ||
423 | p_dev->_win &= ~CLIENT_WIN_REQ(w); | 429 | p_dev->_win &= ~CLIENT_WIN_REQ(w); |
424 | mutex_unlock(&s->ops_mutex); | 430 | mutex_unlock(&s->ops_mutex); |
425 | 431 | ||
@@ -795,17 +801,21 @@ int pcmcia_setup_irq(struct pcmcia_device *p_dev) | |||
795 | } | 801 | } |
796 | 802 | ||
797 | 803 | ||
798 | /** pcmcia_request_window | 804 | /** |
805 | * pcmcia_request_window() - attempt to reserve iomem for PCMCIA devices | ||
799 | * | 806 | * |
800 | * Request_window() establishes a mapping between card memory space | 807 | * pcmcia_request_window() attepts to reserve an iomem ranges specified in |
801 | * and system memory space. | 808 | * struct resource *res pointing to one of the entries in |
809 | * struct pcmcia_device *p_dev->resource[2..5]. The "start" value is the | ||
810 | * requested start of the IO mem resource; "end" reflects the size | ||
811 | * requested. | ||
802 | */ | 812 | */ |
803 | int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_handle_t *wh) | 813 | int pcmcia_request_window(struct pcmcia_device *p_dev, struct resource *res, |
814 | unsigned int speed) | ||
804 | { | 815 | { |
805 | struct pcmcia_socket *s = p_dev->socket; | 816 | struct pcmcia_socket *s = p_dev->socket; |
806 | pccard_mem_map *win; | 817 | pccard_mem_map *win; |
807 | u_long align; | 818 | u_long align; |
808 | struct resource *res; | ||
809 | int w; | 819 | int w; |
810 | 820 | ||
811 | if (!(s->state & SOCKET_PRESENT)) { | 821 | if (!(s->state & SOCKET_PRESENT)) { |
@@ -814,19 +824,19 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
814 | } | 824 | } |
815 | 825 | ||
816 | /* Window size defaults to smallest available */ | 826 | /* Window size defaults to smallest available */ |
817 | if (req->Size == 0) | 827 | if (res->end == 0) |
818 | req->Size = s->map_size; | 828 | res->end = s->map_size; |
819 | align = (s->features & SS_CAP_MEM_ALIGN) ? req->Size : s->map_size; | 829 | align = (s->features & SS_CAP_MEM_ALIGN) ? res->end : s->map_size; |
820 | if (req->Size & (s->map_size-1)) { | 830 | if (res->end & (s->map_size-1)) { |
821 | dev_dbg(&p_dev->dev, "invalid map size\n"); | 831 | dev_dbg(&p_dev->dev, "invalid map size\n"); |
822 | return -EINVAL; | 832 | return -EINVAL; |
823 | } | 833 | } |
824 | if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) || | 834 | if ((res->start && (s->features & SS_CAP_STATIC_MAP)) || |
825 | (req->Base & (align-1))) { | 835 | (res->start & (align-1))) { |
826 | dev_dbg(&p_dev->dev, "invalid base address\n"); | 836 | dev_dbg(&p_dev->dev, "invalid base address\n"); |
827 | return -EINVAL; | 837 | return -EINVAL; |
828 | } | 838 | } |
829 | if (req->Base) | 839 | if (res->start) |
830 | align = 0; | 840 | align = 0; |
831 | 841 | ||
832 | /* Allocate system memory window */ | 842 | /* Allocate system memory window */ |
@@ -843,7 +853,7 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
843 | win = &s->win[w]; | 853 | win = &s->win[w]; |
844 | 854 | ||
845 | if (!(s->features & SS_CAP_STATIC_MAP)) { | 855 | if (!(s->features & SS_CAP_STATIC_MAP)) { |
846 | win->res = pcmcia_find_mem_region(req->Base, req->Size, align, | 856 | win->res = pcmcia_find_mem_region(res->start, res->end, align, |
847 | 0, s); | 857 | 0, s); |
848 | if (!win->res) { | 858 | if (!win->res) { |
849 | dev_dbg(&p_dev->dev, "allocating mem region failed\n"); | 859 | dev_dbg(&p_dev->dev, "allocating mem region failed\n"); |
@@ -855,8 +865,8 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
855 | 865 | ||
856 | /* Configure the socket controller */ | 866 | /* Configure the socket controller */ |
857 | win->map = w+1; | 867 | win->map = w+1; |
858 | win->flags = req->Attributes; | 868 | win->flags = res->flags & WIN_FLAGS_MAP; |
859 | win->speed = req->AccessSpeed; | 869 | win->speed = speed; |
860 | win->card_start = 0; | 870 | win->card_start = 0; |
861 | 871 | ||
862 | if (s->ops->set_mem_map(s, win) != 0) { | 872 | if (s->ops->set_mem_map(s, win) != 0) { |
@@ -868,17 +878,14 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
868 | 878 | ||
869 | /* Return window handle */ | 879 | /* Return window handle */ |
870 | if (s->features & SS_CAP_STATIC_MAP) | 880 | if (s->features & SS_CAP_STATIC_MAP) |
871 | req->Base = win->static_start; | 881 | res->start = win->static_start; |
872 | else | 882 | else |
873 | req->Base = win->res->start; | 883 | res->start = win->res->start; |
874 | 884 | ||
875 | /* convert to new-style resources */ | 885 | /* convert to new-style resources */ |
876 | res = p_dev->resource[w + MAX_IO_WIN]; | 886 | res->end += res->start - 1; |
877 | res->start = req->Base; | 887 | res->flags &= ~WIN_FLAGS_REQ; |
878 | res->end = req->Base + req->Size - 1; | 888 | res->flags |= (win->map << 2) | IORESOURCE_MEM; |
879 | res->flags &= ~IORESOURCE_BITS; | ||
880 | res->flags |= (req->Attributes & WIN_FLAGS_MAP) | (win->map << 2); | ||
881 | res->flags |= IORESOURCE_MEM; | ||
882 | res->parent = win->res; | 889 | res->parent = win->res; |
883 | if (win->res) | 890 | if (win->res) |
884 | request_resource(&iomem_resource, res); | 891 | request_resource(&iomem_resource, res); |
@@ -886,7 +893,6 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
886 | dev_dbg(&p_dev->dev, "request_window results in %pR\n", res); | 893 | dev_dbg(&p_dev->dev, "request_window results in %pR\n", res); |
887 | 894 | ||
888 | mutex_unlock(&s->ops_mutex); | 895 | mutex_unlock(&s->ops_mutex); |
889 | *wh = res; | ||
890 | 896 | ||
891 | return 0; | 897 | return 0; |
892 | } /* pcmcia_request_window */ | 898 | } /* pcmcia_request_window */ |