mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-29 14:05:19 +08:00
a70eb93a24
The DT of_device.h and of_platform.h date back to the separate of_platform_bus_type before it as merged into the regular platform bus. As part of that merge prepping Arm DT support 13 years ago, they "temporarily" include each other. They also include platform_device.h and of.h. As a result, there's a pretty much random mix of those include files used throughout the tree. In order to detangle these headers and replace the implicit includes with struct declarations, users need to explicitly include the correct includes. Signed-off-by: Rob Herring <robh@kernel.org> Acked-by: Rafael J. Wysocki <rafael@kernel.org> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
151 lines
3.1 KiB
C
151 lines
3.1 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* pmi backend for the cbe_cpufreq driver
|
|
*
|
|
* (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007
|
|
*
|
|
* Author: Christian Krafft <krafft@de.ibm.com>
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/types.h>
|
|
#include <linux/timer.h>
|
|
#include <linux/init.h>
|
|
#include <linux/pm_qos.h>
|
|
#include <linux/slab.h>
|
|
|
|
#include <asm/processor.h>
|
|
#include <asm/pmi.h>
|
|
#include <asm/cell-regs.h>
|
|
|
|
#ifdef DEBUG
|
|
#include <asm/time.h>
|
|
#endif
|
|
|
|
#include "ppc_cbe_cpufreq.h"
|
|
|
|
bool cbe_cpufreq_has_pmi = false;
|
|
EXPORT_SYMBOL_GPL(cbe_cpufreq_has_pmi);
|
|
|
|
/*
|
|
* hardware specific functions
|
|
*/
|
|
|
|
int cbe_cpufreq_set_pmode_pmi(int cpu, unsigned int pmode)
|
|
{
|
|
int ret;
|
|
pmi_message_t pmi_msg;
|
|
#ifdef DEBUG
|
|
long time;
|
|
#endif
|
|
pmi_msg.type = PMI_TYPE_FREQ_CHANGE;
|
|
pmi_msg.data1 = cbe_cpu_to_node(cpu);
|
|
pmi_msg.data2 = pmode;
|
|
|
|
#ifdef DEBUG
|
|
time = jiffies;
|
|
#endif
|
|
pmi_send_message(pmi_msg);
|
|
|
|
#ifdef DEBUG
|
|
time = jiffies - time;
|
|
time = jiffies_to_msecs(time);
|
|
pr_debug("had to wait %lu ms for a transition using " \
|
|
"PMI\n", time);
|
|
#endif
|
|
ret = pmi_msg.data2;
|
|
pr_debug("PMI returned slow mode %d\n", ret);
|
|
|
|
return ret;
|
|
}
|
|
EXPORT_SYMBOL_GPL(cbe_cpufreq_set_pmode_pmi);
|
|
|
|
|
|
static void cbe_cpufreq_handle_pmi(pmi_message_t pmi_msg)
|
|
{
|
|
struct cpufreq_policy *policy;
|
|
struct freq_qos_request *req;
|
|
u8 node, slow_mode;
|
|
int cpu, ret;
|
|
|
|
BUG_ON(pmi_msg.type != PMI_TYPE_FREQ_CHANGE);
|
|
|
|
node = pmi_msg.data1;
|
|
slow_mode = pmi_msg.data2;
|
|
|
|
cpu = cbe_node_to_cpu(node);
|
|
|
|
pr_debug("cbe_handle_pmi: node: %d max_freq: %d\n", node, slow_mode);
|
|
|
|
policy = cpufreq_cpu_get(cpu);
|
|
if (!policy) {
|
|
pr_warn("cpufreq policy not found cpu%d\n", cpu);
|
|
return;
|
|
}
|
|
|
|
req = policy->driver_data;
|
|
|
|
ret = freq_qos_update_request(req,
|
|
policy->freq_table[slow_mode].frequency);
|
|
if (ret < 0)
|
|
pr_warn("Failed to update freq constraint: %d\n", ret);
|
|
else
|
|
pr_debug("limiting node %d to slow mode %d\n", node, slow_mode);
|
|
|
|
cpufreq_cpu_put(policy);
|
|
}
|
|
|
|
static struct pmi_handler cbe_pmi_handler = {
|
|
.type = PMI_TYPE_FREQ_CHANGE,
|
|
.handle_pmi_message = cbe_cpufreq_handle_pmi,
|
|
};
|
|
|
|
void cbe_cpufreq_pmi_policy_init(struct cpufreq_policy *policy)
|
|
{
|
|
struct freq_qos_request *req;
|
|
int ret;
|
|
|
|
if (!cbe_cpufreq_has_pmi)
|
|
return;
|
|
|
|
req = kzalloc(sizeof(*req), GFP_KERNEL);
|
|
if (!req)
|
|
return;
|
|
|
|
ret = freq_qos_add_request(&policy->constraints, req, FREQ_QOS_MAX,
|
|
policy->freq_table[0].frequency);
|
|
if (ret < 0) {
|
|
pr_err("Failed to add freq constraint (%d)\n", ret);
|
|
kfree(req);
|
|
return;
|
|
}
|
|
|
|
policy->driver_data = req;
|
|
}
|
|
EXPORT_SYMBOL_GPL(cbe_cpufreq_pmi_policy_init);
|
|
|
|
void cbe_cpufreq_pmi_policy_exit(struct cpufreq_policy *policy)
|
|
{
|
|
struct freq_qos_request *req = policy->driver_data;
|
|
|
|
if (cbe_cpufreq_has_pmi) {
|
|
freq_qos_remove_request(req);
|
|
kfree(req);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(cbe_cpufreq_pmi_policy_exit);
|
|
|
|
void cbe_cpufreq_pmi_init(void)
|
|
{
|
|
if (!pmi_register_handler(&cbe_pmi_handler))
|
|
cbe_cpufreq_has_pmi = true;
|
|
}
|
|
EXPORT_SYMBOL_GPL(cbe_cpufreq_pmi_init);
|
|
|
|
void cbe_cpufreq_pmi_exit(void)
|
|
{
|
|
pmi_unregister_handler(&cbe_pmi_handler);
|
|
cbe_cpufreq_has_pmi = false;
|
|
}
|
|
EXPORT_SYMBOL_GPL(cbe_cpufreq_pmi_exit);
|