aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2009-10-18 12:14:32 -0400
committerDominik Brodowski <linux@dominikbrodowski.net>2009-10-24 11:13:01 -0400
commit6ae3b84d979308671bf6f6a2123c258a8603d61c (patch)
tree63fdd28c8b92cd34fbaf7d4cac3644cc7b06822c /drivers
parentbb015f0c85362aa767f8f00f50a40d85e489414f (diff)
serial_cs: use pcmcia_loop_config() and pre-determined values
As the PCMCIA core already determines the multifunction count, the ConfigBase address and the Present value, we can use them directly instead of parsing the CIS again. By making use of pcmcia_loop_config(), we can further remove the remaining call to pcmcia_get_first_tuple() and friends. CC: linux-serial@vger.kernel.org CC: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/serial/serial_cs.c87
1 files changed, 23 insertions, 64 deletions
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index ff4617e21426..7bf02cf3123f 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -426,21 +426,6 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
426 426
427/*====================================================================*/ 427/*====================================================================*/
428 428
429static int
430first_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse)
431{
432 int i;
433 i = pcmcia_get_first_tuple(handle, tuple);
434 if (i != 0)
435 return i;
436 i = pcmcia_get_tuple_data(handle, tuple);
437 if (i != 0)
438 return i;
439 return pcmcia_parse_tuple(tuple, parse);
440}
441
442/*====================================================================*/
443
444static int simple_config_check(struct pcmcia_device *p_dev, 429static int simple_config_check(struct pcmcia_device *p_dev,
445 cistpl_cftable_entry_t *cf, 430 cistpl_cftable_entry_t *cf,
446 cistpl_cftable_entry_t *dflt, 431 cistpl_cftable_entry_t *dflt,
@@ -665,6 +650,25 @@ static int multi_config(struct pcmcia_device *link)
665 return 0; 650 return 0;
666} 651}
667 652
653static int serial_check_for_multi(struct pcmcia_device *p_dev,
654 cistpl_cftable_entry_t *cf,
655 cistpl_cftable_entry_t *dflt,
656 unsigned int vcc,
657 void *priv_data)
658{
659 struct serial_info *info = p_dev->priv;
660
661 if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
662 info->multi = cf->io.win[0].len >> 3;
663
664 if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
665 (cf->io.win[1].len == 8))
666 info->multi = 2;
667
668 return 0; /* break */
669}
670
671
668/*====================================================================== 672/*======================================================================
669 673
670 serial_config() is scheduled to run after a CARD_INSERTION event 674 serial_config() is scheduled to run after a CARD_INSERTION event
@@ -676,46 +680,14 @@ static int multi_config(struct pcmcia_device *link)
676static int serial_config(struct pcmcia_device * link) 680static int serial_config(struct pcmcia_device * link)
677{ 681{
678 struct serial_info *info = link->priv; 682 struct serial_info *info = link->priv;
679 struct serial_cfg_mem *cfg_mem; 683 int i;
680 tuple_t *tuple;
681 u_char *buf;
682 cisparse_t *parse;
683 cistpl_cftable_entry_t *cf;
684 int i, last_ret, last_fn;
685 684
686 DEBUG(0, "serial_config(0x%p)\n", link); 685 DEBUG(0, "serial_config(0x%p)\n", link);
687 686
688 cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL);
689 if (!cfg_mem)
690 goto failed;
691
692 tuple = &cfg_mem->tuple;
693 parse = &cfg_mem->parse;
694 cf = &parse->cftable_entry;
695 buf = cfg_mem->buf;
696
697 tuple->TupleData = (cisdata_t *) buf;
698 tuple->TupleOffset = 0;
699 tuple->TupleDataMax = 255;
700 tuple->Attributes = 0;
701
702 /* Get configuration register information */
703 tuple->DesiredTuple = CISTPL_CONFIG;
704 last_ret = first_tuple(link, tuple, parse);
705 if (last_ret != 0) {
706 last_fn = ParseTuple;
707 goto cs_failed;
708 }
709 link->conf.ConfigBase = parse->config.base;
710 link->conf.Present = parse->config.rmask[0];
711
712 /* Is this a compliant multifunction card? */ 687 /* Is this a compliant multifunction card? */
713 tuple->DesiredTuple = CISTPL_LONGLINK_MFC; 688 info->multi = (link->socket->functions > 1);
714 tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
715 info->multi = (first_tuple(link, tuple, parse) == 0);
716 689
717 /* Is this a multiport card? */ 690 /* Is this a multiport card? */
718 tuple->DesiredTuple = CISTPL_MANFID;
719 info->manfid = link->manf_id; 691 info->manfid = link->manf_id;
720 info->prodid = link->card_id; 692 info->prodid = link->card_id;
721 693
@@ -730,20 +702,11 @@ static int serial_config(struct pcmcia_device * link)
730 702
731 /* Another check for dual-serial cards: look for either serial or 703 /* Another check for dual-serial cards: look for either serial or
732 multifunction cards that ask for appropriate IO port ranges */ 704 multifunction cards that ask for appropriate IO port ranges */
733 tuple->DesiredTuple = CISTPL_FUNCID;
734 if ((info->multi == 0) && 705 if ((info->multi == 0) &&
735 (link->has_func_id) && 706 (link->has_func_id) &&
736 ((link->func_id == CISTPL_FUNCID_MULTI) || 707 ((link->func_id == CISTPL_FUNCID_MULTI) ||
737 (link->func_id == CISTPL_FUNCID_SERIAL))) { 708 (link->func_id == CISTPL_FUNCID_SERIAL)))
738 tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; 709 pcmcia_loop_config(link, serial_check_for_multi, info);
739 if (first_tuple(link, tuple, parse) == 0) {
740 if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
741 info->multi = cf->io.win[0].len >> 3;
742 if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
743 (cf->io.win[1].len == 8))
744 info->multi = 2;
745 }
746 }
747 710
748 /* 711 /*
749 * Apply any multi-port quirk. 712 * Apply any multi-port quirk.
@@ -768,14 +731,10 @@ static int serial_config(struct pcmcia_device * link)
768 goto failed; 731 goto failed;
769 732
770 link->dev_node = &info->node[0]; 733 link->dev_node = &info->node[0];
771 kfree(cfg_mem);
772 return 0; 734 return 0;
773 735
774cs_failed:
775 cs_error(link, last_fn, last_ret);
776failed: 736failed:
777 serial_remove(link); 737 serial_remove(link);
778 kfree(cfg_mem);
779 return -ENODEV; 738 return -ENODEV;
780} 739}
781 740