// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ #include <linux/atomic.h> #include <linux/bug.h> #include <linux/interrupt.h> #include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/list.h> #include <linux/lockdep.h> #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/types.h> #include <linux/wait.h> #include <soc/qcom/rpmh.h> #include "rpmh-internal.h" #define RPMH_TIMEOUT_MS … #define DEFINE_RPMH_MSG_ONSTACK(device, s, q, name) … #define ctrlr_to_drv(ctrlr) … /** * struct cache_req: the request object for caching * * @addr: the address of the resource * @sleep_val: the sleep vote * @wake_val: the wake vote * @list: linked list obj */ struct cache_req { … }; /** * struct batch_cache_req - An entry in our batch catch * * @list: linked list obj * @count: number of messages * @rpm_msgs: the messages */ struct batch_cache_req { … }; static struct rpmh_ctrlr *get_rpmh_ctrlr(const struct device *dev) { … } void rpmh_tx_done(const struct tcs_request *msg) { … } static struct cache_req *__find_req(struct rpmh_ctrlr *ctrlr, u32 addr) { … } static struct cache_req *cache_rpm_request(struct rpmh_ctrlr *ctrlr, enum rpmh_state state, struct tcs_cmd *cmd) { … } /** * __rpmh_write: Cache and send the RPMH request * * @dev: The device making the request * @state: Active/Sleep request type * @rpm_msg: The data that needs to be sent (cmds). * * Cache the RPMH request and send if the state is ACTIVE_ONLY. * SLEEP/WAKE_ONLY requests are not sent to the controller at * this time. Use rpmh_flush() to send them to the controller. */ static int __rpmh_write(const struct device *dev, enum rpmh_state state, struct rpmh_request *rpm_msg) { … } static int __fill_rpmh_msg(struct rpmh_request *req, enum rpmh_state state, const struct tcs_cmd *cmd, u32 n) { … } /** * rpmh_write_async: Write a set of RPMH commands * * @dev: The device making the request * @state: Active/sleep set * @cmd: The payload data * @n: The number of elements in payload * * Write a set of RPMH commands, the order of commands is maintained * and will be sent as a single shot. */ int rpmh_write_async(const struct device *dev, enum rpmh_state state, const struct tcs_cmd *cmd, u32 n) { … } EXPORT_SYMBOL_GPL(…); /** * rpmh_write: Write a set of RPMH commands and block until response * * @dev: The device making the request * @state: Active/sleep set * @cmd: The payload data * @n: The number of elements in @cmd * * May sleep. Do not call from atomic contexts. */ int rpmh_write(const struct device *dev, enum rpmh_state state, const struct tcs_cmd *cmd, u32 n) { … } EXPORT_SYMBOL_GPL(…); static void cache_batch(struct rpmh_ctrlr *ctrlr, struct batch_cache_req *req) { … } static int flush_batch(struct rpmh_ctrlr *ctrlr) { … } /** * rpmh_write_batch: Write multiple sets of RPMH commands and wait for the * batch to finish. * * @dev: the device making the request * @state: Active/sleep set * @cmd: The payload data * @n: The array of count of elements in each batch, 0 terminated. * * Write a request to the RSC controller without caching. If the request * state is ACTIVE, then the requests are treated as completion request * and sent to the controller immediately. The function waits until all the * commands are complete. If the request was to SLEEP or WAKE_ONLY, then the * request is sent as fire-n-forget and no ack is expected. * * May sleep. Do not call from atomic contexts for ACTIVE_ONLY requests. */ int rpmh_write_batch(const struct device *dev, enum rpmh_state state, const struct tcs_cmd *cmd, u32 *n) { … } EXPORT_SYMBOL_GPL(…); static int is_req_valid(struct cache_req *req) { … } static int send_single(struct rpmh_ctrlr *ctrlr, enum rpmh_state state, u32 addr, u32 data) { … } /** * rpmh_flush() - Flushes the buffered sleep and wake sets to TCSes * * @ctrlr: Controller making request to flush cached data * * Return: * * 0 - Success * * Error code - Otherwise */ int rpmh_flush(struct rpmh_ctrlr *ctrlr) { … } /** * rpmh_invalidate: Invalidate sleep and wake sets in batch_cache * * @dev: The device making the request * * Invalidate the sleep and wake values in batch_cache. */ void rpmh_invalidate(const struct device *dev) { … } EXPORT_SYMBOL_GPL(…);