mirror of
https://github.com/torvalds/linux.git
synced 2026-07-31 03:27:03 +02:00
Merge "drivers: qcom: rpmh: Disallow active requests in solver mode"
This commit is contained in:
commit
219f36ae55
|
|
@ -77,12 +77,14 @@ struct rpmh_request {
|
|||
* @cache: the list of cached requests
|
||||
* @cache_lock: synchronize access to the cache data
|
||||
* @dirty: was the cache updated since flush
|
||||
* @in_solver_mode: Controller is busy in solver mode
|
||||
* @batch_cache: Cache sleep and wake requests sent as batch
|
||||
*/
|
||||
struct rpmh_ctrlr {
|
||||
struct list_head cache;
|
||||
spinlock_t cache_lock;
|
||||
bool dirty;
|
||||
bool in_solver_mode;
|
||||
struct list_head batch_cache;
|
||||
};
|
||||
|
||||
|
|
@ -95,6 +97,7 @@ struct rpmh_ctrlr {
|
|||
* @id: Instance id in the controller (Direct Resource Voter).
|
||||
* @num_tcs: Number of TCSes in this DRV.
|
||||
* @irq: IRQ at gic.
|
||||
* @in_solver_mode: Controller is busy in solver mode
|
||||
* @rsc_pm: CPU PM notifier for controller.
|
||||
* Used when solver mode is not present.
|
||||
* @cpus_in_pm: Number of CPUs not in idle power collapse.
|
||||
|
|
@ -118,6 +121,7 @@ struct rsc_drv {
|
|||
int id;
|
||||
int num_tcs;
|
||||
int irq;
|
||||
bool in_solver_mode;
|
||||
struct notifier_block rsc_pm;
|
||||
atomic_t cpus_in_pm;
|
||||
struct tcs_group tcs[TCS_TYPE_NR];
|
||||
|
|
@ -132,6 +136,7 @@ int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv,
|
|||
const struct tcs_request *msg);
|
||||
void rpmh_rsc_invalidate(struct rsc_drv *drv);
|
||||
void rpmh_rsc_debug(struct rsc_drv *drv, struct completion *compl);
|
||||
int rpmh_rsc_mode_solver_set(struct rsc_drv *drv, bool enable);
|
||||
|
||||
void rpmh_tx_done(const struct tcs_request *msg, int r);
|
||||
int rpmh_flush(struct rpmh_ctrlr *ctrlr);
|
||||
|
|
|
|||
|
|
@ -626,6 +626,12 @@ int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg)
|
|||
|
||||
spin_lock_irqsave(&drv->lock, flags);
|
||||
|
||||
/* Controller is busy in 'solver' mode */
|
||||
if (drv->in_solver_mode) {
|
||||
spin_unlock_irqrestore(&drv->lock, flags);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* Wait forever for a free tcs. It better be there eventually! */
|
||||
wait_event_lock_irq(drv->tcs_wait,
|
||||
(tcs_id = claim_tcs_for_req(drv, tcs, msg)) >= 0,
|
||||
|
|
@ -950,6 +956,31 @@ static int rpmh_rsc_cpu_pm_callback(struct notifier_block *nfb,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* rpmh_rsc_mode_solver_set() - Enable/disable solver mode.
|
||||
* @drv: The controller.
|
||||
* @enable: Boolean state to be set - true/false
|
||||
*
|
||||
* Return:
|
||||
* * 0 - success
|
||||
* * -EBUSY - AMCs are busy
|
||||
*/
|
||||
int rpmh_rsc_mode_solver_set(struct rsc_drv *drv, bool enable)
|
||||
{
|
||||
int ret = -EBUSY;
|
||||
|
||||
if (spin_trylock(&drv->lock)) {
|
||||
if (!enable || !rpmh_rsc_ctrlr_is_busy(drv)) {
|
||||
drv->in_solver_mode = enable;
|
||||
trace_rpmh_solver_set(drv, enable);
|
||||
ret = 0;
|
||||
}
|
||||
spin_unlock(&drv->lock);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rpmh_probe_tcs_config(struct platform_device *pdev,
|
||||
struct rsc_drv *drv, void __iomem *base)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -76,6 +76,22 @@ 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;
|
||||
|
||||
if (state != RPMH_ACTIVE_ONLY_STATE)
|
||||
return ret;
|
||||
|
||||
/* Do not allow sending active votes when in solver mode */
|
||||
spin_lock(&ctrlr->cache_lock);
|
||||
if (ctrlr->in_solver_mode)
|
||||
ret = -EBUSY;
|
||||
spin_unlock(&ctrlr->cache_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void rpmh_tx_done(const struct tcs_request *msg, int r)
|
||||
{
|
||||
struct rpmh_request *rpm_msg = container_of(msg, struct rpmh_request,
|
||||
|
|
@ -229,9 +245,14 @@ static int __fill_rpmh_msg(struct rpmh_request *req, enum rpmh_state state,
|
|||
int rpmh_write_async(const struct device *dev, enum rpmh_state state,
|
||||
const struct tcs_cmd *cmd, u32 n)
|
||||
{
|
||||
struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev);
|
||||
struct rpmh_request *rpm_msg;
|
||||
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;
|
||||
|
|
@ -265,6 +286,10 @@ int rpmh_write(const struct device *dev, enum rpmh_state state,
|
|||
struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev);
|
||||
int ret;
|
||||
|
||||
ret = check_ctrlr_state(ctrlr, state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = __fill_rpmh_msg(&rpm_msg, state, cmd, n);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
@ -343,6 +368,10 @@ int rpmh_write_batch(const struct device *dev, enum rpmh_state state,
|
|||
int ret, i;
|
||||
void *ptr;
|
||||
|
||||
ret = check_ctrlr_state(ctrlr, state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!cmd || !n)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -510,3 +539,28 @@ void rpmh_invalidate(const struct device *dev)
|
|||
spin_unlock_irqrestore(&ctrlr->cache_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(rpmh_invalidate);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* Return:
|
||||
* * 0 - Success
|
||||
* * Error code - Otherwise
|
||||
*/
|
||||
int rpmh_mode_solver_set(const struct device *dev, bool enable)
|
||||
{
|
||||
int ret;
|
||||
struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev);
|
||||
|
||||
spin_lock(&ctrlr->cache_lock);
|
||||
ret = rpmh_rsc_mode_solver_set(ctrlr_to_drv(ctrlr), enable);
|
||||
if (!ret)
|
||||
ctrlr->in_solver_mode = enable;
|
||||
spin_unlock(&ctrlr->cache_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(rpmh_mode_solver_set);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#if !defined(_TRACE_RPMH_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
|
|
@ -71,6 +71,26 @@ TRACE_EVENT(rpmh_send_msg,
|
|||
__entry->addr, __entry->data, __entry->wait)
|
||||
);
|
||||
|
||||
TRACE_EVENT(rpmh_solver_set,
|
||||
|
||||
TP_PROTO(struct rsc_drv *d, bool set),
|
||||
|
||||
TP_ARGS(d, set),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(name, d->name)
|
||||
__field(bool, set)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__assign_str(name, d->name);
|
||||
__entry->set = set;
|
||||
),
|
||||
|
||||
TP_printk("%s: solver mode set: %d",
|
||||
__get_str(name), __entry->set)
|
||||
);
|
||||
|
||||
#endif /* _TRACE_RPMH_H */
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_QCOM_RPMH_H__
|
||||
|
|
@ -20,6 +20,8 @@ int rpmh_write_async(const struct device *dev, enum rpmh_state state,
|
|||
int rpmh_write_batch(const struct device *dev, enum rpmh_state state,
|
||||
const struct tcs_cmd *cmd, u32 *n);
|
||||
|
||||
int rpmh_mode_solver_set(const struct device *dev, bool enable);
|
||||
|
||||
void rpmh_invalidate(const struct device *dev);
|
||||
|
||||
#else
|
||||
|
|
@ -38,6 +40,9 @@ static inline int rpmh_write_batch(const struct device *dev,
|
|||
const struct tcs_cmd *cmd, u32 *n)
|
||||
{ return -ENODEV; }
|
||||
|
||||
static int rpmh_mode_solver_set(const struct device *dev, bool enable)
|
||||
{ return -ENODEV; }
|
||||
|
||||
static inline void rpmh_invalidate(const struct device *dev)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user