cpufreq: Revert incorrect commit 5800043

Commit 5800043 (cpufreq: convert cpufreq_driver to using RCU) causes
the following call trace to be spit on boot:

 BUG: sleeping function called from invalid context at /scratch/rafael/work/linux-pm/mm/slab.c:3179
 in_atomic(): 0, irqs_disabled(): 0, pid: 292, name: systemd-udevd
 2 locks held by systemd-udevd/292:
  #0:  (subsys mutex){+.+.+.}, at: [<ffffffff8146851a>] subsys_interface_register+0x4a/0xe0
  #1:  (rcu_read_lock){.+.+.+}, at: [<ffffffff81538210>] cpufreq_add_dev_interface+0x60/0x5e0
 Pid: 292, comm: systemd-udevd Not tainted 3.9.0-rc8+ #323
 Call Trace:
  [<ffffffff81072c90>] __might_sleep+0x140/0x1f0
  [<ffffffff811581c2>] kmem_cache_alloc+0x42/0x2b0
  [<ffffffff811e7179>] sysfs_new_dirent+0x59/0x130
  [<ffffffff811e63cb>] sysfs_add_file_mode+0x6b/0x110
  [<ffffffff81538210>] ? cpufreq_add_dev_interface+0x60/0x5e0
  [<ffffffff810a3254>] ? __lock_is_held+0x54/0x80
  [<ffffffff811e647d>] sysfs_add_file+0xd/0x10
  [<ffffffff811e6541>] sysfs_create_file+0x21/0x30
  [<ffffffff81538280>] cpufreq_add_dev_interface+0xd0/0x5e0
  [<ffffffff81538210>] ? cpufreq_add_dev_interface+0x60/0x5e0
  [<ffffffffa000337f>] ? acpi_processor_get_platform_limit+0x32/0xbb [processor]
  [<ffffffffa022f540>] ? do_drv_write+0x70/0x70 [acpi_cpufreq]
  [<ffffffff810a3254>] ? __lock_is_held+0x54/0x80
  [<ffffffff8106c97e>] ? up_read+0x1e/0x40
  [<ffffffff8106e632>] ? __blocking_notifier_call_chain+0x72/0xc0
  [<ffffffff81538dbd>] cpufreq_add_dev+0x62d/0xae0
  [<ffffffff815389b8>] ? cpufreq_add_dev+0x228/0xae0
  [<ffffffff81468569>] subsys_interface_register+0x99/0xe0
  [<ffffffffa014d000>] ? 0xffffffffa014cfff
  [<ffffffff81535d5d>] cpufreq_register_driver+0x9d/0x200
  [<ffffffffa014d000>] ? 0xffffffffa014cfff
  [<ffffffffa014d0e9>] acpi_cpufreq_init+0xe9/0x1000 [acpi_cpufreq]
  [<ffffffff810002fa>] do_one_initcall+0x11a/0x170
  [<ffffffff810b4b87>] load_module+0x1cf7/0x2920
  [<ffffffff81322580>] ? ddebug_proc_open+0xb0/0xb0
  [<ffffffff816baee0>] ? retint_restore_args+0xe/0xe
  [<ffffffff810b5887>] sys_init_module+0xd7/0x120
  [<ffffffff816bb6d2>] system_call_fastpath+0x16/0x1b

which is quite obvious, because that commit put (multiple instances
of) sysfs_create_file() under rcu_read_lock()/rcu_read_unlock(),
although sysfs_create_file() may cause memory to be allocated with
GFP_KERNEL and that may sleep, which is not permitted in RCU read
critical section.

Revert the buggy commit altogether along with some changes on top
of it.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index a6f6595..1b8a48e 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -39,7 +39,7 @@
  * level driver of CPUFreq support, and its spinlock. This lock
  * also protects the cpufreq_cpu_data array.
  */
-static struct cpufreq_driver __rcu *cpufreq_driver;
+static struct cpufreq_driver *cpufreq_driver;
 static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
 #ifdef CONFIG_HOTPLUG_CPU
 /* This one keeps track of the previously set governor of a removed CPU */
@@ -130,35 +130,27 @@
 
 bool have_governor_per_policy(void)
 {
-	bool have_governor_per_policy;
-	rcu_read_lock();
-	have_governor_per_policy =
-		rcu_dereference(cpufreq_driver)->have_governor_per_policy;
-	rcu_read_unlock();
-	return have_governor_per_policy;
+	return cpufreq_driver->have_governor_per_policy;
 }
 
 static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs)
 {
 	struct cpufreq_policy *data;
-	struct cpufreq_driver *driver;
 	unsigned long flags;
 
 	if (cpu >= nr_cpu_ids)
 		goto err_out;
 
 	/* get the cpufreq driver */
-	rcu_read_lock();
-	driver = rcu_dereference(cpufreq_driver);
-
-	if (!driver)
-		goto err_out_unlock;
-
-	if (!try_module_get(driver->owner))
-		goto err_out_unlock;
-
 	read_lock_irqsave(&cpufreq_driver_lock, flags);
 
+	if (!cpufreq_driver)
+		goto err_out_unlock;
+
+	if (!try_module_get(cpufreq_driver->owner))
+		goto err_out_unlock;
+
+
 	/* get the CPU */
 	data = per_cpu(cpufreq_cpu_data, cpu);
 
@@ -169,14 +161,12 @@
 		goto err_out_put_module;
 
 	read_unlock_irqrestore(&cpufreq_driver_lock, flags);
-	rcu_read_unlock();
 	return data;
 
 err_out_put_module:
-	module_put(driver->owner);
-	read_unlock_irqrestore(&cpufreq_driver_lock, flags);
+	module_put(cpufreq_driver->owner);
 err_out_unlock:
-	rcu_read_unlock();
+	read_unlock_irqrestore(&cpufreq_driver_lock, flags);
 err_out:
 	return NULL;
 }
@@ -199,9 +189,7 @@
 {
 	if (!sysfs)
 		kobject_put(&data->kobj);
-	rcu_read_lock();
-	module_put(rcu_dereference(cpufreq_driver)->owner);
-	rcu_read_unlock();
+	module_put(cpufreq_driver->owner);
 }
 
 void cpufreq_cpu_put(struct cpufreq_policy *data)
@@ -269,9 +257,7 @@
 	if (cpufreq_disabled())
 		return;
 
-	rcu_read_lock();
-	freqs->flags = rcu_dereference(cpufreq_driver)->flags;
-	rcu_read_unlock();
+	freqs->flags = cpufreq_driver->flags;
 	pr_debug("notification %u of frequency transition to %u kHz\n",
 		state, freqs->new);
 
@@ -282,7 +268,7 @@
 		 * which is not equal to what the cpufreq core thinks is
 		 * "old frequency".
 		 */
-		if (!(freqs->flags & CPUFREQ_CONST_LOOPS)) {
+		if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
 			if ((policy) && (policy->cpu == freqs->cpu) &&
 			    (policy->cur) && (policy->cur != freqs->old)) {
 				pr_debug("Warning: CPU frequency is"
@@ -348,21 +334,11 @@
 				struct cpufreq_governor **governor)
 {
 	int err = -EINVAL;
-	struct cpufreq_driver *driver;
-	bool has_setpolicy;
-	bool has_target;
 
-	rcu_read_lock();
-	driver = rcu_dereference(cpufreq_driver);
-	if (!driver) {
-		rcu_read_unlock();
+	if (!cpufreq_driver)
 		goto out;
-	}
-	has_setpolicy = driver->setpolicy ? true : false;
-	has_target = driver->target ? true : false;
-	rcu_read_unlock();
 
-	if (has_setpolicy) {
+	if (cpufreq_driver->setpolicy) {
 		if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
 			*policy = CPUFREQ_POLICY_PERFORMANCE;
 			err = 0;
@@ -371,7 +347,7 @@
 			*policy = CPUFREQ_POLICY_POWERSAVE;
 			err = 0;
 		}
-	} else if (has_target) {
+	} else if (cpufreq_driver->target) {
 		struct cpufreq_governor *t;
 
 		mutex_lock(&cpufreq_governor_mutex);
@@ -522,12 +498,7 @@
  */
 static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf)
 {
-	ssize_t size;
-	rcu_read_lock();
-	size = scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n",
-		rcu_dereference(cpufreq_driver)->name);
-	rcu_read_unlock();
-	return size;
+	return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n", cpufreq_driver->name);
 }
 
 /**
@@ -539,13 +510,10 @@
 	ssize_t i = 0;
 	struct cpufreq_governor *t;
 
-	rcu_read_lock();
-	if (!rcu_dereference(cpufreq_driver)->target) {
-		rcu_read_unlock();
+	if (!cpufreq_driver->target) {
 		i += sprintf(buf, "performance powersave");
 		goto out;
 	}
-	rcu_read_unlock();
 
 	list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
 		if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
@@ -623,15 +591,9 @@
 static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
 {
 	unsigned int limit;
-	int (*bios_limit)(int cpu, unsigned int *limit);
 	int ret;
-
-	rcu_read_lock();
-	bios_limit = rcu_dereference(cpufreq_driver)->bios_limit;
-	rcu_read_unlock();
-
-	if (bios_limit) {
-		ret = bios_limit(policy->cpu, &limit);
+	if (cpufreq_driver->bios_limit) {
+		ret = cpufreq_driver->bios_limit(policy->cpu, &limit);
 		if (!ret)
 			return sprintf(buf, "%u\n", limit);
 	}
@@ -774,7 +736,6 @@
 {
 	struct cpufreq_policy new_policy;
 	struct freq_attr **drv_attr;
-	struct cpufreq_driver *driver;
 	unsigned long flags;
 	int ret = 0;
 	unsigned int j;
@@ -786,31 +747,28 @@
 		return ret;
 
 	/* set up files for this cpu device */
-	rcu_read_lock();
-	driver = rcu_dereference(cpufreq_driver);
-	drv_attr = driver->attr;
+	drv_attr = cpufreq_driver->attr;
 	while ((drv_attr) && (*drv_attr)) {
 		ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
 		if (ret)
-			goto err_out_unlock;
+			goto err_out_kobj_put;
 		drv_attr++;
 	}
-	if (driver->get) {
+	if (cpufreq_driver->get) {
 		ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
 		if (ret)
-			goto err_out_unlock;
+			goto err_out_kobj_put;
 	}
-	if (driver->target) {
+	if (cpufreq_driver->target) {
 		ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
 		if (ret)
-			goto err_out_unlock;
+			goto err_out_kobj_put;
 	}
-	if (driver->bios_limit) {
+	if (cpufreq_driver->bios_limit) {
 		ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
 		if (ret)
-			goto err_out_unlock;
+			goto err_out_kobj_put;
 	}
-	rcu_read_unlock();
 
 	write_lock_irqsave(&cpufreq_driver_lock, flags);
 	for_each_cpu(j, policy->cpus) {
@@ -833,20 +791,12 @@
 	policy->user_policy.governor = policy->governor;
 
 	if (ret) {
-		int (*exit)(struct cpufreq_policy *policy);
-
 		pr_debug("setting policy failed\n");
-		rcu_read_lock();
-		exit = rcu_dereference(cpufreq_driver)->exit;
-		rcu_read_unlock();
-		if (exit)
-			exit(policy);
-
+		if (cpufreq_driver->exit)
+			cpufreq_driver->exit(policy);
 	}
 	return ret;
 
-err_out_unlock:
-	rcu_read_unlock();
 err_out_kobj_put:
 	kobject_put(&policy->kobj);
 	wait_for_completion(&policy->kobj_unregister);
@@ -858,16 +808,12 @@
 				  struct device *dev)
 {
 	struct cpufreq_policy *policy;
-	int ret = 0, has_target = 0;
+	int ret = 0, has_target = !!cpufreq_driver->target;
 	unsigned long flags;
 
 	policy = cpufreq_cpu_get(sibling);
 	WARN_ON(!policy);
 
-	rcu_read_lock();
-	has_target = !!rcu_dereference(cpufreq_driver)->target;
-	rcu_read_unlock();
-
 	if (has_target)
 		__cpufreq_governor(policy, CPUFREQ_GOV_STOP);
 
@@ -911,8 +857,6 @@
 	unsigned int j, cpu = dev->id;
 	int ret = -ENOMEM;
 	struct cpufreq_policy *policy;
-	struct cpufreq_driver *driver;
-	int (*init)(struct cpufreq_policy *policy);
 	unsigned long flags;
 #ifdef CONFIG_HOTPLUG_CPU
 	struct cpufreq_governor *gov;
@@ -947,15 +891,10 @@
 #endif
 #endif
 
-	rcu_read_lock();
-	driver = rcu_dereference(cpufreq_driver);
-	if (!try_module_get(driver->owner)) {
-		rcu_read_unlock();
+	if (!try_module_get(cpufreq_driver->owner)) {
 		ret = -EINVAL;
 		goto module_out;
 	}
-	init = driver->init;
-	rcu_read_unlock();
 
 	policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
 	if (!policy)
@@ -980,7 +919,7 @@
 	/* call driver. From then on the cpufreq must be able
 	 * to accept all calls to ->verify and ->setpolicy for this CPU
 	 */
-	ret = init(policy);
+	ret = cpufreq_driver->init(policy);
 	if (ret) {
 		pr_debug("initialization failed\n");
 		goto err_set_policy_cpu;
@@ -1015,9 +954,7 @@
 		goto err_out_unregister;
 
 	kobject_uevent(&policy->kobj, KOBJ_ADD);
-	rcu_read_lock();
-	module_put(rcu_dereference(cpufreq_driver)->owner);
-	rcu_read_unlock();
+	module_put(cpufreq_driver->owner);
 	pr_debug("initialization complete\n");
 
 	return 0;
@@ -1039,9 +976,7 @@
 err_free_policy:
 	kfree(policy);
 nomem_out:
-	rcu_read_lock();
-	module_put(rcu_dereference(cpufreq_driver)->owner);
-	rcu_read_unlock();
+	module_put(cpufreq_driver->owner);
 module_out:
 	return ret;
 }
@@ -1075,12 +1010,9 @@
 	unsigned int cpu = dev->id, ret, cpus;
 	unsigned long flags;
 	struct cpufreq_policy *data;
-	struct cpufreq_driver *driver;
 	struct kobject *kobj;
 	struct completion *cmp;
 	struct device *cpu_dev;
-	bool has_target;
-	int (*exit)(struct cpufreq_policy *policy);
 
 	pr_debug("%s: unregistering CPU %u\n", __func__, cpu);
 
@@ -1096,19 +1028,14 @@
 		return -EINVAL;
 	}
 
-	rcu_read_lock();
-	driver = rcu_dereference(cpufreq_driver);
-	has_target = driver->target ? true : false;
-	exit = driver->exit;
-	if (has_target)
+	if (cpufreq_driver->target)
 		__cpufreq_governor(data, CPUFREQ_GOV_STOP);
 
 #ifdef CONFIG_HOTPLUG_CPU
-	if (!driver->setpolicy)
+	if (!cpufreq_driver->setpolicy)
 		strncpy(per_cpu(cpufreq_cpu_governor, cpu),
 			data->governor->name, CPUFREQ_NAME_LEN);
 #endif
-	rcu_read_unlock();
 
 	WARN_ON(lock_policy_rwsem_write(cpu));
 	cpus = cpumask_weight(data->cpus);
@@ -1153,7 +1080,7 @@
 
 	/* If cpu is last user of policy, free policy */
 	if (cpus == 1) {
-		if (has_target)
+		if (cpufreq_driver->target)
 			__cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT);
 
 		lock_policy_rwsem_read(cpu);
@@ -1170,13 +1097,13 @@
 		wait_for_completion(cmp);
 		pr_debug("wait complete\n");
 
-		if (exit)
-			exit(data);
+		if (cpufreq_driver->exit)
+			cpufreq_driver->exit(data);
 
 		free_cpumask_var(data->related_cpus);
 		free_cpumask_var(data->cpus);
 		kfree(data);
-	} else if (has_target) {
+	} else if (cpufreq_driver->target) {
 		__cpufreq_governor(data, CPUFREQ_GOV_START);
 		__cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
 	}
@@ -1250,18 +1177,10 @@
 unsigned int cpufreq_quick_get(unsigned int cpu)
 {
 	struct cpufreq_policy *policy;
-	struct cpufreq_driver *driver;
-	unsigned int (*get)(unsigned int cpu);
 	unsigned int ret_freq = 0;
 
-	rcu_read_lock();
-	driver = rcu_dereference(cpufreq_driver);
-	if (driver && driver->setpolicy && driver->get) {
-		get = driver->get;
-		rcu_read_unlock();
-		return get(cpu);
-	}
-	rcu_read_unlock();
+	if (cpufreq_driver && cpufreq_driver->setpolicy && cpufreq_driver->get)
+		return cpufreq_driver->get(cpu);
 
 	policy = cpufreq_cpu_get(cpu);
 	if (policy) {
@@ -1297,26 +1216,15 @@
 static unsigned int __cpufreq_get(unsigned int cpu)
 {
 	struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
-	struct cpufreq_driver *driver;
-	unsigned int (*get)(unsigned int cpu);
 	unsigned int ret_freq = 0;
-	u8 flags;
 
-
-	rcu_read_lock();
-	driver = rcu_dereference(cpufreq_driver);
-	if (!driver->get) {
-		rcu_read_unlock();
+	if (!cpufreq_driver->get)
 		return ret_freq;
-	}
-	flags = driver->flags;
-	get = driver->get;
-	rcu_read_unlock();
 
-	ret_freq = get(cpu);
+	ret_freq = cpufreq_driver->get(cpu);
 
 	if (ret_freq && policy->cur &&
-		!(flags & CPUFREQ_CONST_LOOPS)) {
+		!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
 		/* verify no discrepancy between actual and
 					saved value exists */
 		if (unlikely(ret_freq != policy->cur)) {
@@ -1372,7 +1280,6 @@
  */
 static int cpufreq_bp_suspend(void)
 {
-	int (*suspend)(struct cpufreq_policy *policy);
 	int ret = 0;
 
 	int cpu = smp_processor_id();
@@ -1385,11 +1292,8 @@
 	if (!cpu_policy)
 		return 0;
 
-	rcu_read_lock();
-	suspend = rcu_dereference(cpufreq_driver)->suspend;
-	rcu_read_unlock();
-	if (suspend) {
-		ret = suspend(cpu_policy);
+	if (cpufreq_driver->suspend) {
+		ret = cpufreq_driver->suspend(cpu_policy);
 		if (ret)
 			printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
 					"step on CPU %u\n", cpu_policy->cpu);
@@ -1415,7 +1319,6 @@
 static void cpufreq_bp_resume(void)
 {
 	int ret = 0;
-	int (*resume)(struct cpufreq_policy *policy);
 
 	int cpu = smp_processor_id();
 	struct cpufreq_policy *cpu_policy;
@@ -1427,12 +1330,8 @@
 	if (!cpu_policy)
 		return;
 
-	rcu_read_lock();
-	resume = rcu_dereference(cpufreq_driver)->resume;
-	rcu_read_unlock();
-
-	if (resume) {
-		ret = resume(cpu_policy);
+	if (cpufreq_driver->resume) {
+		ret = cpufreq_driver->resume(cpu_policy);
 		if (ret) {
 			printk(KERN_ERR "cpufreq: resume failed in ->resume "
 					"step on CPU %u\n", cpu_policy->cpu);
@@ -1459,14 +1358,10 @@
  */
 const char *cpufreq_get_current_driver(void)
 {
-	struct cpufreq_driver *driver;
-	const char *name = NULL;
-	rcu_read_lock();
-	driver = rcu_dereference(cpufreq_driver);
-	if (driver)
-		name = driver->name;
-	rcu_read_unlock();
-	return name;
+	if (cpufreq_driver)
+		return cpufreq_driver->name;
+
+	return NULL;
 }
 EXPORT_SYMBOL_GPL(cpufreq_get_current_driver);
 
@@ -1560,9 +1455,6 @@
 {
 	int retval = -EINVAL;
 	unsigned int old_target_freq = target_freq;
-	int (*target)(struct cpufreq_policy *policy,
-		      unsigned int target_freq,
-		      unsigned int relation);
 
 	if (cpufreq_disabled())
 		return -ENODEV;
@@ -1579,11 +1471,8 @@
 	if (target_freq == policy->cur)
 		return 0;
 
-	rcu_read_lock();
-	target = rcu_dereference(cpufreq_driver)->target;
-	rcu_read_unlock();
-	if (target)
-		retval = target(policy, target_freq, relation);
+	if (cpufreq_driver->target)
+		retval = cpufreq_driver->target(policy, target_freq, relation);
 
 	return retval;
 }
@@ -1616,24 +1505,18 @@
 int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
 {
 	int ret = 0;
-	unsigned int (*getavg)(struct cpufreq_policy *policy,
-			       unsigned int cpu);
 
 	if (cpufreq_disabled())
 		return ret;
 
-	rcu_read_lock();
-	getavg = rcu_dereference(cpufreq_driver)->getavg;
-	rcu_read_unlock();
-
-	if (!getavg)
+	if (!cpufreq_driver->getavg)
 		return 0;
 
 	policy = cpufreq_cpu_get(policy->cpu);
 	if (!policy)
 		return -EINVAL;
 
-	ret = getavg(policy, cpu);
+	ret = cpufreq_driver->getavg(policy, cpu);
 
 	cpufreq_cpu_put(policy);
 	return ret;
@@ -1791,9 +1674,6 @@
 				struct cpufreq_policy *policy)
 {
 	int ret = 0, failed = 1;
-	struct cpufreq_driver *driver;
-	int (*verify)(struct cpufreq_policy *policy);
-	int (*setpolicy)(struct cpufreq_policy *policy);
 
 	pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
 		policy->min, policy->max);
@@ -1807,13 +1687,7 @@
 	}
 
 	/* verify the cpu speed can be set within this limit */
-	rcu_read_lock();
-	driver = rcu_dereference(cpufreq_driver);
-	verify = driver->verify;
-	setpolicy = driver->setpolicy;
-	rcu_read_unlock();
-
-	ret = verify(policy);
+	ret = cpufreq_driver->verify(policy);
 	if (ret)
 		goto error_out;
 
@@ -1827,7 +1701,7 @@
 
 	/* verify the cpu speed can be set within this limit,
 	   which might be different to the first one */
-	ret = verify(policy);
+	ret = cpufreq_driver->verify(policy);
 	if (ret)
 		goto error_out;
 
@@ -1841,10 +1715,10 @@
 	pr_debug("new min and max freqs are %u - %u kHz\n",
 					data->min, data->max);
 
-	if (setpolicy) {
+	if (cpufreq_driver->setpolicy) {
 		data->policy = policy->policy;
 		pr_debug("setting range\n");
-		ret = setpolicy(policy);
+		ret = cpufreq_driver->setpolicy(policy);
 	} else {
 		if (policy->governor != data->governor) {
 			/* save old, working values */
@@ -1904,11 +1778,6 @@
 {
 	struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
 	struct cpufreq_policy policy;
-	struct cpufreq_driver *driver;
-	unsigned int (*get)(unsigned int cpu);
-	int (*target)(struct cpufreq_policy *policy,
-		      unsigned int target_freq,
-		      unsigned int relation);
 	int ret;
 
 	if (!data) {
@@ -1930,18 +1799,13 @@
 
 	/* BIOS might change freq behind our back
 	  -> ask driver for current freq and notify governors about a change */
-	rcu_read_lock();
-	driver = rcu_access_pointer(cpufreq_driver);
-	get = driver->get;
-	target = driver->target;
-	rcu_read_unlock();
-	if (get) {
-		policy.cur = get(cpu);
+	if (cpufreq_driver->get) {
+		policy.cur = cpufreq_driver->get(cpu);
 		if (!data->cur) {
 			pr_debug("Driver did not initialize current freq");
 			data->cur = policy.cur;
 		} else {
-			if (data->cur != policy.cur && target)
+			if (data->cur != policy.cur && cpufreq_driver->target)
 				cpufreq_out_of_sync(cpu, data->cur,
 								policy.cur);
 		}
@@ -2020,19 +1884,18 @@
 		driver_data->flags |= CPUFREQ_CONST_LOOPS;
 
 	write_lock_irqsave(&cpufreq_driver_lock, flags);
-	if (rcu_access_pointer(cpufreq_driver)) {
+	if (cpufreq_driver) {
 		write_unlock_irqrestore(&cpufreq_driver_lock, flags);
 		return -EBUSY;
 	}
-	rcu_assign_pointer(cpufreq_driver, driver_data);
+	cpufreq_driver = driver_data;
 	write_unlock_irqrestore(&cpufreq_driver_lock, flags);
-	synchronize_rcu();
 
 	ret = subsys_interface_register(&cpufreq_interface);
 	if (ret)
 		goto err_null_driver;
 
-	if (!(driver_data->flags & CPUFREQ_STICKY)) {
+	if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
 		int i;
 		ret = -ENODEV;
 
@@ -2059,9 +1922,8 @@
 	subsys_interface_unregister(&cpufreq_interface);
 err_null_driver:
 	write_lock_irqsave(&cpufreq_driver_lock, flags);
-	rcu_assign_pointer(cpufreq_driver, NULL);
+	cpufreq_driver = NULL;
 	write_unlock_irqrestore(&cpufreq_driver_lock, flags);
-	synchronize_rcu();
 	return ret;
 }
 EXPORT_SYMBOL_GPL(cpufreq_register_driver);
@@ -2078,15 +1940,9 @@
 int cpufreq_unregister_driver(struct cpufreq_driver *driver)
 {
 	unsigned long flags;
-	struct cpufreq_driver *old_driver;
 
-	rcu_read_lock();
-	old_driver = rcu_access_pointer(cpufreq_driver);
-	if (!old_driver || (driver != old_driver)) {
-		rcu_read_unlock();
+	if (!cpufreq_driver || (driver != cpufreq_driver))
 		return -EINVAL;
-	}
-	rcu_read_unlock();
 
 	pr_debug("unregistering driver %s\n", driver->name);
 
@@ -2094,9 +1950,8 @@
 	unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
 
 	write_lock_irqsave(&cpufreq_driver_lock, flags);
-	rcu_assign_pointer(cpufreq_driver, NULL);
+	cpufreq_driver = NULL;
 	write_unlock_irqrestore(&cpufreq_driver_lock, flags);
-	synchronize_rcu();
 
 	return 0;
 }