From: xbw <xbw@rock-chips.com> Date: Thu, 8 May 2014 10:36:21 +0000 (+0800) Subject: SDMMC: modify the crash bug in suspend-rusume process when the sdcard is present... X-Git-Tag: firefly_0821_release~5325 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=6a874737c200772c5446447e8a6d903041bb0a82;p=firefly-linux-kernel-4.4.55.git SDMMC: modify the crash bug in suspend-rusume process when the sdcard is present in your machine. --- diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index 7e16ec221367..ff5d7e5fd3de 100755 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -283,6 +283,7 @@ pinctrl-names = "default", "idle"; pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; pinctrl-1 = <&sdmmc0_gpio>; + cd-gpios = <&gpio6 GPIO_C6 GPIO_ACTIVE_HIGH>;/*CD GPIO*/ clocks = <&clk_sdmmc>, <&clk_gates8 3>; clock-names = "clk_mmc", "hclk_mmc"; num-slots = <1>; diff --git a/drivers/mmc/host/rk_sdmmc.c b/drivers/mmc/host/rk_sdmmc.c index 680df561759a..4bfbd77c4952 100755 --- a/drivers/mmc/host/rk_sdmmc.c +++ b/drivers/mmc/host/rk_sdmmc.c @@ -2401,6 +2401,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) if (pending & SDMMC_INT_CD) { mci_writel(host, RINTSTS, SDMMC_INT_CD); + rk_send_wakeup_key();//wake up system queue_work(host->card_workqueue, &host->card_work); } @@ -2640,7 +2641,7 @@ static int dw_mci_of_get_wp_gpio(struct device *dev, u8 slot) static void dw_mci_of_get_cd_gpio(struct device *dev, u8 slot, struct mmc_host *mmc) { - struct device_node *np = dw_mci_of_find_slot_node(dev, slot); + struct device_node *np = dev->of_node;//dw_mci_of_find_slot_node(dev, slot); int gpio; if (!np) @@ -2786,6 +2787,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) mmc->caps |= MMC_CAP_POWER_OFF_CARD; if (of_find_property(host->dev->of_node, "cap-sdio-irq", NULL)) mmc->caps |= MMC_CAP_SDIO_IRQ; + if (of_find_property(host->dev->of_node, "poll-hw-reset", NULL)) + mmc->caps |= MMC_CAP_HW_RESET; if (of_find_property(host->dev->of_node, "full-pwr-cycle", NULL)) mmc->caps2 |= MMC_CAP2_FULL_PWR_CYCLE; if (of_find_property(host->dev->of_node, "keep-power-in-suspend", NULL)) @@ -2851,7 +2854,6 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) } slot->wp_gpio = dw_mci_of_get_wp_gpio(host->dev, slot->id); - dw_mci_of_get_cd_gpio(host->dev, slot->id, mmc); if (mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO) clear_bit(DW_MMC_CARD_PRESENT, &slot->flags); @@ -2870,6 +2872,15 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) printk("%s: Warning : No pinctrl used!\n",mmc_hostname(host->mmc)); else { + host->pins_idle= pinctrl_lookup_state(host->pinctrl,PINCTRL_STATE_IDLE); + if(IS_ERR(host->pins_default)) + printk("%s: Warning : No IDLE pinctrl matched!\n", mmc_hostname(host->mmc)); + else + { + if(pinctrl_select_state(host->pinctrl, host->pins_idle) < 0) + printk("%s: Warning : Idle pinctrl setting failed!\n", mmc_hostname(host->mmc)); + } + host->pins_default = pinctrl_lookup_state(host->pinctrl,PINCTRL_STATE_DEFAULT); if(IS_ERR(host->pins_default)) printk("%s: Warning : No default pinctrl matched!\n", mmc_hostname(host->mmc)); @@ -3369,6 +3380,16 @@ int dw_mci_suspend(struct dw_mci *host) if (host->vmmc) regulator_disable(host->vmmc); + /*only for sdmmc controller*/ + if(host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD) { + disable_irq(host->irq); + + if(pinctrl_select_state(host->pinctrl, host->pins_idle) < 0) + printk("%s: Warning : Idle pinctrl setting failed!\n", mmc_hostname(host->mmc)); + dw_mci_of_get_cd_gpio(host->dev,0,host->mmc); + + enable_irq_wake(host->mmc->slot.cd_irq); + } return 0; } EXPORT_SYMBOL(dw_mci_suspend); @@ -3421,6 +3442,19 @@ int dw_mci_resume(struct dw_mci *host) dw_mci_setup_bus(slot, true); } } + + /*only for sdmmc controller*/ + if(host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD) { + disable_irq_wake(host->mmc->slot.cd_irq); + + mmc_gpio_free_cd(host->mmc); + if(pinctrl_select_state(host->pinctrl, host->pins_default) < 0) + printk("%s: Warning : Default pinctrl setting failed!\n", mmc_hostname(host->mmc)); + + enable_irq(host->irq); + + } + return 0; } EXPORT_SYMBOL(dw_mci_resume); diff --git a/drivers/mmc/host/rk_sdmmc.h b/drivers/mmc/host/rk_sdmmc.h index 262db2025c3e..01a86fd9df5c 100755 --- a/drivers/mmc/host/rk_sdmmc.h +++ b/drivers/mmc/host/rk_sdmmc.h @@ -258,7 +258,7 @@ static struct sdmmc_reg dw_mci_regs[] = #define mci_writeq(dev, reg, value) \ (*(volatile u64 __force *)((dev)->regs + SDMMC_##reg) = (value)) #endif - +extern void rk_send_wakeup_key(void); extern int dw_mci_probe(struct dw_mci *host); extern void dw_mci_remove(struct dw_mci *host); #ifdef CONFIG_PM