Unverified Commit a740f4e6 authored by Leilk Liu's avatar Leilk Liu Committed by Mark Brown
Browse files
parent 9f763fd2
Loading
Loading
Loading
Loading
+69 −16
Original line number Diff line number Diff line
@@ -129,7 +129,7 @@ struct mtk_spi {
	u32 state;
	int pad_num;
	u32 *pad_sel;
	struct clk *parent_clk, *sel_clk, *spi_clk;
	struct clk *parent_clk, *sel_clk, *spi_clk, *spi_hclk;
	struct spi_transfer *cur_transfer;
	u32 xfer_len;
	u32 num_xfered;
@@ -1204,25 +1204,40 @@ static int mtk_spi_probe(struct platform_device *pdev)
		goto err_put_master;
	}

	mdata->spi_hclk = devm_clk_get_optional(&pdev->dev, "hclk");
	if (IS_ERR(mdata->spi_hclk)) {
		ret = PTR_ERR(mdata->spi_hclk);
		dev_err(&pdev->dev, "failed to get hclk: %d\n", ret);
		goto err_put_master;
	}

	ret = clk_prepare_enable(mdata->spi_hclk);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to enable hclk (%d)\n", ret);
		goto err_put_master;
	}

	ret = clk_prepare_enable(mdata->spi_clk);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to enable spi_clk (%d)\n", ret);
		goto err_put_master;
		goto err_disable_spi_hclk;
	}

	ret = clk_set_parent(mdata->sel_clk, mdata->parent_clk);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to clk_set_parent (%d)\n", ret);
		clk_disable_unprepare(mdata->spi_clk);
		goto err_put_master;
		goto err_disable_spi_clk;
	}

	mdata->spi_clk_hz = clk_get_rate(mdata->spi_clk);

	if (mdata->dev_comp->no_need_unprepare)
	if (mdata->dev_comp->no_need_unprepare) {
		clk_disable(mdata->spi_clk);
	else
		clk_disable(mdata->spi_hclk);
	} else {
		clk_disable_unprepare(mdata->spi_clk);
		clk_disable_unprepare(mdata->spi_hclk);
	}

	pm_runtime_enable(&pdev->dev);

@@ -1262,6 +1277,10 @@ static int mtk_spi_probe(struct platform_device *pdev)

err_disable_runtime_pm:
	pm_runtime_disable(&pdev->dev);
err_disable_spi_clk:
	clk_disable_unprepare(mdata->spi_clk);
err_disable_spi_hclk:
	clk_disable_unprepare(mdata->spi_hclk);
err_put_master:
	spi_master_put(master);

@@ -1277,8 +1296,10 @@ static int mtk_spi_remove(struct platform_device *pdev)

	mtk_spi_reset(mdata);

	if (mdata->dev_comp->no_need_unprepare)
	if (mdata->dev_comp->no_need_unprepare) {
		clk_unprepare(mdata->spi_clk);
		clk_unprepare(mdata->spi_hclk);
	}

	return 0;
}
@@ -1294,8 +1315,10 @@ static int mtk_spi_suspend(struct device *dev)
	if (ret)
		return ret;

	if (!pm_runtime_suspended(dev))
	if (!pm_runtime_suspended(dev)) {
		clk_disable_unprepare(mdata->spi_clk);
		clk_disable_unprepare(mdata->spi_hclk);
	}

	return ret;
}
@@ -1312,11 +1335,20 @@ static int mtk_spi_resume(struct device *dev)
			dev_err(dev, "failed to enable spi_clk (%d)\n", ret);
			return ret;
		}

		ret = clk_prepare_enable(mdata->spi_hclk);
		if (ret < 0) {
			dev_err(dev, "failed to enable spi_hclk (%d)\n", ret);
			clk_disable_unprepare(mdata->spi_clk);
			return ret;
		}
	}

	ret = spi_master_resume(master);
	if (ret < 0)
	if (ret < 0) {
		clk_disable_unprepare(mdata->spi_clk);
		clk_disable_unprepare(mdata->spi_hclk);
	}

	return ret;
}
@@ -1328,10 +1360,13 @@ static int mtk_spi_runtime_suspend(struct device *dev)
	struct spi_master *master = dev_get_drvdata(dev);
	struct mtk_spi *mdata = spi_master_get_devdata(master);

	if (mdata->dev_comp->no_need_unprepare)
	if (mdata->dev_comp->no_need_unprepare) {
		clk_disable(mdata->spi_clk);
	else
		clk_disable(mdata->spi_hclk);
	} else {
		clk_disable_unprepare(mdata->spi_clk);
		clk_disable_unprepare(mdata->spi_hclk);
	}

	return 0;
}
@@ -1342,14 +1377,32 @@ static int mtk_spi_runtime_resume(struct device *dev)
	struct mtk_spi *mdata = spi_master_get_devdata(master);
	int ret;

	if (mdata->dev_comp->no_need_unprepare)
	if (mdata->dev_comp->no_need_unprepare) {
		ret = clk_enable(mdata->spi_clk);
	else
		ret = clk_prepare_enable(mdata->spi_clk);
		if (ret < 0) {
			dev_err(dev, "failed to enable spi_clk (%d)\n", ret);
			return ret;
		}
		ret = clk_enable(mdata->spi_hclk);
		if (ret < 0) {
			dev_err(dev, "failed to enable spi_hclk (%d)\n", ret);
			clk_disable(mdata->spi_clk);
			return ret;
		}
	} else {
		ret = clk_prepare_enable(mdata->spi_clk);
		if (ret < 0) {
			dev_err(dev, "failed to prepare_enable spi_clk (%d)\n", ret);
			return ret;
		}

		ret = clk_prepare_enable(mdata->spi_hclk);
		if (ret < 0) {
			dev_err(dev, "failed to prepare_enable spi_hclk (%d)\n", ret);
			clk_disable_unprepare(mdata->spi_clk);
			return ret;
		}
	}

	return 0;
}