Loading drivers/soc/qcom/rpmh-internal.h +2 −0 Original line number Diff line number Diff line Loading @@ -72,12 +72,14 @@ struct rpmh_request { * @cache_lock: synchronize access to the cache data * @dirty: was the cache updated since flush * @batch_cache: Cache sleep and wake requests sent as batch * @in_solver_mode: Controller is busy in solver mode */ struct rpmh_ctrlr { struct list_head cache; spinlock_t cache_lock; bool dirty; struct list_head batch_cache; bool in_solver_mode; }; /** Loading drivers/soc/qcom/rpmh.c +59 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ #include <linux/atomic.h> #include <linux/bug.h> #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/jiffies.h> #include <linux/kernel.h> Loading Loading @@ -75,6 +76,50 @@ static struct rpmh_ctrlr *get_rpmh_ctrlr(const struct device *dev) return &drv->client; } static int check_ctrlr_state(struct rpmh_ctrlr *ctrlr, enum rpmh_state state) { unsigned long flags; int ret = 0; /* Do not allow setting active votes when in solver mode */ spin_lock_irqsave(&ctrlr->cache_lock, flags); if (ctrlr->in_solver_mode && state == RPMH_ACTIVE_ONLY_STATE) ret = -EBUSY; spin_unlock_irqrestore(&ctrlr->cache_lock, flags); return ret; } /** * rpmh_mode_solver_set: Indicate that the RSC controller hardware has * been configured to be in solver mode * * @dev: the device making the request * @enable: Boolean value indicating if the controller is in solver mode. * * When solver mode is enabled, passthru API will not be able to send wake * votes, just awake and active votes. */ int rpmh_mode_solver_set(const struct device *dev, bool enable) { struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev); unsigned long flags; for (;;) { spin_lock_irqsave(&ctrlr->cache_lock, flags); if (rpmh_rsc_ctrlr_is_idle(ctrlr_to_drv(ctrlr))) { ctrlr->in_solver_mode = enable; spin_unlock_irqrestore(&ctrlr->cache_lock, flags); break; } spin_unlock_irqrestore(&ctrlr->cache_lock, flags); udelay(10); } return 0; } EXPORT_SYMBOL(rpmh_mode_solver_set); void rpmh_tx_done(const struct tcs_request *msg, int r) { struct rpmh_request *rpm_msg = container_of(msg, struct rpmh_request, Loading Loading @@ -231,8 +276,13 @@ int rpmh_write_async(const struct device *dev, enum rpmh_state state, const struct tcs_cmd *cmd, u32 n) { struct rpmh_request *rpm_msg; struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev); int ret; ret = check_ctrlr_state(ctrlr, state); if (ret) return ret; rpm_msg = kzalloc(sizeof(*rpm_msg), GFP_ATOMIC); if (!rpm_msg) return -ENOMEM; Loading Loading @@ -263,11 +313,16 @@ int rpmh_write(const struct device *dev, enum rpmh_state state, { DECLARE_COMPLETION_ONSTACK(compl); DEFINE_RPMH_MSG_ONSTACK(dev, state, &compl, rpm_msg); struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev); int ret; if (!cmd || !n || n > MAX_RPMH_PAYLOAD) return -EINVAL; ret = check_ctrlr_state(ctrlr, state); if (ret) return ret; memcpy(rpm_msg.cmd, cmd, n * sizeof(*cmd)); rpm_msg.msg.num_cmds = n; Loading Loading @@ -357,6 +412,10 @@ int rpmh_write_batch(const struct device *dev, enum rpmh_state state, if (!cmd || !n) return -EINVAL; ret = check_ctrlr_state(ctrlr, state); if (ret) return ret; while (n[count] > 0) count++; if (!count) Loading include/soc/qcom/rpmh.h +5 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ int rpmh_invalidate(const struct device *dev); int rpmh_ctrlr_idle(const struct device *dev); int rpmh_mode_solver_set(const struct device *dev, bool enable); #else static inline int rpmh_write(const struct device *dev, enum rpmh_state state, Loading @@ -51,6 +53,9 @@ static inline int rpmh_invalidate(const struct device *dev) static inline int rpmh_ctrlr_idle(const struct device *dev) { return -ENODEV; } static inline int rpmh_mode_solver_set(const struct device *dev, bool enable) { return -ENODEV; } #endif /* CONFIG_QCOM_RPMH */ #endif /* __SOC_QCOM_RPMH_H__ */ Loading
drivers/soc/qcom/rpmh-internal.h +2 −0 Original line number Diff line number Diff line Loading @@ -72,12 +72,14 @@ struct rpmh_request { * @cache_lock: synchronize access to the cache data * @dirty: was the cache updated since flush * @batch_cache: Cache sleep and wake requests sent as batch * @in_solver_mode: Controller is busy in solver mode */ struct rpmh_ctrlr { struct list_head cache; spinlock_t cache_lock; bool dirty; struct list_head batch_cache; bool in_solver_mode; }; /** Loading
drivers/soc/qcom/rpmh.c +59 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ #include <linux/atomic.h> #include <linux/bug.h> #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/jiffies.h> #include <linux/kernel.h> Loading Loading @@ -75,6 +76,50 @@ static struct rpmh_ctrlr *get_rpmh_ctrlr(const struct device *dev) return &drv->client; } static int check_ctrlr_state(struct rpmh_ctrlr *ctrlr, enum rpmh_state state) { unsigned long flags; int ret = 0; /* Do not allow setting active votes when in solver mode */ spin_lock_irqsave(&ctrlr->cache_lock, flags); if (ctrlr->in_solver_mode && state == RPMH_ACTIVE_ONLY_STATE) ret = -EBUSY; spin_unlock_irqrestore(&ctrlr->cache_lock, flags); return ret; } /** * rpmh_mode_solver_set: Indicate that the RSC controller hardware has * been configured to be in solver mode * * @dev: the device making the request * @enable: Boolean value indicating if the controller is in solver mode. * * When solver mode is enabled, passthru API will not be able to send wake * votes, just awake and active votes. */ int rpmh_mode_solver_set(const struct device *dev, bool enable) { struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev); unsigned long flags; for (;;) { spin_lock_irqsave(&ctrlr->cache_lock, flags); if (rpmh_rsc_ctrlr_is_idle(ctrlr_to_drv(ctrlr))) { ctrlr->in_solver_mode = enable; spin_unlock_irqrestore(&ctrlr->cache_lock, flags); break; } spin_unlock_irqrestore(&ctrlr->cache_lock, flags); udelay(10); } return 0; } EXPORT_SYMBOL(rpmh_mode_solver_set); void rpmh_tx_done(const struct tcs_request *msg, int r) { struct rpmh_request *rpm_msg = container_of(msg, struct rpmh_request, Loading Loading @@ -231,8 +276,13 @@ int rpmh_write_async(const struct device *dev, enum rpmh_state state, const struct tcs_cmd *cmd, u32 n) { struct rpmh_request *rpm_msg; struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev); int ret; ret = check_ctrlr_state(ctrlr, state); if (ret) return ret; rpm_msg = kzalloc(sizeof(*rpm_msg), GFP_ATOMIC); if (!rpm_msg) return -ENOMEM; Loading Loading @@ -263,11 +313,16 @@ int rpmh_write(const struct device *dev, enum rpmh_state state, { DECLARE_COMPLETION_ONSTACK(compl); DEFINE_RPMH_MSG_ONSTACK(dev, state, &compl, rpm_msg); struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev); int ret; if (!cmd || !n || n > MAX_RPMH_PAYLOAD) return -EINVAL; ret = check_ctrlr_state(ctrlr, state); if (ret) return ret; memcpy(rpm_msg.cmd, cmd, n * sizeof(*cmd)); rpm_msg.msg.num_cmds = n; Loading Loading @@ -357,6 +412,10 @@ int rpmh_write_batch(const struct device *dev, enum rpmh_state state, if (!cmd || !n) return -EINVAL; ret = check_ctrlr_state(ctrlr, state); if (ret) return ret; while (n[count] > 0) count++; if (!count) Loading
include/soc/qcom/rpmh.h +5 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ int rpmh_invalidate(const struct device *dev); int rpmh_ctrlr_idle(const struct device *dev); int rpmh_mode_solver_set(const struct device *dev, bool enable); #else static inline int rpmh_write(const struct device *dev, enum rpmh_state state, Loading @@ -51,6 +53,9 @@ static inline int rpmh_invalidate(const struct device *dev) static inline int rpmh_ctrlr_idle(const struct device *dev) { return -ENODEV; } static inline int rpmh_mode_solver_set(const struct device *dev, bool enable) { return -ENODEV; } #endif /* CONFIG_QCOM_RPMH */ #endif /* __SOC_QCOM_RPMH_H__ */