diff options
Diffstat (limited to 'drivers/cpufreq/cpufreq.c')
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 89 |
1 files changed, 52 insertions, 37 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 7600c10d275a..0ee008da46f2 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -784,6 +784,57 @@ int cpufreq_add_dev_symlink(unsigned int cpu, struct cpufreq_policy *policy) | |||
784 | return ret; | 784 | return ret; |
785 | } | 785 | } |
786 | 786 | ||
787 | int cpufreq_add_dev_interface(unsigned int cpu, struct cpufreq_policy *policy, | ||
788 | struct sys_device *sys_dev) | ||
789 | { | ||
790 | struct freq_attr **drv_attr; | ||
791 | unsigned long flags; | ||
792 | int ret = 0; | ||
793 | unsigned int j; | ||
794 | |||
795 | /* prepare interface data */ | ||
796 | ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, | ||
797 | &sys_dev->kobj, "cpufreq"); | ||
798 | if (ret) | ||
799 | return ret; | ||
800 | |||
801 | /* set up files for this cpu device */ | ||
802 | drv_attr = cpufreq_driver->attr; | ||
803 | while ((drv_attr) && (*drv_attr)) { | ||
804 | ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); | ||
805 | if (ret) | ||
806 | goto err_out_kobj_put; | ||
807 | drv_attr++; | ||
808 | } | ||
809 | if (cpufreq_driver->get) { | ||
810 | ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr); | ||
811 | if (ret) | ||
812 | goto err_out_kobj_put; | ||
813 | } | ||
814 | if (cpufreq_driver->target) { | ||
815 | ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); | ||
816 | if (ret) | ||
817 | goto err_out_kobj_put; | ||
818 | } | ||
819 | |||
820 | spin_lock_irqsave(&cpufreq_driver_lock, flags); | ||
821 | for_each_cpu(j, policy->cpus) { | ||
822 | if (!cpu_online(j)) | ||
823 | continue; | ||
824 | per_cpu(cpufreq_cpu_data, j) = policy; | ||
825 | per_cpu(policy_cpu, j) = policy->cpu; | ||
826 | } | ||
827 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); | ||
828 | |||
829 | ret = cpufreq_add_dev_symlink(cpu, policy); | ||
830 | return ret; | ||
831 | |||
832 | err_out_kobj_put: | ||
833 | kobject_put(&policy->kobj); | ||
834 | wait_for_completion(&policy->kobj_unregister); | ||
835 | return ret; | ||
836 | } | ||
837 | |||
787 | 838 | ||
788 | /** | 839 | /** |
789 | * cpufreq_add_dev - add a CPU device | 840 | * cpufreq_add_dev - add a CPU device |
@@ -800,7 +851,6 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) | |||
800 | int ret = 0; | 851 | int ret = 0; |
801 | struct cpufreq_policy new_policy; | 852 | struct cpufreq_policy new_policy; |
802 | struct cpufreq_policy *policy; | 853 | struct cpufreq_policy *policy; |
803 | struct freq_attr **drv_attr; | ||
804 | unsigned long flags; | 854 | unsigned long flags; |
805 | unsigned int j; | 855 | unsigned int j; |
806 | 856 | ||
@@ -923,41 +973,7 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) | |||
923 | #endif | 973 | #endif |
924 | memcpy(&new_policy, policy, sizeof(struct cpufreq_policy)); | 974 | memcpy(&new_policy, policy, sizeof(struct cpufreq_policy)); |
925 | 975 | ||
926 | /* prepare interface data */ | 976 | ret = cpufreq_add_dev_interface(cpu, policy, sys_dev); |
927 | ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, &sys_dev->kobj, | ||
928 | "cpufreq"); | ||
929 | if (ret) | ||
930 | goto out_driver_exit; | ||
931 | |||
932 | /* set up files for this cpu device */ | ||
933 | drv_attr = cpufreq_driver->attr; | ||
934 | while ((drv_attr) && (*drv_attr)) { | ||
935 | ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); | ||
936 | if (ret) | ||
937 | goto err_out_kobj_put; | ||
938 | drv_attr++; | ||
939 | } | ||
940 | if (cpufreq_driver->get) { | ||
941 | ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr); | ||
942 | if (ret) | ||
943 | goto err_out_kobj_put; | ||
944 | } | ||
945 | if (cpufreq_driver->target) { | ||
946 | ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); | ||
947 | if (ret) | ||
948 | goto err_out_kobj_put; | ||
949 | } | ||
950 | |||
951 | spin_lock_irqsave(&cpufreq_driver_lock, flags); | ||
952 | for_each_cpu(j, policy->cpus) { | ||
953 | if (!cpu_online(j)) | ||
954 | continue; | ||
955 | per_cpu(cpufreq_cpu_data, j) = policy; | ||
956 | per_cpu(policy_cpu, j) = policy->cpu; | ||
957 | } | ||
958 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); | ||
959 | |||
960 | ret = cpufreq_add_dev_symlink(cpu, policy->cpus, policy); | ||
961 | if (ret) | 977 | if (ret) |
962 | goto err_out_unregister; | 978 | goto err_out_unregister; |
963 | 979 | ||
@@ -990,7 +1006,6 @@ err_out_unregister: | |||
990 | per_cpu(cpufreq_cpu_data, j) = NULL; | 1006 | per_cpu(cpufreq_cpu_data, j) = NULL; |
991 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); | 1007 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); |
992 | 1008 | ||
993 | err_out_kobj_put: | ||
994 | kobject_put(&policy->kobj); | 1009 | kobject_put(&policy->kobj); |
995 | wait_for_completion(&policy->kobj_unregister); | 1010 | wait_for_completion(&policy->kobj_unregister); |
996 | 1011 | ||