diff options
author | Daniel Drake <dsd@laptop.org> | 2012-04-18 15:09:44 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-04-23 15:34:06 -0400 |
commit | 488c3ee77ea0e63c9ae4736b1610aaf39c6527ee (patch) | |
tree | b3d4e4d15cecfe469b22943f883e469e292be5b7 /drivers/net/wireless/libertas | |
parent | 990e08a0f6115ce93b480325a575b535c92513ee (diff) |
libertas CS: convert to asynchronous firmware loading
Signed-off-by: Daniel Drake <dsd@laptop.org>
Tested-by: Dan Williams <dcbw@redhat.com>
Acked-by: Dan Williams <dcbw@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas')
-rw-r--r-- | drivers/net/wireless/libertas/if_cs.c | 88 |
1 files changed, 49 insertions, 39 deletions
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index cee50528522b..16beaf39dc53 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c | |||
@@ -738,6 +738,50 @@ done: | |||
738 | return ret; | 738 | return ret; |
739 | } | 739 | } |
740 | 740 | ||
741 | static void if_cs_prog_firmware(struct lbs_private *priv, int ret, | ||
742 | const struct firmware *helper, | ||
743 | const struct firmware *mainfw) | ||
744 | { | ||
745 | struct if_cs_card *card = priv->card; | ||
746 | |||
747 | if (ret) { | ||
748 | pr_err("failed to find firmware (%d)\n", ret); | ||
749 | return; | ||
750 | } | ||
751 | |||
752 | /* Load the firmware */ | ||
753 | ret = if_cs_prog_helper(card, helper); | ||
754 | if (ret == 0 && (card->model != MODEL_8305)) | ||
755 | ret = if_cs_prog_real(card, mainfw); | ||
756 | if (ret) | ||
757 | goto out; | ||
758 | |||
759 | /* Now actually get the IRQ */ | ||
760 | ret = request_irq(card->p_dev->irq, if_cs_interrupt, | ||
761 | IRQF_SHARED, DRV_NAME, card); | ||
762 | if (ret) { | ||
763 | pr_err("error in request_irq\n"); | ||
764 | goto out; | ||
765 | } | ||
766 | |||
767 | /* | ||
768 | * Clear any interrupt cause that happened while sending | ||
769 | * firmware/initializing card | ||
770 | */ | ||
771 | if_cs_write16(card, IF_CS_CARD_INT_CAUSE, IF_CS_BIT_MASK); | ||
772 | if_cs_enable_ints(card); | ||
773 | |||
774 | /* And finally bring the card up */ | ||
775 | priv->fw_ready = 1; | ||
776 | if (lbs_start_card(priv) != 0) { | ||
777 | pr_err("could not activate card\n"); | ||
778 | free_irq(card->p_dev->irq, card); | ||
779 | } | ||
780 | |||
781 | out: | ||
782 | release_firmware(helper); | ||
783 | release_firmware(mainfw); | ||
784 | } | ||
741 | 785 | ||
742 | 786 | ||
743 | /********************************************************************/ | 787 | /********************************************************************/ |
@@ -809,8 +853,6 @@ static int if_cs_probe(struct pcmcia_device *p_dev) | |||
809 | unsigned int prod_id; | 853 | unsigned int prod_id; |
810 | struct lbs_private *priv; | 854 | struct lbs_private *priv; |
811 | struct if_cs_card *card; | 855 | struct if_cs_card *card; |
812 | const struct firmware *helper = NULL; | ||
813 | const struct firmware *mainfw = NULL; | ||
814 | 856 | ||
815 | lbs_deb_enter(LBS_DEB_CS); | 857 | lbs_deb_enter(LBS_DEB_CS); |
816 | 858 | ||
@@ -890,20 +932,6 @@ static int if_cs_probe(struct pcmcia_device *p_dev) | |||
890 | goto out2; | 932 | goto out2; |
891 | } | 933 | } |
892 | 934 | ||
893 | ret = lbs_get_firmware(&p_dev->dev, card->model, &fw_table[0], | ||
894 | &helper, &mainfw); | ||
895 | if (ret) { | ||
896 | pr_err("failed to find firmware (%d)\n", ret); | ||
897 | goto out2; | ||
898 | } | ||
899 | |||
900 | /* Load the firmware early, before calling into libertas.ko */ | ||
901 | ret = if_cs_prog_helper(card, helper); | ||
902 | if (ret == 0 && (card->model != MODEL_8305)) | ||
903 | ret = if_cs_prog_real(card, mainfw); | ||
904 | if (ret) | ||
905 | goto out2; | ||
906 | |||
907 | /* Make this card known to the libertas driver */ | 935 | /* Make this card known to the libertas driver */ |
908 | priv = lbs_add_card(card, &p_dev->dev); | 936 | priv = lbs_add_card(card, &p_dev->dev); |
909 | if (!priv) { | 937 | if (!priv) { |
@@ -911,37 +939,22 @@ static int if_cs_probe(struct pcmcia_device *p_dev) | |||
911 | goto out2; | 939 | goto out2; |
912 | } | 940 | } |
913 | 941 | ||
914 | /* Finish setting up fields in lbs_private */ | 942 | /* Set up fields in lbs_private */ |
915 | card->priv = priv; | 943 | card->priv = priv; |
916 | priv->card = card; | 944 | priv->card = card; |
917 | priv->hw_host_to_card = if_cs_host_to_card; | 945 | priv->hw_host_to_card = if_cs_host_to_card; |
918 | priv->enter_deep_sleep = NULL; | 946 | priv->enter_deep_sleep = NULL; |
919 | priv->exit_deep_sleep = NULL; | 947 | priv->exit_deep_sleep = NULL; |
920 | priv->reset_deep_sleep_wakeup = NULL; | 948 | priv->reset_deep_sleep_wakeup = NULL; |
921 | priv->fw_ready = 1; | ||
922 | 949 | ||
923 | /* Now actually get the IRQ */ | 950 | /* Get firmware */ |
924 | ret = request_irq(p_dev->irq, if_cs_interrupt, | 951 | ret = lbs_get_firmware_async(priv, &p_dev->dev, card->model, fw_table, |
925 | IRQF_SHARED, DRV_NAME, card); | 952 | if_cs_prog_firmware); |
926 | if (ret) { | 953 | if (ret) { |
927 | pr_err("error in request_irq\n"); | 954 | pr_err("failed to find firmware (%d)\n", ret); |
928 | goto out3; | ||
929 | } | ||
930 | |||
931 | /* | ||
932 | * Clear any interrupt cause that happened while sending | ||
933 | * firmware/initializing card | ||
934 | */ | ||
935 | if_cs_write16(card, IF_CS_CARD_INT_CAUSE, IF_CS_BIT_MASK); | ||
936 | if_cs_enable_ints(card); | ||
937 | |||
938 | /* And finally bring the card up */ | ||
939 | if (lbs_start_card(priv) != 0) { | ||
940 | pr_err("could not activate card\n"); | ||
941 | goto out3; | 955 | goto out3; |
942 | } | 956 | } |
943 | 957 | ||
944 | ret = 0; | ||
945 | goto out; | 958 | goto out; |
946 | 959 | ||
947 | out3: | 960 | out3: |
@@ -951,9 +964,6 @@ out2: | |||
951 | out1: | 964 | out1: |
952 | pcmcia_disable_device(p_dev); | 965 | pcmcia_disable_device(p_dev); |
953 | out: | 966 | out: |
954 | release_firmware(helper); | ||
955 | release_firmware(mainfw); | ||
956 | |||
957 | lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); | 967 | lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); |
958 | return ret; | 968 | return ret; |
959 | } | 969 | } |