LCOV - code coverage report
Current view: top level - drivers/cpufreq - raspberrypi-cpufreq.c (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_real_modules_combined.info Lines: 14 28 50.0 %
Date: 2020-09-30 20:25:40 Functions: 2 4 50.0 %
Branches: 6 12 50.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0
       2                 :            : /*
       3                 :            :  * Raspberry Pi cpufreq driver
       4                 :            :  *
       5                 :            :  * Copyright (C) 2019, Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
       6                 :            :  */
       7                 :            : 
       8                 :            : #include <linux/clk.h>
       9                 :            : #include <linux/cpu.h>
      10                 :            : #include <linux/cpufreq.h>
      11                 :            : #include <linux/module.h>
      12                 :            : #include <linux/platform_device.h>
      13                 :            : #include <linux/pm_opp.h>
      14                 :            : 
      15                 :            : #define RASPBERRYPI_FREQ_INTERVAL       100000000
      16                 :            : 
      17                 :            : static struct platform_device *cpufreq_dt;
      18                 :            : 
      19                 :        207 : static int raspberrypi_cpufreq_probe(struct platform_device *pdev)
      20                 :            : {
      21                 :            :         struct device *cpu_dev;
      22                 :            :         unsigned long min, max;
      23                 :            :         unsigned long rate;
      24                 :            :         struct clk *clk;
      25                 :            :         int ret;
      26                 :            : 
      27                 :        207 :         cpu_dev = get_cpu_device(0);
      28         [ -  + ]:        207 :         if (!cpu_dev) {
      29                 :          0 :                 pr_err("Cannot get CPU for cpufreq driver\n");
      30                 :          0 :                 return -ENODEV;
      31                 :            :         }
      32                 :            : 
      33                 :        207 :         clk = clk_get(cpu_dev, NULL);
      34         [ -  + ]:        207 :         if (IS_ERR(clk)) {
      35                 :          0 :                 dev_err(cpu_dev, "Cannot get clock for CPU0\n");
      36                 :          0 :                 return PTR_ERR(clk);
      37                 :            :         }
      38                 :            : 
      39                 :            :         /*
      40                 :            :          * The max and min frequencies are configurable in the Raspberry Pi
      41                 :            :          * firmware, so we query them at runtime.
      42                 :            :          */
      43                 :        207 :         min = roundup(clk_round_rate(clk, 0), RASPBERRYPI_FREQ_INTERVAL);
      44                 :        207 :         max = roundup(clk_round_rate(clk, ULONG_MAX), RASPBERRYPI_FREQ_INTERVAL);
      45                 :        207 :         clk_put(clk);
      46                 :            : 
      47         [ +  + ]:       1035 :         for (rate = min; rate <= max; rate += RASPBERRYPI_FREQ_INTERVAL) {
      48                 :        828 :                 ret = dev_pm_opp_add(cpu_dev, rate, 0);
      49         [ +  - ]:        828 :                 if (ret)
      50                 :            :                         goto remove_opp;
      51                 :            :         }
      52                 :            : 
      53                 :        207 :         cpufreq_dt = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
      54                 :            :         ret = PTR_ERR_OR_ZERO(cpufreq_dt);
      55         [ -  + ]:        207 :         if (ret) {
      56                 :          0 :                 dev_err(cpu_dev, "Failed to create platform device, %d\n", ret);
      57                 :          0 :                 goto remove_opp;
      58                 :            :         }
      59                 :            : 
      60                 :            :         return 0;
      61                 :            : 
      62                 :            : remove_opp:
      63                 :          0 :         dev_pm_opp_remove_all_dynamic(cpu_dev);
      64                 :            : 
      65                 :          0 :         return ret;
      66                 :            : }
      67                 :            : 
      68                 :          0 : static int raspberrypi_cpufreq_remove(struct platform_device *pdev)
      69                 :            : {
      70                 :            :         struct device *cpu_dev;
      71                 :            : 
      72                 :          0 :         cpu_dev = get_cpu_device(0);
      73         [ #  # ]:          0 :         if (cpu_dev)
      74                 :          0 :                 dev_pm_opp_remove_all_dynamic(cpu_dev);
      75                 :            : 
      76                 :          0 :         platform_device_unregister(cpufreq_dt);
      77                 :            : 
      78                 :          0 :         return 0;
      79                 :            : }
      80                 :            : 
      81                 :            : /*
      82                 :            :  * Since the driver depends on clk-raspberrypi, which may return EPROBE_DEFER,
      83                 :            :  * all the activity is performed in the probe, which may be defered as well.
      84                 :            :  */
      85                 :            : static struct platform_driver raspberrypi_cpufreq_driver = {
      86                 :            :         .driver = {
      87                 :            :                 .name = "raspberrypi-cpufreq",
      88                 :            :         },
      89                 :            :         .probe          = raspberrypi_cpufreq_probe,
      90                 :            :         .remove         = raspberrypi_cpufreq_remove,
      91                 :            : };
      92                 :        207 : module_platform_driver(raspberrypi_cpufreq_driver);
      93                 :            : 
      94                 :            : MODULE_AUTHOR("Nicolas Saenz Julienne <nsaenzjulienne@suse.de");
      95                 :            : MODULE_DESCRIPTION("Raspberry Pi cpufreq driver");
      96                 :            : MODULE_LICENSE("GPL");
      97                 :            : MODULE_ALIAS("platform:raspberrypi-cpufreq");

Generated by: LCOV version 1.14