]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/pnp/manager.c
Merge ssh://master.kernel.org/pub/scm/linux/kernel/git/sam/kbuild
[linux-2.6-omap-h63xx.git] / drivers / pnp / manager.c
1 /*
2  * manager.c - Resource Management, Conflict Resolution, Activation and Disabling of Devices
3  *
4  * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz>
5  * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
6  */
7
8 #include <linux/errno.h>
9 #include <linux/module.h>
10 #include <linux/init.h>
11 #include <linux/kernel.h>
12 #include <linux/pnp.h>
13 #include <linux/slab.h>
14 #include <linux/bitmap.h>
15 #include "base.h"
16
17 DECLARE_MUTEX(pnp_res_mutex);
18
19 static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
20 {
21         resource_size_t *start, *end;
22         unsigned long *flags;
23
24         if (idx >= PNP_MAX_PORT) {
25                 pnp_err
26                     ("More than 4 ports is incompatible with pnp specifications.");
27                 /* pretend we were successful so at least the manager won't try again */
28                 return 1;
29         }
30
31         /* check if this resource has been manually set, if so skip */
32         if (!(dev->res.port_resource[idx].flags & IORESOURCE_AUTO))
33                 return 1;
34
35         start = &dev->res.port_resource[idx].start;
36         end = &dev->res.port_resource[idx].end;
37         flags = &dev->res.port_resource[idx].flags;
38
39         /* set the initial values */
40         *flags |= rule->flags | IORESOURCE_IO;
41         *flags &= ~IORESOURCE_UNSET;
42
43         if (!rule->size) {
44                 *flags |= IORESOURCE_DISABLED;
45                 return 1;       /* skip disabled resource requests */
46         }
47
48         *start = rule->min;
49         *end = *start + rule->size - 1;
50
51         /* run through until pnp_check_port is happy */
52         while (!pnp_check_port(dev, idx)) {
53                 *start += rule->align;
54                 *end = *start + rule->size - 1;
55                 if (*start > rule->max || !rule->align)
56                         return 0;
57         }
58         return 1;
59 }
60
61 static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
62 {
63         resource_size_t *start, *end;
64         unsigned long *flags;
65
66         if (idx >= PNP_MAX_MEM) {
67                 pnp_err
68                     ("More than 8 mems is incompatible with pnp specifications.");
69                 /* pretend we were successful so at least the manager won't try again */
70                 return 1;
71         }
72
73         /* check if this resource has been manually set, if so skip */
74         if (!(dev->res.mem_resource[idx].flags & IORESOURCE_AUTO))
75                 return 1;
76
77         start = &dev->res.mem_resource[idx].start;
78         end = &dev->res.mem_resource[idx].end;
79         flags = &dev->res.mem_resource[idx].flags;
80
81         /* set the initial values */
82         *flags |= rule->flags | IORESOURCE_MEM;
83         *flags &= ~IORESOURCE_UNSET;
84
85         /* convert pnp flags to standard Linux flags */
86         if (!(rule->flags & IORESOURCE_MEM_WRITEABLE))
87                 *flags |= IORESOURCE_READONLY;
88         if (rule->flags & IORESOURCE_MEM_CACHEABLE)
89                 *flags |= IORESOURCE_CACHEABLE;
90         if (rule->flags & IORESOURCE_MEM_RANGELENGTH)
91                 *flags |= IORESOURCE_RANGELENGTH;
92         if (rule->flags & IORESOURCE_MEM_SHADOWABLE)
93                 *flags |= IORESOURCE_SHADOWABLE;
94
95         if (!rule->size) {
96                 *flags |= IORESOURCE_DISABLED;
97                 return 1;       /* skip disabled resource requests */
98         }
99
100         *start = rule->min;
101         *end = *start + rule->size - 1;
102
103         /* run through until pnp_check_mem is happy */
104         while (!pnp_check_mem(dev, idx)) {
105                 *start += rule->align;
106                 *end = *start + rule->size - 1;
107                 if (*start > rule->max || !rule->align)
108                         return 0;
109         }
110         return 1;
111 }
112
113 static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
114 {
115         resource_size_t *start, *end;
116         unsigned long *flags;
117         int i;
118
119         /* IRQ priority: this table is good for i386 */
120         static unsigned short xtab[16] = {
121                 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
122         };
123
124         if (idx >= PNP_MAX_IRQ) {
125                 pnp_err
126                     ("More than 2 irqs is incompatible with pnp specifications.");
127                 /* pretend we were successful so at least the manager won't try again */
128                 return 1;
129         }
130
131         /* check if this resource has been manually set, if so skip */
132         if (!(dev->res.irq_resource[idx].flags & IORESOURCE_AUTO))
133                 return 1;
134
135         start = &dev->res.irq_resource[idx].start;
136         end = &dev->res.irq_resource[idx].end;
137         flags = &dev->res.irq_resource[idx].flags;
138
139         /* set the initial values */
140         *flags |= rule->flags | IORESOURCE_IRQ;
141         *flags &= ~IORESOURCE_UNSET;
142
143         if (bitmap_empty(rule->map, PNP_IRQ_NR)) {
144                 *flags |= IORESOURCE_DISABLED;
145                 return 1;       /* skip disabled resource requests */
146         }
147
148         /* TBD: need check for >16 IRQ */
149         *start = find_next_bit(rule->map, PNP_IRQ_NR, 16);
150         if (*start < PNP_IRQ_NR) {
151                 *end = *start;
152                 return 1;
153         }
154         for (i = 0; i < 16; i++) {
155                 if (test_bit(xtab[i], rule->map)) {
156                         *start = *end = xtab[i];
157                         if (pnp_check_irq(dev, idx))
158                                 return 1;
159                 }
160         }
161         return 0;
162 }
163
164 static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
165 {
166         resource_size_t *start, *end;
167         unsigned long *flags;
168         int i;
169
170         /* DMA priority: this table is good for i386 */
171         static unsigned short xtab[8] = {
172                 1, 3, 5, 6, 7, 0, 2, 4
173         };
174
175         if (idx >= PNP_MAX_DMA) {
176                 pnp_err
177                     ("More than 2 dmas is incompatible with pnp specifications.");
178                 /* pretend we were successful so at least the manager won't try again */
179                 return 1;
180         }
181
182         /* check if this resource has been manually set, if so skip */
183         if (!(dev->res.dma_resource[idx].flags & IORESOURCE_AUTO))
184                 return 1;
185
186         start = &dev->res.dma_resource[idx].start;
187         end = &dev->res.dma_resource[idx].end;
188         flags = &dev->res.dma_resource[idx].flags;
189
190         /* set the initial values */
191         *flags |= rule->flags | IORESOURCE_DMA;
192         *flags &= ~IORESOURCE_UNSET;
193
194         if (!rule->map) {
195                 *flags |= IORESOURCE_DISABLED;
196                 return 1;       /* skip disabled resource requests */
197         }
198
199         for (i = 0; i < 8; i++) {
200                 if (rule->map & (1 << xtab[i])) {
201                         *start = *end = xtab[i];
202                         if (pnp_check_dma(dev, idx))
203                                 return 1;
204                 }
205         }
206         return 0;
207 }
208
209 /**
210  * pnp_init_resources - Resets a resource table to default values.
211  * @table: pointer to the desired resource table
212  */
213 void pnp_init_resource_table(struct pnp_resource_table *table)
214 {
215         int idx;
216
217         for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
218                 table->irq_resource[idx].name = NULL;
219                 table->irq_resource[idx].start = -1;
220                 table->irq_resource[idx].end = -1;
221                 table->irq_resource[idx].flags =
222                     IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET;
223         }
224         for (idx = 0; idx < PNP_MAX_DMA; idx++) {
225                 table->dma_resource[idx].name = NULL;
226                 table->dma_resource[idx].start = -1;
227                 table->dma_resource[idx].end = -1;
228                 table->dma_resource[idx].flags =
229                     IORESOURCE_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET;
230         }
231         for (idx = 0; idx < PNP_MAX_PORT; idx++) {
232                 table->port_resource[idx].name = NULL;
233                 table->port_resource[idx].start = 0;
234                 table->port_resource[idx].end = 0;
235                 table->port_resource[idx].flags =
236                     IORESOURCE_IO | IORESOURCE_AUTO | IORESOURCE_UNSET;
237         }
238         for (idx = 0; idx < PNP_MAX_MEM; idx++) {
239                 table->mem_resource[idx].name = NULL;
240                 table->mem_resource[idx].start = 0;
241                 table->mem_resource[idx].end = 0;
242                 table->mem_resource[idx].flags =
243                     IORESOURCE_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET;
244         }
245 }
246
247 /**
248  * pnp_clean_resources - clears resources that were not manually set
249  * @res: the resources to clean
250  */
251 static void pnp_clean_resource_table(struct pnp_resource_table *res)
252 {
253         int idx;
254
255         for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
256                 if (!(res->irq_resource[idx].flags & IORESOURCE_AUTO))
257                         continue;
258                 res->irq_resource[idx].start = -1;
259                 res->irq_resource[idx].end = -1;
260                 res->irq_resource[idx].flags =
261                     IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET;
262         }
263         for (idx = 0; idx < PNP_MAX_DMA; idx++) {
264                 if (!(res->dma_resource[idx].flags & IORESOURCE_AUTO))
265                         continue;
266                 res->dma_resource[idx].start = -1;
267                 res->dma_resource[idx].end = -1;
268                 res->dma_resource[idx].flags =
269                     IORESOURCE_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET;
270         }
271         for (idx = 0; idx < PNP_MAX_PORT; idx++) {
272                 if (!(res->port_resource[idx].flags & IORESOURCE_AUTO))
273                         continue;
274                 res->port_resource[idx].start = 0;
275                 res->port_resource[idx].end = 0;
276                 res->port_resource[idx].flags =
277                     IORESOURCE_IO | IORESOURCE_AUTO | IORESOURCE_UNSET;
278         }
279         for (idx = 0; idx < PNP_MAX_MEM; idx++) {
280                 if (!(res->mem_resource[idx].flags & IORESOURCE_AUTO))
281                         continue;
282                 res->mem_resource[idx].start = 0;
283                 res->mem_resource[idx].end = 0;
284                 res->mem_resource[idx].flags =
285                     IORESOURCE_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET;
286         }
287 }
288
289 /**
290  * pnp_assign_resources - assigns resources to the device based on the specified dependent number
291  * @dev: pointer to the desired device
292  * @depnum: the dependent function number
293  *
294  * Only set depnum to 0 if the device does not have dependent options.
295  */
296 static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
297 {
298         struct pnp_port *port;
299         struct pnp_mem *mem;
300         struct pnp_irq *irq;
301         struct pnp_dma *dma;
302         int nport = 0, nmem = 0, nirq = 0, ndma = 0;
303
304         if (!pnp_can_configure(dev))
305                 return -ENODEV;
306
307         down(&pnp_res_mutex);
308         pnp_clean_resource_table(&dev->res);    /* start with a fresh slate */
309         if (dev->independent) {
310                 port = dev->independent->port;
311                 mem = dev->independent->mem;
312                 irq = dev->independent->irq;
313                 dma = dev->independent->dma;
314                 while (port) {
315                         if (!pnp_assign_port(dev, port, nport))
316                                 goto fail;
317                         nport++;
318                         port = port->next;
319                 }
320                 while (mem) {
321                         if (!pnp_assign_mem(dev, mem, nmem))
322                                 goto fail;
323                         nmem++;
324                         mem = mem->next;
325                 }
326                 while (irq) {
327                         if (!pnp_assign_irq(dev, irq, nirq))
328                                 goto fail;
329                         nirq++;
330                         irq = irq->next;
331                 }
332                 while (dma) {
333                         if (!pnp_assign_dma(dev, dma, ndma))
334                                 goto fail;
335                         ndma++;
336                         dma = dma->next;
337                 }
338         }
339
340         if (depnum) {
341                 struct pnp_option *dep;
342                 int i;
343                 for (i = 1, dep = dev->dependent; i < depnum;
344                      i++, dep = dep->next)
345                         if (!dep)
346                                 goto fail;
347                 port = dep->port;
348                 mem = dep->mem;
349                 irq = dep->irq;
350                 dma = dep->dma;
351                 while (port) {
352                         if (!pnp_assign_port(dev, port, nport))
353                                 goto fail;
354                         nport++;
355                         port = port->next;
356                 }
357                 while (mem) {
358                         if (!pnp_assign_mem(dev, mem, nmem))
359                                 goto fail;
360                         nmem++;
361                         mem = mem->next;
362                 }
363                 while (irq) {
364                         if (!pnp_assign_irq(dev, irq, nirq))
365                                 goto fail;
366                         nirq++;
367                         irq = irq->next;
368                 }
369                 while (dma) {
370                         if (!pnp_assign_dma(dev, dma, ndma))
371                                 goto fail;
372                         ndma++;
373                         dma = dma->next;
374                 }
375         } else if (dev->dependent)
376                 goto fail;
377
378         up(&pnp_res_mutex);
379         return 1;
380
381 fail:
382         pnp_clean_resource_table(&dev->res);
383         up(&pnp_res_mutex);
384         return 0;
385 }
386
387 /**
388  * pnp_manual_config_dev - Disables Auto Config and Manually sets the resource table
389  * @dev: pointer to the desired device
390  * @res: pointer to the new resource config
391  * @mode: 0 or PNP_CONFIG_FORCE
392  *
393  * This function can be used by drivers that want to manually set thier resources.
394  */
395 int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res,
396                           int mode)
397 {
398         int i;
399         struct pnp_resource_table *bak;
400
401         if (!pnp_can_configure(dev))
402                 return -ENODEV;
403         bak = pnp_alloc(sizeof(struct pnp_resource_table));
404         if (!bak)
405                 return -ENOMEM;
406         *bak = dev->res;
407
408         down(&pnp_res_mutex);
409         dev->res = *res;
410         if (!(mode & PNP_CONFIG_FORCE)) {
411                 for (i = 0; i < PNP_MAX_PORT; i++) {
412                         if (!pnp_check_port(dev, i))
413                                 goto fail;
414                 }
415                 for (i = 0; i < PNP_MAX_MEM; i++) {
416                         if (!pnp_check_mem(dev, i))
417                                 goto fail;
418                 }
419                 for (i = 0; i < PNP_MAX_IRQ; i++) {
420                         if (!pnp_check_irq(dev, i))
421                                 goto fail;
422                 }
423                 for (i = 0; i < PNP_MAX_DMA; i++) {
424                         if (!pnp_check_dma(dev, i))
425                                 goto fail;
426                 }
427         }
428         up(&pnp_res_mutex);
429
430         kfree(bak);
431         return 0;
432
433 fail:
434         dev->res = *bak;
435         up(&pnp_res_mutex);
436         kfree(bak);
437         return -EINVAL;
438 }
439
440 /**
441  * pnp_auto_config_dev - automatically assigns resources to a device
442  * @dev: pointer to the desired device
443  */
444 int pnp_auto_config_dev(struct pnp_dev *dev)
445 {
446         struct pnp_option *dep;
447         int i = 1;
448
449         if (!pnp_can_configure(dev)) {
450                 pnp_dbg("Device %s does not support resource configuration.",
451                         dev->dev.bus_id);
452                 return -ENODEV;
453         }
454
455         if (!dev->dependent) {
456                 if (pnp_assign_resources(dev, 0))
457                         return 0;
458         } else {
459                 dep = dev->dependent;
460                 do {
461                         if (pnp_assign_resources(dev, i))
462                                 return 0;
463                         dep = dep->next;
464                         i++;
465                 } while (dep);
466         }
467
468         pnp_err("Unable to assign resources to device %s.", dev->dev.bus_id);
469         return -EBUSY;
470 }
471
472 /**
473  * pnp_start_dev - low-level start of the PnP device
474  * @dev: pointer to the desired device
475  *
476  * assumes that resources have already been allocated
477  */
478 int pnp_start_dev(struct pnp_dev *dev)
479 {
480         if (!pnp_can_write(dev)) {
481                 pnp_dbg("Device %s does not support activation.",
482                         dev->dev.bus_id);
483                 return -EINVAL;
484         }
485
486         if (dev->protocol->set(dev, &dev->res) < 0) {
487                 pnp_err("Failed to activate device %s.", dev->dev.bus_id);
488                 return -EIO;
489         }
490
491         pnp_info("Device %s activated.", dev->dev.bus_id);
492         return 0;
493 }
494
495 /**
496  * pnp_stop_dev - low-level disable of the PnP device
497  * @dev: pointer to the desired device
498  *
499  * does not free resources
500  */
501 int pnp_stop_dev(struct pnp_dev *dev)
502 {
503         if (!pnp_can_disable(dev)) {
504                 pnp_dbg("Device %s does not support disabling.",
505                         dev->dev.bus_id);
506                 return -EINVAL;
507         }
508         if (dev->protocol->disable(dev) < 0) {
509                 pnp_err("Failed to disable device %s.", dev->dev.bus_id);
510                 return -EIO;
511         }
512
513         pnp_info("Device %s disabled.", dev->dev.bus_id);
514         return 0;
515 }
516
517 /**
518  * pnp_activate_dev - activates a PnP device for use
519  * @dev: pointer to the desired device
520  *
521  * does not validate or set resources so be careful.
522  */
523 int pnp_activate_dev(struct pnp_dev *dev)
524 {
525         int error;
526
527         if (dev->active)
528                 return 0;       /* the device is already active */
529
530         /* ensure resources are allocated */
531         if (pnp_auto_config_dev(dev))
532                 return -EBUSY;
533
534         error = pnp_start_dev(dev);
535         if (error)
536                 return error;
537
538         dev->active = 1;
539         return 1;
540 }
541
542 /**
543  * pnp_disable_dev - disables device
544  * @dev: pointer to the desired device
545  *
546  * inform the correct pnp protocol so that resources can be used by other devices
547  */
548 int pnp_disable_dev(struct pnp_dev *dev)
549 {
550         int error;
551
552         if (!dev->active)
553                 return 0;       /* the device is already disabled */
554
555         error = pnp_stop_dev(dev);
556         if (error)
557                 return error;
558
559         dev->active = 0;
560
561         /* release the resources so that other devices can use them */
562         down(&pnp_res_mutex);
563         pnp_clean_resource_table(&dev->res);
564         up(&pnp_res_mutex);
565
566         return 1;
567 }
568
569 /**
570  * pnp_resource_change - change one resource
571  * @resource: pointer to resource to be changed
572  * @start: start of region
573  * @size: size of region
574  */
575 void pnp_resource_change(struct resource *resource, resource_size_t start,
576                          resource_size_t size)
577 {
578         resource->flags &= ~(IORESOURCE_AUTO | IORESOURCE_UNSET);
579         resource->start = start;
580         resource->end = start + size - 1;
581 }
582
583 EXPORT_SYMBOL(pnp_manual_config_dev);
584 EXPORT_SYMBOL(pnp_start_dev);
585 EXPORT_SYMBOL(pnp_stop_dev);
586 EXPORT_SYMBOL(pnp_activate_dev);
587 EXPORT_SYMBOL(pnp_disable_dev);
588 EXPORT_SYMBOL(pnp_resource_change);
589 EXPORT_SYMBOL(pnp_init_resource_table);