18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * RPM over SMD communication wrapper for interconnects 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2019 Linaro Ltd 68c2ecf20Sopenharmony_ci * Author: Georgi Djakov <georgi.djakov@linaro.org> 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/interconnect-provider.h> 108c2ecf20Sopenharmony_ci#include <linux/module.h> 118c2ecf20Sopenharmony_ci#include <linux/of.h> 128c2ecf20Sopenharmony_ci#include <linux/of_platform.h> 138c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 148c2ecf20Sopenharmony_ci#include <linux/soc/qcom/smd-rpm.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#include "smd-rpm.h" 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#define RPM_KEY_BW 0x00007762 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_cistatic struct qcom_smd_rpm *icc_smd_rpm; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistruct icc_rpm_smd_req { 238c2ecf20Sopenharmony_ci __le32 key; 248c2ecf20Sopenharmony_ci __le32 nbytes; 258c2ecf20Sopenharmony_ci __le32 value; 268c2ecf20Sopenharmony_ci}; 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_cibool qcom_icc_rpm_smd_available(void) 298c2ecf20Sopenharmony_ci{ 308c2ecf20Sopenharmony_ci return !!icc_smd_rpm; 318c2ecf20Sopenharmony_ci} 328c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(qcom_icc_rpm_smd_available); 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ciint qcom_icc_rpm_smd_send(int ctx, int rsc_type, int id, u32 val) 358c2ecf20Sopenharmony_ci{ 368c2ecf20Sopenharmony_ci struct icc_rpm_smd_req req = { 378c2ecf20Sopenharmony_ci .key = cpu_to_le32(RPM_KEY_BW), 388c2ecf20Sopenharmony_ci .nbytes = cpu_to_le32(sizeof(u32)), 398c2ecf20Sopenharmony_ci .value = cpu_to_le32(val), 408c2ecf20Sopenharmony_ci }; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci return qcom_rpm_smd_write(icc_smd_rpm, ctx, rsc_type, id, &req, 438c2ecf20Sopenharmony_ci sizeof(req)); 448c2ecf20Sopenharmony_ci} 458c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(qcom_icc_rpm_smd_send); 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic int qcom_icc_rpm_smd_remove(struct platform_device *pdev) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci icc_smd_rpm = NULL; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci return 0; 528c2ecf20Sopenharmony_ci} 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_cistatic int qcom_icc_rpm_smd_probe(struct platform_device *pdev) 558c2ecf20Sopenharmony_ci{ 568c2ecf20Sopenharmony_ci icc_smd_rpm = dev_get_drvdata(pdev->dev.parent); 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci if (!icc_smd_rpm) { 598c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "unable to retrieve handle to RPM\n"); 608c2ecf20Sopenharmony_ci return -ENODEV; 618c2ecf20Sopenharmony_ci } 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci return 0; 648c2ecf20Sopenharmony_ci} 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_cistatic struct platform_driver qcom_interconnect_rpm_smd_driver = { 678c2ecf20Sopenharmony_ci .driver = { 688c2ecf20Sopenharmony_ci .name = "icc_smd_rpm", 698c2ecf20Sopenharmony_ci }, 708c2ecf20Sopenharmony_ci .probe = qcom_icc_rpm_smd_probe, 718c2ecf20Sopenharmony_ci .remove = qcom_icc_rpm_smd_remove, 728c2ecf20Sopenharmony_ci}; 738c2ecf20Sopenharmony_cimodule_platform_driver(qcom_interconnect_rpm_smd_driver); 748c2ecf20Sopenharmony_ciMODULE_AUTHOR("Georgi Djakov <georgi.djakov@linaro.org>"); 758c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Qualcomm SMD RPM interconnect proxy driver"); 768c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2"); 778c2ecf20Sopenharmony_ciMODULE_ALIAS("platform:icc_smd_rpm"); 78