// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note /* * * (C) COPYRIGHT 2022 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the * GNU General Public License version 2 as published by the Free Software * Foundation, and any use by you of this program is subject to the terms * of such GNU license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, you can access it online at * http://www.gnu.org/licenses/gpl-2.0.html. * */ #include #include #include #include #include #include #include #include #include #include "sources/coresight_mali_sources.h" static int coresight_mali_source_trace_id(struct coresight_device *csdev) { struct coresight_mali_source_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); return drvdata->trcid; } static int coresight_mali_enable_source(struct coresight_device *csdev, struct perf_event *event, u32 mode) { return coresight_mali_enable_component(csdev, mode); } static void coresight_mali_disable_source(struct coresight_device *csdev, struct perf_event *event) { coresight_mali_disable_component(csdev); } static const struct coresight_ops_source coresight_mali_source_ops = { .trace_id = coresight_mali_source_trace_id, .enable = coresight_mali_enable_source, .disable = coresight_mali_disable_source }; static const struct coresight_ops mali_cs_ops = { .source_ops = &coresight_mali_source_ops, }; int coresight_mali_sources_probe(struct platform_device *pdev) { int ret = 0; struct coresight_platform_data *pdata = NULL; struct coresight_mali_source_drvdata *drvdata = NULL; struct coresight_desc desc = { 0 }; struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct platform_device *gpu_pdev = NULL; struct device_node *gpu_node = NULL; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; dev_set_drvdata(dev, drvdata); drvdata->base.dev = dev; #if KERNEL_VERSION(5, 3, 0) <= LINUX_VERSION_CODE pdata = coresight_get_platform_data(dev); #else if (np) pdata = of_get_coresight_platform_data(dev, np); #endif if (IS_ERR(pdata)) { dev_err(drvdata->base.dev, "Failed to get platform data\n"); ret = PTR_ERR(pdata); goto devm_kfree_drvdata; } dev->platform_data = pdata; gpu_node = of_parse_phandle(np, "gpu", 0); if (!gpu_node) { dev_err(drvdata->base.dev, "GPU node not available\n"); goto devm_kfree_drvdata; } gpu_pdev = of_find_device_by_node(gpu_node); if (gpu_pdev == NULL) { dev_err(drvdata->base.dev, "Couldn't find GPU device from node\n"); goto devm_kfree_drvdata; } drvdata->base.gpu_dev = platform_get_drvdata(gpu_pdev); if (!drvdata->base.gpu_dev) { dev_err(drvdata->base.dev, "GPU dev not available\n"); goto devm_kfree_drvdata; } ret = coresight_mali_sources_init_drvdata(drvdata); if (ret) { dev_err(drvdata->base.dev, "Failed to init source driver data\n"); goto kbase_client_unregister; } desc.type = CORESIGHT_DEV_TYPE_SOURCE; desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE; desc.ops = &mali_cs_ops; desc.pdata = pdata; desc.dev = dev; desc.groups = coresight_mali_source_groups_get(); #if KERNEL_VERSION(5, 3, 0) <= LINUX_VERSION_CODE desc.name = devm_kasprintf(dev, GFP_KERNEL, "%s", drvdata->type_name); if (!desc.name) { ret = -ENOMEM; goto devm_kfree_drvdata; } #endif drvdata->base.csdev = coresight_register(&desc); if (IS_ERR(drvdata->base.csdev)) { dev_err(drvdata->base.dev, "Failed to register coresight device\n"); ret = PTR_ERR(drvdata->base.csdev); goto devm_kfree_drvdata; } return ret; kbase_client_unregister: if (drvdata->base.csdev != NULL) coresight_unregister(drvdata->base.csdev); coresight_mali_sources_deinit_drvdata(drvdata); devm_kfree_drvdata: devm_kfree(dev, drvdata); return ret; } int coresight_mali_sources_remove(struct platform_device *pdev) { struct coresight_mali_source_drvdata *drvdata = dev_get_drvdata(&pdev->dev); if (drvdata->base.csdev != NULL) coresight_unregister(drvdata->base.csdev); coresight_mali_sources_deinit_drvdata(drvdata); devm_kfree(&pdev->dev, drvdata); return 0; } MODULE_AUTHOR("ARM Ltd."); MODULE_DESCRIPTION("Arm Coresight Mali source"); MODULE_LICENSE("GPL");