Commit 76855ba7 authored by Glen Lee's avatar Glen Lee Committed by Greg Kroah-Hartman

staging: wilc1000: add sdio resume/suspend

This patch introduces sdio device suspend and resume functionality. sdio_reset
function is added to reset sdio. Remove static inline keyword from
chip_allow_sleep and chip_wakeup, and export symbols.
Signed-off-by: default avatarGlen Lee <glen.lee@atmel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent fdc2ac1a
...@@ -42,6 +42,7 @@ static wilc_sdio_t g_sdio; ...@@ -42,6 +42,7 @@ static wilc_sdio_t g_sdio;
static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data); static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data);
static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data); static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data);
static int sdio_init(struct wilc *wilc);
static void wilc_sdio_interrupt(struct sdio_func *func) static void wilc_sdio_interrupt(struct sdio_func *func)
{ {
...@@ -142,11 +143,82 @@ static void linux_sdio_remove(struct sdio_func *func) ...@@ -142,11 +143,82 @@ static void linux_sdio_remove(struct sdio_func *func)
wilc_netdev_cleanup(sdio_get_drvdata(func)); wilc_netdev_cleanup(sdio_get_drvdata(func));
} }
static int sdio_reset(struct wilc *wilc)
{
sdio_cmd52_t cmd;
int ret;
struct sdio_func *func = dev_to_sdio_func(wilc->dev);
cmd.read_write = 1;
cmd.function = 0;
cmd.raw = 0;
cmd.address = 0x6;
cmd.data = 0x8;
ret = wilc_sdio_cmd52(wilc, &cmd);
if (ret) {
dev_err(&func->dev, "Fail cmd 52, reset cmd ...\n");
return ret;
}
return 0;
}
static int wilc_sdio_suspend(struct device *dev)
{
struct sdio_func *func = dev_to_sdio_func(dev);
struct wilc *wilc = sdio_get_drvdata(func);
int ret;
dev_info(dev, "sdio suspend\n");
chip_wakeup(wilc);
if (!wilc->suspend_event) {
wilc_chip_sleep_manually(wilc);
} else {
host_sleep_notify(wilc);
chip_allow_sleep(wilc);
}
ret = sdio_reset(wilc);
if (ret) {
dev_err(&func->dev, "Fail reset sdio\n");
return ret;
}
sdio_claim_host(func);
return 0;
}
static int wilc_sdio_resume(struct device *dev)
{
struct sdio_func *func = dev_to_sdio_func(dev);
struct wilc *wilc = sdio_get_drvdata(func);
dev_info(dev, "sdio resume\n");
sdio_release_host(func);
chip_wakeup(wilc);
sdio_init(wilc);
if (wilc->suspend_event)
host_wakeup_notify(wilc);
chip_allow_sleep(wilc);
return 0;
}
static const struct dev_pm_ops wilc_sdio_pm_ops = {
.suspend = wilc_sdio_suspend,
.resume = wilc_sdio_resume,
};
static struct sdio_driver wilc1000_sdio_driver = { static struct sdio_driver wilc1000_sdio_driver = {
.name = SDIO_MODALIAS, .name = SDIO_MODALIAS,
.id_table = wilc_sdio_ids, .id_table = wilc_sdio_ids,
.probe = linux_sdio_probe, .probe = linux_sdio_probe,
.remove = linux_sdio_remove, .remove = linux_sdio_remove,
.drv = {
.pm = &wilc_sdio_pm_ops,
}
}; };
module_driver(wilc1000_sdio_driver, module_driver(wilc1000_sdio_driver,
sdio_register_driver, sdio_register_driver,
......
...@@ -215,6 +215,7 @@ struct wilc { ...@@ -215,6 +215,7 @@ struct wilc {
const struct firmware *firmware; const struct firmware *firmware;
struct device *dev; struct device *dev;
bool suspend_event;
}; };
struct WILC_WFI_mon_priv { struct WILC_WFI_mon_priv {
......
...@@ -3,8 +3,6 @@ ...@@ -3,8 +3,6 @@
#include "wilc_wfi_netdevice.h" #include "wilc_wfi_netdevice.h"
#include "wilc_wlan_cfg.h" #include "wilc_wlan_cfg.h"
static inline void chip_allow_sleep(struct wilc *wilc);
static inline void chip_wakeup(struct wilc *wilc);
static u32 dbgflag = N_INIT | N_ERR | N_INTR | N_TXQ | N_RXQ; static u32 dbgflag = N_INIT | N_ERR | N_INTR | N_TXQ | N_RXQ;
/* FIXME: replace with dev_debug() */ /* FIXME: replace with dev_debug() */
...@@ -515,7 +513,7 @@ static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc) ...@@ -515,7 +513,7 @@ static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc)
return NULL; return NULL;
} }
static inline void chip_allow_sleep(struct wilc *wilc) void chip_allow_sleep(struct wilc *wilc)
{ {
u32 reg = 0; u32 reg = 0;
...@@ -524,8 +522,9 @@ static inline void chip_allow_sleep(struct wilc *wilc) ...@@ -524,8 +522,9 @@ static inline void chip_allow_sleep(struct wilc *wilc)
wilc->hif_func->hif_write_reg(wilc, 0xf0, reg & ~BIT(0)); wilc->hif_func->hif_write_reg(wilc, 0xf0, reg & ~BIT(0));
wilc->hif_func->hif_write_reg(wilc, 0xfa, 0); wilc->hif_func->hif_write_reg(wilc, 0xfa, 0);
} }
EXPORT_SYMBOL_GPL(chip_allow_sleep);
static inline void chip_wakeup(struct wilc *wilc) void chip_wakeup(struct wilc *wilc)
{ {
u32 reg, clk_status_reg, trials = 0; u32 reg, clk_status_reg, trials = 0;
...@@ -584,6 +583,7 @@ static inline void chip_wakeup(struct wilc *wilc) ...@@ -584,6 +583,7 @@ static inline void chip_wakeup(struct wilc *wilc)
} }
chip_ps_state = CHIP_WAKEDUP; chip_ps_state = CHIP_WAKEDUP;
} }
EXPORT_SYMBOL_GPL(chip_wakeup);
void wilc_chip_sleep_manually(struct wilc *wilc) void wilc_chip_sleep_manually(struct wilc *wilc)
{ {
...@@ -597,6 +597,7 @@ void wilc_chip_sleep_manually(struct wilc *wilc) ...@@ -597,6 +597,7 @@ void wilc_chip_sleep_manually(struct wilc *wilc)
chip_ps_state = CHIP_SLEEPING_MANUAL; chip_ps_state = CHIP_SLEEPING_MANUAL;
release_bus(wilc, RELEASE_ONLY); release_bus(wilc, RELEASE_ONLY);
} }
EXPORT_SYMBOL_GPL(wilc_chip_sleep_manually);
void host_wakeup_notify(struct wilc *wilc) void host_wakeup_notify(struct wilc *wilc)
{ {
...@@ -604,6 +605,7 @@ void host_wakeup_notify(struct wilc *wilc) ...@@ -604,6 +605,7 @@ void host_wakeup_notify(struct wilc *wilc)
wilc->hif_func->hif_write_reg(wilc, 0x10b0, 1); wilc->hif_func->hif_write_reg(wilc, 0x10b0, 1);
release_bus(wilc, RELEASE_ONLY); release_bus(wilc, RELEASE_ONLY);
} }
EXPORT_SYMBOL_GPL(host_wakeup_notify);
void host_sleep_notify(struct wilc *wilc) void host_sleep_notify(struct wilc *wilc)
{ {
...@@ -611,6 +613,7 @@ void host_sleep_notify(struct wilc *wilc) ...@@ -611,6 +613,7 @@ void host_sleep_notify(struct wilc *wilc)
wilc->hif_func->hif_write_reg(wilc, 0x10ac, 1); wilc->hif_func->hif_write_reg(wilc, 0x10ac, 1);
release_bus(wilc, RELEASE_ONLY); release_bus(wilc, RELEASE_ONLY);
} }
EXPORT_SYMBOL_GPL(host_sleep_notify);
int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
{ {
......
...@@ -298,5 +298,6 @@ void WILC_WFI_p2p_rx(struct net_device *dev, u8 *buff, u32 size); ...@@ -298,5 +298,6 @@ void WILC_WFI_p2p_rx(struct net_device *dev, u8 *buff, u32 size);
void host_wakeup_notify(struct wilc *wilc); void host_wakeup_notify(struct wilc *wilc);
void host_sleep_notify(struct wilc *wilc); void host_sleep_notify(struct wilc *wilc);
extern bool wilc_enable_ps; extern bool wilc_enable_ps;
void chip_allow_sleep(struct wilc *wilc);
void chip_wakeup(struct wilc *wilc);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment