mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
CPUFreq arm updates for 7.4
- Minor fixes to in various cpufreq drivers (Alexander Koskovich, Daniel Schwierzeck, Frank Zhang, Haotian Zhang, Kathiravan Thirumoorthy, Sumeet Pawnikar, and Xueqin Luo). - Fix wrong behaviors on multi-node servers in Loongson driver (Huacai Chen). - Reject NULL from cpufreq_cpu_get() in the Rust code (Mehmet Koseoglu). - Add suspend OPP to mediatek driver and DT (Ryan Brue). -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEx73Crsp7f6M6scA70rkcPK6BEhwFAmrRv6UACgkQ0rkcPK6B EhzA1RAAh7mh2kSOkyyoUJV2fqvSP5fEzH1oX+FXZI/3Rmq8ycEuPIK6Xpz00Nj7 XkX9MDi/hVgdqzM7CpuSR8KBdd73ZmMpUwxQI2efPlNLl7svLwUUkm/mWVIolP30 ML1mP6qiLV41jKk9WtsCg05hNLt+jBdhyMXi6mHk6y8t7yNNLovEJVWry/f9MNSZ Rcr7vDjF99N95W9hCo77ERTpn2ILYajTlenzbLgakrzUkdHs8BzIi0chDFPq+OW0 zvYaMxAiAPbzDBSzQ4XNwnZB7LBnqLOlnVZoJhD3yryWeesVgwMLeXmVpcqKuEBa aWUjSDKLKyyQEGtVD9GMQJ4SnG+5b8CT53R7NXNet2OMxW15UxrAkxUDtx0eyf8n FhHqOt3J5/qatOtw8lFm+AyOcrrWKd2p3Is1EJJ9f0q9F3H4KKth16wAlWTFYTTE LzZVyD6ZpARxnpC/g9y1Q4jhGIyHw7A61hrVxQmXueFubn0aKXaUO3bhPSbU9DEI rHDaujycOsLdaYCMTUZSfM9VtXpgWS7gaWNpRzKjVCd+0XSTe9sbmHFvtpliCohX qxgvVGQWajd9QP/JlDC7yJOUZEiZqVQE+NgHF8C2D7Acf9lj2NCkgb0hNKhbmPUo 6KuwDgXrquMc5gcdicetb8gmgfGUdPv8HhrNT1WIAWxXhD7/onc= =vDid -----END PGP SIGNATURE----- Merge tag 'cpufreq-arm-updates-7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm Pull CPUFreq Arm updates for 7.4 from Viresh Kumar: "- Minor fixes to in various cpufreq drivers (Alexander Koskovich, Daniel Schwierzeck, Frank Zhang, Haotian Zhang, Kathiravan Thirumoorthy, Sumeet Pawnikar, and Xueqin Luo). - Fix wrong behaviors on multi-node servers in Loongson driver (Huacai Chen). - Reject NULL from cpufreq_cpu_get() in the Rust code (Mehmet Koseoglu). - Add suspend OPP to mediatek driver and DT (Ryan Brue)." * tag 'cpufreq-arm-updates-7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm: cpufreq: loongson3: Replace IOCSR read/write with MMIO ones cpufreq: loongson3: Use global physical CPU ID in get/target callbacks cpufreq: loongson3: Replace per-package mutex with per-node cpufreq: loongson3: Adjust the width of id and val in smc_message cpufreq: loongson3: Make this driver depend on MACH_LOONGSON64 arm64: dts: mediatek: mt8173: Mark the lowest CPU OPPs for suspend cpufreq: mediatek: Enter system sleep at the suspend OPP cpufreq: qcom-cpufreq-hw: fix device node refcount leak in phandle parsing cpufreq: qcom-nvmem: Add IPQ9650 support cpufreq: Add Milos to cpufreq-dt-platdev blocklist cpufreq: Use %pe to print error pointers symbolically rust: rcpufreq_dt: add module alias cpufreq: sti: avoid NULL dereference in dev_err() cpufreq: tegra194: fix double-pointer error in get_cpu_ndiv cpufreq: sparc-us2e: fix frequency table index copy-paste error rust: cpufreq: reject NULL from cpufreq_cpu_get() cpufreq: airoha: fix probe failure with correct error check
This commit is contained in:
commit
c291ee973d
|
|
@ -56,6 +56,7 @@ cluster0_opp: opp-table-0 {
|
|||
opp-507000000 {
|
||||
opp-hz = /bits/ 64 <507000000>;
|
||||
opp-microvolt = <859000>;
|
||||
opp-suspend;
|
||||
};
|
||||
opp-702000000 {
|
||||
opp-hz = /bits/ 64 <702000000>;
|
||||
|
|
@ -93,6 +94,7 @@ cluster1_opp: opp-table-1 {
|
|||
opp-507000000 {
|
||||
opp-hz = /bits/ 64 <507000000>;
|
||||
opp-microvolt = <828000>;
|
||||
opp-suspend;
|
||||
};
|
||||
opp-702000000 {
|
||||
opp-hz = /bits/ 64 <702000000>;
|
||||
|
|
|
|||
|
|
@ -288,6 +288,7 @@ endif
|
|||
if LOONGARCH
|
||||
config LOONGSON3_CPUFREQ
|
||||
tristate "Loongson3 CPUFreq Driver"
|
||||
depends on MACH_LOONGSON64
|
||||
help
|
||||
This option adds a CPUFreq driver for Loongson processors which
|
||||
support software configurable cpu frequency.
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ static int airoha_cpufreq_probe(struct platform_device *pdev)
|
|||
/* Attach PM for OPP */
|
||||
ret = dev_pm_domain_attach_list(cpu_dev, &attach_data,
|
||||
&priv->pd_list);
|
||||
if (ret)
|
||||
if (ret < 0)
|
||||
goto clear_opp_config;
|
||||
|
||||
cpufreq_dt = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
|
||||
|
|
|
|||
|
|
@ -132,8 +132,8 @@ static int bmips_cpufreq_init(struct cpufreq_policy *policy)
|
|||
|
||||
freq_table = bmips_cpufreq_get_freq_table(policy);
|
||||
if (IS_ERR(freq_table)) {
|
||||
pr_err("%s: couldn't determine frequency table (%ld).\n",
|
||||
BMIPS_CPUFREQ_NAME, PTR_ERR(freq_table));
|
||||
pr_err("%s: couldn't determine frequency table (%pe).\n",
|
||||
BMIPS_CPUFREQ_NAME, freq_table);
|
||||
return PTR_ERR(freq_table);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -230,8 +230,8 @@ static void cppc_fie_kworker_init(void)
|
|||
|
||||
kworker_fie = kthread_run_worker(0, "cppc_fie");
|
||||
if (IS_ERR(kworker_fie)) {
|
||||
pr_warn("%s: failed to create kworker_fie: %ld\n", __func__,
|
||||
PTR_ERR(kworker_fie));
|
||||
pr_warn("%s: failed to create kworker_fie: %pe\n", __func__,
|
||||
kworker_fie);
|
||||
fie_disabled = FIE_DISABLED;
|
||||
kworker_fie = NULL;
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -155,6 +155,7 @@ static const struct of_device_id blocklist[] __initconst = {
|
|||
{ .compatible = "nvidia,tegra234", },
|
||||
|
||||
{ .compatible = "qcom,apq8096", },
|
||||
{ .compatible = "qcom,milos", },
|
||||
{ .compatible = "qcom,msm8909", },
|
||||
{ .compatible = "qcom,msm8996", },
|
||||
{ .compatible = "qcom,msm8998", },
|
||||
|
|
@ -209,6 +210,7 @@ static const struct of_device_id blocklist[] __initconst = {
|
|||
{ .compatible = "qcom,ipq8064", },
|
||||
{ .compatible = "qcom,ipq8074", },
|
||||
{ .compatible = "qcom,ipq9574", },
|
||||
{ .compatible = "qcom,ipq9650", },
|
||||
{ .compatible = "qcom,apq8064", },
|
||||
{ .compatible = "qcom,msm8974", },
|
||||
{ .compatible = "qcom,msm8960", },
|
||||
|
|
|
|||
|
|
@ -16,14 +16,16 @@
|
|||
#include <asm/idle.h>
|
||||
#include <asm/loongarch.h>
|
||||
#include <asm/loongson.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/numa.h>
|
||||
|
||||
/* Message */
|
||||
union smc_message {
|
||||
u32 value;
|
||||
struct {
|
||||
u32 id : 4;
|
||||
u32 id : 8;
|
||||
u32 info : 4;
|
||||
u32 val : 16;
|
||||
u32 val : 12;
|
||||
u32 cmd : 6;
|
||||
u32 extra : 1;
|
||||
u32 complete : 1;
|
||||
|
|
@ -164,27 +166,47 @@ union smc_message {
|
|||
|
||||
#define FREQ_MAX_LEVEL 16
|
||||
|
||||
#define MMIO_SMCMBX(node) \
|
||||
((void __iomem *)(nid_to_addrbase(node) | IO_BASE | LOONGSON_REG_BASE | LOONGARCH_IOCSR_SMCMBX))
|
||||
|
||||
#define MMIO_MISC_FUNC(node) \
|
||||
((void __iomem *)(nid_to_addrbase(node) | IO_BASE | LOONGSON_REG_BASE | LOONGARCH_IOCSR_MISC_FUNC))
|
||||
|
||||
struct loongson3_freq_data {
|
||||
unsigned int def_freq_level;
|
||||
struct cpufreq_frequency_table table[];
|
||||
};
|
||||
|
||||
static struct mutex cpufreq_mutex[MAX_PACKAGES];
|
||||
static struct mutex cpufreq_mutex[MAX_NUMNODES];
|
||||
static struct cpufreq_driver loongson3_cpufreq_driver;
|
||||
static DEFINE_PER_CPU(struct loongson3_freq_data *, freq_data);
|
||||
|
||||
static inline int do_service_request(u32 id, u32 info, u32 cmd, u32 val, u32 extra)
|
||||
{
|
||||
int retries;
|
||||
unsigned int cpu = raw_smp_processor_id();
|
||||
unsigned int package = cpu_data[cpu].package;
|
||||
unsigned int cpu = 0, nid;
|
||||
union smc_message msg, last;
|
||||
|
||||
mutex_lock(&cpufreq_mutex[package]);
|
||||
#ifdef CONFIG_SMP
|
||||
switch (cmd) {
|
||||
case CMD_GET_FREQ_INFO:
|
||||
case CMD_SET_FREQ_INFO:
|
||||
case CMD_GET_FREQ_LEVEL_NUM:
|
||||
case CMD_GET_FREQ_LEVEL_INFO:
|
||||
case CMD_GET_FREQ_BOOST_LEVEL:
|
||||
cpu = cpu_number_map(id);
|
||||
break;
|
||||
default:
|
||||
cpu = raw_smp_processor_id();
|
||||
}
|
||||
#endif
|
||||
nid = cpu_to_node(cpu);
|
||||
|
||||
last.value = iocsr_read32(LOONGARCH_IOCSR_SMCMBX);
|
||||
mutex_lock(&cpufreq_mutex[nid]);
|
||||
|
||||
last.value = readl(MMIO_SMCMBX(nid));
|
||||
if (!last.complete) {
|
||||
mutex_unlock(&cpufreq_mutex[package]);
|
||||
mutex_unlock(&cpufreq_mutex[nid]);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
|
|
@ -195,12 +217,11 @@ static inline int do_service_request(u32 id, u32 info, u32 cmd, u32 val, u32 ext
|
|||
msg.extra = extra;
|
||||
msg.complete = 0;
|
||||
|
||||
iocsr_write32(msg.value, LOONGARCH_IOCSR_SMCMBX);
|
||||
iocsr_write32(iocsr_read32(LOONGARCH_IOCSR_MISC_FUNC) | IOCSR_MISC_FUNC_SOFT_INT,
|
||||
LOONGARCH_IOCSR_MISC_FUNC);
|
||||
writel(msg.value, MMIO_SMCMBX(nid));
|
||||
writel(readl(MMIO_MISC_FUNC(nid)) | IOCSR_MISC_FUNC_SOFT_INT, MMIO_MISC_FUNC(nid));
|
||||
|
||||
for (retries = 0; retries < 10000; retries++) {
|
||||
msg.value = iocsr_read32(LOONGARCH_IOCSR_SMCMBX);
|
||||
msg.value = readl(MMIO_SMCMBX(nid));
|
||||
if (msg.complete)
|
||||
break;
|
||||
|
||||
|
|
@ -208,49 +229,51 @@ static inline int do_service_request(u32 id, u32 info, u32 cmd, u32 val, u32 ext
|
|||
}
|
||||
|
||||
if (!msg.complete || msg.cmd != CMD_OK) {
|
||||
mutex_unlock(&cpufreq_mutex[package]);
|
||||
mutex_unlock(&cpufreq_mutex[nid]);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
mutex_unlock(&cpufreq_mutex[package]);
|
||||
mutex_unlock(&cpufreq_mutex[nid]);
|
||||
|
||||
return msg.val;
|
||||
}
|
||||
|
||||
static unsigned int loongson3_cpufreq_get(unsigned int cpu)
|
||||
{
|
||||
int ret;
|
||||
int ret, core = cpu_logical_map(cpu);
|
||||
|
||||
ret = do_service_request(cpu, FREQ_INFO_TYPE_FREQ, CMD_GET_FREQ_INFO, 0, 0);
|
||||
ret = do_service_request(core, FREQ_INFO_TYPE_FREQ, CMD_GET_FREQ_INFO, 0, 0);
|
||||
|
||||
return ret * KILO;
|
||||
return (ret < 0) ? 0 : ret * KILO;
|
||||
}
|
||||
|
||||
static int loongson3_cpufreq_target(struct cpufreq_policy *policy, unsigned int index)
|
||||
{
|
||||
int ret;
|
||||
int ret, core = cpu_logical_map(policy->cpu);
|
||||
|
||||
ret = do_service_request(cpu_data[policy->cpu].core,
|
||||
FREQ_INFO_TYPE_LEVEL, CMD_SET_FREQ_INFO, index, 0);
|
||||
ret = do_service_request(core, FREQ_INFO_TYPE_LEVEL, CMD_SET_FREQ_INFO,
|
||||
index, 0);
|
||||
|
||||
return (ret >= 0) ? 0 : ret;
|
||||
}
|
||||
|
||||
static int configure_freq_table(int cpu)
|
||||
{
|
||||
int i, ret, boost_level, max_level, freq_level;
|
||||
int i, ret, core, boost_level, max_level, freq_level;
|
||||
struct platform_device *pdev = cpufreq_get_driver_data();
|
||||
struct loongson3_freq_data *data;
|
||||
|
||||
if (per_cpu(freq_data, cpu))
|
||||
return 0;
|
||||
|
||||
ret = do_service_request(cpu, 0, CMD_GET_FREQ_LEVEL_NUM, 0, 0);
|
||||
core = cpu_logical_map(cpu);
|
||||
|
||||
ret = do_service_request(core, 0, CMD_GET_FREQ_LEVEL_NUM, 0, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
max_level = ret;
|
||||
|
||||
ret = do_service_request(cpu, 0, CMD_GET_FREQ_BOOST_LEVEL, 0, 0);
|
||||
ret = do_service_request(core, 0, CMD_GET_FREQ_BOOST_LEVEL, 0, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
boost_level = ret;
|
||||
|
|
@ -263,7 +286,7 @@ static int configure_freq_table(int cpu)
|
|||
data->def_freq_level = boost_level - 1;
|
||||
|
||||
for (i = 0; i < freq_level; i++) {
|
||||
ret = do_service_request(cpu, FREQ_INFO_TYPE_FREQ, CMD_GET_FREQ_LEVEL_INFO, i, 0);
|
||||
ret = do_service_request(core, FREQ_INFO_TYPE_FREQ, CMD_GET_FREQ_LEVEL_INFO, i, 0);
|
||||
if (ret < 0) {
|
||||
devm_kfree(&pdev->dev, data);
|
||||
return ret;
|
||||
|
|
@ -337,7 +360,7 @@ static int loongson3_cpufreq_probe(struct platform_device *pdev)
|
|||
{
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < MAX_PACKAGES; i++) {
|
||||
for (i = 0; i < MAX_NUMNODES; i++) {
|
||||
ret = devm_mutex_init(&pdev->dev, &cpufreq_mutex[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -603,6 +603,7 @@ static int mtk_cpufreq_init(struct cpufreq_policy *policy)
|
|||
policy->freq_table = freq_table;
|
||||
policy->driver_data = info;
|
||||
policy->clk = info->cpu_clk;
|
||||
policy->suspend_freq = dev_pm_opp_get_suspend_opp_freq(info->cpu_dev) / 1000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -624,6 +625,7 @@ static struct cpufreq_driver mtk_cpufreq_driver = {
|
|||
.init = mtk_cpufreq_init,
|
||||
.exit = mtk_cpufreq_exit,
|
||||
.register_em = cpufreq_register_em_with_opp,
|
||||
.suspend = cpufreq_generic_suspend,
|
||||
.name = "mtk-cpufreq",
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -322,6 +322,8 @@ static void qcom_get_related_cpus(int index, struct cpumask *m)
|
|||
|
||||
if (index == args.args[0])
|
||||
cpumask_set_cpu(cpu, m);
|
||||
|
||||
of_node_put(args.np);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -554,6 +556,7 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
|
|||
return ret;
|
||||
|
||||
index = args.args[0];
|
||||
of_node_put(args.np);
|
||||
data = &qcom_cpufreq.data[index];
|
||||
|
||||
/* HW should be in enabled state to proceed */
|
||||
|
|
|
|||
|
|
@ -211,6 +211,14 @@ static int qcom_cpufreq_kryo_name_version(struct device *cpu_dev,
|
|||
case QCOM_ID_IPQ5404:
|
||||
drv->versions = (*speedbin == 0x3b) ? BIT(1) : BIT(0);
|
||||
break;
|
||||
case QCOM_ID_IPQ9610:
|
||||
case QCOM_ID_IPQ9620:
|
||||
case QCOM_ID_IPQ9630:
|
||||
case QCOM_ID_IPQ9640:
|
||||
case QCOM_ID_IPQ9650:
|
||||
case QCOM_ID_IPQ9670:
|
||||
drv->versions = (*speedbin == 0x4b) ? BIT(3) : BIT(2);
|
||||
break;
|
||||
case QCOM_ID_MSM8996SG:
|
||||
case QCOM_ID_APQ8096SG:
|
||||
drv->versions = 1 << ((unsigned int)(*speedbin) + 4);
|
||||
|
|
@ -633,6 +641,7 @@ static const struct of_device_id qcom_cpufreq_match_list[] __initconst __maybe_u
|
|||
{ .compatible = "qcom,ipq8074", .data = &match_data_ipq8074 },
|
||||
{ .compatible = "qcom,apq8064", .data = &match_data_krait },
|
||||
{ .compatible = "qcom,ipq9574", .data = &match_data_kryo },
|
||||
{ .compatible = "qcom,ipq9650", .data = &match_data_kryo },
|
||||
{ .compatible = "qcom,msm8974", .data = &match_data_krait },
|
||||
{ .compatible = "qcom,msm8960", .data = &match_data_krait },
|
||||
{},
|
||||
|
|
|
|||
|
|
@ -57,8 +57,7 @@ static u32 get_bus_freq(void)
|
|||
/* get platform freq by its clock name */
|
||||
pltclk = clk_get(NULL, "cg-pll0-div1");
|
||||
if (IS_ERR(pltclk)) {
|
||||
pr_err("%s: can't get bus frequency %ld\n",
|
||||
__func__, PTR_ERR(pltclk));
|
||||
pr_err("%s: can't get bus frequency %pe\n", __func__, pltclk);
|
||||
return PTR_ERR(pltclk);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -225,4 +225,5 @@ fn probe<'bound>(
|
|||
authors: ["Viresh Kumar <viresh.kumar@linaro.org>"],
|
||||
description: "Generic CPUFreq DT driver",
|
||||
license: "GPL v2",
|
||||
alias: ["platform:cpufreq-dt"],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -152,15 +152,14 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
|
|||
|
||||
policy->clk = clk_get(NULL, "armclk");
|
||||
if (IS_ERR(policy->clk)) {
|
||||
pr_err("Unable to obtain ARMCLK: %ld\n",
|
||||
PTR_ERR(policy->clk));
|
||||
pr_err("Unable to obtain ARMCLK: %pe\n", policy->clk);
|
||||
return PTR_ERR(policy->clk);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_REGULATOR
|
||||
vddarm = regulator_get(NULL, "vddarm");
|
||||
if (IS_ERR(vddarm)) {
|
||||
pr_err("Failed to obtain VDDARM: %ld\n", PTR_ERR(vddarm));
|
||||
pr_err("Failed to obtain VDDARM: %pe\n", vddarm);
|
||||
pr_err("Only frequency scaling available\n");
|
||||
vddarm = NULL;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -282,12 +282,11 @@ static int us2e_freq_cpu_init(struct cpufreq_policy *policy)
|
|||
table[1].frequency = clock_tick / 2;
|
||||
table[2].driver_data = 2;
|
||||
table[2].frequency = clock_tick / 4;
|
||||
table[2].driver_data = 3;
|
||||
table[2].frequency = clock_tick / 6;
|
||||
table[2].driver_data = 4;
|
||||
table[2].frequency = clock_tick / 8;
|
||||
table[2].driver_data = 5;
|
||||
table[3].frequency = CPUFREQ_TABLE_END;
|
||||
table[3].driver_data = 3;
|
||||
table[3].frequency = clock_tick / 6;
|
||||
table[4].driver_data = 4;
|
||||
table[4].frequency = clock_tick / 8;
|
||||
table[5].frequency = CPUFREQ_TABLE_END;
|
||||
|
||||
policy->cpuinfo.transition_latency = 0;
|
||||
policy->cur = clock_tick;
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ static int __init sti_cpufreq_init(void)
|
|||
|
||||
ddata.cpu = get_cpu_device(0);
|
||||
if (!ddata.cpu) {
|
||||
dev_err(ddata.cpu, "Failed to get device for CPU0\n");
|
||||
pr_err("Failed to get device for CPU0\n");
|
||||
goto skip_voltage_scaling;
|
||||
}
|
||||
|
||||
|
|
@ -281,7 +281,7 @@ static int __init sti_cpufreq_init(void)
|
|||
goto register_cpufreq_dt;
|
||||
|
||||
skip_voltage_scaling:
|
||||
dev_err(ddata.cpu, "Not doing voltage scaling\n");
|
||||
pr_err("Not doing voltage scaling\n");
|
||||
|
||||
register_cpufreq_dt:
|
||||
platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
|
||||
|
|
|
|||
|
|
@ -367,7 +367,7 @@ static void tegra194_get_cpu_ndiv_sysreg(void *ndiv)
|
|||
|
||||
static int tegra194_get_cpu_ndiv(u32 cpu, u32 cpuid, u32 clusterid, u64 *ndiv)
|
||||
{
|
||||
return smp_call_function_single(cpu, tegra194_get_cpu_ndiv_sysreg, &ndiv, true);
|
||||
return smp_call_function_single(cpu, tegra194_get_cpu_ndiv_sysreg, ndiv, true);
|
||||
}
|
||||
|
||||
static void tegra194_set_cpu_ndiv_sysreg(void *data)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,13 @@
|
|||
cpumask,
|
||||
device::{Bound, Device},
|
||||
devres,
|
||||
error::{code::*, from_err_ptr, from_result, to_result, Result, VTABLE_DEFAULT_ERROR},
|
||||
error::{
|
||||
code::*,
|
||||
from_result,
|
||||
to_result,
|
||||
Result,
|
||||
VTABLE_DEFAULT_ERROR, //
|
||||
},
|
||||
ffi::{c_char, c_ulong},
|
||||
prelude::*,
|
||||
types::ForeignOwnable,
|
||||
|
|
@ -29,7 +35,10 @@
|
|||
marker::PhantomData,
|
||||
ops::{Deref, DerefMut},
|
||||
pin::Pin,
|
||||
ptr,
|
||||
ptr::{
|
||||
self,
|
||||
NonNull, //
|
||||
},
|
||||
};
|
||||
|
||||
use macros::vtable;
|
||||
|
|
@ -687,12 +696,13 @@ fn clear_data<T: ForeignOwnable>(&mut self) -> Option<T> {
|
|||
impl<'a> PolicyCpu<'a> {
|
||||
fn from_cpu(cpu: CpuId) -> Result<Self> {
|
||||
// SAFETY: It is safe to call `cpufreq_cpu_get` for any valid CPU.
|
||||
let ptr = from_err_ptr(unsafe { bindings::cpufreq_cpu_get(u32::from(cpu)) })?;
|
||||
let ptr =
|
||||
NonNull::new(unsafe { bindings::cpufreq_cpu_get(u32::from(cpu)) }).ok_or(ENODEV)?;
|
||||
|
||||
Ok(Self(
|
||||
// SAFETY: The `ptr` is guaranteed to be valid and remains valid for the lifetime of
|
||||
// the returned reference.
|
||||
unsafe { Policy::from_raw_mut(ptr) },
|
||||
// SAFETY: `ptr` is non-NULL and `cpufreq_cpu_get()` took a reference on it, so it is
|
||||
// valid for writing and remains valid for the lifetime of the returned reference.
|
||||
unsafe { Policy::from_raw_mut(ptr.as_ptr()) },
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user