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