diff options
Diffstat (limited to 'drivers/net/wireless/mwifiex/sdio.c')
-rw-r--r-- | drivers/net/wireless/mwifiex/sdio.c | 95 |
1 files changed, 44 insertions, 51 deletions
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index 5ee5ed02eccd..09185c963248 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c | |||
@@ -51,6 +51,7 @@ static struct mwifiex_if_ops sdio_ops; | |||
51 | static struct semaphore add_remove_card_sem; | 51 | static struct semaphore add_remove_card_sem; |
52 | 52 | ||
53 | static int mwifiex_sdio_resume(struct device *dev); | 53 | static int mwifiex_sdio_resume(struct device *dev); |
54 | static void mwifiex_sdio_interrupt(struct sdio_func *func); | ||
54 | 55 | ||
55 | /* | 56 | /* |
56 | * SDIO probe. | 57 | * SDIO probe. |
@@ -296,6 +297,15 @@ static struct sdio_driver mwifiex_sdio = { | |||
296 | } | 297 | } |
297 | }; | 298 | }; |
298 | 299 | ||
300 | /* Write data into SDIO card register. Caller claims SDIO device. */ | ||
301 | static int | ||
302 | mwifiex_write_reg_locked(struct sdio_func *func, u32 reg, u8 data) | ||
303 | { | ||
304 | int ret = -1; | ||
305 | sdio_writeb(func, data, reg, &ret); | ||
306 | return ret; | ||
307 | } | ||
308 | |||
299 | /* | 309 | /* |
300 | * This function writes data into SDIO card register. | 310 | * This function writes data into SDIO card register. |
301 | */ | 311 | */ |
@@ -303,10 +313,10 @@ static int | |||
303 | mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u8 data) | 313 | mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u8 data) |
304 | { | 314 | { |
305 | struct sdio_mmc_card *card = adapter->card; | 315 | struct sdio_mmc_card *card = adapter->card; |
306 | int ret = -1; | 316 | int ret; |
307 | 317 | ||
308 | sdio_claim_host(card->func); | 318 | sdio_claim_host(card->func); |
309 | sdio_writeb(card->func, data, reg, &ret); | 319 | ret = mwifiex_write_reg_locked(card->func, reg, data); |
310 | sdio_release_host(card->func); | 320 | sdio_release_host(card->func); |
311 | 321 | ||
312 | return ret; | 322 | return ret; |
@@ -685,23 +695,15 @@ mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat) | |||
685 | * The host interrupt mask is read, the disable bit is reset and | 695 | * The host interrupt mask is read, the disable bit is reset and |
686 | * written back to the card host interrupt mask register. | 696 | * written back to the card host interrupt mask register. |
687 | */ | 697 | */ |
688 | static int mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter) | 698 | static void mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter) |
689 | { | 699 | { |
690 | u8 host_int_mask, host_int_disable = HOST_INT_DISABLE; | 700 | struct sdio_mmc_card *card = adapter->card; |
691 | 701 | struct sdio_func *func = card->func; | |
692 | /* Read back the host_int_mask register */ | ||
693 | if (mwifiex_read_reg(adapter, HOST_INT_MASK_REG, &host_int_mask)) | ||
694 | return -1; | ||
695 | |||
696 | /* Update with the mask and write back to the register */ | ||
697 | host_int_mask &= ~host_int_disable; | ||
698 | |||
699 | if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, host_int_mask)) { | ||
700 | dev_err(adapter->dev, "disable host interrupt failed\n"); | ||
701 | return -1; | ||
702 | } | ||
703 | 702 | ||
704 | return 0; | 703 | sdio_claim_host(func); |
704 | mwifiex_write_reg_locked(func, HOST_INT_MASK_REG, 0); | ||
705 | sdio_release_irq(func); | ||
706 | sdio_release_host(func); | ||
705 | } | 707 | } |
706 | 708 | ||
707 | /* | 709 | /* |
@@ -713,14 +715,29 @@ static int mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter) | |||
713 | static int mwifiex_sdio_enable_host_int(struct mwifiex_adapter *adapter) | 715 | static int mwifiex_sdio_enable_host_int(struct mwifiex_adapter *adapter) |
714 | { | 716 | { |
715 | struct sdio_mmc_card *card = adapter->card; | 717 | struct sdio_mmc_card *card = adapter->card; |
718 | struct sdio_func *func = card->func; | ||
719 | int ret; | ||
720 | |||
721 | sdio_claim_host(func); | ||
722 | |||
723 | /* Request the SDIO IRQ */ | ||
724 | ret = sdio_claim_irq(func, mwifiex_sdio_interrupt); | ||
725 | if (ret) { | ||
726 | dev_err(adapter->dev, "claim irq failed: ret=%d\n", ret); | ||
727 | goto out; | ||
728 | } | ||
716 | 729 | ||
717 | /* Simply write the mask to the register */ | 730 | /* Simply write the mask to the register */ |
718 | if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, | 731 | ret = mwifiex_write_reg_locked(func, HOST_INT_MASK_REG, |
719 | card->reg->host_int_enable)) { | 732 | card->reg->host_int_enable); |
733 | if (ret) { | ||
720 | dev_err(adapter->dev, "enable host interrupt failed\n"); | 734 | dev_err(adapter->dev, "enable host interrupt failed\n"); |
721 | return -1; | 735 | sdio_release_irq(func); |
722 | } | 736 | } |
723 | return 0; | 737 | |
738 | out: | ||
739 | sdio_release_host(func); | ||
740 | return ret; | ||
724 | } | 741 | } |
725 | 742 | ||
726 | /* | 743 | /* |
@@ -997,9 +1014,6 @@ mwifiex_sdio_interrupt(struct sdio_func *func) | |||
997 | } | 1014 | } |
998 | adapter = card->adapter; | 1015 | adapter = card->adapter; |
999 | 1016 | ||
1000 | if (adapter->surprise_removed) | ||
1001 | return; | ||
1002 | |||
1003 | if (!adapter->pps_uapsd_mode && adapter->ps_state == PS_STATE_SLEEP) | 1017 | if (!adapter->pps_uapsd_mode && adapter->ps_state == PS_STATE_SLEEP) |
1004 | adapter->ps_state = PS_STATE_AWAKE; | 1018 | adapter->ps_state = PS_STATE_AWAKE; |
1005 | 1019 | ||
@@ -1625,8 +1639,8 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, | |||
1625 | /* Allocate buffer and copy payload */ | 1639 | /* Allocate buffer and copy payload */ |
1626 | blk_size = MWIFIEX_SDIO_BLOCK_SIZE; | 1640 | blk_size = MWIFIEX_SDIO_BLOCK_SIZE; |
1627 | buf_block_len = (pkt_len + blk_size - 1) / blk_size; | 1641 | buf_block_len = (pkt_len + blk_size - 1) / blk_size; |
1628 | *(u16 *) &payload[0] = (u16) pkt_len; | 1642 | *(__le16 *)&payload[0] = cpu_to_le16((u16)pkt_len); |
1629 | *(u16 *) &payload[2] = type; | 1643 | *(__le16 *)&payload[2] = cpu_to_le16(type); |
1630 | 1644 | ||
1631 | /* | 1645 | /* |
1632 | * This is SDIO specific header | 1646 | * This is SDIO specific header |
@@ -1728,9 +1742,7 @@ mwifiex_unregister_dev(struct mwifiex_adapter *adapter) | |||
1728 | struct sdio_mmc_card *card = adapter->card; | 1742 | struct sdio_mmc_card *card = adapter->card; |
1729 | 1743 | ||
1730 | if (adapter->card) { | 1744 | if (adapter->card) { |
1731 | /* Release the SDIO IRQ */ | ||
1732 | sdio_claim_host(card->func); | 1745 | sdio_claim_host(card->func); |
1733 | sdio_release_irq(card->func); | ||
1734 | sdio_disable_func(card->func); | 1746 | sdio_disable_func(card->func); |
1735 | sdio_release_host(card->func); | 1747 | sdio_release_host(card->func); |
1736 | sdio_set_drvdata(card->func, NULL); | 1748 | sdio_set_drvdata(card->func, NULL); |
@@ -1744,7 +1756,7 @@ mwifiex_unregister_dev(struct mwifiex_adapter *adapter) | |||
1744 | */ | 1756 | */ |
1745 | static int mwifiex_register_dev(struct mwifiex_adapter *adapter) | 1757 | static int mwifiex_register_dev(struct mwifiex_adapter *adapter) |
1746 | { | 1758 | { |
1747 | int ret = 0; | 1759 | int ret; |
1748 | struct sdio_mmc_card *card = adapter->card; | 1760 | struct sdio_mmc_card *card = adapter->card; |
1749 | struct sdio_func *func = card->func; | 1761 | struct sdio_func *func = card->func; |
1750 | 1762 | ||
@@ -1753,22 +1765,14 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) | |||
1753 | 1765 | ||
1754 | sdio_claim_host(func); | 1766 | sdio_claim_host(func); |
1755 | 1767 | ||
1756 | /* Request the SDIO IRQ */ | ||
1757 | ret = sdio_claim_irq(func, mwifiex_sdio_interrupt); | ||
1758 | if (ret) { | ||
1759 | pr_err("claim irq failed: ret=%d\n", ret); | ||
1760 | goto disable_func; | ||
1761 | } | ||
1762 | |||
1763 | /* Set block size */ | 1768 | /* Set block size */ |
1764 | ret = sdio_set_block_size(card->func, MWIFIEX_SDIO_BLOCK_SIZE); | 1769 | ret = sdio_set_block_size(card->func, MWIFIEX_SDIO_BLOCK_SIZE); |
1770 | sdio_release_host(func); | ||
1765 | if (ret) { | 1771 | if (ret) { |
1766 | pr_err("cannot set SDIO block size\n"); | 1772 | pr_err("cannot set SDIO block size\n"); |
1767 | ret = -1; | 1773 | return ret; |
1768 | goto release_irq; | ||
1769 | } | 1774 | } |
1770 | 1775 | ||
1771 | sdio_release_host(func); | ||
1772 | sdio_set_drvdata(func, card); | 1776 | sdio_set_drvdata(func, card); |
1773 | 1777 | ||
1774 | adapter->dev = &func->dev; | 1778 | adapter->dev = &func->dev; |
@@ -1776,15 +1780,6 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) | |||
1776 | strcpy(adapter->fw_name, card->firmware); | 1780 | strcpy(adapter->fw_name, card->firmware); |
1777 | 1781 | ||
1778 | return 0; | 1782 | return 0; |
1779 | |||
1780 | release_irq: | ||
1781 | sdio_release_irq(func); | ||
1782 | disable_func: | ||
1783 | sdio_disable_func(func); | ||
1784 | sdio_release_host(func); | ||
1785 | adapter->card = NULL; | ||
1786 | |||
1787 | return -1; | ||
1788 | } | 1783 | } |
1789 | 1784 | ||
1790 | /* | 1785 | /* |
@@ -1813,9 +1808,6 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter) | |||
1813 | */ | 1808 | */ |
1814 | mwifiex_read_reg(adapter, HOST_INTSTATUS_REG, &sdio_ireg); | 1809 | mwifiex_read_reg(adapter, HOST_INTSTATUS_REG, &sdio_ireg); |
1815 | 1810 | ||
1816 | /* Disable host interrupt mask register for SDIO */ | ||
1817 | mwifiex_sdio_disable_host_int(adapter); | ||
1818 | |||
1819 | /* Get SDIO ioport */ | 1811 | /* Get SDIO ioport */ |
1820 | mwifiex_init_sdio_ioport(adapter); | 1812 | mwifiex_init_sdio_ioport(adapter); |
1821 | 1813 | ||
@@ -1957,6 +1949,7 @@ static struct mwifiex_if_ops sdio_ops = { | |||
1957 | .register_dev = mwifiex_register_dev, | 1949 | .register_dev = mwifiex_register_dev, |
1958 | .unregister_dev = mwifiex_unregister_dev, | 1950 | .unregister_dev = mwifiex_unregister_dev, |
1959 | .enable_int = mwifiex_sdio_enable_host_int, | 1951 | .enable_int = mwifiex_sdio_enable_host_int, |
1952 | .disable_int = mwifiex_sdio_disable_host_int, | ||
1960 | .process_int_status = mwifiex_process_int_status, | 1953 | .process_int_status = mwifiex_process_int_status, |
1961 | .host_to_card = mwifiex_sdio_host_to_card, | 1954 | .host_to_card = mwifiex_sdio_host_to_card, |
1962 | .wakeup = mwifiex_pm_wakeup_card, | 1955 | .wakeup = mwifiex_pm_wakeup_card, |