当我们最终使用kernel 提供的cpufreq的时候一定要调用cpufreq_register_driver,系统中governer 可以有5个,但是driver只能有一个。
我们来看看cpufreq_register_driver 具体做了什么操作.
从2429和2430 可以看出driver_data->target_index和 driver_data->target 必须实现一个,因为最终是调用这两个函数中的一个将freq设定到cpu的寄存器中.
2442行如果cpufreq_driver 不为NULL,则退出。证明我们前面说的系统中只能有一个cpufreq_driver。
2459行为每个cpu 添加governer.
2471行,因为cpu 可能hotplug,因此注册通知链,来动态为cpu添加governer或者移除governer.
2420 int cpufreq_register_driver(struct cpufreq_driver *driver_data)
2421 {
2422 unsigned long flags;
2423 int ret;
2424
2425 if (cpufreq_disabled())
2426 return -ENODEV;
2427
2428 if (!driver_data || !driver_data->verify || !driver_data->init ||
2429 !(driver_data->setpolicy || driver_data->target_index ||
2430 driver_data->target) ||
2431 (driver_data->setpolicy && (driver_data->target_index ||
2432 driver_data->target)) ||
2433 (!!driver_data->get_intermediate != !!driver_data->target_intermediate))
2434 return -EINVAL;
2435
2436 pr_debug("trying to register driver %s\n", driver_data->name);
2437
2438 /* Protect against concurrent CPU online/offline. */
2439 get_online_cpus();
2440
2441 write_lock_irqsave(&cpufreq_driver_lock, flags);
2442 if (cpufreq_driver) {
2443 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
2444 ret = -EEXIST;
2445 goto out;
2446 }
2447 cpufreq_driver = driver_data;
2448 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
2449
2450 if (driver_data->setpolicy)
2451 driver_data->flags |= CPUFREQ_CONST_LOOPS;
2452
2453 if (cpufreq_boost_supported()) {
2454 ret = create_boost_sysfs_file();
2455 if (ret)
2456 goto err_null_driver;
2457 }
2458
2459 ret = subsys_interface_register(&cpufreq_interface);
2460 if (ret)
2461 goto err_boost_unreg;
2462
2463 if (!(cpufreq_driver->flags & CPUFREQ_STICKY) &&
2464 list_empty(&cpufreq_policy_list)) {
2465 /* if all ->init() calls failed, unregister */
2466 pr_debug("%s: No CPU initialized for driver %s\n", __func__,
2467 driver_data->name);
2468 goto err_if_unreg;
2469 }
2470
2471 register_hotcpu_notifier(&cpufreq_cpu_notifier);
2472 pr_debug("driver %s up and running\n", driver_data->name);
2473 goto out;
2474
2475 err_if_unreg:
2476 subsys_interface_unregister(&cpufreq_interface);
2477 err_boost_unreg:
2478 remove_boost_sysfs_file();
2479 err_null_driver:
2480 write_lock_irqsave(&cpufreq_driver_lock, flags);
2481 cpufreq_driver = NULL;
2482 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
2483 out:
2484 put_online_cpus();
2485 return ret;
2486 }
2487 EXPORT_SYMBOL_GPL(cpufreq_register_driver);
我们来看看cpufreq_register_driver 具体做了什么操作.
从2429和2430 可以看出driver_data->target_index和 driver_data->target 必须实现一个,因为最终是调用这两个函数中的一个将freq设定到cpu的寄存器中.
2442行如果cpufreq_driver 不为NULL,则退出。证明我们前面说的系统中只能有一个cpufreq_driver。
2459行为每个cpu 添加governer.
2471行,因为cpu 可能hotplug,因此注册通知链,来动态为cpu添加governer或者移除governer.
2420 int cpufreq_register_driver(struct cpufreq_driver *driver_data)
2421 {
2422 unsigned long flags;
2423 int ret;
2424
2425 if (cpufreq_disabled())
2426 return -ENODEV;
2427
2428 if (!driver_data || !driver_data->verify || !driver_data->init ||
2429 !(driver_data->setpolicy || driver_data->target_index ||
2430 driver_data->target) ||
2431 (driver_data->setpolicy && (driver_data->target_index ||
2432 driver_data->target)) ||
2433 (!!driver_data->get_intermediate != !!driver_data->target_intermediate))
2434 return -EINVAL;
2435
2436 pr_debug("trying to register driver %s\n", driver_data->name);
2437
2438 /* Protect against concurrent CPU online/offline. */
2439 get_online_cpus();
2440
2441 write_lock_irqsave(&cpufreq_driver_lock, flags);
2442 if (cpufreq_driver) {
2443 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
2444 ret = -EEXIST;
2445 goto out;
2446 }
2447 cpufreq_driver = driver_data;
2448 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
2449
2450 if (driver_data->setpolicy)
2451 driver_data->flags |= CPUFREQ_CONST_LOOPS;
2452
2453 if (cpufreq_boost_supported()) {
2454 ret = create_boost_sysfs_file();
2455 if (ret)
2456 goto err_null_driver;
2457 }
2458
2459 ret = subsys_interface_register(&cpufreq_interface);
2460 if (ret)
2461 goto err_boost_unreg;
2462
2463 if (!(cpufreq_driver->flags & CPUFREQ_STICKY) &&
2464 list_empty(&cpufreq_policy_list)) {
2465 /* if all ->init() calls failed, unregister */
2466 pr_debug("%s: No CPU initialized for driver %s\n", __func__,
2467 driver_data->name);
2468 goto err_if_unreg;
2469 }
2470
2471 register_hotcpu_notifier(&cpufreq_cpu_notifier);
2472 pr_debug("driver %s up and running\n", driver_data->name);
2473 goto out;
2474
2475 err_if_unreg:
2476 subsys_interface_unregister(&cpufreq_interface);
2477 err_boost_unreg:
2478 remove_boost_sysfs_file();
2479 err_null_driver:
2480 write_lock_irqsave(&cpufreq_driver_lock, flags);
2481 cpufreq_driver = NULL;
2482 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
2483 out:
2484 put_online_cpus();
2485 return ret;
2486 }
2487 EXPORT_SYMBOL_GPL(cpufreq_register_driver);