aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/wilc1000/wilc_sdio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/wilc1000/wilc_sdio.c')
-rw-r--r--drivers/staging/wilc1000/wilc_sdio.c152
1 files changed, 108 insertions, 44 deletions
diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c
index e961b5004902..a839a7967dd8 100644
--- a/drivers/staging/wilc1000/wilc_sdio.c
+++ b/drivers/staging/wilc1000/wilc_sdio.c
@@ -30,18 +30,19 @@ static const struct sdio_device_id wilc_sdio_ids[] = {
#define WILC_SDIO_BLOCK_SIZE 512
-typedef struct {
+struct wilc_sdio {
bool irq_gpio;
u32 block_size;
int nint;
#define MAX_NUN_INT_THRPT_ENH2 (5) /* Max num interrupts allowed in registers 0xf7, 0xf8 */
int has_thrpt_enh3;
-} wilc_sdio_t;
+};
-static wilc_sdio_t g_sdio;
+static struct wilc_sdio g_sdio;
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_init(struct wilc *wilc, bool resume);
static void wilc_sdio_interrupt(struct sdio_func *func)
{
@@ -50,7 +51,7 @@ static void wilc_sdio_interrupt(struct sdio_func *func)
sdio_claim_host(func);
}
-static int wilc_sdio_cmd52(struct wilc *wilc, sdio_cmd52_t *cmd)
+static int wilc_sdio_cmd52(struct wilc *wilc, struct sdio_cmd52 *cmd)
{
struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev);
int ret;
@@ -80,7 +81,7 @@ static int wilc_sdio_cmd52(struct wilc *wilc, sdio_cmd52_t *cmd)
}
-static int wilc_sdio_cmd53(struct wilc *wilc, sdio_cmd53_t *cmd)
+static int wilc_sdio_cmd53(struct wilc *wilc, struct sdio_cmd53 *cmd)
{
struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev);
int size, ret;
@@ -142,11 +143,82 @@ static void linux_sdio_remove(struct sdio_func *func)
wilc_netdev_cleanup(sdio_get_drvdata(func));
}
+static int sdio_reset(struct wilc *wilc)
+{
+ struct sdio_cmd52 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, true);
+
+ 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 = {
.name = SDIO_MODALIAS,
.id_table = wilc_sdio_ids,
.probe = linux_sdio_probe,
.remove = linux_sdio_remove,
+ .drv = {
+ .pm = &wilc_sdio_pm_ops,
+ }
};
module_driver(wilc1000_sdio_driver,
sdio_register_driver,
@@ -185,11 +257,6 @@ static void wilc_sdio_disable_interrupt(struct wilc *dev)
dev_info(&func->dev, "wilc_sdio_disable_interrupt OUT\n");
}
-static int wilc_sdio_init(void)
-{
- return 1;
-}
-
/********************************************
*
* Function 0
@@ -199,7 +266,7 @@ static int wilc_sdio_init(void)
static int sdio_set_func0_csa_address(struct wilc *wilc, u32 adr)
{
struct sdio_func *func = dev_to_sdio_func(wilc->dev);
- sdio_cmd52_t cmd;
+ struct sdio_cmd52 cmd;
int ret;
/**
@@ -240,7 +307,7 @@ _fail_:
static int sdio_set_func0_block_size(struct wilc *wilc, u32 block_size)
{
struct sdio_func *func = dev_to_sdio_func(wilc->dev);
- sdio_cmd52_t cmd;
+ struct sdio_cmd52 cmd;
int ret;
cmd.read_write = 1;
@@ -276,7 +343,7 @@ _fail_:
static int sdio_set_func1_block_size(struct wilc *wilc, u32 block_size)
{
struct sdio_func *func = dev_to_sdio_func(wilc->dev);
- sdio_cmd52_t cmd;
+ struct sdio_cmd52 cmd;
int ret;
cmd.read_write = 1;
@@ -315,7 +382,7 @@ static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data)
data = cpu_to_le32(data);
if ((addr >= 0xf0) && (addr <= 0xff)) {
- sdio_cmd52_t cmd;
+ struct sdio_cmd52 cmd;
cmd.read_write = 1;
cmd.function = 0;
@@ -329,7 +396,7 @@ static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data)
goto _fail_;
}
} else {
- sdio_cmd53_t cmd;
+ struct sdio_cmd53 cmd;
/**
* set the AHB address
@@ -364,7 +431,7 @@ static int sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
{
struct sdio_func *func = dev_to_sdio_func(wilc->dev);
u32 block_size = g_sdio.block_size;
- sdio_cmd53_t cmd;
+ struct sdio_cmd53 cmd;
int nblk, nleft, ret;
cmd.read_write = 1;
@@ -455,7 +522,7 @@ static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data)
int ret;
if ((addr >= 0xf0) && (addr <= 0xff)) {
- sdio_cmd52_t cmd;
+ struct sdio_cmd52 cmd;
cmd.read_write = 0;
cmd.function = 0;
@@ -469,7 +536,7 @@ static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data)
}
*data = cmd.data;
} else {
- sdio_cmd53_t cmd;
+ struct sdio_cmd53 cmd;
if (!sdio_set_func0_csa_address(wilc, addr))
goto _fail_;
@@ -504,7 +571,7 @@ static int sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
{
struct sdio_func *func = dev_to_sdio_func(wilc->dev);
u32 block_size = g_sdio.block_size;
- sdio_cmd53_t cmd;
+ struct sdio_cmd53 cmd;
int nblk, nleft, ret;
cmd.read_write = 0;
@@ -600,22 +667,16 @@ static int sdio_deinit(struct wilc *wilc)
return 1;
}
-static int sdio_init(struct wilc *wilc)
+static int sdio_init(struct wilc *wilc, bool resume)
{
struct sdio_func *func = dev_to_sdio_func(wilc->dev);
- sdio_cmd52_t cmd;
+ struct sdio_cmd52 cmd;
int loop, ret;
u32 chipid;
- memset(&g_sdio, 0, sizeof(wilc_sdio_t));
-
- g_sdio.irq_gpio = (wilc->dev_irq_num);
-
- if (!wilc_sdio_init()) {
- dev_err(&func->dev, "Failed io init bus...\n");
- return 0;
- } else {
- return 0;
+ if (!resume) {
+ memset(&g_sdio, 0, sizeof(struct wilc_sdio));
+ g_sdio.irq_gpio = wilc->dev_irq_num;
}
/**
@@ -706,16 +767,19 @@ static int sdio_init(struct wilc *wilc)
/**
* make sure can read back chip id correctly
**/
- if (!sdio_read_reg(wilc, 0x1000, &chipid)) {
- dev_err(&func->dev, "Fail cmd read chip id...\n");
- goto _fail_;
+ if (!resume) {
+ if (!sdio_read_reg(wilc, 0x1000, &chipid)) {
+ dev_err(&func->dev, "Fail cmd read chip id...\n");
+ goto _fail_;
+ }
+ dev_err(&func->dev, "chipid (%08x)\n", chipid);
+ if ((chipid & 0xfff) > 0x2a0)
+ g_sdio.has_thrpt_enh3 = 1;
+ else
+ g_sdio.has_thrpt_enh3 = 0;
+ dev_info(&func->dev, "has_thrpt_enh3 = %d...\n",
+ g_sdio.has_thrpt_enh3);
}
- dev_err(&func->dev, "chipid (%08x)\n", chipid);
- if ((chipid & 0xfff) > 0x2a0)
- g_sdio.has_thrpt_enh3 = 1;
- else
- g_sdio.has_thrpt_enh3 = 0;
- dev_info(&func->dev, "has_thrpt_enh3 = %d...\n", g_sdio.has_thrpt_enh3);
return 1;
@@ -727,7 +791,7 @@ _fail_:
static int sdio_read_size(struct wilc *wilc, u32 *size)
{
u32 tmp;
- sdio_cmd52_t cmd;
+ struct sdio_cmd52 cmd;
/**
* Read DMA count in words
@@ -756,7 +820,7 @@ static int sdio_read_int(struct wilc *wilc, u32 *int_status)
{
struct sdio_func *func = dev_to_sdio_func(wilc->dev);
u32 tmp;
- sdio_cmd52_t cmd;
+ struct sdio_cmd52 cmd;
sdio_read_size(wilc, &tmp);
@@ -835,7 +899,7 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val)
if ((val & EN_VMM) == EN_VMM)
reg |= BIT(7);
if (reg) {
- sdio_cmd52_t cmd;
+ struct sdio_cmd52 cmd;
cmd.read_write = 1;
cmd.function = 0;
@@ -865,7 +929,7 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val)
ret = 1;
for (i = 0; i < g_sdio.nint; i++) {
if (flags & 1) {
- sdio_cmd52_t cmd;
+ struct sdio_cmd52 cmd;
cmd.read_write = 1;
cmd.function = 0;
@@ -913,7 +977,7 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val)
vmm_ctl |= BIT(2);
if (vmm_ctl) {
- sdio_cmd52_t cmd;
+ struct sdio_cmd52 cmd;
cmd.read_write = 1;
cmd.function = 0;