mirror of
https://github.com/torvalds/linux.git
synced 2026-06-03 12:03:54 +02:00
Merge branches 'pm-cpuidle' and 'pm-powercap'
Merge cpuidle and power capping changes for 6.18-rc1: - Fail cpuidle device registration if there is one already to avoid sysfs-related issues (Rafael Wysocki) - Use sysfs_emit()/sysfs_emit_at() instead of sprintf()/scnprintf() in cpuidle (Vivek Yadav) - Fix device and OF node leaks at probe in the qcom-spm cpuidle driver and drop unnecessary initialisations from it (Johan Hovold) - Remove unnecessary address-of operators from the intel_idle cpuidle driver (Kaushlendra Kumar) - Rearrange main loop in menu_select() to make the code in that funtion easier to follow (Rafael Wysocki) - Convert values in microseconds to ktime using us_to_ktime() where applicable in the intel_idle power capping driver (Xichao Zhao) * pm-cpuidle: cpuidle: Fail cpuidle device registration if there is one already cpuidle: sysfs: Use sysfs_emit()/sysfs_emit_at() instead of sprintf()/scnprintf() cpuidle: qcom-spm: drop unnecessary initialisations cpuidle: qcom-spm: fix device and OF node leaks at probe intel_idle: Remove unnecessary address-of operators cpuidle: governors: menu: Rearrange main loop in menu_select() * pm-powercap: powercap: idle_inject: use us_to_ktime() where appropriate
This commit is contained in:
commit
101642e43d
|
|
@ -86,9 +86,9 @@ static const struct of_device_id qcom_idle_state_match[] = {
|
|||
|
||||
static int spm_cpuidle_register(struct device *cpuidle_dev, int cpu)
|
||||
{
|
||||
struct platform_device *pdev = NULL;
|
||||
struct platform_device *pdev;
|
||||
struct device_node *cpu_node, *saw_node;
|
||||
struct cpuidle_qcom_spm_data *data = NULL;
|
||||
struct cpuidle_qcom_spm_data *data;
|
||||
int ret;
|
||||
|
||||
cpu_node = of_cpu_device_node_get(cpu);
|
||||
|
|
@ -96,20 +96,23 @@ static int spm_cpuidle_register(struct device *cpuidle_dev, int cpu)
|
|||
return -ENODEV;
|
||||
|
||||
saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0);
|
||||
of_node_put(cpu_node);
|
||||
if (!saw_node)
|
||||
return -ENODEV;
|
||||
|
||||
pdev = of_find_device_by_node(saw_node);
|
||||
of_node_put(saw_node);
|
||||
of_node_put(cpu_node);
|
||||
if (!pdev)
|
||||
return -ENODEV;
|
||||
|
||||
data = devm_kzalloc(cpuidle_dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
if (!data) {
|
||||
put_device(&pdev->dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
data->spm = dev_get_drvdata(&pdev->dev);
|
||||
put_device(&pdev->dev);
|
||||
if (!data->spm)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
|
|||
|
|
@ -635,8 +635,14 @@ static void __cpuidle_device_init(struct cpuidle_device *dev)
|
|||
static int __cpuidle_register_device(struct cpuidle_device *dev)
|
||||
{
|
||||
struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
|
||||
unsigned int cpu = dev->cpu;
|
||||
int i, ret;
|
||||
|
||||
if (per_cpu(cpuidle_devices, cpu)) {
|
||||
pr_info("CPU%d: cpuidle device already registered\n", cpu);
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
if (!try_module_get(drv->owner))
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -648,7 +654,7 @@ static int __cpuidle_register_device(struct cpuidle_device *dev)
|
|||
dev->states_usage[i].disable |= CPUIDLE_STATE_DISABLED_BY_USER;
|
||||
}
|
||||
|
||||
per_cpu(cpuidle_devices, dev->cpu) = dev;
|
||||
per_cpu(cpuidle_devices, cpu) = dev;
|
||||
list_add(&dev->device_list, &cpuidle_detected_devices);
|
||||
|
||||
ret = cpuidle_coupled_register_device(dev);
|
||||
|
|
|
|||
|
|
@ -314,45 +314,47 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
|
|||
if (s->exit_latency_ns > latency_req)
|
||||
break;
|
||||
|
||||
if (s->target_residency_ns > predicted_ns) {
|
||||
/*
|
||||
* Use a physical idle state, not busy polling, unless
|
||||
* a timer is going to trigger soon enough.
|
||||
*/
|
||||
if ((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) &&
|
||||
s->target_residency_ns <= data->next_timer_ns) {
|
||||
predicted_ns = s->target_residency_ns;
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
if (predicted_ns < TICK_NSEC)
|
||||
break;
|
||||
|
||||
if (!tick_nohz_tick_stopped()) {
|
||||
/*
|
||||
* If the state selected so far is shallow,
|
||||
* waking up early won't hurt, so retain the
|
||||
* tick in that case and let the governor run
|
||||
* again in the next iteration of the loop.
|
||||
*/
|
||||
predicted_ns = drv->states[idx].target_residency_ns;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the state selected so far is shallow and this
|
||||
* state's target residency matches the time till the
|
||||
* closest timer event, select this one to avoid getting
|
||||
* stuck in the shallow one for too long.
|
||||
*/
|
||||
if (drv->states[idx].target_residency_ns < TICK_NSEC &&
|
||||
s->target_residency_ns <= delta_tick)
|
||||
idx = i;
|
||||
|
||||
return idx;
|
||||
if (s->target_residency_ns <= predicted_ns) {
|
||||
idx = i;
|
||||
continue;
|
||||
}
|
||||
|
||||
idx = i;
|
||||
/*
|
||||
* Use a physical idle state, not busy polling, unless a timer
|
||||
* is going to trigger soon enough.
|
||||
*/
|
||||
if ((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) &&
|
||||
s->target_residency_ns <= data->next_timer_ns) {
|
||||
predicted_ns = s->target_residency_ns;
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (predicted_ns < TICK_NSEC)
|
||||
break;
|
||||
|
||||
if (!tick_nohz_tick_stopped()) {
|
||||
/*
|
||||
* If the state selected so far is shallow, waking up
|
||||
* early won't hurt, so retain the tick in that case and
|
||||
* let the governor run again in the next iteration of
|
||||
* the idle loop.
|
||||
*/
|
||||
predicted_ns = drv->states[idx].target_residency_ns;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the state selected so far is shallow and this state's
|
||||
* target residency matches the time till the closest timer
|
||||
* event, select this one to avoid getting stuck in the shallow
|
||||
* one for too long.
|
||||
*/
|
||||
if (drv->states[idx].target_residency_ns < TICK_NSEC &&
|
||||
s->target_residency_ns <= delta_tick)
|
||||
idx = i;
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
if (idx == -1)
|
||||
|
|
|
|||
|
|
@ -27,14 +27,14 @@ static ssize_t show_available_governors(struct device *dev,
|
|||
|
||||
mutex_lock(&cpuidle_lock);
|
||||
list_for_each_entry(tmp, &cpuidle_governors, governor_list) {
|
||||
if (i >= (ssize_t) (PAGE_SIZE - (CPUIDLE_NAME_LEN + 2)))
|
||||
if (i >= (ssize_t)(PAGE_SIZE - (CPUIDLE_NAME_LEN + 2)))
|
||||
goto out;
|
||||
|
||||
i += scnprintf(&buf[i], CPUIDLE_NAME_LEN + 1, "%s ", tmp->name);
|
||||
i += sysfs_emit_at(buf, i, "%.*s ", CPUIDLE_NAME_LEN, tmp->name);
|
||||
}
|
||||
|
||||
out:
|
||||
i+= sprintf(&buf[i], "\n");
|
||||
i += sysfs_emit_at(buf, i, "\n");
|
||||
mutex_unlock(&cpuidle_lock);
|
||||
return i;
|
||||
}
|
||||
|
|
@ -49,9 +49,9 @@ static ssize_t show_current_driver(struct device *dev,
|
|||
spin_lock(&cpuidle_driver_lock);
|
||||
drv = cpuidle_get_driver();
|
||||
if (drv)
|
||||
ret = sprintf(buf, "%s\n", drv->name);
|
||||
ret = sysfs_emit(buf, "%s\n", drv->name);
|
||||
else
|
||||
ret = sprintf(buf, "none\n");
|
||||
ret = sysfs_emit(buf, "none\n");
|
||||
spin_unlock(&cpuidle_driver_lock);
|
||||
|
||||
return ret;
|
||||
|
|
@ -65,9 +65,9 @@ static ssize_t show_current_governor(struct device *dev,
|
|||
|
||||
mutex_lock(&cpuidle_lock);
|
||||
if (cpuidle_curr_governor)
|
||||
ret = sprintf(buf, "%s\n", cpuidle_curr_governor->name);
|
||||
ret = sysfs_emit(buf, "%s\n", cpuidle_curr_governor->name);
|
||||
else
|
||||
ret = sprintf(buf, "none\n");
|
||||
ret = sysfs_emit(buf, "none\n");
|
||||
mutex_unlock(&cpuidle_lock);
|
||||
|
||||
return ret;
|
||||
|
|
@ -230,7 +230,7 @@ static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0644, show, store)
|
|||
static ssize_t show_state_##_name(struct cpuidle_state *state, \
|
||||
struct cpuidle_state_usage *state_usage, char *buf) \
|
||||
{ \
|
||||
return sprintf(buf, "%u\n", state->_name);\
|
||||
return sysfs_emit(buf, "%u\n", state->_name);\
|
||||
}
|
||||
|
||||
#define define_show_state_ull_function(_name) \
|
||||
|
|
@ -238,7 +238,7 @@ static ssize_t show_state_##_name(struct cpuidle_state *state, \
|
|||
struct cpuidle_state_usage *state_usage, \
|
||||
char *buf) \
|
||||
{ \
|
||||
return sprintf(buf, "%llu\n", state_usage->_name);\
|
||||
return sysfs_emit(buf, "%llu\n", state_usage->_name);\
|
||||
}
|
||||
|
||||
#define define_show_state_str_function(_name) \
|
||||
|
|
@ -247,8 +247,8 @@ static ssize_t show_state_##_name(struct cpuidle_state *state, \
|
|||
char *buf) \
|
||||
{ \
|
||||
if (state->_name[0] == '\0')\
|
||||
return sprintf(buf, "<null>\n");\
|
||||
return sprintf(buf, "%s\n", state->_name);\
|
||||
return sysfs_emit(buf, "<null>\n");\
|
||||
return sysfs_emit(buf, "%s\n", state->_name);\
|
||||
}
|
||||
|
||||
#define define_show_state_time_function(_name) \
|
||||
|
|
@ -256,7 +256,7 @@ static ssize_t show_state_##_name(struct cpuidle_state *state, \
|
|||
struct cpuidle_state_usage *state_usage, \
|
||||
char *buf) \
|
||||
{ \
|
||||
return sprintf(buf, "%llu\n", ktime_to_us(state->_name##_ns)); \
|
||||
return sysfs_emit(buf, "%llu\n", ktime_to_us(state->_name##_ns)); \
|
||||
}
|
||||
|
||||
define_show_state_time_function(exit_latency)
|
||||
|
|
@ -273,14 +273,14 @@ static ssize_t show_state_time(struct cpuidle_state *state,
|
|||
struct cpuidle_state_usage *state_usage,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%llu\n", ktime_to_us(state_usage->time_ns));
|
||||
return sysfs_emit(buf, "%llu\n", ktime_to_us(state_usage->time_ns));
|
||||
}
|
||||
|
||||
static ssize_t show_state_disable(struct cpuidle_state *state,
|
||||
struct cpuidle_state_usage *state_usage,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%llu\n",
|
||||
return sysfs_emit(buf, "%llu\n",
|
||||
state_usage->disable & CPUIDLE_STATE_DISABLED_BY_USER);
|
||||
}
|
||||
|
||||
|
|
@ -310,7 +310,7 @@ static ssize_t show_state_default_status(struct cpuidle_state *state,
|
|||
struct cpuidle_state_usage *state_usage,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%s\n",
|
||||
return sysfs_emit(buf, "%s\n",
|
||||
state->flags & CPUIDLE_FLAG_OFF ? "disabled" : "enabled");
|
||||
}
|
||||
|
||||
|
|
@ -358,7 +358,7 @@ static ssize_t show_state_s2idle_##_name(struct cpuidle_state *state, \
|
|||
struct cpuidle_state_usage *state_usage, \
|
||||
char *buf) \
|
||||
{ \
|
||||
return sprintf(buf, "%llu\n", state_usage->s2idle_##_name);\
|
||||
return sysfs_emit(buf, "%llu\n", state_usage->s2idle_##_name);\
|
||||
}
|
||||
|
||||
define_show_state_s2idle_ull_function(usage);
|
||||
|
|
@ -550,7 +550,7 @@ static ssize_t show_driver_name(struct cpuidle_driver *drv, char *buf)
|
|||
ssize_t ret;
|
||||
|
||||
spin_lock(&cpuidle_driver_lock);
|
||||
ret = sprintf(buf, "%s\n", drv ? drv->name : "none");
|
||||
ret = sysfs_emit(buf, "%s\n", drv ? drv->name : "none");
|
||||
spin_unlock(&cpuidle_driver_lock);
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -133,7 +133,7 @@ static enum hrtimer_restart idle_inject_timer_fn(struct hrtimer *timer)
|
|||
duration_us = READ_ONCE(ii_dev->run_duration_us);
|
||||
duration_us += READ_ONCE(ii_dev->idle_duration_us);
|
||||
|
||||
hrtimer_forward_now(timer, ns_to_ktime(duration_us * NSEC_PER_USEC));
|
||||
hrtimer_forward_now(timer, us_to_ktime(duration_us));
|
||||
|
||||
return HRTIMER_RESTART;
|
||||
}
|
||||
|
|
@ -232,8 +232,7 @@ int idle_inject_start(struct idle_inject_device *ii_dev)
|
|||
idle_inject_wakeup(ii_dev);
|
||||
|
||||
hrtimer_start(&ii_dev->timer,
|
||||
ns_to_ktime((idle_duration_us + run_duration_us) *
|
||||
NSEC_PER_USEC),
|
||||
us_to_ktime(idle_duration_us + run_duration_us),
|
||||
HRTIMER_MODE_REL);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user