diff options
| author | Bjorn Helgaas <bjorn.helgaas@hp.com> | 2008-06-27 18:57:01 -0400 |
|---|---|---|
| committer | Andi Kleen <andi@basil.nowhere.org> | 2008-07-16 17:27:06 -0400 |
| commit | 57fd51a8be26921b56747ddd09d1d9e01c11c9e0 (patch) | |
| tree | 8b34c3d57867a217cfabf09a73a1af19242bdc7b | |
| parent | f61ed7e32d2d6a0a8c3c101da513ccedd542e14d (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.c | 62 | ||||
| -rw-r--r-- | drivers/serial/8250_pnp.c | 24 | ||||
| -rw-r--r-- | include/linux/pnp.h | 5 |
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 | ||
| 627 | static 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 | */ | ||
| 676 | int 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 | } | ||
| 687 | EXPORT_SYMBOL(pnp_possible_config); | ||
| 688 | |||
| 627 | /* format is: pnp_reserve_irq=irq1[,irq2] .... */ | 689 | /* format is: pnp_reserve_irq=irq1[,irq2] .... */ |
| 628 | static int __init pnp_setup_reserve_irq(char *str) | 690 | static 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 | ||
| 386 | static int __devinit check_resources(struct pnp_option *option) | 386 | static 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); | |||
| 479 | extern struct list_head pnp_cards; | 479 | extern struct list_head pnp_cards; |
| 480 | 480 | ||
| 481 | /* resource management */ | 481 | /* resource management */ |
| 482 | int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t base, | ||
| 483 | resource_size_t size); | ||
| 482 | int pnp_auto_config_dev(struct pnp_dev *dev); | 484 | int pnp_auto_config_dev(struct pnp_dev *dev); |
| 483 | int pnp_start_dev(struct pnp_dev *dev); | 485 | int pnp_start_dev(struct pnp_dev *dev); |
| 484 | int pnp_stop_dev(struct pnp_dev *dev); | 486 | int pnp_stop_dev(struct pnp_dev *dev); |
| @@ -506,6 +508,9 @@ static inline int pnp_register_card_driver(struct pnp_card_driver *drv) { return | |||
| 506 | static inline void pnp_unregister_card_driver(struct pnp_card_driver *drv) { } | 508 | static inline void pnp_unregister_card_driver(struct pnp_card_driver *drv) { } |
| 507 | 509 | ||
| 508 | /* resource management */ | 510 | /* resource management */ |
| 511 | static inline int pnp_possible_config(struct pnp_dev *dev, int type, | ||
| 512 | resource_size_t base, | ||
| 513 | resource_size_t size) { return 0; } | ||
| 509 | static inline int pnp_auto_config_dev(struct pnp_dev *dev) { return -ENODEV; } | 514 | static inline int pnp_auto_config_dev(struct pnp_dev *dev) { return -ENODEV; } |
| 510 | static inline int pnp_start_dev(struct pnp_dev *dev) { return -ENODEV; } | 515 | static inline int pnp_start_dev(struct pnp_dev *dev) { return -ENODEV; } |
| 511 | static inline int pnp_stop_dev(struct pnp_dev *dev) { return -ENODEV; } | 516 | static inline int pnp_stop_dev(struct pnp_dev *dev) { return -ENODEV; } |
