Question

I am developing a cpufreq driver (as a loadable kernel module) for the microblaze architecture. I have some FPGA logic that is able to scale the on-system clock and it works quite well. I have followed the information in Documentation/cpu-freq/cpu-drivers.txt and looked at the model in the blackfin cpufreq driver.

I have also made the necessary changes to arch/microblaze/Kconfig in order to have the cpufreq options built into the kernel (not modules).

When I first loaded the driver, cpufreq_register_driver() was returning -ENODEV, which implied that it couldn't find a CPU. I set the driver flag to CPUFREQ_STICKY and was able to insert the module.

However, at this point I realized that /sys/devices/system/cpu/cpu0 isn't present (although /sys/devices/system/cpu/cpufreq is there). So, why is that? What part of the kernel code is responsible for creating that directory?

Was it helpful?

Solution

I discovered where the /sys/devices/system/cpu/cpuX sysfs entry was created by looking at the cpufreq_cpu_callback() in drivers/cpufreq/cpufreq.c. This has a call to get_cpu_sysdev(), which I assumed was the element that I was looking for.

This call is defined in drivers/base/cpu.c, where I also noticed the code that puts together the cpu specific sysdev entry; register_cpu(). For most architectures, this is in arch/${ARCH}/kernel/setup.c, and I used the blackfin code as an example.

DEFINE_PER_CPU(struct cpu, cpu_data);
static int __init topology_init(void)
{
    unsigned int cpu;
    for_each_possible_cpu(cpu) {
        register_cpu(&per_cpu(cpu_data, cpu), cpu);
    }
    return 0;
}

After adding this code to arch/microblaze/kernel/setup.c, I now have the directory I need and I'm able to make use of the different governors available to talk to my cpufreq driver. Now I just have to make sleep 1 take 1 second at 1/3 the clock rate instead of 3 seconds!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top