Loading drivers/soc/qcom/rpmh-internal.h +5 −0 Original line number Diff line number Diff line Loading @@ -69,12 +69,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 @@ -84,6 +86,7 @@ struct rpmh_ctrlr { * @name: controller identifier * @tcs_base: start address of the TCS registers in this controller * @id: instance id in the controller (Direct Resource Voter) * @in_solver_mode: Controller is in solver mode * @num_tcs: number of TCSes in this DRV * @tcs: TCS groups * @tcs_in_use: s/w state of the TCS Loading @@ -94,6 +97,7 @@ struct rsc_drv { const char *name; void __iomem *tcs_base; int id; bool in_solver_mode; int num_tcs; struct tcs_group tcs[TCS_TYPE_NR]; DECLARE_BITMAP(tcs_in_use, MAX_TCS_NR); Loading @@ -105,6 +109,7 @@ int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg); int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv, const struct tcs_request *msg); int rpmh_rsc_invalidate(struct rsc_drv *drv); void rpmh_rsc_mode_solver_set(struct rsc_drv *drv, bool enable); void rpmh_tx_done(const struct tcs_request *msg, int r); Loading drivers/soc/qcom/rpmh-rsc.c +31 −2 Original line number Diff line number Diff line Loading @@ -92,8 +92,7 @@ static void write_tcs_reg_sync(struct rsc_drv *drv, int reg, int tcs_id, static bool tcs_is_free(struct rsc_drv *drv, int tcs_id) { return !test_bit(tcs_id, drv->tcs_in_use) && read_tcs_reg(drv, RSC_DRV_STATUS, tcs_id, 0); return !test_bit(tcs_id, drv->tcs_in_use); } static struct tcs_group *get_tcs_of_type(struct rsc_drv *drv, int type) Loading Loading @@ -386,6 +385,11 @@ static int tcs_write(struct rsc_drv *drv, const struct tcs_request *msg) spin_lock_irqsave(&tcs->lock, flags); spin_lock(&drv->lock); if (msg->state == RPMH_ACTIVE_ONLY_STATE && drv->in_solver_mode) { ret = -EINVAL; spin_unlock(&drv->lock); goto done_write; } /* * The h/w does not like if we send a request to the same address, * when one is already in-flight or being processed. Loading Loading @@ -552,6 +556,30 @@ int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv, const struct tcs_request *msg) return tcs_ctrl_write(drv, msg); } /** * rpmh_rsc_mode_solver_set: Enable/disable solver mode * * @drv: The controller * * enable: boolean state to be set - true/false */ void rpmh_rsc_mode_solver_set(struct rsc_drv *drv, bool enable) { int m; struct tcs_group *tcs = get_tcs_of_type(drv, ACTIVE_TCS); again: spin_lock(&drv->lock); for (m = tcs->offset; m < tcs->offset + tcs->num_tcs; m++) { if (!tcs_is_free(drv, m)) { spin_unlock(&drv->lock); goto again; } } drv->in_solver_mode = enable; spin_unlock(&drv->lock); } static int rpmh_probe_tcs_config(struct platform_device *pdev, struct rsc_drv *drv) { Loading Loading @@ -682,6 +710,7 @@ static int rpmh_rsc_probe(struct platform_device *pdev) return ret; spin_lock_init(&drv->lock); drv->in_solver_mode = false; bitmap_zero(drv->tcs_in_use, MAX_TCS_NR); irq = platform_get_irq(pdev, drv->id); Loading drivers/soc/qcom/rpmh.c +52 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,44 @@ 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) { int ret = 0; unsigned long flags; /* 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; spin_lock_irqsave(&ctrlr->cache_lock, flags); rpmh_rsc_mode_solver_set(ctrlr_to_drv(ctrlr), enable); ctrlr->in_solver_mode = enable; spin_unlock_irqrestore(&ctrlr->cache_lock, flags); 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 @@ -229,8 +267,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 @@ -261,11 +304,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 @@ -356,6 +404,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 @@ -22,6 +22,8 @@ int rpmh_flush(const struct device *dev); int rpmh_invalidate(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 @@ -44,6 +46,9 @@ static inline int rpmh_flush(const struct device *dev) static inline int rpmh_invalidate(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 +5 −0 Original line number Diff line number Diff line Loading @@ -69,12 +69,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 @@ -84,6 +86,7 @@ struct rpmh_ctrlr { * @name: controller identifier * @tcs_base: start address of the TCS registers in this controller * @id: instance id in the controller (Direct Resource Voter) * @in_solver_mode: Controller is in solver mode * @num_tcs: number of TCSes in this DRV * @tcs: TCS groups * @tcs_in_use: s/w state of the TCS Loading @@ -94,6 +97,7 @@ struct rsc_drv { const char *name; void __iomem *tcs_base; int id; bool in_solver_mode; int num_tcs; struct tcs_group tcs[TCS_TYPE_NR]; DECLARE_BITMAP(tcs_in_use, MAX_TCS_NR); Loading @@ -105,6 +109,7 @@ int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg); int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv, const struct tcs_request *msg); int rpmh_rsc_invalidate(struct rsc_drv *drv); void rpmh_rsc_mode_solver_set(struct rsc_drv *drv, bool enable); void rpmh_tx_done(const struct tcs_request *msg, int r); Loading
drivers/soc/qcom/rpmh-rsc.c +31 −2 Original line number Diff line number Diff line Loading @@ -92,8 +92,7 @@ static void write_tcs_reg_sync(struct rsc_drv *drv, int reg, int tcs_id, static bool tcs_is_free(struct rsc_drv *drv, int tcs_id) { return !test_bit(tcs_id, drv->tcs_in_use) && read_tcs_reg(drv, RSC_DRV_STATUS, tcs_id, 0); return !test_bit(tcs_id, drv->tcs_in_use); } static struct tcs_group *get_tcs_of_type(struct rsc_drv *drv, int type) Loading Loading @@ -386,6 +385,11 @@ static int tcs_write(struct rsc_drv *drv, const struct tcs_request *msg) spin_lock_irqsave(&tcs->lock, flags); spin_lock(&drv->lock); if (msg->state == RPMH_ACTIVE_ONLY_STATE && drv->in_solver_mode) { ret = -EINVAL; spin_unlock(&drv->lock); goto done_write; } /* * The h/w does not like if we send a request to the same address, * when one is already in-flight or being processed. Loading Loading @@ -552,6 +556,30 @@ int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv, const struct tcs_request *msg) return tcs_ctrl_write(drv, msg); } /** * rpmh_rsc_mode_solver_set: Enable/disable solver mode * * @drv: The controller * * enable: boolean state to be set - true/false */ void rpmh_rsc_mode_solver_set(struct rsc_drv *drv, bool enable) { int m; struct tcs_group *tcs = get_tcs_of_type(drv, ACTIVE_TCS); again: spin_lock(&drv->lock); for (m = tcs->offset; m < tcs->offset + tcs->num_tcs; m++) { if (!tcs_is_free(drv, m)) { spin_unlock(&drv->lock); goto again; } } drv->in_solver_mode = enable; spin_unlock(&drv->lock); } static int rpmh_probe_tcs_config(struct platform_device *pdev, struct rsc_drv *drv) { Loading Loading @@ -682,6 +710,7 @@ static int rpmh_rsc_probe(struct platform_device *pdev) return ret; spin_lock_init(&drv->lock); drv->in_solver_mode = false; bitmap_zero(drv->tcs_in_use, MAX_TCS_NR); irq = platform_get_irq(pdev, drv->id); Loading
drivers/soc/qcom/rpmh.c +52 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,44 @@ 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) { int ret = 0; unsigned long flags; /* 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; spin_lock_irqsave(&ctrlr->cache_lock, flags); rpmh_rsc_mode_solver_set(ctrlr_to_drv(ctrlr), enable); ctrlr->in_solver_mode = enable; spin_unlock_irqrestore(&ctrlr->cache_lock, flags); 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 @@ -229,8 +267,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 @@ -261,11 +304,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 @@ -356,6 +404,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 @@ -22,6 +22,8 @@ int rpmh_flush(const struct device *dev); int rpmh_invalidate(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 @@ -44,6 +46,9 @@ static inline int rpmh_flush(const struct device *dev) static inline int rpmh_invalidate(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__ */