diff options
Diffstat (limited to 'drivers/serial/serial_cs.c')
| -rw-r--r-- | drivers/serial/serial_cs.c | 62 |
1 files changed, 36 insertions, 26 deletions
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 141c69554bd4..7d475b2a79e8 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c | |||
| @@ -335,8 +335,6 @@ static int serial_probe(struct pcmcia_device *link) | |||
| 335 | info->p_dev = link; | 335 | info->p_dev = link; |
| 336 | link->priv = info; | 336 | link->priv = info; |
| 337 | 337 | ||
| 338 | link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; | ||
| 339 | link->resource[0]->end = 8; | ||
| 340 | link->conf.Attributes = CONF_ENABLE_IRQ; | 338 | link->conf.Attributes = CONF_ENABLE_IRQ; |
| 341 | if (do_sound) { | 339 | if (do_sound) { |
| 342 | link->conf.Attributes |= CONF_ENABLE_SPKR; | 340 | link->conf.Attributes |= CONF_ENABLE_SPKR; |
| @@ -411,6 +409,27 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info, | |||
| 411 | 409 | ||
| 412 | /*====================================================================*/ | 410 | /*====================================================================*/ |
| 413 | 411 | ||
| 412 | static int pfc_config(struct pcmcia_device *p_dev) | ||
| 413 | { | ||
| 414 | unsigned int port = 0; | ||
| 415 | struct serial_info *info = p_dev->priv; | ||
| 416 | |||
| 417 | if ((p_dev->resource[1]->end != 0) && | ||
| 418 | (resource_size(p_dev->resource[1]) == 8)) { | ||
| 419 | port = p_dev->resource[1]->start; | ||
| 420 | info->slave = 1; | ||
| 421 | } else if ((info->manfid == MANFID_OSITECH) && | ||
| 422 | (resource_size(p_dev->resource[0]) == 0x40)) { | ||
| 423 | port = p_dev->resource[0]->start + 0x28; | ||
| 424 | info->slave = 1; | ||
| 425 | } | ||
| 426 | if (info->slave) | ||
| 427 | return setup_serial(p_dev, info, port, p_dev->irq); | ||
| 428 | |||
| 429 | dev_warn(&p_dev->dev, "no usable port range found, giving up\n"); | ||
| 430 | return -ENODEV; | ||
| 431 | } | ||
| 432 | |||
| 414 | static int simple_config_check(struct pcmcia_device *p_dev, | 433 | static int simple_config_check(struct pcmcia_device *p_dev, |
| 415 | cistpl_cftable_entry_t *cf, | 434 | cistpl_cftable_entry_t *cf, |
| 416 | cistpl_cftable_entry_t *dflt, | 435 | cistpl_cftable_entry_t *dflt, |
| @@ -461,23 +480,8 @@ static int simple_config(struct pcmcia_device *link) | |||
| 461 | struct serial_info *info = link->priv; | 480 | struct serial_info *info = link->priv; |
| 462 | int i = -ENODEV, try; | 481 | int i = -ENODEV, try; |
| 463 | 482 | ||
| 464 | /* If the card is already configured, look up the port and irq */ | 483 | link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; |
| 465 | if (link->function_config) { | 484 | link->resource[0]->end = 8; |
| 466 | unsigned int port = 0; | ||
| 467 | if ((link->resource[1]->end != 0) && | ||
| 468 | (resource_size(link->resource[1]) == 8)) { | ||
| 469 | port = link->resource[1]->end; | ||
| 470 | info->slave = 1; | ||
| 471 | } else if ((info->manfid == MANFID_OSITECH) && | ||
| 472 | (resource_size(link->resource[0]) == 0x40)) { | ||
| 473 | port = link->resource[0]->start + 0x28; | ||
| 474 | info->slave = 1; | ||
| 475 | } | ||
| 476 | if (info->slave) { | ||
| 477 | return setup_serial(link, info, port, | ||
| 478 | link->irq); | ||
| 479 | } | ||
| 480 | } | ||
| 481 | 485 | ||
| 482 | /* First pass: look for a config entry that looks normal. | 486 | /* First pass: look for a config entry that looks normal. |
| 483 | * Two tries: without IO aliases, then with aliases */ | 487 | * Two tries: without IO aliases, then with aliases */ |
| @@ -491,8 +495,7 @@ static int simple_config(struct pcmcia_device *link) | |||
| 491 | if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL)) | 495 | if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL)) |
| 492 | goto found_port; | 496 | goto found_port; |
| 493 | 497 | ||
| 494 | printk(KERN_NOTICE | 498 | dev_warn(&link->dev, "no usable port range found, giving up\n"); |
| 495 | "serial_cs: no usable port range found, giving up\n"); | ||
| 496 | return -1; | 499 | return -1; |
| 497 | 500 | ||
| 498 | found_port: | 501 | found_port: |
| @@ -558,6 +561,7 @@ static int multi_config(struct pcmcia_device *link) | |||
| 558 | int i, base2 = 0; | 561 | int i, base2 = 0; |
| 559 | 562 | ||
| 560 | /* First, look for a generic full-sized window */ | 563 | /* First, look for a generic full-sized window */ |
| 564 | link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; | ||
| 561 | link->resource[0]->end = info->multi * 8; | 565 | link->resource[0]->end = info->multi * 8; |
| 562 | if (pcmcia_loop_config(link, multi_config_check, &base2)) { | 566 | if (pcmcia_loop_config(link, multi_config_check, &base2)) { |
| 563 | /* If that didn't work, look for two windows */ | 567 | /* If that didn't work, look for two windows */ |
| @@ -565,15 +569,14 @@ static int multi_config(struct pcmcia_device *link) | |||
| 565 | info->multi = 2; | 569 | info->multi = 2; |
| 566 | if (pcmcia_loop_config(link, multi_config_check_notpicky, | 570 | if (pcmcia_loop_config(link, multi_config_check_notpicky, |
| 567 | &base2)) { | 571 | &base2)) { |
| 568 | printk(KERN_NOTICE "serial_cs: no usable port range" | 572 | dev_warn(&link->dev, "no usable port range " |
| 569 | "found, giving up\n"); | 573 | "found, giving up\n"); |
| 570 | return -ENODEV; | 574 | return -ENODEV; |
| 571 | } | 575 | } |
| 572 | } | 576 | } |
| 573 | 577 | ||
| 574 | if (!link->irq) | 578 | if (!link->irq) |
| 575 | dev_warn(&link->dev, | 579 | dev_warn(&link->dev, "no usable IRQ found, continuing...\n"); |
| 576 | "serial_cs: no usable IRQ found, continuing...\n"); | ||
| 577 | 580 | ||
| 578 | /* | 581 | /* |
| 579 | * Apply any configuration quirks. | 582 | * Apply any configuration quirks. |
| @@ -675,6 +678,7 @@ static int serial_config(struct pcmcia_device * link) | |||
| 675 | multifunction cards that ask for appropriate IO port ranges */ | 678 | multifunction cards that ask for appropriate IO port ranges */ |
| 676 | if ((info->multi == 0) && | 679 | if ((info->multi == 0) && |
| 677 | (link->has_func_id) && | 680 | (link->has_func_id) && |
| 681 | (link->socket->pcmcia_pfc == 0) && | ||
| 678 | ((link->func_id == CISTPL_FUNCID_MULTI) || | 682 | ((link->func_id == CISTPL_FUNCID_MULTI) || |
| 679 | (link->func_id == CISTPL_FUNCID_SERIAL))) | 683 | (link->func_id == CISTPL_FUNCID_SERIAL))) |
| 680 | pcmcia_loop_config(link, serial_check_for_multi, info); | 684 | pcmcia_loop_config(link, serial_check_for_multi, info); |
| @@ -685,7 +689,13 @@ static int serial_config(struct pcmcia_device * link) | |||
| 685 | if (info->quirk && info->quirk->multi != -1) | 689 | if (info->quirk && info->quirk->multi != -1) |
| 686 | info->multi = info->quirk->multi; | 690 | info->multi = info->quirk->multi; |
| 687 | 691 | ||
| 688 | if (info->multi > 1) | 692 | dev_info(&link->dev, |
| 693 | "trying to set up [0x%04x:0x%04x] (pfc: %d, multi: %d, quirk: %p)\n", | ||
| 694 | link->manf_id, link->card_id, | ||
| 695 | link->socket->pcmcia_pfc, info->multi, info->quirk); | ||
| 696 | if (link->socket->pcmcia_pfc) | ||
| 697 | i = pfc_config(link); | ||
| 698 | else if (info->multi > 1) | ||
| 689 | i = multi_config(link); | 699 | i = multi_config(link); |
| 690 | else | 700 | else |
| 691 | i = simple_config(link); | 701 | i = simple_config(link); |
| @@ -704,7 +714,7 @@ static int serial_config(struct pcmcia_device * link) | |||
| 704 | return 0; | 714 | return 0; |
| 705 | 715 | ||
| 706 | failed: | 716 | failed: |
| 707 | dev_warn(&link->dev, "serial_cs: failed to initialize\n"); | 717 | dev_warn(&link->dev, "failed to initialize\n"); |
| 708 | serial_remove(link); | 718 | serial_remove(link); |
| 709 | return -ENODEV; | 719 | return -ENODEV; |
| 710 | } | 720 | } |
