diff options
Diffstat (limited to 'drivers/bluetooth/bt3c_cs.c')
-rw-r--r-- | drivers/bluetooth/bt3c_cs.c | 130 |
1 files changed, 39 insertions, 91 deletions
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 7e21b1ff27c4..b94ac2f9f7ba 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c | |||
@@ -72,7 +72,7 @@ MODULE_LICENSE("GPL"); | |||
72 | 72 | ||
73 | 73 | ||
74 | typedef struct bt3c_info_t { | 74 | typedef struct bt3c_info_t { |
75 | dev_link_t link; | 75 | struct pcmcia_device *p_dev; |
76 | dev_node_t node; | 76 | dev_node_t node; |
77 | 77 | ||
78 | struct hci_dev *hdev; | 78 | struct hci_dev *hdev; |
@@ -88,8 +88,8 @@ typedef struct bt3c_info_t { | |||
88 | } bt3c_info_t; | 88 | } bt3c_info_t; |
89 | 89 | ||
90 | 90 | ||
91 | static void bt3c_config(dev_link_t *link); | 91 | static int bt3c_config(struct pcmcia_device *link); |
92 | static void bt3c_release(dev_link_t *link); | 92 | static void bt3c_release(struct pcmcia_device *link); |
93 | 93 | ||
94 | static void bt3c_detach(struct pcmcia_device *p_dev); | 94 | static void bt3c_detach(struct pcmcia_device *p_dev); |
95 | 95 | ||
@@ -191,11 +191,11 @@ static void bt3c_write_wakeup(bt3c_info_t *info) | |||
191 | return; | 191 | return; |
192 | 192 | ||
193 | do { | 193 | do { |
194 | register unsigned int iobase = info->link.io.BasePort1; | 194 | register unsigned int iobase = info->p_dev->io.BasePort1; |
195 | register struct sk_buff *skb; | 195 | register struct sk_buff *skb; |
196 | register int len; | 196 | register int len; |
197 | 197 | ||
198 | if (!(info->link.state & DEV_PRESENT)) | 198 | if (!pcmcia_dev_present(info->p_dev)) |
199 | break; | 199 | break; |
200 | 200 | ||
201 | 201 | ||
@@ -229,7 +229,7 @@ static void bt3c_receive(bt3c_info_t *info) | |||
229 | return; | 229 | return; |
230 | } | 230 | } |
231 | 231 | ||
232 | iobase = info->link.io.BasePort1; | 232 | iobase = info->p_dev->io.BasePort1; |
233 | 233 | ||
234 | avail = bt3c_read(iobase, 0x7006); | 234 | avail = bt3c_read(iobase, 0x7006); |
235 | //printk("bt3c_cs: receiving %d bytes\n", avail); | 235 | //printk("bt3c_cs: receiving %d bytes\n", avail); |
@@ -350,7 +350,7 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst, struct pt_regs *regs) | |||
350 | return IRQ_NONE; | 350 | return IRQ_NONE; |
351 | } | 351 | } |
352 | 352 | ||
353 | iobase = info->link.io.BasePort1; | 353 | iobase = info->p_dev->io.BasePort1; |
354 | 354 | ||
355 | spin_lock(&(info->lock)); | 355 | spin_lock(&(info->lock)); |
356 | 356 | ||
@@ -481,7 +481,7 @@ static int bt3c_load_firmware(bt3c_info_t *info, unsigned char *firmware, int co | |||
481 | unsigned int iobase, size, addr, fcs, tmp; | 481 | unsigned int iobase, size, addr, fcs, tmp; |
482 | int i, err = 0; | 482 | int i, err = 0; |
483 | 483 | ||
484 | iobase = info->link.io.BasePort1; | 484 | iobase = info->p_dev->io.BasePort1; |
485 | 485 | ||
486 | /* Reset */ | 486 | /* Reset */ |
487 | bt3c_io_write(iobase, 0x8040, 0x0404); | 487 | bt3c_io_write(iobase, 0x8040, 0x0404); |
@@ -562,7 +562,6 @@ static int bt3c_open(bt3c_info_t *info) | |||
562 | { | 562 | { |
563 | const struct firmware *firmware; | 563 | const struct firmware *firmware; |
564 | struct hci_dev *hdev; | 564 | struct hci_dev *hdev; |
565 | client_handle_t handle; | ||
566 | int err; | 565 | int err; |
567 | 566 | ||
568 | spin_lock_init(&(info->lock)); | 567 | spin_lock_init(&(info->lock)); |
@@ -594,10 +593,8 @@ static int bt3c_open(bt3c_info_t *info) | |||
594 | 593 | ||
595 | hdev->owner = THIS_MODULE; | 594 | hdev->owner = THIS_MODULE; |
596 | 595 | ||
597 | handle = info->link.handle; | ||
598 | |||
599 | /* Load firmware */ | 596 | /* Load firmware */ |
600 | err = request_firmware(&firmware, "BT3CPCC.bin", &handle_to_dev(handle)); | 597 | err = request_firmware(&firmware, "BT3CPCC.bin", &info->p_dev->dev); |
601 | if (err < 0) { | 598 | if (err < 0) { |
602 | BT_ERR("Firmware request failed"); | 599 | BT_ERR("Firmware request failed"); |
603 | goto error; | 600 | goto error; |
@@ -648,17 +645,16 @@ static int bt3c_close(bt3c_info_t *info) | |||
648 | return 0; | 645 | return 0; |
649 | } | 646 | } |
650 | 647 | ||
651 | static int bt3c_attach(struct pcmcia_device *p_dev) | 648 | static int bt3c_probe(struct pcmcia_device *link) |
652 | { | 649 | { |
653 | bt3c_info_t *info; | 650 | bt3c_info_t *info; |
654 | dev_link_t *link; | ||
655 | 651 | ||
656 | /* Create new info device */ | 652 | /* Create new info device */ |
657 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 653 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
658 | if (!info) | 654 | if (!info) |
659 | return -ENOMEM; | 655 | return -ENOMEM; |
660 | 656 | ||
661 | link = &info->link; | 657 | info->p_dev = link; |
662 | link->priv = info; | 658 | link->priv = info; |
663 | 659 | ||
664 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 660 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; |
@@ -670,31 +666,21 @@ static int bt3c_attach(struct pcmcia_device *p_dev) | |||
670 | link->irq.Instance = info; | 666 | link->irq.Instance = info; |
671 | 667 | ||
672 | link->conf.Attributes = CONF_ENABLE_IRQ; | 668 | link->conf.Attributes = CONF_ENABLE_IRQ; |
673 | link->conf.Vcc = 50; | ||
674 | link->conf.IntType = INT_MEMORY_AND_IO; | 669 | link->conf.IntType = INT_MEMORY_AND_IO; |
675 | 670 | ||
676 | link->handle = p_dev; | 671 | return bt3c_config(link); |
677 | p_dev->instance = link; | ||
678 | |||
679 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
680 | bt3c_config(link); | ||
681 | |||
682 | return 0; | ||
683 | } | 672 | } |
684 | 673 | ||
685 | 674 | ||
686 | static void bt3c_detach(struct pcmcia_device *p_dev) | 675 | static void bt3c_detach(struct pcmcia_device *link) |
687 | { | 676 | { |
688 | dev_link_t *link = dev_to_instance(p_dev); | ||
689 | bt3c_info_t *info = link->priv; | 677 | bt3c_info_t *info = link->priv; |
690 | 678 | ||
691 | if (link->state & DEV_CONFIG) | 679 | bt3c_release(link); |
692 | bt3c_release(link); | ||
693 | |||
694 | kfree(info); | 680 | kfree(info); |
695 | } | 681 | } |
696 | 682 | ||
697 | static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) | 683 | static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) |
698 | { | 684 | { |
699 | int i; | 685 | int i; |
700 | 686 | ||
@@ -705,30 +691,28 @@ static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) | |||
705 | return pcmcia_parse_tuple(handle, tuple, parse); | 691 | return pcmcia_parse_tuple(handle, tuple, parse); |
706 | } | 692 | } |
707 | 693 | ||
708 | static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) | 694 | static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) |
709 | { | 695 | { |
710 | if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) | 696 | if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) |
711 | return CS_NO_MORE_ITEMS; | 697 | return CS_NO_MORE_ITEMS; |
712 | return get_tuple(handle, tuple, parse); | 698 | return get_tuple(handle, tuple, parse); |
713 | } | 699 | } |
714 | 700 | ||
715 | static int next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) | 701 | static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) |
716 | { | 702 | { |
717 | if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS) | 703 | if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS) |
718 | return CS_NO_MORE_ITEMS; | 704 | return CS_NO_MORE_ITEMS; |
719 | return get_tuple(handle, tuple, parse); | 705 | return get_tuple(handle, tuple, parse); |
720 | } | 706 | } |
721 | 707 | ||
722 | static void bt3c_config(dev_link_t *link) | 708 | static int bt3c_config(struct pcmcia_device *link) |
723 | { | 709 | { |
724 | static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; | 710 | static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; |
725 | client_handle_t handle = link->handle; | ||
726 | bt3c_info_t *info = link->priv; | 711 | bt3c_info_t *info = link->priv; |
727 | tuple_t tuple; | 712 | tuple_t tuple; |
728 | u_short buf[256]; | 713 | u_short buf[256]; |
729 | cisparse_t parse; | 714 | cisparse_t parse; |
730 | cistpl_cftable_entry_t *cf = &parse.cftable_entry; | 715 | cistpl_cftable_entry_t *cf = &parse.cftable_entry; |
731 | config_info_t config; | ||
732 | int i, j, try, last_ret, last_fn; | 716 | int i, j, try, last_ret, last_fn; |
733 | 717 | ||
734 | tuple.TupleData = (cisdata_t *)buf; | 718 | tuple.TupleData = (cisdata_t *)buf; |
@@ -738,7 +722,7 @@ static void bt3c_config(dev_link_t *link) | |||
738 | 722 | ||
739 | /* Get configuration register information */ | 723 | /* Get configuration register information */ |
740 | tuple.DesiredTuple = CISTPL_CONFIG; | 724 | tuple.DesiredTuple = CISTPL_CONFIG; |
741 | last_ret = first_tuple(handle, &tuple, &parse); | 725 | last_ret = first_tuple(link, &tuple, &parse); |
742 | if (last_ret != CS_SUCCESS) { | 726 | if (last_ret != CS_SUCCESS) { |
743 | last_fn = ParseTuple; | 727 | last_fn = ParseTuple; |
744 | goto cs_failed; | 728 | goto cs_failed; |
@@ -746,11 +730,6 @@ static void bt3c_config(dev_link_t *link) | |||
746 | link->conf.ConfigBase = parse.config.base; | 730 | link->conf.ConfigBase = parse.config.base; |
747 | link->conf.Present = parse.config.rmask[0]; | 731 | link->conf.Present = parse.config.rmask[0]; |
748 | 732 | ||
749 | /* Configure card */ | ||
750 | link->state |= DEV_CONFIG; | ||
751 | i = pcmcia_get_configuration_info(handle, &config); | ||
752 | link->conf.Vcc = config.Vcc; | ||
753 | |||
754 | /* First pass: look for a config entry that looks normal. */ | 733 | /* First pass: look for a config entry that looks normal. */ |
755 | tuple.TupleData = (cisdata_t *)buf; | 734 | tuple.TupleData = (cisdata_t *)buf; |
756 | tuple.TupleOffset = 0; | 735 | tuple.TupleOffset = 0; |
@@ -759,59 +738,59 @@ static void bt3c_config(dev_link_t *link) | |||
759 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 738 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; |
760 | /* Two tries: without IO aliases, then with aliases */ | 739 | /* Two tries: without IO aliases, then with aliases */ |
761 | for (try = 0; try < 2; try++) { | 740 | for (try = 0; try < 2; try++) { |
762 | i = first_tuple(handle, &tuple, &parse); | 741 | i = first_tuple(link, &tuple, &parse); |
763 | while (i != CS_NO_MORE_ITEMS) { | 742 | while (i != CS_NO_MORE_ITEMS) { |
764 | if (i != CS_SUCCESS) | 743 | if (i != CS_SUCCESS) |
765 | goto next_entry; | 744 | goto next_entry; |
766 | if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) | 745 | if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) |
767 | link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; | 746 | link->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; |
768 | if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) { | 747 | if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) { |
769 | link->conf.ConfigIndex = cf->index; | 748 | link->conf.ConfigIndex = cf->index; |
770 | link->io.BasePort1 = cf->io.win[0].base; | 749 | link->io.BasePort1 = cf->io.win[0].base; |
771 | link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; | 750 | link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; |
772 | i = pcmcia_request_io(link->handle, &link->io); | 751 | i = pcmcia_request_io(link, &link->io); |
773 | if (i == CS_SUCCESS) | 752 | if (i == CS_SUCCESS) |
774 | goto found_port; | 753 | goto found_port; |
775 | } | 754 | } |
776 | next_entry: | 755 | next_entry: |
777 | i = next_tuple(handle, &tuple, &parse); | 756 | i = next_tuple(link, &tuple, &parse); |
778 | } | 757 | } |
779 | } | 758 | } |
780 | 759 | ||
781 | /* Second pass: try to find an entry that isn't picky about | 760 | /* Second pass: try to find an entry that isn't picky about |
782 | its base address, then try to grab any standard serial port | 761 | its base address, then try to grab any standard serial port |
783 | address, and finally try to get any free port. */ | 762 | address, and finally try to get any free port. */ |
784 | i = first_tuple(handle, &tuple, &parse); | 763 | i = first_tuple(link, &tuple, &parse); |
785 | while (i != CS_NO_MORE_ITEMS) { | 764 | while (i != CS_NO_MORE_ITEMS) { |
786 | if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { | 765 | if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { |
787 | link->conf.ConfigIndex = cf->index; | 766 | link->conf.ConfigIndex = cf->index; |
788 | for (j = 0; j < 5; j++) { | 767 | for (j = 0; j < 5; j++) { |
789 | link->io.BasePort1 = base[j]; | 768 | link->io.BasePort1 = base[j]; |
790 | link->io.IOAddrLines = base[j] ? 16 : 3; | 769 | link->io.IOAddrLines = base[j] ? 16 : 3; |
791 | i = pcmcia_request_io(link->handle, &link->io); | 770 | i = pcmcia_request_io(link, &link->io); |
792 | if (i == CS_SUCCESS) | 771 | if (i == CS_SUCCESS) |
793 | goto found_port; | 772 | goto found_port; |
794 | } | 773 | } |
795 | } | 774 | } |
796 | i = next_tuple(handle, &tuple, &parse); | 775 | i = next_tuple(link, &tuple, &parse); |
797 | } | 776 | } |
798 | 777 | ||
799 | found_port: | 778 | found_port: |
800 | if (i != CS_SUCCESS) { | 779 | if (i != CS_SUCCESS) { |
801 | BT_ERR("No usable port range found"); | 780 | BT_ERR("No usable port range found"); |
802 | cs_error(link->handle, RequestIO, i); | 781 | cs_error(link, RequestIO, i); |
803 | goto failed; | 782 | goto failed; |
804 | } | 783 | } |
805 | 784 | ||
806 | i = pcmcia_request_irq(link->handle, &link->irq); | 785 | i = pcmcia_request_irq(link, &link->irq); |
807 | if (i != CS_SUCCESS) { | 786 | if (i != CS_SUCCESS) { |
808 | cs_error(link->handle, RequestIRQ, i); | 787 | cs_error(link, RequestIRQ, i); |
809 | link->irq.AssignedIRQ = 0; | 788 | link->irq.AssignedIRQ = 0; |
810 | } | 789 | } |
811 | 790 | ||
812 | i = pcmcia_request_configuration(link->handle, &link->conf); | 791 | i = pcmcia_request_configuration(link, &link->conf); |
813 | if (i != CS_SUCCESS) { | 792 | if (i != CS_SUCCESS) { |
814 | cs_error(link->handle, RequestConfiguration, i); | 793 | cs_error(link, RequestConfiguration, i); |
815 | goto failed; | 794 | goto failed; |
816 | } | 795 | } |
817 | 796 | ||
@@ -819,55 +798,26 @@ found_port: | |||
819 | goto failed; | 798 | goto failed; |
820 | 799 | ||
821 | strcpy(info->node.dev_name, info->hdev->name); | 800 | strcpy(info->node.dev_name, info->hdev->name); |
822 | link->dev = &info->node; | 801 | link->dev_node = &info->node; |
823 | link->state &= ~DEV_CONFIG_PENDING; | ||
824 | 802 | ||
825 | return; | 803 | return 0; |
826 | 804 | ||
827 | cs_failed: | 805 | cs_failed: |
828 | cs_error(link->handle, last_fn, last_ret); | 806 | cs_error(link, last_fn, last_ret); |
829 | 807 | ||
830 | failed: | 808 | failed: |
831 | bt3c_release(link); | 809 | bt3c_release(link); |
810 | return -ENODEV; | ||
832 | } | 811 | } |
833 | 812 | ||
834 | 813 | ||
835 | static void bt3c_release(dev_link_t *link) | 814 | static void bt3c_release(struct pcmcia_device *link) |
836 | { | 815 | { |
837 | bt3c_info_t *info = link->priv; | 816 | bt3c_info_t *info = link->priv; |
838 | 817 | ||
839 | if (link->state & DEV_PRESENT) | 818 | bt3c_close(info); |
840 | bt3c_close(info); | ||
841 | |||
842 | link->dev = NULL; | ||
843 | |||
844 | pcmcia_release_configuration(link->handle); | ||
845 | pcmcia_release_io(link->handle, &link->io); | ||
846 | pcmcia_release_irq(link->handle, &link->irq); | ||
847 | |||
848 | link->state &= ~DEV_CONFIG; | ||
849 | } | ||
850 | |||
851 | static int bt3c_suspend(struct pcmcia_device *dev) | ||
852 | { | ||
853 | dev_link_t *link = dev_to_instance(dev); | ||
854 | 819 | ||
855 | link->state |= DEV_SUSPEND; | 820 | pcmcia_disable_device(link); |
856 | if (link->state & DEV_CONFIG) | ||
857 | pcmcia_release_configuration(link->handle); | ||
858 | |||
859 | return 0; | ||
860 | } | ||
861 | |||
862 | static int bt3c_resume(struct pcmcia_device *dev) | ||
863 | { | ||
864 | dev_link_t *link = dev_to_instance(dev); | ||
865 | |||
866 | link->state &= ~DEV_SUSPEND; | ||
867 | if (DEV_OK(link)) | ||
868 | pcmcia_request_configuration(link->handle, &link->conf); | ||
869 | |||
870 | return 0; | ||
871 | } | 821 | } |
872 | 822 | ||
873 | 823 | ||
@@ -882,11 +832,9 @@ static struct pcmcia_driver bt3c_driver = { | |||
882 | .drv = { | 832 | .drv = { |
883 | .name = "bt3c_cs", | 833 | .name = "bt3c_cs", |
884 | }, | 834 | }, |
885 | .probe = bt3c_attach, | 835 | .probe = bt3c_probe, |
886 | .remove = bt3c_detach, | 836 | .remove = bt3c_detach, |
887 | .id_table = bt3c_ids, | 837 | .id_table = bt3c_ids, |
888 | .suspend = bt3c_suspend, | ||
889 | .resume = bt3c_resume, | ||
890 | }; | 838 | }; |
891 | 839 | ||
892 | static int __init init_bt3c_cs(void) | 840 | static int __init init_bt3c_cs(void) |