diff options
| author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-08-17 10:57:56 +0400 | 
|---|---|---|
| committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-08-17 11:01:08 +0400 | 
| commit | a22ddff8bedfe33eeb1330bbb7ef1fbe007a42c4 (patch) | |
| tree | 61a2eb7fa62f5af10c2b913ca429e6b068b0eb2d /arch/x86/kernel/microcode_core.c | |
| parent | 20d5a540e55a29daeef12706f9ee73baf5641c16 (diff) | |
| parent | d9875690d9b89a866022ff49e3fcea892345ad92 (diff) | |
| download | linux-a22ddff8bedfe33eeb1330bbb7ef1fbe007a42c4.tar.xz | |
Merge tag 'v3.6-rc2' into drm-intel-next
Backmerge Linux 3.6-rc2 to resolve a few funny conflicts before we put
even more madness on top:
- drivers/gpu/drm/i915/i915_irq.c: Just a spurious WARN removed in
  -fixes, that has been changed in a variable-rename in -next, too.
- drivers/gpu/drm/i915/intel_ringbuffer.c: -next remove scratch_addr
  (since all their users have been extracted in another fucntion),
  -fixes added another user for a hw workaroudn.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'arch/x86/kernel/microcode_core.c')
| -rw-r--r-- | arch/x86/kernel/microcode_core.c | 66 | 
1 files changed, 51 insertions, 15 deletions
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c index fbdfc6917180..4873e62db6a1 100644 --- a/arch/x86/kernel/microcode_core.c +++ b/arch/x86/kernel/microcode_core.c @@ -87,6 +87,7 @@  #include <asm/microcode.h>  #include <asm/processor.h>  #include <asm/cpu_device_id.h> +#include <asm/perf_event.h>  MODULE_DESCRIPTION("Microcode Update Driver");  MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>"); @@ -277,7 +278,6 @@ static int reload_for_cpu(int cpu)  	struct ucode_cpu_info *uci = ucode_cpu_info + cpu;  	int err = 0; -	mutex_lock(µcode_mutex);  	if (uci->valid) {  		enum ucode_state ustate; @@ -288,7 +288,6 @@ static int reload_for_cpu(int cpu)  			if (ustate == UCODE_ERROR)  				err = -EINVAL;  	} -	mutex_unlock(µcode_mutex);  	return err;  } @@ -298,19 +297,31 @@ static ssize_t reload_store(struct device *dev,  			    const char *buf, size_t size)  {  	unsigned long val; -	int cpu = dev->id; -	ssize_t ret = 0; +	int cpu; +	ssize_t ret = 0, tmp_ret;  	ret = kstrtoul(buf, 0, &val);  	if (ret)  		return ret; -	if (val == 1) { -		get_online_cpus(); -		if (cpu_online(cpu)) -			ret = reload_for_cpu(cpu); -		put_online_cpus(); +	if (val != 1) +		return size; + +	get_online_cpus(); +	mutex_lock(µcode_mutex); +	for_each_online_cpu(cpu) { +		tmp_ret = reload_for_cpu(cpu); +		if (tmp_ret != 0) +			pr_warn("Error reloading microcode on CPU %d\n", cpu); + +		/* save retval of the first encountered reload error */ +		if (!ret) +			ret = tmp_ret;  	} +	if (!ret) +		perf_check_microcode(); +	mutex_unlock(µcode_mutex); +	put_online_cpus();  	if (!ret)  		ret = size; @@ -339,7 +350,6 @@ static DEVICE_ATTR(version, 0400, version_show, NULL);  static DEVICE_ATTR(processor_flags, 0400, pf_show, NULL);  static struct attribute *mc_default_attrs[] = { -	&dev_attr_reload.attr,  	&dev_attr_version.attr,  	&dev_attr_processor_flags.attr,  	NULL @@ -504,7 +514,7 @@ static struct notifier_block __refdata mc_cpu_notifier = {  #ifdef MODULE  /* Autoload on Intel and AMD systems */ -static const struct x86_cpu_id microcode_id[] = { +static const struct x86_cpu_id __initconst microcode_id[] = {  #ifdef CONFIG_MICROCODE_INTEL  	{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, },  #endif @@ -516,6 +526,16 @@ static const struct x86_cpu_id microcode_id[] = {  MODULE_DEVICE_TABLE(x86cpu, microcode_id);  #endif +static struct attribute *cpu_root_microcode_attrs[] = { +	&dev_attr_reload.attr, +	NULL +}; + +static struct attribute_group cpu_root_microcode_group = { +	.name  = "microcode", +	.attrs = cpu_root_microcode_attrs, +}; +  static int __init microcode_init(void)  {  	struct cpuinfo_x86 *c = &cpu_data(0); @@ -540,16 +560,25 @@ static int __init microcode_init(void)  	mutex_lock(µcode_mutex);  	error = subsys_interface_register(&mc_cpu_interface); - +	if (!error) +		perf_check_microcode();  	mutex_unlock(µcode_mutex);  	put_online_cpus();  	if (error)  		goto out_pdev; +	error = sysfs_create_group(&cpu_subsys.dev_root->kobj, +				   &cpu_root_microcode_group); + +	if (error) { +		pr_err("Error creating microcode group!\n"); +		goto out_driver; +	} +  	error = microcode_dev_init();  	if (error) -		goto out_driver; +		goto out_ucode_group;  	register_syscore_ops(&mc_syscore_ops);  	register_hotcpu_notifier(&mc_cpu_notifier); @@ -559,7 +588,11 @@ static int __init microcode_init(void)  	return 0; -out_driver: + out_ucode_group: +	sysfs_remove_group(&cpu_subsys.dev_root->kobj, +			   &cpu_root_microcode_group); + + out_driver:  	get_online_cpus();  	mutex_lock(µcode_mutex); @@ -568,7 +601,7 @@ out_driver:  	mutex_unlock(µcode_mutex);  	put_online_cpus(); -out_pdev: + out_pdev:  	platform_device_unregister(microcode_pdev);  	return error; @@ -584,6 +617,9 @@ static void __exit microcode_exit(void)  	unregister_hotcpu_notifier(&mc_cpu_notifier);  	unregister_syscore_ops(&mc_syscore_ops); +	sysfs_remove_group(&cpu_subsys.dev_root->kobj, +			   &cpu_root_microcode_group); +  	get_online_cpus();  	mutex_lock(µcode_mutex);  | 
