18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Synopsys G210 Test Chip driver 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com) 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Authors: Joao Pinto <jpinto@synopsys.com> 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/kernel.h> 118c2ecf20Sopenharmony_ci#include <linux/module.h> 128c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 138c2ecf20Sopenharmony_ci#include <linux/of.h> 148c2ecf20Sopenharmony_ci#include <linux/delay.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#include "ufshcd-pltfrm.h" 178c2ecf20Sopenharmony_ci#include "ufshcd-dwc.h" 188c2ecf20Sopenharmony_ci#include "tc-dwc-g210.h" 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci/* 218c2ecf20Sopenharmony_ci * UFS DWC specific variant operations 228c2ecf20Sopenharmony_ci */ 238c2ecf20Sopenharmony_cistatic struct ufs_hba_variant_ops tc_dwc_g210_20bit_pltfm_hba_vops = { 248c2ecf20Sopenharmony_ci .name = "tc-dwc-g210-pltfm", 258c2ecf20Sopenharmony_ci .link_startup_notify = ufshcd_dwc_link_startup_notify, 268c2ecf20Sopenharmony_ci .phy_initialization = tc_dwc_g210_config_20_bit, 278c2ecf20Sopenharmony_ci}; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_cistatic struct ufs_hba_variant_ops tc_dwc_g210_40bit_pltfm_hba_vops = { 308c2ecf20Sopenharmony_ci .name = "tc-dwc-g210-pltfm", 318c2ecf20Sopenharmony_ci .link_startup_notify = ufshcd_dwc_link_startup_notify, 328c2ecf20Sopenharmony_ci .phy_initialization = tc_dwc_g210_config_40_bit, 338c2ecf20Sopenharmony_ci}; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistatic const struct of_device_id tc_dwc_g210_pltfm_match[] = { 368c2ecf20Sopenharmony_ci { 378c2ecf20Sopenharmony_ci .compatible = "snps,g210-tc-6.00-20bit", 388c2ecf20Sopenharmony_ci .data = &tc_dwc_g210_20bit_pltfm_hba_vops, 398c2ecf20Sopenharmony_ci }, 408c2ecf20Sopenharmony_ci { 418c2ecf20Sopenharmony_ci .compatible = "snps,g210-tc-6.00-40bit", 428c2ecf20Sopenharmony_ci .data = &tc_dwc_g210_40bit_pltfm_hba_vops, 438c2ecf20Sopenharmony_ci }, 448c2ecf20Sopenharmony_ci { }, 458c2ecf20Sopenharmony_ci}; 468c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, tc_dwc_g210_pltfm_match); 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci/** 498c2ecf20Sopenharmony_ci * tc_dwc_g210_pltfm_probe() 508c2ecf20Sopenharmony_ci * @pdev: pointer to platform device structure 518c2ecf20Sopenharmony_ci * 528c2ecf20Sopenharmony_ci */ 538c2ecf20Sopenharmony_cistatic int tc_dwc_g210_pltfm_probe(struct platform_device *pdev) 548c2ecf20Sopenharmony_ci{ 558c2ecf20Sopenharmony_ci int err; 568c2ecf20Sopenharmony_ci const struct of_device_id *of_id; 578c2ecf20Sopenharmony_ci struct ufs_hba_variant_ops *vops; 588c2ecf20Sopenharmony_ci struct device *dev = &pdev->dev; 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci of_id = of_match_node(tc_dwc_g210_pltfm_match, dev->of_node); 618c2ecf20Sopenharmony_ci vops = (struct ufs_hba_variant_ops *)of_id->data; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci /* Perform generic probe */ 648c2ecf20Sopenharmony_ci err = ufshcd_pltfrm_init(pdev, vops); 658c2ecf20Sopenharmony_ci if (err) 668c2ecf20Sopenharmony_ci dev_err(dev, "ufshcd_pltfrm_init() failed %d\n", err); 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci return err; 698c2ecf20Sopenharmony_ci} 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci/** 728c2ecf20Sopenharmony_ci * tc_dwc_g210_pltfm_remove() 738c2ecf20Sopenharmony_ci * @pdev: pointer to platform device structure 748c2ecf20Sopenharmony_ci * 758c2ecf20Sopenharmony_ci */ 768c2ecf20Sopenharmony_cistatic int tc_dwc_g210_pltfm_remove(struct platform_device *pdev) 778c2ecf20Sopenharmony_ci{ 788c2ecf20Sopenharmony_ci struct ufs_hba *hba = platform_get_drvdata(pdev); 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci pm_runtime_get_sync(&(pdev)->dev); 818c2ecf20Sopenharmony_ci ufshcd_remove(hba); 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci return 0; 848c2ecf20Sopenharmony_ci} 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_cistatic const struct dev_pm_ops tc_dwc_g210_pltfm_pm_ops = { 878c2ecf20Sopenharmony_ci .suspend = ufshcd_pltfrm_suspend, 888c2ecf20Sopenharmony_ci .resume = ufshcd_pltfrm_resume, 898c2ecf20Sopenharmony_ci .runtime_suspend = ufshcd_pltfrm_runtime_suspend, 908c2ecf20Sopenharmony_ci .runtime_resume = ufshcd_pltfrm_runtime_resume, 918c2ecf20Sopenharmony_ci .runtime_idle = ufshcd_pltfrm_runtime_idle, 928c2ecf20Sopenharmony_ci}; 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_cistatic struct platform_driver tc_dwc_g210_pltfm_driver = { 958c2ecf20Sopenharmony_ci .probe = tc_dwc_g210_pltfm_probe, 968c2ecf20Sopenharmony_ci .remove = tc_dwc_g210_pltfm_remove, 978c2ecf20Sopenharmony_ci .shutdown = ufshcd_pltfrm_shutdown, 988c2ecf20Sopenharmony_ci .driver = { 998c2ecf20Sopenharmony_ci .name = "tc-dwc-g210-pltfm", 1008c2ecf20Sopenharmony_ci .pm = &tc_dwc_g210_pltfm_pm_ops, 1018c2ecf20Sopenharmony_ci .of_match_table = of_match_ptr(tc_dwc_g210_pltfm_match), 1028c2ecf20Sopenharmony_ci }, 1038c2ecf20Sopenharmony_ci}; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_cimodule_platform_driver(tc_dwc_g210_pltfm_driver); 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ciMODULE_ALIAS("platform:tc-dwc-g210-pltfm"); 1088c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Synopsys Test Chip G210 platform glue driver"); 1098c2ecf20Sopenharmony_ciMODULE_AUTHOR("Joao Pinto <Joao.Pinto@synopsys.com>"); 1108c2ecf20Sopenharmony_ciMODULE_LICENSE("Dual BSD/GPL"); 111