123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- // SPDX-License-Identifier: GPL-2.0-only
- /*
- * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
- */
- #include <linux/interconnect.h>
- #include "cam_soc_bus.h"
- /**
- * struct cam_soc_bus_client_data : Bus client data
- *
- * @icc_data: Bus icc path information
- */
- struct cam_soc_bus_client_data {
- struct icc_path *icc_data;
- };
- int cam_soc_bus_client_update_request(void *client, unsigned int idx)
- {
- int rc = 0;
- uint64_t ab = 0, ib = 0;
- struct cam_soc_bus_client *bus_client =
- (struct cam_soc_bus_client *) client;
- struct cam_soc_bus_client_data *bus_client_data =
- (struct cam_soc_bus_client_data *) bus_client->client_data;
- if (idx >= bus_client->common_data->num_usecases) {
- CAM_ERR(CAM_UTIL, "Invalid vote level=%d, usecases=%d", idx,
- bus_client->common_data->num_usecases);
- rc = -EINVAL;
- goto end;
- }
- ab = bus_client->common_data->bw_pair[idx].ab;
- ib = bus_client->common_data->bw_pair[idx].ib;
- CAM_DBG(CAM_PERF, "Bus client=[%s] index[%d] ab[%llu] ib[%llu]",
- bus_client->common_data->name, idx, ab, ib);
- rc = icc_set_bw(bus_client_data->icc_data, Bps_to_icc(ab),
- Bps_to_icc(ib));
- if (rc) {
- CAM_ERR(CAM_UTIL,
- "Update request failed, client[%s], idx: %d",
- bus_client->common_data->name, idx);
- goto end;
- }
- end:
- return rc;
- }
- int cam_soc_bus_client_update_bw(void *client, uint64_t ab, uint64_t ib)
- {
- struct cam_soc_bus_client *bus_client =
- (struct cam_soc_bus_client *) client;
- struct cam_soc_bus_client_data *bus_client_data =
- (struct cam_soc_bus_client_data *) bus_client->client_data;
- int rc = 0;
- CAM_DBG(CAM_PERF, "Bus client=[%s] :ab[%llu] ib[%llu]",
- bus_client->common_data->name, ab, ib);
- rc = icc_set_bw(bus_client_data->icc_data, Bps_to_icc(ab),
- Bps_to_icc(ib));
- if (rc) {
- CAM_ERR(CAM_UTIL, "Update request failed, client[%s]",
- bus_client->common_data->name);
- goto end;
- }
- end:
- return rc;
- }
- int cam_soc_bus_client_register(struct platform_device *pdev,
- struct device_node *dev_node, void **client,
- struct cam_soc_bus_client_common_data *common_data)
- {
- struct cam_soc_bus_client *bus_client = NULL;
- struct cam_soc_bus_client_data *bus_client_data = NULL;
- int rc = 0;
- bus_client = kzalloc(sizeof(struct cam_soc_bus_client), GFP_KERNEL);
- if (!bus_client) {
- CAM_ERR(CAM_UTIL, "soc bus client is NULL");
- rc = -ENOMEM;
- goto end;
- }
- *client = bus_client;
- bus_client_data = kzalloc(sizeof(struct cam_soc_bus_client_data),
- GFP_KERNEL);
- if (!bus_client_data) {
- kfree(bus_client);
- *client = NULL;
- rc = -ENOMEM;
- goto end;
- }
- bus_client->client_data = bus_client_data;
- bus_client->common_data = common_data;
- bus_client_data->icc_data = icc_get(&pdev->dev,
- bus_client->common_data->src_id,
- bus_client->common_data->dst_id);
- if (!bus_client_data->icc_data) {
- CAM_ERR(CAM_UTIL, "failed in register bus client");
- rc = -EINVAL;
- goto error;
- }
- rc = icc_set_bw(bus_client_data->icc_data, 0, 0);
- if (rc) {
- CAM_ERR(CAM_UTIL, "Bus client update request failed, rc = %d",
- rc);
- goto fail_unregister_client;
- }
- CAM_DBG(CAM_PERF, "Register Bus Client=[%s] : src=%d, dst=%d",
- bus_client->common_data->name, bus_client->common_data->src_id,
- bus_client->common_data->dst_id);
- return 0;
- fail_unregister_client:
- icc_put(bus_client_data->icc_data);
- error:
- kfree(bus_client_data);
- bus_client->client_data = NULL;
- kfree(bus_client);
- *client = NULL;
- end:
- return rc;
- }
- void cam_soc_bus_client_unregister(void **client)
- {
- struct cam_soc_bus_client *bus_client =
- (struct cam_soc_bus_client *) (*client);
- struct cam_soc_bus_client_data *bus_client_data =
- (struct cam_soc_bus_client_data *) bus_client->client_data;
- icc_put(bus_client_data->icc_data);
- kfree(bus_client_data);
- bus_client->client_data = NULL;
- kfree(bus_client);
- *client = NULL;
- }
|