diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-03-20 08:10:47 -0400 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-05-10 04:23:19 -0400 |
commit | b19a7275dec4b470ea9abaae6129d21a0d75ab2f (patch) | |
tree | 9a3824270dee0494a198f969ae5b8c53e4950165 /drivers/pcmcia/pcmcia_resource.c | |
parent | 49b1153adfe18a3cce7e70aa26c690f275917cd0 (diff) |
pcmcia: clarify alloc_io_space, move it to resource handlers
Clean up the alloc_io_space() function by moving most of it to
the actual resource_ops. This allows for a bit less re-directions.
Future cleanups will follow, and will make up for the code
duplication currently present between rsrc_iodyn and rsrc_nonstatic
(which are hardly ever built at the same time anyway, therefore no
increase in built size).
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/pcmcia/pcmcia_resource.c')
-rw-r--r-- | drivers/pcmcia/pcmcia_resource.c | 71 |
1 files changed, 6 insertions, 65 deletions
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 9c5f9cd5e03d..c6419c18a6c8 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c | |||
@@ -40,23 +40,6 @@ static int io_speed; | |||
40 | module_param(io_speed, int, 0444); | 40 | module_param(io_speed, int, 0444); |
41 | 41 | ||
42 | 42 | ||
43 | static int pcmcia_adjust_io_region(struct resource *res, unsigned long start, | ||
44 | unsigned long end, struct pcmcia_socket *s) | ||
45 | { | ||
46 | if (s->resource_ops->adjust_io_region) | ||
47 | return s->resource_ops->adjust_io_region(res, start, end, s); | ||
48 | return -ENOMEM; | ||
49 | } | ||
50 | |||
51 | static struct resource *pcmcia_find_io_region(unsigned long base, int num, | ||
52 | unsigned long align, | ||
53 | struct pcmcia_socket *s) | ||
54 | { | ||
55 | if (s->resource_ops->find_io) | ||
56 | return s->resource_ops->find_io(base, num, align, s); | ||
57 | return NULL; | ||
58 | } | ||
59 | |||
60 | int pcmcia_validate_mem(struct pcmcia_socket *s) | 43 | int pcmcia_validate_mem(struct pcmcia_socket *s) |
61 | { | 44 | { |
62 | if (s->resource_ops->validate_mem) | 45 | if (s->resource_ops->validate_mem) |
@@ -82,8 +65,7 @@ struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align, | |||
82 | static int alloc_io_space(struct pcmcia_socket *s, u_int attr, | 65 | static int alloc_io_space(struct pcmcia_socket *s, u_int attr, |
83 | unsigned int *base, unsigned int num, u_int lines) | 66 | unsigned int *base, unsigned int num, u_int lines) |
84 | { | 67 | { |
85 | int i; | 68 | unsigned int align; |
86 | unsigned int try, align; | ||
87 | 69 | ||
88 | align = (*base) ? (lines ? 1<<lines : 0) : 1; | 70 | align = (*base) ? (lines ? 1<<lines : 0) : 1; |
89 | if (align && (align < num)) { | 71 | if (align && (align < num)) { |
@@ -100,50 +82,8 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr, | |||
100 | *base, align); | 82 | *base, align); |
101 | align = 0; | 83 | align = 0; |
102 | } | 84 | } |
103 | if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) { | 85 | |
104 | *base = s->io_offset | (*base & 0x0fff); | 86 | return s->resource_ops->find_io(s, attr, base, num, align); |
105 | return 0; | ||
106 | } | ||
107 | /* Check for an already-allocated window that must conflict with | ||
108 | * what was asked for. It is a hack because it does not catch all | ||
109 | * potential conflicts, just the most obvious ones. | ||
110 | */ | ||
111 | for (i = 0; i < MAX_IO_WIN; i++) | ||
112 | if ((s->io[i].res) && *base && | ||
113 | ((s->io[i].res->start & (align-1)) == *base)) | ||
114 | return 1; | ||
115 | for (i = 0; i < MAX_IO_WIN; i++) { | ||
116 | if (!s->io[i].res) { | ||
117 | s->io[i].res = pcmcia_find_io_region(*base, num, align, s); | ||
118 | if (s->io[i].res) { | ||
119 | *base = s->io[i].res->start; | ||
120 | s->io[i].res->flags = (s->io[i].res->flags & ~IORESOURCE_BITS) | (attr & IORESOURCE_BITS); | ||
121 | s->io[i].InUse = num; | ||
122 | break; | ||
123 | } else | ||
124 | return 1; | ||
125 | } else if ((s->io[i].res->flags & IORESOURCE_BITS) != (attr & IORESOURCE_BITS)) | ||
126 | continue; | ||
127 | /* Try to extend top of window */ | ||
128 | try = s->io[i].res->end + 1; | ||
129 | if ((*base == 0) || (*base == try)) | ||
130 | if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start, | ||
131 | s->io[i].res->end + num, s) == 0) { | ||
132 | *base = try; | ||
133 | s->io[i].InUse += num; | ||
134 | break; | ||
135 | } | ||
136 | /* Try to extend bottom of window */ | ||
137 | try = s->io[i].res->start - num; | ||
138 | if ((*base == 0) || (*base == try)) | ||
139 | if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start - num, | ||
140 | s->io[i].res->end, s) == 0) { | ||
141 | *base = try; | ||
142 | s->io[i].InUse += num; | ||
143 | break; | ||
144 | } | ||
145 | } | ||
146 | return (i == MAX_IO_WIN); | ||
147 | } /* alloc_io_space */ | 87 | } /* alloc_io_space */ |
148 | 88 | ||
149 | 89 | ||
@@ -683,7 +623,8 @@ EXPORT_SYMBOL(pcmcia_request_irq); | |||
683 | * free_irq themselves, too), or the pcmcia_request_irq() function. | 623 | * free_irq themselves, too), or the pcmcia_request_irq() function. |
684 | */ | 624 | */ |
685 | int __must_check | 625 | int __must_check |
686 | pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev, irq_handler_t handler) | 626 | __pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev, |
627 | irq_handler_t handler) | ||
687 | { | 628 | { |
688 | int ret; | 629 | int ret; |
689 | 630 | ||
@@ -705,7 +646,7 @@ pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev, irq_handler_t handler) | |||
705 | 646 | ||
706 | return ret; | 647 | return ret; |
707 | } /* pcmcia_request_exclusive_irq */ | 648 | } /* pcmcia_request_exclusive_irq */ |
708 | EXPORT_SYMBOL(pcmcia_request_exclusive_irq); | 649 | EXPORT_SYMBOL(__pcmcia_request_exclusive_irq); |
709 | 650 | ||
710 | 651 | ||
711 | #ifdef CONFIG_PCMCIA_PROBE | 652 | #ifdef CONFIG_PCMCIA_PROBE |