diff options
Diffstat (limited to 'drivers/staging/wilc1000/wilc_sdio.c')
-rw-r--r-- | drivers/staging/wilc1000/wilc_sdio.c | 152 |
1 files changed, 108 insertions, 44 deletions
diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index e961b5004..a839a7967 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; |