aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/pcmcia_resource.c
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2010-03-20 08:10:47 -0400
committerDominik Brodowski <linux@dominikbrodowski.net>2010-05-10 04:23:19 -0400
commitb19a7275dec4b470ea9abaae6129d21a0d75ab2f (patch)
tree9a3824270dee0494a198f969ae5b8c53e4950165 /drivers/pcmcia/pcmcia_resource.c
parent49b1153adfe18a3cce7e70aa26c690f275917cd0 (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.c71
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;
40module_param(io_speed, int, 0444); 40module_param(io_speed, int, 0444);
41 41
42 42
43static 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
51static 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
60int pcmcia_validate_mem(struct pcmcia_socket *s) 43int 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,
82static int alloc_io_space(struct pcmcia_socket *s, u_int attr, 65static 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 */
685int __must_check 625int __must_check
686pcmcia_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 */
708EXPORT_SYMBOL(pcmcia_request_exclusive_irq); 649EXPORT_SYMBOL(__pcmcia_request_exclusive_irq);
709 650
710 651
711#ifdef CONFIG_PCMCIA_PROBE 652#ifdef CONFIG_PCMCIA_PROBE