[go: nahoru, domu]

1036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao/*
2036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao * Copyright (c) 2013 Linaro Ltd.
3036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao * Copyright (c) 2013 Hisilicon Limited.
4036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao *
5036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao * This program is free software; you can redistribute it and/or modify
6036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao * it under the terms of the GNU General Public License as published by
7036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao * the Free Software Foundation; either version 2 of the License, or
8036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao * (at your option) any later version.
9036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao */
10036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao
11036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao#include <linux/module.h>
12036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao#include <linux/platform_device.h>
13036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao#include <linux/clk.h>
14036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao#include <linux/mmc/host.h>
15036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao#include <linux/mmc/dw_mmc.h>
16036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao#include <linux/of_address.h>
17036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao
18036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao#include "dw_mmc.h"
19036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao#include "dw_mmc-pltfm.h"
20036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao
21036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gaostatic void dw_mci_k3_set_ios(struct dw_mci *host, struct mmc_ios *ios)
22036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao{
23036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	int ret;
24036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao
250e662440e9658163128b71a925dbf6a30d4db625Zhangfei Gao	ret = clk_set_rate(host->ciu_clk, ios->clock);
26036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	if (ret)
270e662440e9658163128b71a925dbf6a30d4db625Zhangfei Gao		dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock);
28036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao
29036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	host->bus_hz = clk_get_rate(host->ciu_clk);
30036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao}
31036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao
32036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gaostatic const struct dw_mci_drv_data k3_drv_data = {
33036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	.set_ios		= dw_mci_k3_set_ios,
34036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao};
35036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao
36036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gaostatic const struct of_device_id dw_mci_k3_match[] = {
37036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	{ .compatible = "hisilicon,hi4511-dw-mshc", .data = &k3_drv_data, },
38036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	{},
39036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao};
40036f29d554e84fa288411d950c2f0ae797be9146Zhangfei GaoMODULE_DEVICE_TABLE(of, dw_mci_k3_match);
41036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao
42036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gaostatic int dw_mci_k3_probe(struct platform_device *pdev)
43036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao{
44036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	const struct dw_mci_drv_data *drv_data;
45036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	const struct of_device_id *match;
46036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao
47036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	match = of_match_node(dw_mci_k3_match, pdev->dev.of_node);
48036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	drv_data = match->data;
49036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao
50036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	return dw_mci_pltfm_register(pdev, drv_data);
51036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao}
52036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao
53370aede6a18a41e01f2668108d847b598443fbc0Felipe Balbi#ifdef CONFIG_PM_SLEEP
54036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gaostatic int dw_mci_k3_suspend(struct device *dev)
55036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao{
56036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	struct dw_mci *host = dev_get_drvdata(dev);
57036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	int ret;
58036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao
59036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	ret = dw_mci_suspend(host);
60036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	if (!ret)
61036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao		clk_disable_unprepare(host->ciu_clk);
62036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao
63036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	return ret;
64036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao}
65036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao
66036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gaostatic int dw_mci_k3_resume(struct device *dev)
67036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao{
68036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	struct dw_mci *host = dev_get_drvdata(dev);
69036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	int ret;
70036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao
71036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	ret = clk_prepare_enable(host->ciu_clk);
72036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	if (ret) {
73036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao		dev_err(host->dev, "failed to enable ciu clock\n");
74036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao		return ret;
75036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	}
76036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao
77036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	return dw_mci_resume(host);
78036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao}
79370aede6a18a41e01f2668108d847b598443fbc0Felipe Balbi#endif /* CONFIG_PM_SLEEP */
80036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao
8185136b74dc7fbbcaf173b660406de8aa1dd0068aWei Yongjunstatic SIMPLE_DEV_PM_OPS(dw_mci_k3_pmops, dw_mci_k3_suspend, dw_mci_k3_resume);
82036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao
83036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gaostatic struct platform_driver dw_mci_k3_pltfm_driver = {
84036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	.probe		= dw_mci_k3_probe,
85036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	.remove		= dw_mci_pltfm_remove,
86036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	.driver		= {
87036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao		.name		= "dwmmc_k3",
88036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao		.of_match_table	= dw_mci_k3_match,
89036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao		.pm		= &dw_mci_k3_pmops,
90036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao	},
91036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao};
92036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao
93036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gaomodule_platform_driver(dw_mci_k3_pltfm_driver);
94036f29d554e84fa288411d950c2f0ae797be9146Zhangfei Gao
95036f29d554e84fa288411d950c2f0ae797be9146Zhangfei GaoMODULE_DESCRIPTION("K3 Specific DW-MSHC Driver Extension");
96036f29d554e84fa288411d950c2f0ae797be9146Zhangfei GaoMODULE_LICENSE("GPL v2");
97036f29d554e84fa288411d950c2f0ae797be9146Zhangfei GaoMODULE_ALIAS("platform:dwmmc-k3");
98