aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2010-07-28 04:59:06 -0400
committerDominik Brodowski <linux@dominikbrodowski.net>2010-09-29 11:20:21 -0400
commitcdb138080b78146d1cdadba9f5dadbeb97445b91 (patch)
treefae26f709ed0f19648db79059234faf9fa028051 /drivers/pcmcia
parent899611ee7d373e5eeda08e9a8632684e1ebbbf00 (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.c60
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)
204EXPORT_SYMBOL(pcmcia_write_config_byte); 204EXPORT_SYMBOL(pcmcia_write_config_byte);
205 205
206 206
207int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t wh, 207int 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 */
390int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res) 394int 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 */
803int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_handle_t *wh) 813int 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 */