浏览代码

mmc sdhc i.MX: do not depend on grouped clocks

the current i.MX clock support groups together unrelated clocks
to a single clock which is then used by the driver. This can't
be accomplished with the generic clock framework so we instead
request the individual clocks in the driver. For i.MX there are
generally three different clocks:

ipg: bus clock (needed to access registers)
ahb: dma relevant clock, sometimes referred to as hclk in the datasheet
per: bit clock, pixel clock

This patch changes the driver to request the individual clocks.
Currently all clk_get will get the same clock until the SoCs
are converted to the generic clock framework

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Sascha Hauer 13 年之前
父节点
当前提交
52dac61505
共有 1 个文件被更改,包括 31 次插入11 次删除
  1. 31 11
      drivers/mmc/host/sdhci-esdhc-imx.c

+ 31 - 11
drivers/mmc/host/sdhci-esdhc-imx.c

@@ -69,6 +69,9 @@ struct pltfm_imx_data {
 	u32 scratchpad;
 	u32 scratchpad;
 	enum imx_esdhc_type devtype;
 	enum imx_esdhc_type devtype;
 	struct esdhc_platform_data boarddata;
 	struct esdhc_platform_data boarddata;
+	struct clk *clk_ipg;
+	struct clk *clk_ahb;
+	struct clk *clk_per;
 };
 };
 
 
 static struct platform_device_id imx_esdhc_devtype[] = {
 static struct platform_device_id imx_esdhc_devtype[] = {
@@ -437,7 +440,6 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
 	struct sdhci_pltfm_host *pltfm_host;
 	struct sdhci_pltfm_host *pltfm_host;
 	struct sdhci_host *host;
 	struct sdhci_host *host;
 	struct esdhc_platform_data *boarddata;
 	struct esdhc_platform_data *boarddata;
-	struct clk *clk;
 	int err;
 	int err;
 	struct pltfm_imx_data *imx_data;
 	struct pltfm_imx_data *imx_data;
 
 
@@ -458,14 +460,29 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
 	imx_data->devtype = pdev->id_entry->driver_data;
 	imx_data->devtype = pdev->id_entry->driver_data;
 	pltfm_host->priv = imx_data;
 	pltfm_host->priv = imx_data;
 
 
-	clk = clk_get(mmc_dev(host->mmc), NULL);
-	if (IS_ERR(clk)) {
-		dev_err(mmc_dev(host->mmc), "clk err\n");
-		err = PTR_ERR(clk);
+	imx_data->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+	if (IS_ERR(imx_data->clk_ipg)) {
+		err = PTR_ERR(imx_data->clk_ipg);
 		goto err_clk_get;
 		goto err_clk_get;
 	}
 	}
-	clk_prepare_enable(clk);
-	pltfm_host->clk = clk;
+
+	imx_data->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
+	if (IS_ERR(imx_data->clk_ahb)) {
+		err = PTR_ERR(imx_data->clk_ahb);
+		goto err_clk_get;
+	}
+
+	imx_data->clk_per = devm_clk_get(&pdev->dev, "per");
+	if (IS_ERR(imx_data->clk_per)) {
+		err = PTR_ERR(imx_data->clk_per);
+		goto err_clk_get;
+	}
+
+	pltfm_host->clk = imx_data->clk_per;
+
+	clk_prepare_enable(imx_data->clk_per);
+	clk_prepare_enable(imx_data->clk_ipg);
+	clk_prepare_enable(imx_data->clk_ahb);
 
 
 	host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
 	host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
 
 
@@ -558,8 +575,9 @@ no_card_detect_irq:
 		gpio_free(boarddata->wp_gpio);
 		gpio_free(boarddata->wp_gpio);
 no_card_detect_pin:
 no_card_detect_pin:
 no_board_data:
 no_board_data:
-	clk_disable_unprepare(pltfm_host->clk);
-	clk_put(pltfm_host->clk);
+	clk_disable_unprepare(imx_data->clk_per);
+	clk_disable_unprepare(imx_data->clk_ipg);
+	clk_disable_unprepare(imx_data->clk_ahb);
 err_clk_get:
 err_clk_get:
 	kfree(imx_data);
 	kfree(imx_data);
 err_imx_data:
 err_imx_data:
@@ -585,8 +603,10 @@ static int __devexit sdhci_esdhc_imx_remove(struct platform_device *pdev)
 		gpio_free(boarddata->cd_gpio);
 		gpio_free(boarddata->cd_gpio);
 	}
 	}
 
 
-	clk_disable_unprepare(pltfm_host->clk);
-	clk_put(pltfm_host->clk);
+	clk_disable_unprepare(imx_data->clk_per);
+	clk_disable_unprepare(imx_data->clk_ipg);
+	clk_disable_unprepare(imx_data->clk_ahb);
+
 	kfree(imx_data);
 	kfree(imx_data);
 
 
 	sdhci_pltfm_free(pdev);
 	sdhci_pltfm_free(pdev);