aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Helgaas <bjorn.helgaas@hp.com>2008-06-27 18:57:01 -0400
committerAndi Kleen <andi@basil.nowhere.org>2008-07-16 17:27:06 -0400
commit57fd51a8be26921b56747ddd09d1d9e01c11c9e0 (patch)
tree8b34c3d57867a217cfabf09a73a1af19242bdc7b
parentf61ed7e32d2d6a0a8c3c101da513ccedd542e14d (diff)
PNP: add pnp_possible_config() -- can a device could be configured this way?
As part of a heuristic to identify modem devices, 8250_pnp.c checks to see whether a device can be configured at any of the legacy COM port addresses. This patch moves the code that traverses the PNP "possible resource options" from 8250_pnp.c to the PNP subsystem. This encapsulation is important because a future patch will change the implementation of those resource options. Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Signed-off-by: Andi Kleen <ak@linux.intel.com> Acked-by: Rene Herman <rene.herman@gmail.com> Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r--drivers/pnp/resource.c62
-rw-r--r--drivers/serial/8250_pnp.c24
-rw-r--r--include/linux/pnp.h5
3 files changed, 74 insertions, 17 deletions
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index ff79aa6168cf..786fd356916d 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -624,6 +624,68 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
624 return pnp_res; 624 return pnp_res;
625} 625}
626 626
627static int pnp_possible_option(struct pnp_option *option, int type,
628 resource_size_t start, resource_size_t size)
629{
630 struct pnp_option *tmp;
631 struct pnp_port *port;
632 struct pnp_mem *mem;
633 struct pnp_irq *irq;
634 struct pnp_dma *dma;
635
636 if (!option)
637 return 0;
638
639 for (tmp = option; tmp; tmp = tmp->next) {
640 switch (type) {
641 case IORESOURCE_IO:
642 for (port = tmp->port; port; port = port->next) {
643 if (port->min == start && port->size == size)
644 return 1;
645 }
646 break;
647 case IORESOURCE_MEM:
648 for (mem = tmp->mem; mem; mem = mem->next) {
649 if (mem->min == start && mem->size == size)
650 return 1;
651 }
652 break;
653 case IORESOURCE_IRQ:
654 for (irq = tmp->irq; irq; irq = irq->next) {
655 if (start < PNP_IRQ_NR &&
656 test_bit(start, irq->map))
657 return 1;
658 }
659 break;
660 case IORESOURCE_DMA:
661 for (dma = tmp->dma; dma; dma = dma->next) {
662 if (dma->map & (1 << start))
663 return 1;
664 }
665 break;
666 }
667 }
668
669 return 0;
670}
671
672/*
673 * Determine whether the specified resource is a possible configuration
674 * for this device.
675 */
676int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start,
677 resource_size_t size)
678{
679 if (pnp_possible_option(dev->independent, type, start, size))
680 return 1;
681
682 if (pnp_possible_option(dev->dependent, type, start, size))
683 return 1;
684
685 return 0;
686}
687EXPORT_SYMBOL(pnp_possible_config);
688
627/* format is: pnp_reserve_irq=irq1[,irq2] .... */ 689/* format is: pnp_reserve_irq=irq1[,irq2] .... */
628static int __init pnp_setup_reserve_irq(char *str) 690static int __init pnp_setup_reserve_irq(char *str)
629{ 691{
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index 97c68d021d28..638b68649e79 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -383,21 +383,14 @@ static int __devinit check_name(char *name)
383 return 0; 383 return 0;
384} 384}
385 385
386static int __devinit check_resources(struct pnp_option *option) 386static int __devinit check_resources(struct pnp_dev *dev)
387{ 387{
388 struct pnp_option *tmp; 388 resource_size_t base[] = {0x2f8, 0x3f8, 0x2e8, 0x3e8};
389 if (!option) 389 int i;
390 return 0;
391 390
392 for (tmp = option; tmp; tmp = tmp->next) { 391 for (i = 0; i < ARRAY_SIZE(base); i++) {
393 struct pnp_port *port; 392 if (pnp_possible_config(dev, IORESOURCE_IO, base[i], 8))
394 for (port = tmp->port; port; port = port->next) 393 return 1;
395 if ((port->size == 8) &&
396 ((port->min == 0x2f8) ||
397 (port->min == 0x3f8) ||
398 (port->min == 0x2e8) ||
399 (port->min == 0x3e8)))
400 return 1;
401 } 394 }
402 395
403 return 0; 396 return 0;
@@ -420,10 +413,7 @@ static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags)
420 (dev->card && check_name(dev->card->name)))) 413 (dev->card && check_name(dev->card->name))))
421 return -ENODEV; 414 return -ENODEV;
422 415
423 if (check_resources(dev->independent)) 416 if (check_resources(dev))
424 return 0;
425
426 if (check_resources(dev->dependent))
427 return 0; 417 return 0;
428 418
429 return -ENODEV; 419 return -ENODEV;
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index dfaa567e04a8..e033e1b14c27 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -479,6 +479,8 @@ void pnp_unregister_card_driver(struct pnp_card_driver *drv);
479extern struct list_head pnp_cards; 479extern struct list_head pnp_cards;
480 480
481/* resource management */ 481/* resource management */
482int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t base,
483 resource_size_t size);
482int pnp_auto_config_dev(struct pnp_dev *dev); 484int pnp_auto_config_dev(struct pnp_dev *dev);
483int pnp_start_dev(struct pnp_dev *dev); 485int pnp_start_dev(struct pnp_dev *dev);
484int pnp_stop_dev(struct pnp_dev *dev); 486int pnp_stop_dev(struct pnp_dev *dev);
@@ -506,6 +508,9 @@ static inline int pnp_register_card_driver(struct pnp_card_driver *drv) { return
506static inline void pnp_unregister_card_driver(struct pnp_card_driver *drv) { } 508static inline void pnp_unregister_card_driver(struct pnp_card_driver *drv) { }
507 509
508/* resource management */ 510/* resource management */
511static inline int pnp_possible_config(struct pnp_dev *dev, int type,
512 resource_size_t base,
513 resource_size_t size) { return 0; }
509static inline int pnp_auto_config_dev(struct pnp_dev *dev) { return -ENODEV; } 514static inline int pnp_auto_config_dev(struct pnp_dev *dev) { return -ENODEV; }
510static inline int pnp_start_dev(struct pnp_dev *dev) { return -ENODEV; } 515static inline int pnp_start_dev(struct pnp_dev *dev) { return -ENODEV; }
511static inline int pnp_stop_dev(struct pnp_dev *dev) { return -ENODEV; } 516static inline int pnp_stop_dev(struct pnp_dev *dev) { return -ENODEV; }