summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRahul Bansal <rbansal@nvidia.com>2010-10-27 18:10:15 +0530
committerVarun Colbert <vcolbert@nvidia.com>2010-11-15 20:13:56 -0800
commit696d14b5dee46679980c9a41883d29feb19fa9b4 (patch)
treeb2c571a0744248c9c5a76cf83d8e33c66d707afb
parent29d62945618a5767b32c3dbc5a6cace5b9b8ac50 (diff)
[arm/tegra] Support for Wake-On-Wireless Event.
Support for device wakeup on receiving SDIO interrupt in LP1/LP0 for incoming wifi pakcket. Bug: 730157 Change-Id: Ia2e9bf2af215f33d6d6d8d78ba0cdf2d71011917 Reviewed-on: http://git-master/r/9813 Reviewed-by: Rahul Bansal <rbansal@nvidia.com> Tested-by: Rahul Bansal <rbansal@nvidia.com> Reviewed-by: Rakesh Kumar <krakesh@nvidia.com> Tested-by: Rakesh Kumar <krakesh@nvidia.com> Reviewed-by: Udaykumar Rameshchan Raval <uraval@nvidia.com> Reviewed-by: Pavan Kunapuli <pkunapuli@nvidia.com> Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com> Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com>
-rwxr-xr-xarch/arm/mach-tegra/board-nvodm.c6
-rwxr-xr-x[-rw-r--r--]arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c2
-rwxr-xr-xarch/arm/mach-tegra/odm_kit/query/ventana/nvodm_query.c2
-rwxr-xr-x[-rw-r--r--]arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c2
-rwxr-xr-xdrivers/mmc/host/sdhci-tegra.c37
5 files changed, 24 insertions, 25 deletions
diff --git a/arch/arm/mach-tegra/board-nvodm.c b/arch/arm/mach-tegra/board-nvodm.c
index 39229f28ec7d..d362bb538c6a 100755
--- a/arch/arm/mach-tegra/board-nvodm.c
+++ b/arch/arm/mach-tegra/board-nvodm.c
@@ -1543,14 +1543,14 @@ static void __init tegra_setup_suspend(void)
gpio_to_irq(TEGRA_GPIO_PU5), gpio_to_irq(TEGRA_GPIO_PU6),
gpio_to_irq(TEGRA_GPIO_PC7), gpio_to_irq(TEGRA_GPIO_PS2),
gpio_to_irq(TEGRA_GPIO_PAA1), gpio_to_irq(TEGRA_GPIO_PW3),
- gpio_to_irq(TEGRA_GPIO_PW2), gpio_to_irq(TEGRA_GPIO_PY6),
+ /* FIXME: USB/SDMMC wake pad interrupt mapping may be wrong */
+ gpio_to_irq(TEGRA_GPIO_PW2), INT_SDMMC1,
gpio_to_irq(TEGRA_GPIO_PV6), gpio_to_irq(TEGRA_GPIO_PJ7),
INT_RTC, INT_KBC, INT_EXTERNAL_PMU,
- /* FIXME: USB wake pad interrupt mapping may be wrong */
INT_USB, INT_USB3, INT_USB, INT_USB3,
gpio_to_irq(TEGRA_GPIO_PI5), gpio_to_irq(TEGRA_GPIO_PV2),
gpio_to_irq(TEGRA_GPIO_PS4), gpio_to_irq(TEGRA_GPIO_PS5),
- gpio_to_irq(TEGRA_GPIO_PS0), gpio_to_irq(TEGRA_GPIO_PQ6),
+ INT_SDMMC2, gpio_to_irq(TEGRA_GPIO_PQ6),
gpio_to_irq(TEGRA_GPIO_PQ7), gpio_to_irq(TEGRA_GPIO_PN2),
};
#endif
diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c
index 60a6d9db0faf..67d32cc71c37 100644..100755
--- a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c
+++ b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c
@@ -311,7 +311,7 @@ static NvOdmWakeupPadInfo s_NvOdmWakeupPadInfo[] =
{NV_FALSE, 10, NvOdmWakeupPadPolarity_High}, // Wake Event 10 - gmi_ad21 (Accelerometer_TH/TAP)
{NV_TRUE, 11, NvOdmWakeupPadPolarity_Low}, // Wake Event 11 - spi2_cs2 (PEN_INT, AUDIO-IRQ, LOW_BAT#)
{NV_FALSE, 12, NvOdmWakeupPadPolarity_Low}, // Wake Event 12 - spi2_cs1 (HEADSET_DET, not used)
- {NV_FALSE, 13, NvOdmWakeupPadPolarity_Low}, // Wake Event 13 - sdio1_dat1
+ {NV_TRUE, 13, NvOdmWakeupPadPolarity_Low}, // Wake Event 13 - sdio1_dat1 (WLAN_WAKE)
{NV_FALSE, 14, NvOdmWakeupPadPolarity_High}, // Wake Event 14 - gp3_pv[6] (WLAN_INT)
{NV_FALSE, 15, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 15 - gmi_ad16 (SPI3_DOUT, DTV_SPI4_CS1)
{NV_TRUE, 16, NvOdmWakeupPadPolarity_High}, // Wake Event 16 - rtc_irq
diff --git a/arch/arm/mach-tegra/odm_kit/query/ventana/nvodm_query.c b/arch/arm/mach-tegra/odm_kit/query/ventana/nvodm_query.c
index dfab844188a0..cbd4ad4932d2 100755
--- a/arch/arm/mach-tegra/odm_kit/query/ventana/nvodm_query.c
+++ b/arch/arm/mach-tegra/odm_kit/query/ventana/nvodm_query.c
@@ -65,7 +65,7 @@ static NvOdmWakeupPadInfo s_NvOdmWakeupPadInfo[] =
{NV_FALSE, 10, NvOdmWakeupPadPolarity_High}, // Wake Event 10 - gmi_ad21 (Accelerometer_TH/TAP)
{NV_FALSE, 11, NvOdmWakeupPadPolarity_Low}, // Wake Event 11 - spi2_cs2 (PEN_INT, AUDIO-IRQ, LOW_BAT#)
{NV_FALSE, 12, NvOdmWakeupPadPolarity_Low}, // Wake Event 12 - spi2_cs1 (HEADSET_DET, not used)
- {NV_FALSE, 13, NvOdmWakeupPadPolarity_Low}, // Wake Event 13 - sdio1_dat1
+ {NV_TRUE, 13, NvOdmWakeupPadPolarity_Low}, // Wake Event 13 - sdio1_dat1 (WLAN_WAKE)
{NV_FALSE, 14, NvOdmWakeupPadPolarity_High}, // Wake Event 14 - gp3_pv[6] (WLAN_INT)
{NV_FALSE, 15, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 15 - gmi_ad16 (SPI3_DOUT, DTV_SPI4_CS1)
{NV_TRUE, 16, NvOdmWakeupPadPolarity_High}, // Wake Event 16 - rtc_irq
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c
index 5b0c63bb8486..5526029823e5 100644..100755
--- a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c
@@ -1581,7 +1581,7 @@ static NvOdmWakeupPadInfo s_NvOdmWakeupPadInfo[] =
{NV_FALSE, 24, NvOdmWakeupPadPolarity_High}, // Wake Event 24 - gp3_pv[2] (BB_MOD, MODEM WAKEUP_AP15, SPI-SS)
{NV_FALSE, 25, NvOdmWakeupPadPolarity_High}, // Wake Event 25 - gp3_ps[4] (KB_COL12)
{NV_FALSE, 26, NvOdmWakeupPadPolarity_High}, // Wake Event 26 - gp3_ps[5] (KB_COL10)
- {NV_FALSE, 27, NvOdmWakeupPadPolarity_High}, // Wake Event 27 - gp3_ps[0] (KB_COL8)
+ {NV_TRUE, 27, NvOdmWakeupPadPolarity_Low}, // Wake Event 27 - gp3_ps[0] (KB_COL8) / SDIO2_DAT1 (WLAN_WAKE)
{NV_FALSE, 28, NvOdmWakeupPadPolarity_Low}, // Wake Event 28 - gp3_pq[6] (KB_ROW6)
{NV_FALSE, 29, NvOdmWakeupPadPolarity_Low}, // Wake Event 29 - gp3_pq[7] (KB_ROW6)
{NV_FALSE, 30, NvOdmWakeupPadPolarity_High} // Wake Event 30 - dap1_dout (DAP1_DOUT)
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 7d4006084eb1..60d23213e7d1 100755
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -23,6 +23,8 @@
#define NV_DEBUG 0
#include <linux/mmc/host.h>
+#include <linux/mmc/sdio_func.h>
+
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/irq.h>
@@ -461,29 +463,26 @@ static int tegra_sdhci_suspend(struct device *dev)
int ret = 0;
if (host->card_always_on && is_card_sdio(sdhost->mmc->card)) {
- struct mmc_ios ios;
- ios.clock = 0;
- ios.vdd = 0;
- ios.power_mode = MMC_POWER_OFF;
- ios.bus_width = MMC_BUS_WIDTH_1;
- ios.timing = MMC_TIMING_LEGACY;
+ int div;
+ u16 clk;
+ unsigned int clock = 100000;
/* save interrupt status before suspending */
host->sdhci_ints = sdhci_readl(sdhost, SDHCI_INT_ENABLE);
- sdhost->mmc->ops->set_ios(sdhost->mmc, &ios);
- /* keep CARD_INT enabled - if used as wakeup source */
- if (host->sdhci_ints & SDHCI_INT_CARD_INT) {
- u32 ier = sdhci_readl(sdhost, SDHCI_INT_ENABLE);
- ier |= SDHCI_INT_CARD_INT;
- sdhci_writel(sdhost, ier, SDHCI_INT_ENABLE);
- sdhci_writel(sdhost, ier, SDHCI_SIGNAL_ENABLE);
-
- if (sdhost->quirks & SDHCI_QUIRK_ENABLE_INTERRUPT_AT_BLOCK_GAP) {
- u8 gap_ctrl = sdhci_readb(sdhost, SDHCI_BLOCK_GAP_CONTROL);
- gap_ctrl |= 0x8;
- sdhci_writeb(sdhost, gap_ctrl, SDHCI_BLOCK_GAP_CONTROL);
- }
+
+ /* reduce host controller clk and card clk to 100 KHz */
+ tegra_sdhci_set_clock(sdhost, clock);
+ sdhci_writew(sdhost, 0, SDHCI_CLOCK_CONTROL);
+
+ for (div = 1;div < 256;div *= 2) {
+ if ((sdhost->max_clk / div) <= clock)
+ break;
}
+ div >>= 1;
+
+ clk = div << SDHCI_DIVIDER_SHIFT;
+ clk |= SDHCI_CLOCK_INT_EN | SDHCI_CLOCK_CARD_EN;
+ sdhci_writew(sdhost, clk, SDHCI_CLOCK_CONTROL);
return ret;
}