Pull CPUFreq Arm updates for 7.3 from Viresh Kumar: "- Minor fixes / cleanups in cpufreq drivers (Dan Carpenter, Guru Das Srinagesh, Haoxiang Li, Karl Mehltretter, Sasha Finkelstein, and Pan Chuang). - Fix cpufreq table creation and bios_limits() callback in the Rust bindings (Priya Bala Govindasamy). - Add IPQ5210 support to qcom-nvmem driver (Varadarajan Narayanan)." * tag 'cpufreq-arm-updates-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm: cpufreq: imx6q: fix out-of-bounds write when probed more than once cpufreq: imx6q: fix devres accumulation across driver rebind rust: cpufreq: Fix temporary write in Registration::bios_limit_callback rust: cpufreq: Add CPUFREQ_TABLE_END as last table entry in TableBuilder::to_table cpufreq: apple-soc: Calculate frequency as a 64-bit value cpufreq: spear: Fix an IS_ERR() vs NULL bug in spear1340_set_cpu_rate() cpufreq: brcmstb-avs: Remove redundant dev_err() rust: rcpufreq_dt: use vertical import style cpufreq: apple-soc: Fix OPP table cleanup cpufreq: qcom-nvmem: Add IPQ5210 support
Unified · Split
| @@ -249,21 +249,19 @@ static int apple_soc_cpufreq_init(struct cpufreq_policy *policy) · 248 unmodified lines | ||
| 249 | 249 | return -ENODEV; |
| 250 | 250 | } |
| 251 | 251 | |
| 252 | − ret = dev_pm_opp_of_add_table(cpu_dev); | |
| 253 | − if (ret < 0) { | |
| 254 | − dev_err(cpu_dev, "%s: failed to add OPP table: %d\n", __func__, ret); | |
| 255 | − return ret; | |
| 256 | − } | |
| 252 | + priv = kzalloc_obj(*priv); | |
| 253 | + if (!priv) | |
| 254 | + return -ENOMEM; | |
| 257 | 255 | |
| 258 | 256 | ret = apple_soc_cpufreq_find_cluster(policy, ®_base, &info); |
| 259 | 257 | if (ret) { |
| 260 | 258 | dev_err(cpu_dev, "%s: failed to get cluster info: %d\n", __func__, ret); |
| 261 | − return ret; | |
| 259 | + goto out_free_priv; | |
| 262 | 260 | } |
| 263 | 261 | |
| 264 | − ret = dev_pm_opp_set_sharing_cpus(cpu_dev, policy->cpus); | |
| 265 | − if (ret) { | |
| 266 | − dev_err(cpu_dev, "%s: failed to mark OPPs as shared: %d\n", __func__, ret); | |
| 262 | + ret = dev_pm_opp_of_cpumask_add_table(policy->cpus); | |
| 263 | + if (ret < 0) { | |
| 264 | + dev_err(cpu_dev, "%s: failed to add OPP table: %d\n", __func__, ret); | |
| 267 | 265 | goto out_iounmap; |
| 268 | 266 | } |
| 269 | 267 | |
| @@ -271,24 +269,18 @@ static int apple_soc_cpufreq_init(struct cpufreq_policy *policy) · 1 unmodified line | ||
| 271 | 269 | if (ret <= 0) { |
| 272 | 270 | dev_dbg(cpu_dev, "OPP table is not ready, deferring probe\n"); |
| 273 | 271 | ret = -EPROBE_DEFER; |
| 274 | − goto out_free_opp; | |
| 275 | − } | |
| 276 | − | |
| 277 | − priv = kzalloc_obj(*priv); | |
| 278 | − if (!priv) { | |
| 279 | − ret = -ENOMEM; | |
| 280 | − goto out_free_opp; | |
| 272 | + goto out_free_table; | |
| 281 | 273 | } |
| 282 | 274 | |
| 283 | 275 | ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); |
| 284 | 276 | if (ret) { |
| 285 | 277 | dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret); |
| 286 | − goto out_free_priv; | |
| 278 | + goto out_free_table; | |
| 287 | 279 | } |
| 288 | 280 | |
| 289 | 281 | /* Get OPP levels (p-state indexes) and stash them in driver_data */ |
| 290 | 282 | for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { |
| 291 | − unsigned long rate = freq_table[i].frequency * 1000 + 999; | |
| 283 | + unsigned long rate = freq_table[i].frequency * 1000UL + 999; | |
| 292 | 284 | struct dev_pm_opp *opp = dev_pm_opp_find_freq_floor(cpu_dev, &rate); |
| 293 | 285 | |
| 294 | 286 | if (IS_ERR(opp)) { |
| @@ -318,12 +310,12 @@ static int apple_soc_cpufreq_init(struct cpufreq_policy *policy) · 23 unmodified lines | ||
| 318 | 310 | |
| 319 | 311 | out_free_cpufreq_table: |
| 320 | 312 | dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); |
| 321 | −out_free_priv: | |
| 322 | − kfree(priv); | |
| 323 | −out_free_opp: | |
| 324 | − dev_pm_opp_remove_all_dynamic(cpu_dev); | |
| 313 | +out_free_table: | |
| 314 | + dev_pm_opp_of_cpumask_remove_table(policy->cpus); | |
| 325 | 315 | out_iounmap: |
| 326 | 316 | iounmap(reg_base); |
| 317 | +out_free_priv: | |
| 318 | + kfree(priv); | |
| 327 | 319 | return ret; |
| 328 | 320 | } |
| 329 | 321 | |
| @@ -332,7 +324,7 @@ static void apple_soc_cpufreq_exit(struct cpufreq_policy *policy) · 2 unmodified lines | ||
| 332 | 324 | struct apple_cpu_priv *priv = policy->driver_data; |
| 333 | 325 | |
| 334 | 326 | dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table); |
| 335 | − dev_pm_opp_remove_all_dynamic(priv->cpu_dev); | |
| 327 | + dev_pm_opp_of_cpumask_remove_table(policy->cpus); | |
| 336 | 328 | iounmap(priv->reg_base); |
| 337 | 329 | kfree(priv); |
| 338 | 330 | } |
| @@ -584,11 +584,8 @@ static int brcm_avs_prepare_init(struct platform_device *pdev) · 583 unmodified lines | ||
| 584 | 584 | ret = devm_request_irq(dev, priv->host_irq, irq_handler, |
| 585 | 585 | IRQF_TRIGGER_RISING, |
| 586 | 586 | BRCM_AVS_HOST_INTR, priv); |
| 587 | − if (ret && priv->host_irq >= 0) { | |
| 588 | − dev_err(dev, "IRQ request failed: %s (%d) -- %d\n", | |
| 589 | − BRCM_AVS_HOST_INTR, priv->host_irq, ret); | |
| 587 | + if (ret && priv->host_irq >= 0) | |
| 590 | 588 | goto unmap_intr_base; |
| 591 | − } | |
| 592 | 589 | |
| 593 | 590 | if (brcm_avs_is_firmware_loaded(priv)) |
| 594 | 591 | return 0; |
| @@ -200,6 +200,7 @@ static const struct of_device_id blocklist[] __initconst = { · 199 unmodified lines | ||
| 200 | 200 | { .compatible = "ti,am62l3", }, |
| 201 | 201 | { .compatible = "ti,am62p5", }, |
| 202 | 202 | |
| 203 | + { .compatible = "qcom,ipq5210", }, | |
| 203 | 204 | { .compatible = "qcom,ipq5332", }, |
| 204 | 205 | { .compatible = "qcom,ipq5424", }, |
| 205 | 206 | { .compatible = "qcom,ipq6018", }, |
| @@ -55,7 +55,6 @@ static unsigned int max_freq; · 54 unmodified lines | ||
| 55 | 55 | static unsigned int transition_latency; |
| 56 | 56 | |
| 57 | 57 | static u32 *imx6_soc_volt; |
| 58 | −static u32 soc_opp_count; | |
| 59 | 58 | |
| 60 | 59 | static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index) |
| 61 | 60 | { |
| @@ -330,6 +329,7 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev) · 268 unmodified lines | ||
| 330 | 329 | const struct property *prop; |
| 331 | 330 | const __be32 *val; |
| 332 | 331 | u32 nr, i, j; |
| 332 | + u32 soc_opp_count = 0; | |
| 333 | 333 | |
| 334 | 334 | cpu_dev = get_cpu_device(0); |
| 335 | 335 | if (!cpu_dev) { |
| @@ -400,7 +400,7 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev) · 64 unmodified lines | ||
| 400 | 400 | } |
| 401 | 401 | |
| 402 | 402 | /* Make imx6_soc_volt array's size same as arm opp number */ |
| 403 | − imx6_soc_volt = devm_kcalloc(cpu_dev, num, sizeof(*imx6_soc_volt), | |
| 403 | + imx6_soc_volt = devm_kcalloc(&pdev->dev, num, sizeof(*imx6_soc_volt), | |
| 404 | 404 | GFP_KERNEL); |
| 405 | 405 | if (imx6_soc_volt == NULL) { |
| 406 | 406 | ret = -ENOMEM; |
| @@ -485,6 +485,7 @@ soc_opp_out: · 78 unmodified lines | ||
| 485 | 485 | return 0; |
| 486 | 486 | |
| 487 | 487 | free_freq_table: |
| 488 | + imx6_soc_volt = NULL; | |
| 488 | 489 | dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); |
| 489 | 490 | out_free_opp: |
| 490 | 491 | dev_pm_opp_of_remove_table(cpu_dev); |
| @@ -506,6 +507,7 @@ put_node: · 15 unmodified lines | ||
| 506 | 507 | static void imx6q_cpufreq_remove(struct platform_device *pdev) |
| 507 | 508 | { |
| 508 | 509 | cpufreq_unregister_driver(&imx6q_cpufreq_driver); |
| 510 | + imx6_soc_volt = NULL; | |
| 509 | 511 | dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); |
| 510 | 512 | dev_pm_opp_of_remove_table(cpu_dev); |
| 511 | 513 | regulator_put(arm_reg); |
| @@ -200,6 +200,13 @@ static int qcom_cpufreq_kryo_name_version(struct device *cpu_dev, · 199 unmodified lines | ||
| 200 | 200 | case QCOM_ID_IPQ9574: |
| 201 | 201 | drv->versions = 1 << (unsigned int)(*speedbin); |
| 202 | 202 | break; |
| 203 | + case QCOM_ID_IPQ5200: | |
| 204 | + case QCOM_ID_IPQ5210: | |
| 205 | + case QCOM_ID_QCF2200: | |
| 206 | + case QCOM_ID_QCF3200: | |
| 207 | + case QCOM_ID_QCF3210: | |
| 208 | + drv->versions = (*speedbin == 0xcd) ? BIT(1) : BIT(0); | |
| 209 | + break; | |
| 203 | 210 | case QCOM_ID_IPQ5424: |
| 204 | 211 | case QCOM_ID_IPQ5404: |
| 205 | 212 | drv->versions = (*speedbin == 0x3b) ? BIT(1) : BIT(0); |
| @@ -618,6 +625,7 @@ static const struct of_device_id qcom_cpufreq_match_list[] __initconst __maybe_u · 412 unmodified lines | ||
| 618 | 625 | { .compatible = "qcom,msm8909", .data = &match_data_msm8909 }, |
| 619 | 626 | { .compatible = "qcom,msm8996", .data = &match_data_kryo }, |
| 620 | 627 | { .compatible = "qcom,qcs404", .data = &match_data_qcs404 }, |
| 628 | + { .compatible = "qcom,ipq5210", .data = &match_data_kryo }, | |
| 621 | 629 | { .compatible = "qcom,ipq5332", .data = &match_data_kryo }, |
| 622 | 630 | { .compatible = "qcom,ipq5424", .data = &match_data_kryo }, |
| 623 | 631 | { .compatible = "qcom,ipq6018", .data = &match_data_ipq6018 }, |
| @@ -4,12 +4,19 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | use kernel::{ |
| 6 | 6 | clk::Clk, |
| 7 | − cpu, cpufreq, | |
| 7 | + cpu, | |
| 8 | + cpufreq, // | |
| 8 | 9 | cpumask::CpumaskVar, |
| 9 | − device::{Core, Device}, | |
| 10 | + device::{ | |
| 11 | + Core, | |
| 12 | + Device, // | |
| 13 | + }, | |
| 10 | 14 | error::code::*, |
| 11 | 15 | macros::vtable, |
| 12 | − module_platform_driver, of, opp, platform, | |
| 16 | + module_platform_driver, | |
| 17 | + of, | |
| 18 | + opp, | |
| 19 | + platform, // | |
| 13 | 20 | prelude::*, |
| 14 | 21 | str::CString, |
| 15 | 22 | sync::Arc, |
| @@ -79,9 +79,9 @@ static int spear1340_set_cpu_rate(struct clk *sys_pclk, unsigned long newfreq) · 78 unmodified lines | ||
| 79 | 79 | int ret = 0; |
| 80 | 80 | |
| 81 | 81 | sys_clk = clk_get_parent(spear_cpufreq.clk); |
| 82 | − if (IS_ERR(sys_clk)) { | |
| 82 | + if (!sys_clk) { | |
| 83 | 83 | pr_err("failed to get cpu's parent (sys) clock\n"); |
| 84 | − return PTR_ERR(sys_clk); | |
| 84 | + return -EINVAL; | |
| 85 | 85 | } |
| 86 | 86 | |
| 87 | 87 | /* Set the rate of the source clock before changing the parent */ |
| @@ -361,23 +361,28 @@ impl TableBuilder { · 360 unmodified lines | ||
| 361 | 361 | } |
| 362 | 362 | } |
| 363 | 363 | |
| 364 | − /// Adds a new entry to the table. | |
| 365 | − pub fn add(&mut self, freq: Hertz, flags: u32, driver_data: u32) -> Result { | |
| 364 | + /// Adds a raw frequency-table entry. | |
| 365 | + fn push(&mut self, frequency: u32, flags: u32, driver_data: u32) -> Result { | |
| 366 | 366 | // Adds the new entry at the end of the vector. |
| 367 | 367 | Ok(self.entries.push( |
| 368 | 368 | bindings::cpufreq_frequency_table { |
| 369 | 369 | flags, |
| 370 | 370 | driver_data, |
| 371 | − frequency: freq.as_khz() as u32, | |
| 371 | + frequency, | |
| 372 | 372 | }, |
| 373 | 373 | GFP_KERNEL, |
| 374 | 374 | )?) |
| 375 | 375 | } |
| 376 | 376 | |
| 377 | + /// Adds a new entry to the table. | |
| 378 | + pub fn add(&mut self, freq: Hertz, flags: u32, driver_data: u32) -> Result { | |
| 379 | + self.push(freq.as_khz() as u32, flags, driver_data) | |
| 380 | + } | |
| 381 | + | |
| 377 | 382 | /// Consumes the [`TableBuilder`] and returns [`TableBox`]. |
| 378 | 383 | pub fn to_table(mut self) -> Result<TableBox> { |
| 379 | 384 | // Add last entry to the table. |
| 380 | − self.add(Hertz(c_ulong::MAX), 0, 0)?; | |
| 385 | + self.push(bindings::CPUFREQ_TABLE_END as u32, 0, 0)?; | |
| 381 | 386 | |
| 382 | 387 | TableBox::new(self.entries) |
| 383 | 388 | } |
| @@ -823,7 +828,9 @@ pub trait Driver { · 439 unmodified lines | ||
| 823 | 828 | } |
| 824 | 829 | |
| 825 | 830 | /// Driver's `bios_limit` callback. |
| 826 | − fn bios_limit(_policy: &mut Policy, _limit: &mut u32) -> Result { | |
| 831 | + /// | |
| 832 | + /// Returns HW/BIOS max frequency limitations for the CPU. | |
| 833 | + fn bios_limit(_policy: &mut Policy) -> Result<u32> { | |
| 827 | 834 | build_error!(VTABLE_DEFAULT_ERROR) |
| 828 | 835 | } |
| 829 | 836 | |
| @@ -1359,9 +1366,12 @@ impl<T: Driver> Registration<T> { · 529 unmodified lines | ||
| 1359 | 1366 | |
| 1360 | 1367 | from_result(|| { |
| 1361 | 1368 | let mut policy = PolicyCpu::from_cpu(cpu_id)?; |
| 1362 | − | |
| 1369 | + let val = T::bios_limit(&mut policy)?; | |
| 1363 | 1370 | // SAFETY: `limit` is guaranteed by the C code to be valid. |
| 1364 | − T::bios_limit(&mut policy, &mut (unsafe { *limit })).map(|()| 0) | |
| 1371 | + unsafe { | |
| 1372 | + *limit = val; | |
| 1373 | + } | |
| 1374 | + Ok(0) | |
| 1365 | 1375 | }) |
| 1366 | 1376 | } |
| 1367 | 1377 | |