From 429f7aef65bcf3552dd4276e78f0c72cbd03fa22 Mon Sep 17 00:00:00 2001 From: lintao Date: Mon, 31 Mar 2014 14:49:28 +0800 Subject: [PATCH] mmc: host: rockchips: Delay sched init for sdmmc & sdio controllers' probe for optimization. --- arch/arm/boot/dts/rk3288.dtsi | 89 +++++++++++++++--------------- drivers/mmc/host/dw_mmc-rockchip.c | 33 ++++++++++- drivers/mmc/host/rk_sdmmc.h | 2 + 3 files changed, 76 insertions(+), 48 deletions(-) diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index 84b28b148fb9..259386ceae67 100755 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -232,13 +232,13 @@ emmc: rksdmmc@ff0f0000 { compatible = "rockchip,rk_mmc"; + device_type = "emmc"; reg = <0xff0f0000 0x4000>; interrupts = ;/*irq=67*/ #address-cells = <1>; #size-cells = <0>; //pinctrl-names = "default",,"suspend"; //pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_wp &sd0_pwr &sd0_bus1 &sd0_bus4>; - clocks = <&clk_emmc>, <&clk_gates8 6>; clock-names = "clk_mmc", "hclk_mmc"; num-slots = <1>; @@ -247,61 +247,58 @@ }; sdmmc: rksdmmc@ff0c0000 { - compatible = "rockchip,rk_mmc"; - reg = <0xff0c0000 0x4000>; - interrupts = ; /*irq=64*/ - #address-cells = <1>; - #size-cells = <0>; - - pinctrl-names = "default","idle"; - pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; - pinctrl-1 = <&sdmmc0_gpio>; - - clocks = <&clk_sdmmc>, <&clk_gates8 3>; - clock-names = "clk_mmc", "hclk_mmc"; - num-slots = <1>; - fifo-depth = <0x100>; - bus-width = <4>; + compatible = "rockchip,rk_mmc"; + device_type = "sdmmc"; + reg = <0xff0c0000 0x4000>; + interrupts = ; /*irq=64*/ + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default","idle"; + pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; + pinctrl-1 = <&sdmmc0_gpio>; + clocks = <&clk_sdmmc>, <&clk_gates8 3>; + clock-names = "clk_mmc", "hclk_mmc"; + num-slots = <1>; + fifo-depth = <0x100>; + bus-width = <4>; }; sdio: rksdmmc@ff0d0000 { compatible = "rockchip,rk_mmc"; - reg = <0xff0d0000 0x4000>; - interrupts = ; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-names = "default","idle"; - pinctrl-0 = <&sdio0_clk &sdio0_cmd &sdio0_dectn &sdio0_wrprt &sdio0_pwr &sdio0_bkpwr + device_type = "sdio"; + reg = <0xff0d0000 0x4000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default","idle"; + pinctrl-0 = <&sdio0_clk &sdio0_cmd &sdio0_dectn &sdio0_wrprt &sdio0_pwr &sdio0_bkpwr &sdio0_intn &sdio0_bus4>; - pinctrl-1 = <&sdio0_gpio>; - - clocks = <&clk_sdio0>, <&clk_gates8 4>; + pinctrl-1 = <&sdio0_gpio>; + clocks = <&clk_sdio0>, <&clk_gates8 4>; clock-names = "clk_mmc", "hclk_mmc"; - num-slots = <1>; - - fifo-depth = <0x100>; - bus-width = <4>; + num-slots = <1>; + fifo-depth = <0x100>; + bus-width = <4>; }; - sdio1: rksdmmc@ff0e0000 { - compatible = "rockchip,rk_mmc"; - reg = <0xff0e0000 0x4000>; - interrupts = ; - #address-cells = <1>; - #size-cells = <0>; - //pinctrl-names = "default","suspend"; - //pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_cd &sd1_wp &sd1_bus1 &sd1_bus4>; - - /*gate8_0 --hclk_sdmmc_ahb_arbi_gate_en, gate13_2 --clk_sdio1_src_gate_en*/ - clocks = <&clk_sdio1>, <&clk_gates8 5>; - clock-names = "clk_mmc", "hclk_mmc"; - num-slots = <1>; - - fifo-depth = <0x100>; - bus-width = <4>; + sdio1: rksdmmc@ff0e0000 { + compatible = "rockchip,rk_mmc"; + device_type = "sdio"; + reg = <0xff0e0000 0x4000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + //pinctrl-names = "default","suspend"; + //pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_cd &sd1_wp &sd1_bus1 &sd1_bus4>; + /*gate8_0 --hclk_sdmmc_ahb_arbi_gate_en, gate13_2 --clk_sdio1_src_gate_en*/ + clocks = <&clk_sdio1>, <&clk_gates8 5>; + clock-names = "clk_mmc", "hclk_mmc"; + num-slots = <1>; + fifo-depth = <0x100>; + bus-width = <4>; status = "disabled"; - }; + }; spi0: spi@ff110000 { compatible = "rockchip,rockchip-spi"; diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c index c5031f540150..98a9683c6686 100755 --- a/drivers/mmc/host/dw_mmc-rockchip.c +++ b/drivers/mmc/host/dw_mmc-rockchip.c @@ -189,9 +189,24 @@ MODULE_DEVICE_TABLE(of, dw_mci_rockchip_match); extern void rockchip_mmc_of_probe(struct device_node *np,struct rk_sdmmc_of *mmc_property); #endif +static struct platform_device *sdmmc_pdev; +static struct dw_mci_drv_data *sdmmc_drv_data; +static struct platform_device *sdio_pdev; +static struct dw_mci_drv_data *sdio_drv_data; + +static void dw_mci_sdmmc_delayed_work(struct work_struct *work) +{ + dw_mci_pltfm_register(sdmmc_pdev, sdmmc_drv_data); +} +static void dw_mci_sdio_delayed_work(struct work_struct *work) +{ + dw_mci_pltfm_register(sdio_pdev, sdio_drv_data); +} + + static int dw_mci_rockchip_probe(struct platform_device *pdev) { - const struct dw_mci_drv_data *drv_data; + struct dw_mci_drv_data *drv_data; const struct of_device_id *match; #if DW_MMC_OF_PROBE @@ -213,7 +228,21 @@ static int dw_mci_rockchip_probe(struct platform_device *pdev) match = of_match_node(dw_mci_rockchip_match, pdev->dev.of_node); drv_data = match->data; - return dw_mci_pltfm_register(pdev, drv_data); + + if(strcmp(pdev->dev.of_node->type,"sdmmc") == 0){ + sdmmc_pdev = pdev; + sdmmc_drv_data = drv_data; + INIT_DELAYED_WORK(&drv_data->dw_mci_sdmmc_delayed_work, dw_mci_sdmmc_delayed_work); + return schedule_delayed_work(&drv_data->dw_mci_sdmmc_delayed_work, msecs_to_jiffies(50)); + }else if (strcmp(pdev->dev.of_node->type,"sdio") == 0){ + sdio_pdev = pdev; + sdio_drv_data = drv_data; + INIT_DELAYED_WORK(&drv_data->dw_mci_sdio_delayed_work, dw_mci_sdio_delayed_work); + return schedule_delayed_work(&drv_data->dw_mci_sdio_delayed_work, msecs_to_jiffies(50)); + }else{ + /*eMMC*/ + return dw_mci_pltfm_register(pdev, drv_data); + } } static struct platform_driver dw_mci_rockchip_pltfm_driver = { diff --git a/drivers/mmc/host/rk_sdmmc.h b/drivers/mmc/host/rk_sdmmc.h index e0e92b980c40..706efe7261cd 100755 --- a/drivers/mmc/host/rk_sdmmc.h +++ b/drivers/mmc/host/rk_sdmmc.h @@ -318,6 +318,8 @@ struct dw_mci_tuning_data { struct dw_mci_drv_data { unsigned long *caps; unsigned int *hold_reg_flag; + struct delayed_work dw_mci_sdmmc_delayed_work; + struct delayed_work dw_mci_sdio_delayed_work; int (*init)(struct dw_mci *host); int (*setup_clock)(struct dw_mci *host); void (*prepare_command)(struct dw_mci *host, u32 *cmdr); -- 2.34.1