[kernel] r19164 - in dists/sid/linux/debian: . patches patches/bugfix/all patches/features/all patches/features/all/cpu-devices
Ben Hutchings
benh at alioth.debian.org
Mon Jun 18 05:14:27 UTC 2012
Author: benh
Date: Mon Jun 18 05:14:25 2012
New Revision: 19164
Log:
CPU sysdev removal from 3.3 and x86 CPU auto-loading from 3.4
* cpu: Convert 'cpu' and 'machinecheck' sysdev_class to a regular subsystem
* [x86] Add driver auto probing for x86 features
- crypto: Add support for x86 cpuid auto loading for x86 crypto drivers
(Closes: #568008)
- intel-idle: convert to x86_cpu_id auto probing
- HWMON: Convert coretemp to x86 cpuid autoprobing
- HWMON: Convert via-cputemp to x86 cpuid autoprobing
- cpufreq: Add support for x86 cpuinfo auto loading (Closes: #664813)
* [x86] ACPI: Load acpi-cpufreq from processor driver automatically
Added:
dists/sid/linux/debian/patches/features/all/cpu-devices/
dists/sid/linux/debian/patches/features/all/cpu-devices/ACPI-Load-acpi-cpufreq-from-processor-driver-automat.patch
dists/sid/linux/debian/patches/features/all/cpu-devices/Add-driver-auto-probing-for-x86-features-v4.patch
dists/sid/linux/debian/patches/features/all/cpu-devices/CPU-Introduce-ARCH_HAS_CPU_AUTOPROBE-and-X86-parts.patch
dists/sid/linux/debian/patches/features/all/cpu-devices/HWMON-Convert-coretemp-to-x86-cpuid-autoprobing.patch
dists/sid/linux/debian/patches/features/all/cpu-devices/HWMON-Convert-via-cputemp-to-x86-cpuid-autoprobing.patch
dists/sid/linux/debian/patches/features/all/cpu-devices/Partially-revert-cpufreq-Add-support-for-x86-cpuinfo.patch
dists/sid/linux/debian/patches/features/all/cpu-devices/X86-Introduce-HW-Pstate-scattered-cpuid-feature.patch
dists/sid/linux/debian/patches/features/all/cpu-devices/cpu-Do-not-return-errors-from-cpu_dev_init-which-wil.patch
dists/sid/linux/debian/patches/features/all/cpu-devices/cpu-Register-a-generic-CPU-device-on-architectures-t.patch
dists/sid/linux/debian/patches/features/all/cpu-devices/cpu-convert-cpu-and-machinecheck-sysdev_class-to-a-r.patch
dists/sid/linux/debian/patches/features/all/cpu-devices/cpufreq-Add-support-for-x86-cpuinfo-auto-loading-v4.patch
dists/sid/linux/debian/patches/features/all/cpu-devices/crypto-Add-support-for-x86-cpuid-auto-loading-for-x8.patch
dists/sid/linux/debian/patches/features/all/cpu-devices/driver-core-cpu-fix-kobject-warning-when-hotplugging.patch
dists/sid/linux/debian/patches/features/all/cpu-devices/driver-core-cpu-remove-kernel-warning-when-removing-.patch
dists/sid/linux/debian/patches/features/all/cpu-devices/driver-core-implement-sysdev-functionality-for-regul.patch
dists/sid/linux/debian/patches/features/all/cpu-devices/intel-idle-convert-to-x86_cpu_id-auto-probing.patch
dists/sid/linux/debian/patches/features/all/cpu-devices/intel_idle-Fix-ID-for-Nehalem-EX-Xeon-in-device-ID-t.patch
dists/sid/linux/debian/patches/features/all/cpu-devices/intel_idle-Revert-change-of-auto_demotion_disable_fl.patch
dists/sid/linux/debian/patches/features/all/cpu-devices/powernow-k6-Really-enable-auto-loading.patch
dists/sid/linux/debian/patches/features/all/cpu-devices/powernow-k7-Fix-CPU-family-number.patch
dists/sid/linux/debian/patches/features/all/cpu-devices/topology-Provide-CPU-topology-in-sysfs-in-SMP-configura.patch
dists/sid/linux/debian/patches/features/all/cpu-devices/x86-cpu-Clean-up-modalias-feature-matching.patch
dists/sid/linux/debian/patches/features/all/cpu-devices/x86-cpu-Fix-overrun-check-in-arch_print_cpu_modalias.patch
Deleted:
dists/sid/linux/debian/patches/bugfix/all/cpu-Do-not-return-errors-from-cpu_dev_init-which-wil.patch
dists/sid/linux/debian/patches/bugfix/all/cpu-Register-a-generic-CPU-device-on-architectures-t.patch
dists/sid/linux/debian/patches/features/all/topology-Provide-CPU-topology-in-sysfs-in-SMP-configura.patch
Modified:
dists/sid/linux/debian/changelog
dists/sid/linux/debian/patches/series
Modified: dists/sid/linux/debian/changelog
==============================================================================
--- dists/sid/linux/debian/changelog Sun Jun 17 19:52:06 2012 (r19163)
+++ dists/sid/linux/debian/changelog Mon Jun 18 05:14:25 2012 (r19164)
@@ -6,7 +6,16 @@
* [arm,m68k,sh4] udeb: Build ipv6-modules
* ethtool: allow ETHTOOL_GSSET_INFO for users
* [rt] bump version to 3.2.20-rt32
-
+ * cpu: Convert 'cpu' and 'machinecheck' sysdev_class to a regular subsystem
+ * [x86] Add driver auto probing for x86 features
+ - crypto: Add support for x86 cpuid auto loading for x86 crypto drivers
+ (Closes: #568008)
+ - intel-idle: convert to x86_cpu_id auto probing
+ - HWMON: Convert coretemp to x86 cpuid autoprobing
+ - HWMON: Convert via-cputemp to x86 cpuid autoprobing
+ - cpufreq: Add support for x86 cpuinfo auto loading (Closes: #664813)
+ * [x86] ACPI: Load acpi-cpufreq from processor driver automatically
+
[ Aurelien Jarno ]
* [mips,mipsel] udeb: Remove rivafb and nvidiafb.
* [ppc64]: add udebs, based on powerpc/powerpc64.
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/ACPI-Load-acpi-cpufreq-from-processor-driver-automat.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/ACPI-Load-acpi-cpufreq-from-processor-driver-automat.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,81 @@
+From: Andi Kleen <ak at linux.intel.com>
+Date: Thu, 26 Jan 2012 00:09:08 +0100
+Subject: ACPI: Load acpi-cpufreq from processor driver automatically
+
+commit 9061e0e16700ef228837e96987ff51794c956197 upstream.
+
+The only left over hole in automatic cpufreq driver loading was the loading
+of ACPI cpufreq. This driver should be loaded when ACPI supports a _PDC
+method and the CPU vendor wants to use acpi cpufreq.
+
+Simply add a request module call to the acpi processor core driver
+when this is true. This seems like the simplest solution for this.
+
+Cc: Len Brown <lenb at kernel.org>
+Signed-off-by: Andi Kleen <ak at linux.intel.com>
+Signed-off-by: Thomas Renninger <trenn at suse.de>
+Acked-by: H. Peter Anvin <hpa at zytor.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+---
+ drivers/acpi/processor_driver.c | 1 +
+ drivers/acpi/processor_perflib.c | 22 ++++++++++++++++++++++
+ include/acpi/processor.h | 1 +
+ 3 files changed, 24 insertions(+)
+
+diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
+index 0034ede..e6920d0 100644
+--- a/drivers/acpi/processor_driver.c
++++ b/drivers/acpi/processor_driver.c
+@@ -497,6 +497,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
+
+ #ifdef CONFIG_CPU_FREQ
+ acpi_processor_ppc_has_changed(pr, 0);
++ acpi_processor_load_module(pr);
+ #endif
+ acpi_processor_get_throttling_info(pr);
+ acpi_processor_get_limit_info(pr);
+diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
+index 85b3237..0af48a8 100644
+--- a/drivers/acpi/processor_perflib.c
++++ b/drivers/acpi/processor_perflib.c
+@@ -240,6 +240,28 @@ void acpi_processor_ppc_exit(void)
+ acpi_processor_ppc_status &= ~PPC_REGISTERED;
+ }
+
++/*
++ * Do a quick check if the systems looks like it should use ACPI
++ * cpufreq. We look at a _PCT method being available, but don't
++ * do a whole lot of sanity checks.
++ */
++void acpi_processor_load_module(struct acpi_processor *pr)
++{
++ static int requested;
++ acpi_status status = 0;
++ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
++
++ if (!arch_has_acpi_pdc() || requested)
++ return;
++ status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer);
++ if (!ACPI_FAILURE(status)) {
++ printk(KERN_INFO PREFIX "Requesting acpi_cpufreq\n");
++ request_module_nowait("acpi_cpufreq");
++ requested = 1;
++ }
++ kfree(buffer.pointer);
++}
++
+ static int acpi_processor_get_performance_control(struct acpi_processor *pr)
+ {
+ int result = 0;
+diff --git a/include/acpi/processor.h b/include/acpi/processor.h
+index 610f6fb..da57fdc 100644
+--- a/include/acpi/processor.h
++++ b/include/acpi/processor.h
+@@ -224,6 +224,7 @@ struct acpi_processor_errata {
+ } piix4;
+ };
+
++extern void acpi_processor_load_module(struct acpi_processor *pr);
+ extern int acpi_processor_preregister_performance(struct
+ acpi_processor_performance
+ __percpu *performance);
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/Add-driver-auto-probing-for-x86-features-v4.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/Add-driver-auto-probing-for-x86-features-v4.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,313 @@
+From: Andi Kleen <ak at linux.intel.com>
+Date: Thu, 26 Jan 2012 00:09:05 +0100
+Subject: Add driver auto probing for x86 features v4
+
+commit 644e9cbbe3fc032cc92d0936057e166a994dc246 upstream.
+
+There's a growing number of drivers that support a specific x86 feature
+or CPU. Currently loading these drivers currently on a generic
+distribution requires various driver specific hacks and it often
+doesn't work.
+
+This patch adds auto probing for drivers based on the x86 cpuid
+information, in particular based on vendor/family/model number
+and also based on CPUID feature bits.
+
+For example a common issue is not loading the SSE 4.2 accelerated
+CRC module: this can significantly lower the performance of BTRFS
+which relies on fast CRC.
+
+Another issue is loading the right CPUFREQ driver for the current CPU.
+Currently distributions often try all all possible driver until
+one sticks, which is not really a good way to do this.
+
+It works with existing udev without any changes. The code
+exports the x86 information as a generic string in sysfs
+that can be matched by udev's pattern matching.
+
+This scheme does not support numeric ranges, so if you want to
+handle e.g. ranges of model numbers they have to be encoded
+in ASCII or simply all models or families listed. Fixing
+that would require changing udev.
+
+Another issue is that udev will happily load all drivers that match,
+there is currently no nice way to stop a specific driver from
+being loaded if it's not needed (e.g. if you don't need fast CRC)
+But there are not that many cpu specific drivers around and they're
+all not that bloated, so this isn't a particularly serious issue.
+
+Originally this patch added the modalias to the normal cpu
+sysdevs. However sysdevs don't have all the infrastructure
+needed for udev, so it couldn't really autoload drivers.
+This patch instead adds the CPU modaliases to the cpuid devices,
+which are real devices with full support for udev. This implies
+that the cpuid driver has to be loaded to use this.
+
+This patch just adds infrastructure, some driver conversions
+in followups.
+
+Thanks to Kay for helping with some sysfs magic.
+
+v2: Constifcation, some updates
+v4: (trenn at suse.de):
+ - Use kzalloc instead of kmalloc to terminate modalias buffer
+ - Use uppercase hex values to match correctly against hex values containing
+ letters
+
+Cc: Dave Jones <davej at redhat.com>
+Cc: Kay Sievers <kay.sievers at vrfy.org>
+Cc: Jen Axboe <axboe at kernel.dk>
+Cc: Herbert Xu <herbert at gondor.apana.org.au>
+Cc: Huang Ying <ying.huang at intel.com>
+Cc: Len Brown <lenb at kernel.org>
+Signed-off-by: Andi Kleen <ak at linux.intel.com>
+Signed-off-by: Thomas Renninger <trenn at suse.de>
+Acked-by: H. Peter Anvin <hpa at zytor.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+[bwh: Backported to 3.2:
+ - adjust context
+ - make do without ADD_TO_DEVTABLE in file2alias]
+---
+--- /dev/null
++++ b/arch/x86/include/asm/cpu_device_id.h
+@@ -0,0 +1,13 @@
++#ifndef _CPU_DEVICE_ID
++#define _CPU_DEVICE_ID 1
++
++/*
++ * Declare drivers belonging to specific x86 CPUs
++ * Similar in spirit to pci_device_id and related PCI functions
++ */
++
++#include <linux/mod_devicetable.h>
++
++extern const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match);
++
++#endif
+--- a/arch/x86/kernel/cpu/Makefile
++++ b/arch/x86/kernel/cpu/Makefile
+@@ -16,6 +16,7 @@
+ obj-y += proc.o capflags.o powerflags.o common.o
+ obj-y += vmware.o hypervisor.o sched.o mshyperv.o
+ obj-y += rdrand.o
++obj-y += match.o
+
+ obj-$(CONFIG_X86_32) += bugs.o
+ obj-$(CONFIG_X86_64) += bugs_64.o
+--- /dev/null
++++ b/arch/x86/kernel/cpu/match.c
+@@ -0,0 +1,48 @@
++#include <asm/cpu_device_id.h>
++#include <asm/processor.h>
++#include <linux/cpu.h>
++#include <linux/module.h>
++
++/**
++ * x86_match_cpu - match current CPU again an array of x86_cpu_ids
++ * @match: Pointer to array of x86_cpu_ids. Last entry terminated with
++ * {}.
++ *
++ * Return the entry if the current CPU matches the entries in the
++ * passed x86_cpu_id match table. Otherwise NULL. The match table
++ * contains vendor (X86_VENDOR_*), family, model and feature bits or
++ * respective wildcard entries.
++ *
++ * A typical table entry would be to match a specific CPU
++ * { X86_VENDOR_INTEL, 6, 0x12 }
++ * or to match a specific CPU feature
++ * { X86_FEATURE_MATCH(X86_FEATURE_FOOBAR) }
++ *
++ * Fields can be wildcarded with %X86_VENDOR_ANY, %X86_FAMILY_ANY,
++ * %X86_MODEL_ANY, %X86_FEATURE_ANY or 0 (except for vendor)
++ *
++ * Arrays used to match for this should also be declared using
++ * MODULE_DEVICE_TABLE(x86_cpu, ...)
++ *
++ * This always matches against the boot cpu, assuming models and features are
++ * consistent over all CPUs.
++ */
++const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match)
++{
++ const struct x86_cpu_id *m;
++ struct cpuinfo_x86 *c = &boot_cpu_data;
++
++ for (m = match; m->vendor | m->family | m->model | m->feature; m++) {
++ if (m->vendor != X86_VENDOR_ANY && c->x86_vendor != m->vendor)
++ continue;
++ if (m->family != X86_FAMILY_ANY && c->x86 != m->family)
++ continue;
++ if (m->model != X86_MODEL_ANY && c->x86_model != m->model)
++ continue;
++ if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature))
++ continue;
++ return m;
++ }
++ return NULL;
++}
++EXPORT_SYMBOL(x86_match_cpu);
+--- a/arch/x86/kernel/cpuid.c
++++ b/arch/x86/kernel/cpuid.c
+@@ -40,6 +40,7 @@
+ #include <linux/notifier.h>
+ #include <linux/uaccess.h>
+ #include <linux/gfp.h>
++#include <linux/slab.h>
+
+ #include <asm/processor.h>
+ #include <asm/msr.h>
+@@ -138,13 +139,57 @@
+ .open = cpuid_open,
+ };
+
++static ssize_t print_cpu_modalias(struct device *dev,
++ struct device_attribute *attr,
++ char *bufptr)
++{
++ int size = PAGE_SIZE;
++ int i, n;
++ char *buf = bufptr;
++
++ n = snprintf(buf, size, "x86cpu:vendor:%04X:family:"
++ "%04X:model:%04X:feature:",
++ boot_cpu_data.x86_vendor,
++ boot_cpu_data.x86,
++ boot_cpu_data.x86_model);
++ size -= n;
++ buf += n;
++ size -= 2;
++ for (i = 0; i < NCAPINTS*32; i++) {
++ if (boot_cpu_has(i)) {
++ n = snprintf(buf, size, ",%04X", i);
++ if (n < 0) {
++ WARN(1, "x86 features overflow page\n");
++ break;
++ }
++ size -= n;
++ buf += n;
++ }
++ }
++ *buf++ = ',';
++ *buf++ = '\n';
++ return buf - bufptr;
++}
++
++static DEVICE_ATTR(modalias, 0444, print_cpu_modalias, NULL);
++
+ static __cpuinit int cpuid_device_create(int cpu)
+ {
+ struct device *dev;
++ int err;
+
+ dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu), NULL,
+ "cpu%d", cpu);
+- return IS_ERR(dev) ? PTR_ERR(dev) : 0;
++ if (IS_ERR(dev))
++ return PTR_ERR(dev);
++
++ err = device_create_file(dev, &dev_attr_modalias);
++ if (err) {
++ /* keep device around on error. attribute is optional. */
++ err = 0;
++ }
++
++ return 0;
+ }
+
+ static void cpuid_device_destroy(int cpu)
+@@ -182,6 +227,17 @@
+ return kasprintf(GFP_KERNEL, "cpu/%u/cpuid", MINOR(dev->devt));
+ }
+
++static int cpuid_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
++{
++ char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
++ if (buf) {
++ print_cpu_modalias(NULL, NULL, buf);
++ add_uevent_var(env, "MODALIAS=%s", buf);
++ kfree(buf);
++ }
++ return 0;
++}
++
+ static int __init cpuid_init(void)
+ {
+ int i, err = 0;
+@@ -200,6 +256,7 @@
+ goto out_chrdev;
+ }
+ cpuid_class->devnode = cpuid_devnode;
++ cpuid_class->dev_uevent = cpuid_dev_uevent;
+ for_each_online_cpu(i) {
+ err = cpuid_device_create(i);
+ if (err != 0)
+--- a/include/linux/mod_devicetable.h
++++ b/include/linux/mod_devicetable.h
+@@ -542,4 +542,25 @@
+ kernel_ulong_t driver_data; /* data private to the driver */
+ };
+
++/*
++ * Match x86 CPUs for CPU specific drivers.
++ * See documentation of "x86_match_cpu" for details.
++ */
++
++struct x86_cpu_id {
++ __u16 vendor;
++ __u16 family;
++ __u16 model;
++ __u16 feature; /* bit index */
++ kernel_ulong_t driver_data;
++};
++
++#define X86_FEATURE_MATCH(x) \
++ { X86_VENDOR_ANY, X86_FAMILY_ANY, X86_MODEL_ANY, x }
++
++#define X86_VENDOR_ANY 0xffff
++#define X86_FAMILY_ANY 0
++#define X86_MODEL_ANY 0
++#define X86_FEATURE_ANY 0 /* Same as FPU, you can't test for that */
++
+ #endif /* LINUX_MOD_DEVICETABLE_H */
+--- a/scripts/mod/file2alias.c
++++ b/scripts/mod/file2alias.c
+@@ -880,6 +880,29 @@
+ return 1;
+ }
+
++/* LOOKS like x86cpu:vendor:VVVV:family:FFFF:model:MMMM:feature:*,FEAT,*
++ * All fields are numbers. It would be nicer to use strings for vendor
++ * and feature, but getting those out of the build system here is too
++ * complicated.
++ */
++
++static int do_x86cpu_entry(const char *filename, struct x86_cpu_id *id,
++ char *alias)
++{
++ id->feature = TO_NATIVE(id->feature);
++ id->family = TO_NATIVE(id->family);
++ id->model = TO_NATIVE(id->model);
++ id->vendor = TO_NATIVE(id->vendor);
++
++ strcpy(alias, "x86cpu:");
++ ADD(alias, "vendor:", id->vendor != X86_VENDOR_ANY, id->vendor);
++ ADD(alias, ":family:", id->family != X86_FAMILY_ANY, id->family);
++ ADD(alias, ":model:", id->model != X86_MODEL_ANY, id->model);
++ ADD(alias, ":feature:*,", id->feature != X86_FEATURE_ANY, id->feature);
++ strcat(alias, ",*");
++ return 1;
++}
++
+ /* Ignore any prefix, eg. some architectures prepend _ */
+ static inline int sym_is(const char *symbol, const char *name)
+ {
+@@ -1051,6 +1074,10 @@
+ do_table(symval, sym->st_size,
+ sizeof(struct isapnp_device_id), "isa",
+ do_isapnp_entry, mod);
++ else if (sym_is(symname, "__mod_x86cpu_device_table"))
++ do_table(symval, sym->st_size,
++ sizeof(struct x86_cpu_id), "x86cpu",
++ do_x86cpu_entry, mod);
+ free(zeros);
+ }
+
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/CPU-Introduce-ARCH_HAS_CPU_AUTOPROBE-and-X86-parts.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/CPU-Introduce-ARCH_HAS_CPU_AUTOPROBE-and-X86-parts.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,266 @@
+From: Thomas Renninger <trenn at suse.de>
+Date: Thu, 26 Jan 2012 00:09:14 +0100
+Subject: CPU: Introduce ARCH_HAS_CPU_AUTOPROBE and X86 parts
+
+commit fad12ac8c8c2591c7f4e61d19b6a9d76cd49fafa upstream.
+
+This patch is based on Andi Kleen's work:
+Implement autoprobing/loading of modules serving CPU
+specific features (x86cpu autoloading).
+
+And Kay Siever's work to get rid of sysdev cpu structures
+and making use of struct device instead.
+
+Before, the cpuid driver had to be loaded to get the x86cpu
+autoloading feature. With this patch autoloading works through
+the /sys/devices/system/cpu object
+
+Cc: Kay Sievers <kay.sievers at vrfy.org>
+Cc: Dave Jones <davej at redhat.com>
+Cc: Jens Axboe <axboe at kernel.dk>
+Cc: Herbert Xu <herbert at gondor.apana.org.au>
+Cc: Huang Ying <ying.huang at intel.com>
+Cc: Len Brown <lenb at kernel.org>
+Acked-by: Andi Kleen <ak at linux.intel.com>
+Signed-off-by: Thomas Renninger <trenn at suse.de>
+Acked-by: H. Peter Anvin <hpa at zytor.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+---
+ arch/x86/Kconfig | 3 +++
+ arch/x86/kernel/cpu/match.c | 44 ++++++++++++++++++++++++++++++++
+ arch/x86/kernel/cpuid.c | 59 +------------------------------------------
+ drivers/base/cpu.c | 11 ++++++++
+ include/linux/cpu.h | 7 +++++
+ 5 files changed, 66 insertions(+), 58 deletions(-)
+
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index 864cc6e..6baa1e6 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -179,6 +179,9 @@ config ARCH_HAS_DEFAULT_IDLE
+ config ARCH_HAS_CACHE_LINE_SIZE
+ def_bool y
+
++config ARCH_HAS_CPU_AUTOPROBE
++ def_bool y
++
+ config HAVE_SETUP_PER_CPU_AREA
+ def_bool y
+
+diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c
+index 7acc961..940e2d4 100644
+--- a/arch/x86/kernel/cpu/match.c
++++ b/arch/x86/kernel/cpu/match.c
+@@ -2,6 +2,7 @@
+ #include <asm/processor.h>
+ #include <linux/cpu.h>
+ #include <linux/module.h>
++#include <linux/slab.h>
+
+ /**
+ * x86_match_cpu - match current CPU again an array of x86_cpu_ids
+@@ -46,3 +47,46 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match)
+ return NULL;
+ }
+ EXPORT_SYMBOL(x86_match_cpu);
++
++ssize_t arch_print_cpu_modalias(struct device *dev,
++ struct device_attribute *attr,
++ char *bufptr)
++{
++ int size = PAGE_SIZE;
++ int i, n;
++ char *buf = bufptr;
++
++ n = snprintf(buf, size, "x86cpu:vendor:%04X:family:%04X:"
++ "model:%04X:feature:",
++ boot_cpu_data.x86_vendor,
++ boot_cpu_data.x86,
++ boot_cpu_data.x86_model);
++ size -= n;
++ buf += n;
++ size -= 2;
++ for (i = 0; i < NCAPINTS*32; i++) {
++ if (boot_cpu_has(i)) {
++ n = snprintf(buf, size, ",%04X", i);
++ if (n < 0) {
++ WARN(1, "x86 features overflow page\n");
++ break;
++ }
++ size -= n;
++ buf += n;
++ }
++ }
++ *buf++ = ',';
++ *buf++ = '\n';
++ return buf - bufptr;
++}
++
++int arch_cpu_uevent(struct device *dev, struct kobj_uevent_env *env)
++{
++ char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
++ if (buf) {
++ arch_print_cpu_modalias(NULL, NULL, buf);
++ add_uevent_var(env, "MODALIAS=%s", buf);
++ kfree(buf);
++ }
++ return 0;
++}
+diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c
+index 7c89880..a524353 100644
+--- a/arch/x86/kernel/cpuid.c
++++ b/arch/x86/kernel/cpuid.c
+@@ -40,7 +40,6 @@
+ #include <linux/notifier.h>
+ #include <linux/uaccess.h>
+ #include <linux/gfp.h>
+-#include <linux/slab.h>
+
+ #include <asm/processor.h>
+ #include <asm/msr.h>
+@@ -139,57 +138,13 @@ static const struct file_operations cpuid_fops = {
+ .open = cpuid_open,
+ };
+
+-static ssize_t print_cpu_modalias(struct device *dev,
+- struct device_attribute *attr,
+- char *bufptr)
+-{
+- int size = PAGE_SIZE;
+- int i, n;
+- char *buf = bufptr;
+-
+- n = snprintf(buf, size, "x86cpu:vendor:%04X:family:"
+- "%04X:model:%04X:feature:",
+- boot_cpu_data.x86_vendor,
+- boot_cpu_data.x86,
+- boot_cpu_data.x86_model);
+- size -= n;
+- buf += n;
+- size -= 2;
+- for (i = 0; i < NCAPINTS*32; i++) {
+- if (boot_cpu_has(i)) {
+- n = snprintf(buf, size, ",%04X", i);
+- if (n < 0) {
+- WARN(1, "x86 features overflow page\n");
+- break;
+- }
+- size -= n;
+- buf += n;
+- }
+- }
+- *buf++ = ',';
+- *buf++ = '\n';
+- return buf - bufptr;
+-}
+-
+-static DEVICE_ATTR(modalias, 0444, print_cpu_modalias, NULL);
+-
+ static __cpuinit int cpuid_device_create(int cpu)
+ {
+ struct device *dev;
+- int err;
+
+ dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu), NULL,
+ "cpu%d", cpu);
+- if (IS_ERR(dev))
+- return PTR_ERR(dev);
+-
+- err = device_create_file(dev, &dev_attr_modalias);
+- if (err) {
+- /* keep device around on error. attribute is optional. */
+- err = 0;
+- }
+-
+- return 0;
++ return IS_ERR(dev) ? PTR_ERR(dev) : 0;
+ }
+
+ static void cpuid_device_destroy(int cpu)
+@@ -227,17 +182,6 @@ static char *cpuid_devnode(struct device *dev, umode_t *mode)
+ return kasprintf(GFP_KERNEL, "cpu/%u/cpuid", MINOR(dev->devt));
+ }
+
+-static int cpuid_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
+-{
+- char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+- if (buf) {
+- print_cpu_modalias(NULL, NULL, buf);
+- add_uevent_var(env, "MODALIAS=%s", buf);
+- kfree(buf);
+- }
+- return 0;
+-}
+-
+ static int __init cpuid_init(void)
+ {
+ int i, err = 0;
+@@ -256,7 +200,6 @@ static int __init cpuid_init(void)
+ goto out_chrdev;
+ }
+ cpuid_class->devnode = cpuid_devnode;
+- cpuid_class->dev_uevent = cpuid_dev_uevent;
+ for_each_online_cpu(i) {
+ err = cpuid_device_create(i);
+ if (err != 0)
+diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
+index db87e78..2a0c670 100644
+--- a/drivers/base/cpu.c
++++ b/drivers/base/cpu.c
+@@ -11,6 +11,7 @@
+ #include <linux/device.h>
+ #include <linux/node.h>
+ #include <linux/gfp.h>
++#include <linux/slab.h>
+ #include <linux/percpu.h>
+
+ #include "base.h"
+@@ -223,6 +224,9 @@ int __cpuinit register_cpu(struct cpu *cpu, int num)
+ cpu->node_id = cpu_to_node(num);
+ cpu->dev.id = num;
+ cpu->dev.bus = &cpu_subsys;
++#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
++ cpu->dev.bus->uevent = arch_cpu_uevent;
++#endif
+ error = device_register(&cpu->dev);
+ if (!error && cpu->hotpluggable)
+ register_cpu_control(cpu);
+@@ -247,6 +251,10 @@ struct device *get_cpu_device(unsigned cpu)
+ }
+ EXPORT_SYMBOL_GPL(get_cpu_device);
+
++#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
++static DEVICE_ATTR(modalias, 0444, arch_print_cpu_modalias, NULL);
++#endif
++
+ static struct attribute *cpu_root_attrs[] = {
+ #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
+ &dev_attr_probe.attr,
+@@ -257,6 +265,9 @@ static struct attribute *cpu_root_attrs[] = {
+ &cpu_attrs[2].attr.attr,
+ &dev_attr_kernel_max.attr,
+ &dev_attr_offline.attr,
++#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
++ &dev_attr_modalias.attr,
++#endif
+ NULL
+ };
+
+diff --git a/include/linux/cpu.h b/include/linux/cpu.h
+index 1f65875..6e53b48 100644
+--- a/include/linux/cpu.h
++++ b/include/linux/cpu.h
+@@ -44,6 +44,13 @@ extern ssize_t arch_cpu_release(const char *, size_t);
+ #endif
+ struct notifier_block;
+
++#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
++extern int arch_cpu_uevent(struct device *dev, struct kobj_uevent_env *env);
++extern ssize_t arch_print_cpu_modalias(struct device *dev,
++ struct device_attribute *attr,
++ char *bufptr);
++#endif
++
+ /*
+ * CPU notifier priorities.
+ */
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/HWMON-Convert-coretemp-to-x86-cpuid-autoprobing.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/HWMON-Convert-coretemp-to-x86-cpuid-autoprobing.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,59 @@
+From: Andi Kleen <ak at linux.intel.com>
+Date: Thu, 26 Jan 2012 00:09:10 +0100
+Subject: HWMON: Convert coretemp to x86 cpuid autoprobing
+
+commit 9b38096fde5f9b93c3657911c3be7892cc155cbd upstream.
+
+Use the new x86 cpuid autoprobe interface for the Intel coretemp
+driver.
+
+Cc: Fenghua Yu <fenghua.yu at intel.com>
+Cc: Jean Delvare <khali at linux-fr.org>
+Cc: Guenter Roeck <guenter.roeck at ericsson.com>
+Signed-off-by: Andi Kleen <ak at linux.intel.com>
+Signed-off-by: Thomas Renninger <trenn at suse.de>
+Acked-by: H. Peter Anvin <hpa at zytor.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+---
+ drivers/hwmon/coretemp.c | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
+index a6c6ec3..249ac46 100644
+--- a/drivers/hwmon/coretemp.c
++++ b/drivers/hwmon/coretemp.c
+@@ -39,6 +39,7 @@
+ #include <linux/moduleparam.h>
+ #include <asm/msr.h>
+ #include <asm/processor.h>
++#include <asm/cpu_device_id.h>
+
+ #define DRVNAME "coretemp"
+
+@@ -759,13 +760,23 @@ static struct notifier_block coretemp_cpu_notifier __refdata = {
+ .notifier_call = coretemp_cpu_callback,
+ };
+
++static const struct x86_cpu_id coretemp_ids[] = {
++ { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTS },
++ {}
++};
++MODULE_DEVICE_TABLE(x86cpu, coretemp_ids);
++
+ static int __init coretemp_init(void)
+ {
+ int i, err = -ENODEV;
+
+- /* quick check if we run Intel */
+- if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL)
+- goto exit;
++ /*
++ * CPUID.06H.EAX[0] indicates whether the CPU has thermal
++ * sensors. We check this bit only, all the early CPUs
++ * without thermal sensors will be filtered out.
++ */
++ if (!x86_match_cpu(coretemp_ids))
++ return -ENODEV;
+
+ err = platform_driver_register(&coretemp_driver);
+ if (err)
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/HWMON-Convert-via-cputemp-to-x86-cpuid-autoprobing.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/HWMON-Convert-via-cputemp-to-x86-cpuid-autoprobing.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,56 @@
+From: Andi Kleen <ak at linux.intel.com>
+Date: Thu, 26 Jan 2012 00:09:09 +0100
+Subject: HWMON: Convert via-cputemp to x86 cpuid autoprobing
+
+commit 267fc9788d0cdb77edafb506063f06961e1418f5 upstream.
+
+Use the new x86 cpuid autoprobe interface.
+
+Cc: Jean Delvare <khali at linux-fr.org>
+Cc: Guenter Roeck <guenter.roeck at ericsson.com>
+Signed-off-by: Andi Kleen <ak at linux.intel.com>
+Signed-off-by: Thomas Renninger <trenn at suse.de>
+Acked-by: H. Peter Anvin <hpa at zytor.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+---
+ drivers/hwmon/via-cputemp.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c
+index 8eac67d..8689664 100644
+--- a/drivers/hwmon/via-cputemp.c
++++ b/drivers/hwmon/via-cputemp.c
+@@ -37,6 +37,7 @@
+ #include <linux/cpu.h>
+ #include <asm/msr.h>
+ #include <asm/processor.h>
++#include <asm/cpu_device_id.h>
+
+ #define DRVNAME "via_cputemp"
+
+@@ -308,15 +309,20 @@ static struct notifier_block via_cputemp_cpu_notifier __refdata = {
+ .notifier_call = via_cputemp_cpu_callback,
+ };
+
++static const struct x86_cpu_id cputemp_ids[] = {
++ { X86_VENDOR_CENTAUR, 6, 0xa, }, /* C7 A */
++ { X86_VENDOR_CENTAUR, 6, 0xd, }, /* C7 D */
++ { X86_VENDOR_CENTAUR, 6, 0xf, }, /* Nano */
++ {}
++};
++MODULE_DEVICE_TABLE(x86cpu, cputemp_ids);
++
+ static int __init via_cputemp_init(void)
+ {
+ int i, err;
+
+- if (cpu_data(0).x86_vendor != X86_VENDOR_CENTAUR) {
+- printk(KERN_DEBUG DRVNAME ": Not a VIA CPU\n");
+- err = -ENODEV;
+- goto exit;
+- }
++ if (!x86_match_cpu(cputemp_ids))
++ return -ENODEV;
+
+ err = platform_driver_register(&via_cputemp_driver);
+ if (err)
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/Partially-revert-cpufreq-Add-support-for-x86-cpuinfo.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/Partially-revert-cpufreq-Add-support-for-x86-cpuinfo.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,55 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Mon, 18 Jun 2012 02:56:40 +0100
+Subject: Partially revert "cpufreq: Add support for x86 cpuinfo auto loading
+ v4"
+
+This reverts commit fa8031aefec0cf7ea6c2387c93610d99d9659aa2 in
+drivers/cpufreq/e_powersaver.c only.
+
+e_powersaver may cause the CPU to run too fast on some systems, and is
+therefore unsafe to auto-load.
+---
+ drivers/cpufreq/e_powersaver.c | 20 +++++++++-----------
+ 1 file changed, 9 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c
+index 3fffbe6..4bd6815 100644
+--- a/drivers/cpufreq/e_powersaver.c
++++ b/drivers/cpufreq/e_powersaver.c
+@@ -16,7 +16,6 @@
+ #include <linux/io.h>
+ #include <linux/delay.h>
+
+-#include <asm/cpu_device_id.h>
+ #include <asm/msr.h>
+ #include <asm/tsc.h>
+
+@@ -438,19 +437,18 @@ static struct cpufreq_driver eps_driver = {
+ .attr = eps_attr,
+ };
+
+-
+-/* This driver will work only on Centaur C7 processors with
+- * Enhanced SpeedStep/PowerSaver registers */
+-static const struct x86_cpu_id eps_cpu_id[] = {
+- { X86_VENDOR_CENTAUR, 6, X86_MODEL_ANY, X86_FEATURE_EST },
+- {}
+-};
+-MODULE_DEVICE_TABLE(x86cpu, eps_cpu_id);
+-
+ static int __init eps_init(void)
+ {
+- if (!x86_match_cpu(eps_cpu_id) || boot_cpu_data.x86_model < 10)
++ struct cpuinfo_x86 *c = &cpu_data(0);
++
++ /* This driver will work only on Centaur C7 processors with
++ * Enhanced SpeedStep/PowerSaver registers */
++ if (c->x86_vendor != X86_VENDOR_CENTAUR
++ || c->x86 != 6 || c->x86_model < 10)
++ return -ENODEV;
++ if (!cpu_has(c, X86_FEATURE_EST))
+ return -ENODEV;
++
+ if (cpufreq_register_driver(&eps_driver))
+ return -EINVAL;
+ return 0;
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/X86-Introduce-HW-Pstate-scattered-cpuid-feature.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/X86-Introduce-HW-Pstate-scattered-cpuid-feature.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,48 @@
+From: Thomas Renninger <trenn at suse.de>
+Date: Thu, 26 Jan 2012 00:09:11 +0100
+Subject: X86: Introduce HW-Pstate scattered cpuid feature
+
+commit 2f1e097e24defe64a86535b53768f5c8ab0368d1 upstream.
+
+It is rather similar to CPB (boot capability) feature
+and exists since fam10h (can be looked up in AMD's BKDG).
+
+The feature is needed for powernow-k8 to cleanup init functions and to
+provide proper autoloading matching with the new x86cpu modalias
+feature.
+
+Cc: Kay Sievers <kay.sievers at vrfy.org>
+Cc: Dave Jones <davej at redhat.com>
+Cc: Borislav Petkov <bp at amd64.org>
+Signed-off-by: Thomas Renninger <trenn at suse.de>
+Acked-by: H. Peter Anvin <hpa at zytor.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+---
+ arch/x86/include/asm/cpufeature.h | 1 +
+ arch/x86/kernel/cpu/scattered.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
+index 17c5d4b..67b0910 100644
+--- a/arch/x86/include/asm/cpufeature.h
++++ b/arch/x86/include/asm/cpufeature.h
+@@ -176,6 +176,7 @@
+ #define X86_FEATURE_PLN (7*32+ 5) /* Intel Power Limit Notification */
+ #define X86_FEATURE_PTS (7*32+ 6) /* Intel Package Thermal Status */
+ #define X86_FEATURE_DTS (7*32+ 7) /* Digital Thermal Sensor */
++#define X86_FEATURE_HW_PSTATE (7*32+ 8) /* AMD HW-PState */
+
+ /* Virtualization flags: Linux defined, word 8 */
+ #define X86_FEATURE_TPR_SHADOW (8*32+ 0) /* Intel TPR Shadow */
+diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c
+index c7f64e6..addf9e8 100644
+--- a/arch/x86/kernel/cpu/scattered.c
++++ b/arch/x86/kernel/cpu/scattered.c
+@@ -40,6 +40,7 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
+ { X86_FEATURE_EPB, CR_ECX, 3, 0x00000006, 0 },
+ { X86_FEATURE_XSAVEOPT, CR_EAX, 0, 0x0000000d, 1 },
+ { X86_FEATURE_CPB, CR_EDX, 9, 0x80000007, 0 },
++ { X86_FEATURE_HW_PSTATE, CR_EDX, 7, 0x80000007, 0 },
+ { X86_FEATURE_NPT, CR_EDX, 0, 0x8000000a, 0 },
+ { X86_FEATURE_LBRV, CR_EDX, 1, 0x8000000a, 0 },
+ { X86_FEATURE_SVML, CR_EDX, 2, 0x8000000a, 0 },
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/cpu-Do-not-return-errors-from-cpu_dev_init-which-wil.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/cpu-Do-not-return-errors-from-cpu_dev_init-which-wil.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,63 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Tue, 10 Jan 2012 02:59:49 +0000
+Subject: cpu: Do not return errors from cpu_dev_init() which will be ignored
+
+commit 024f78462c3da710642a54939888a92e28704653 upstream.
+
+cpu_dev_init() is only called from driver_init(), which does not check
+its return value. Therefore make cpu_dev_init() return void.
+
+We must register the CPU subsystem, so panic if this fails.
+
+If sched_create_sysfs_power_savings_entries() fails, the damage is
+contained, so ignore this (as before).
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+---
+ drivers/base/base.h | 2 +-
+ drivers/base/cpu.c | 13 +++++--------
+ 2 files changed, 6 insertions(+), 9 deletions(-)
+
+--- a/drivers/base/base.h
++++ b/drivers/base/base.h
+@@ -94,7 +94,7 @@
+ static inline int hypervisor_init(void) { return 0; }
+ #endif
+ extern int platform_bus_init(void);
+-extern int cpu_dev_init(void);
++extern void cpu_dev_init(void);
+
+ extern int bus_add_device(struct device *dev);
+ extern void bus_probe_device(struct device *dev);
+--- a/drivers/base/cpu.c
++++ b/drivers/base/cpu.c
+@@ -2,6 +2,7 @@
+ * CPU subsystem support
+ */
+
++#include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/sched.h>
+@@ -267,16 +268,12 @@
+ NULL,
+ };
+
+-int __init cpu_dev_init(void)
++void __init cpu_dev_init(void)
+ {
+- int err;
+-
+- err = subsys_system_register(&cpu_subsys, cpu_root_attr_groups);
+- if (err)
+- return err;
++ if (subsys_system_register(&cpu_subsys, cpu_root_attr_groups))
++ panic("Failed to register CPU subsystem");
+
+ #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
+- err = sched_create_sysfs_power_savings_entries(cpu_subsys.dev_root);
++ sched_create_sysfs_power_savings_entries(cpu_subsys.dev_root);
+ #endif
+- return err;
+ }
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/cpu-Register-a-generic-CPU-device-on-architectures-t.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/cpu-Register-a-generic-CPU-device-on-architectures-t.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,163 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Tue, 10 Jan 2012 03:04:32 +0000
+Subject: cpu: Register a generic CPU device on architectures that currently
+ do not
+
+commit 9f13a1fd452f11c18004ba2422a6384b424ec8a9 upstream.
+
+frv, h8300, m68k, microblaze, openrisc, score, um and xtensa currently
+do not register a CPU device. Add the config option GENERIC_CPU_DEVICES
+which causes a generic CPU device to be registered for each present CPU,
+and make all these architectures select it.
+
+Richard Weinberger <richard at nod.at> covered UML and suggested using
+per_cpu.
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+---
+ arch/frv/Kconfig | 1 +
+ arch/h8300/Kconfig | 1 +
+ arch/m68k/Kconfig | 1 +
+ arch/microblaze/Kconfig | 1 +
+ arch/openrisc/Kconfig | 1 +
+ arch/score/Kconfig | 1 +
+ arch/um/Kconfig.common | 1 +
+ arch/xtensa/Kconfig | 1 +
+ drivers/base/Kconfig | 4 ++++
+ drivers/base/cpu.c | 19 +++++++++++++++++++
+ 10 files changed, 31 insertions(+)
+
+--- a/arch/frv/Kconfig
++++ b/arch/frv/Kconfig
+@@ -8,6 +8,7 @@
+ select HAVE_GENERIC_HARDIRQS
+ select GENERIC_IRQ_SHOW
+ select ARCH_HAVE_NMI_SAFE_CMPXCHG
++ select GENERIC_CPU_DEVICES
+
+ config ZONE_DMA
+ bool
+--- a/arch/h8300/Kconfig
++++ b/arch/h8300/Kconfig
+@@ -4,6 +4,7 @@
+ select HAVE_IDE
+ select HAVE_GENERIC_HARDIRQS
+ select GENERIC_IRQ_SHOW
++ select GENERIC_CPU_DEVICES
+
+ config SYMBOL_PREFIX
+ string
+--- a/arch/m68k/Kconfig
++++ b/arch/m68k/Kconfig
+@@ -7,6 +7,7 @@
+ select HAVE_GENERIC_HARDIRQS
+ select GENERIC_IRQ_SHOW
+ select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
++ select GENERIC_CPU_DEVICES
+
+ config RWSEM_GENERIC_SPINLOCK
+ bool
+--- a/arch/microblaze/Kconfig
++++ b/arch/microblaze/Kconfig
+@@ -17,6 +17,7 @@
+ select HAVE_GENERIC_HARDIRQS
+ select GENERIC_IRQ_PROBE
+ select GENERIC_IRQ_SHOW
++ select GENERIC_CPU_DEVICES
+
+ config SWAP
+ def_bool n
+--- a/arch/openrisc/Kconfig
++++ b/arch/openrisc/Kconfig
+@@ -15,6 +15,7 @@
+ select GENERIC_IRQ_PROBE
+ select GENERIC_IRQ_SHOW
+ select GENERIC_IOMAP
++ select GENERIC_CPU_DEVICES
+
+ config MMU
+ def_bool y
+--- a/arch/score/Kconfig
++++ b/arch/score/Kconfig
+@@ -4,6 +4,7 @@
+ def_bool y
+ select HAVE_GENERIC_HARDIRQS
+ select GENERIC_IRQ_SHOW
++ select GENERIC_CPU_DEVICES
+
+ choice
+ prompt "System type"
+--- a/arch/um/Kconfig.common
++++ b/arch/um/Kconfig.common
+@@ -8,6 +8,7 @@
+ default y
+ select HAVE_GENERIC_HARDIRQS
+ select GENERIC_IRQ_SHOW
++ select GENERIC_CPU_DEVICES
+
+ config MMU
+ bool
+--- a/arch/xtensa/Kconfig
++++ b/arch/xtensa/Kconfig
+@@ -9,6 +9,7 @@
+ select HAVE_IDE
+ select HAVE_GENERIC_HARDIRQS
+ select GENERIC_IRQ_SHOW
++ select GENERIC_CPU_DEVICES
+ help
+ Xtensa processors are 32-bit RISC machines designed by Tensilica
+ primarily for embedded systems. These processors are both
+--- a/drivers/base/Kconfig
++++ b/drivers/base/Kconfig
+@@ -172,6 +172,10 @@
+ bool
+ default n
+
++config GENERIC_CPU_DEVICES
++ bool
++ default n
++
+ source "drivers/base/regmap/Kconfig"
+
+ endmenu
+--- a/drivers/base/cpu.c
++++ b/drivers/base/cpu.c
+@@ -11,6 +11,7 @@
+ #include <linux/device.h>
+ #include <linux/node.h>
+ #include <linux/gfp.h>
++#include <linux/percpu.h>
+
+ #include "base.h"
+
+@@ -268,11 +269,29 @@
+ NULL,
+ };
+
++#ifdef CONFIG_GENERIC_CPU_DEVICES
++static DEFINE_PER_CPU(struct cpu, cpu_devices);
++#endif
++
++static void __init cpu_dev_register_generic(void)
++{
++#ifdef CONFIG_GENERIC_CPU_DEVICES
++ int i;
++
++ for_each_possible_cpu(i) {
++ if (register_cpu(&per_cpu(cpu_devices, i), i))
++ panic("Failed to register CPU device");
++ }
++#endif
++}
++
+ void __init cpu_dev_init(void)
+ {
+ if (subsys_system_register(&cpu_subsys, cpu_root_attr_groups))
+ panic("Failed to register CPU subsystem");
+
++ cpu_dev_register_generic();
++
+ #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
+ sched_create_sysfs_power_savings_entries(cpu_subsys.dev_root);
+ #endif
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/cpu-convert-cpu-and-machinecheck-sysdev_class-to-a-r.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/cpu-convert-cpu-and-machinecheck-sysdev_class-to-a-r.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,4365 @@
+From: Kay Sievers <kay.sievers at vrfy.org>
+Date: Wed, 21 Dec 2011 14:29:42 -0800
+Subject: cpu: convert 'cpu' and 'machinecheck' sysdev_class to a regular
+ subsystem
+
+commit 8a25a2fd126c621f44f3aeaef80d51f00fc11639 upstream.
+
+This moves the 'cpu sysdev_class' over to a regular 'cpu' subsystem
+and converts the devices to regular devices. The sysdev drivers are
+implemented as subsystem interfaces now.
+
+After all sysdev classes are ported to regular driver core entities, the
+sysdev implementation will be entirely removed from the kernel.
+
+Userspace relies on events and generic sysfs subsystem infrastructure
+from sysdev devices, which are made available with this conversion.
+
+Cc: Haavard Skinnemoen <hskinnemoen at gmail.com>
+Cc: Hans-Christian Egtvedt <egtvedt at samfundet.no>
+Cc: Tony Luck <tony.luck at intel.com>
+Cc: Fenghua Yu <fenghua.yu at intel.com>
+Cc: Arnd Bergmann <arnd at arndb.de>
+Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>
+Cc: Paul Mackerras <paulus at samba.org>
+Cc: Martin Schwidefsky <schwidefsky at de.ibm.com>
+Cc: Heiko Carstens <heiko.carstens at de.ibm.com>
+Cc: Paul Mundt <lethal at linux-sh.org>
+Cc: "David S. Miller" <davem at davemloft.net>
+Cc: Chris Metcalf <cmetcalf at tilera.com>
+Cc: Thomas Gleixner <tglx at linutronix.de>
+Cc: Ingo Molnar <mingo at redhat.com>
+Cc: "H. Peter Anvin" <hpa at zytor.com>
+Cc: Borislav Petkov <bp at amd64.org>
+Cc: Tigran Aivazian <tigran at aivazian.fsnet.co.uk>
+Cc: Len Brown <lenb at kernel.org>
+Cc: Zhang Rui <rui.zhang at intel.com>
+Cc: Dave Jones <davej at redhat.com>
+Cc: Peter Zijlstra <peterz at infradead.org>
+Cc: Russell King <rmk+kernel at arm.linux.org.uk>
+Cc: Andrew Morton <akpm at linux-foundation.org>
+Cc: Arjan van de Ven <arjan at linux.intel.com>
+Cc: "Rafael J. Wysocki" <rjw at sisk.pl>
+Cc: "Srivatsa S. Bhat" <srivatsa.bhat at linux.vnet.ibm.com>
+Signed-off-by: Kay Sievers <kay.sievers at vrfy.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+[bwh: Backported to 3.2:
+ - call to sysfs_remove_group() in mc_sysdev_add() was already removed
+ - microcode_init() failure path was fixed and needs to be adjusted too]
+---
+ arch/avr32/kernel/cpu.c | 74 +++----
+ arch/ia64/kernel/err_inject.c | 52 ++---
+ arch/ia64/kernel/topology.c | 10 +-
+ arch/powerpc/include/asm/spu.h | 12 +-
+ arch/powerpc/include/asm/topology.h | 10 +-
+ arch/powerpc/kernel/cacheinfo.c | 10 +-
+ arch/powerpc/kernel/smp.c | 2 +-
+ arch/powerpc/kernel/sysfs.c | 257 +++++++++++------------
+ arch/powerpc/mm/numa.c | 8 +-
+ arch/powerpc/platforms/cell/cbe_thermal.c | 144 ++++++-------
+ arch/powerpc/platforms/cell/spu_base.c | 61 +++---
+ arch/powerpc/platforms/pseries/pseries_energy.c | 71 +++----
+ arch/powerpc/sysdev/ppc4xx_cpm.c | 6 +-
+ arch/s390/kernel/smp.c | 76 +++----
+ arch/s390/kernel/topology.c | 6 +-
+ arch/sh/kernel/cpu/sh4/sq.c | 24 ++-
+ arch/sparc/kernel/sysfs.c | 122 +++++------
+ arch/tile/kernel/sysfs.c | 61 +++---
+ arch/x86/include/asm/mce.h | 2 +-
+ arch/x86/kernel/cpu/intel_cacheinfo.c | 25 ++-
+ arch/x86/kernel/cpu/mcheck/mce-internal.h | 4 +-
+ arch/x86/kernel/cpu/mcheck/mce.c | 128 +++++------
+ arch/x86/kernel/cpu/mcheck/mce_amd.c | 11 +-
+ arch/x86/kernel/cpu/mcheck/therm_throt.c | 63 +++---
+ arch/x86/kernel/microcode_core.c | 58 ++---
+ drivers/acpi/processor_driver.c | 6 +-
+ drivers/acpi/processor_thermal.c | 1 -
+ drivers/base/cpu.c | 146 +++++++------
+ drivers/base/node.c | 8 +-
+ drivers/base/topology.c | 51 +++--
+ drivers/cpufreq/cpufreq.c | 79 ++++---
+ drivers/cpufreq/cpufreq_stats.c | 1 -
+ drivers/cpuidle/cpuidle.c | 12 +-
+ drivers/cpuidle/cpuidle.h | 10 +-
+ drivers/cpuidle/sysfs.c | 74 ++++---
+ drivers/s390/char/sclp_config.c | 8 +-
+ include/linux/cpu.h | 18 +-
+ kernel/sched.c | 40 ++--
+ 38 files changed, 874 insertions(+), 877 deletions(-)
+
+--- a/arch/avr32/kernel/cpu.c
++++ b/arch/avr32/kernel/cpu.c
+@@ -6,7 +6,7 @@
+ * published by the Free Software Foundation.
+ */
+ #include <linux/init.h>
+-#include <linux/sysdev.h>
++#include <linux/device.h>
+ #include <linux/seq_file.h>
+ #include <linux/cpu.h>
+ #include <linux/module.h>
+@@ -26,16 +26,16 @@
+ * XXX: If/when a SMP-capable implementation of AVR32 will ever be
+ * made, we must make sure that the code executes on the correct CPU.
+ */
+-static ssize_t show_pc0event(struct sys_device *dev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t show_pc0event(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+ unsigned long pccr;
+
+ pccr = sysreg_read(PCCR);
+ return sprintf(buf, "0x%lx\n", (pccr >> 12) & 0x3f);
+ }
+-static ssize_t store_pc0event(struct sys_device *dev,
+- struct sysdev_attribute *attr, const char *buf,
++static ssize_t store_pc0event(struct device *dev,
++ struct device_attribute *attr, const char *buf,
+ size_t count)
+ {
+ unsigned long val;
+@@ -48,16 +48,16 @@
+ sysreg_write(PCCR, val);
+ return count;
+ }
+-static ssize_t show_pc0count(struct sys_device *dev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t show_pc0count(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+ unsigned long pcnt0;
+
+ pcnt0 = sysreg_read(PCNT0);
+ return sprintf(buf, "%lu\n", pcnt0);
+ }
+-static ssize_t store_pc0count(struct sys_device *dev,
+- struct sysdev_attribute *attr,
++static ssize_t store_pc0count(struct device *dev,
++ struct device_attribute *attr,
+ const char *buf, size_t count)
+ {
+ unsigned long val;
+@@ -71,16 +71,16 @@
+ return count;
+ }
+
+-static ssize_t show_pc1event(struct sys_device *dev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t show_pc1event(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+ unsigned long pccr;
+
+ pccr = sysreg_read(PCCR);
+ return sprintf(buf, "0x%lx\n", (pccr >> 18) & 0x3f);
+ }
+-static ssize_t store_pc1event(struct sys_device *dev,
+- struct sysdev_attribute *attr, const char *buf,
++static ssize_t store_pc1event(struct device *dev,
++ struct device_attribute *attr, const char *buf,
+ size_t count)
+ {
+ unsigned long val;
+@@ -93,16 +93,16 @@
+ sysreg_write(PCCR, val);
+ return count;
+ }
+-static ssize_t show_pc1count(struct sys_device *dev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t show_pc1count(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+ unsigned long pcnt1;
+
+ pcnt1 = sysreg_read(PCNT1);
+ return sprintf(buf, "%lu\n", pcnt1);
+ }
+-static ssize_t store_pc1count(struct sys_device *dev,
+- struct sysdev_attribute *attr, const char *buf,
++static ssize_t store_pc1count(struct device *dev,
++ struct device_attribute *attr, const char *buf,
+ size_t count)
+ {
+ unsigned long val;
+@@ -116,16 +116,16 @@
+ return count;
+ }
+
+-static ssize_t show_pccycles(struct sys_device *dev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t show_pccycles(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+ unsigned long pccnt;
+
+ pccnt = sysreg_read(PCCNT);
+ return sprintf(buf, "%lu\n", pccnt);
+ }
+-static ssize_t store_pccycles(struct sys_device *dev,
+- struct sysdev_attribute *attr, const char *buf,
++static ssize_t store_pccycles(struct device *dev,
++ struct device_attribute *attr, const char *buf,
+ size_t count)
+ {
+ unsigned long val;
+@@ -139,16 +139,16 @@
+ return count;
+ }
+
+-static ssize_t show_pcenable(struct sys_device *dev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t show_pcenable(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+ unsigned long pccr;
+
+ pccr = sysreg_read(PCCR);
+ return sprintf(buf, "%c\n", (pccr & 1)?'1':'0');
+ }
+-static ssize_t store_pcenable(struct sys_device *dev,
+- struct sysdev_attribute *attr, const char *buf,
++static ssize_t store_pcenable(struct device *dev,
++ struct device_attribute *attr, const char *buf,
+ size_t count)
+ {
+ unsigned long pccr, val;
+@@ -167,12 +167,12 @@
+ return count;
+ }
+
+-static SYSDEV_ATTR(pc0event, 0600, show_pc0event, store_pc0event);
+-static SYSDEV_ATTR(pc0count, 0600, show_pc0count, store_pc0count);
+-static SYSDEV_ATTR(pc1event, 0600, show_pc1event, store_pc1event);
+-static SYSDEV_ATTR(pc1count, 0600, show_pc1count, store_pc1count);
+-static SYSDEV_ATTR(pccycles, 0600, show_pccycles, store_pccycles);
+-static SYSDEV_ATTR(pcenable, 0600, show_pcenable, store_pcenable);
++static DEVICE_ATTR(pc0event, 0600, show_pc0event, store_pc0event);
++static DEVICE_ATTR(pc0count, 0600, show_pc0count, store_pc0count);
++static DEVICE_ATTR(pc1event, 0600, show_pc1event, store_pc1event);
++static DEVICE_ATTR(pc1count, 0600, show_pc1count, store_pc1count);
++static DEVICE_ATTR(pccycles, 0600, show_pccycles, store_pccycles);
++static DEVICE_ATTR(pcenable, 0600, show_pcenable, store_pcenable);
+
+ #endif /* CONFIG_PERFORMANCE_COUNTERS */
+
+@@ -186,12 +186,12 @@
+ register_cpu(c, cpu);
+
+ #ifdef CONFIG_PERFORMANCE_COUNTERS
+- sysdev_create_file(&c->sysdev, &attr_pc0event);
+- sysdev_create_file(&c->sysdev, &attr_pc0count);
+- sysdev_create_file(&c->sysdev, &attr_pc1event);
+- sysdev_create_file(&c->sysdev, &attr_pc1count);
+- sysdev_create_file(&c->sysdev, &attr_pccycles);
+- sysdev_create_file(&c->sysdev, &attr_pcenable);
++ device_create_file(&c->dev, &dev_attr_pc0event);
++ device_create_file(&c->dev, &dev_attr_pc0count);
++ device_create_file(&c->dev, &dev_attr_pc1event);
++ device_create_file(&c->dev, &dev_attr_pc1count);
++ device_create_file(&c->dev, &dev_attr_pccycles);
++ device_create_file(&c->dev, &dev_attr_pcenable);
+ #endif
+ }
+
+--- a/arch/ia64/kernel/err_inject.c
++++ b/arch/ia64/kernel/err_inject.c
+@@ -24,7 +24,7 @@
+ * Copyright (C) 2006, Intel Corp. All rights reserved.
+ *
+ */
+-#include <linux/sysdev.h>
++#include <linux/device.h>
+ #include <linux/init.h>
+ #include <linux/mm.h>
+ #include <linux/cpu.h>
+@@ -35,10 +35,10 @@
+ #define ERR_DATA_BUFFER_SIZE 3 // Three 8-byte;
+
+ #define define_one_ro(name) \
+-static SYSDEV_ATTR(name, 0444, show_##name, NULL)
++static DEVICE_ATTR(name, 0444, show_##name, NULL)
+
+ #define define_one_rw(name) \
+-static SYSDEV_ATTR(name, 0644, show_##name, store_##name)
++static DEVICE_ATTR(name, 0644, show_##name, store_##name)
+
+ static u64 call_start[NR_CPUS];
+ static u64 phys_addr[NR_CPUS];
+@@ -55,7 +55,7 @@
+
+ #define show(name) \
+ static ssize_t \
+-show_##name(struct sys_device *dev, struct sysdev_attribute *attr, \
++show_##name(struct device *dev, struct device_attribute *attr, \
+ char *buf) \
+ { \
+ u32 cpu=dev->id; \
+@@ -64,7 +64,7 @@
+
+ #define store(name) \
+ static ssize_t \
+-store_##name(struct sys_device *dev, struct sysdev_attribute *attr, \
++store_##name(struct device *dev, struct device_attribute *attr, \
+ const char *buf, size_t size) \
+ { \
+ unsigned int cpu=dev->id; \
+@@ -78,7 +78,7 @@
+ * processor. The cpu number in driver is only used for storing data.
+ */
+ static ssize_t
+-store_call_start(struct sys_device *dev, struct sysdev_attribute *attr,
++store_call_start(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t size)
+ {
+ unsigned int cpu=dev->id;
+@@ -127,7 +127,7 @@
+ store(err_type_info)
+
+ static ssize_t
+-show_virtual_to_phys(struct sys_device *dev, struct sysdev_attribute *attr,
++show_virtual_to_phys(struct device *dev, struct device_attribute *attr,
+ char *buf)
+ {
+ unsigned int cpu=dev->id;
+@@ -135,7 +135,7 @@
+ }
+
+ static ssize_t
+-store_virtual_to_phys(struct sys_device *dev, struct sysdev_attribute *attr,
++store_virtual_to_phys(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t size)
+ {
+ unsigned int cpu=dev->id;
+@@ -159,8 +159,8 @@
+ store(err_struct_info)
+
+ static ssize_t
+-show_err_data_buffer(struct sys_device *dev,
+- struct sysdev_attribute *attr, char *buf)
++show_err_data_buffer(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+ unsigned int cpu=dev->id;
+
+@@ -171,8 +171,8 @@
+ }
+
+ static ssize_t
+-store_err_data_buffer(struct sys_device *dev,
+- struct sysdev_attribute *attr,
++store_err_data_buffer(struct device *dev,
++ struct device_attribute *attr,
+ const char *buf, size_t size)
+ {
+ unsigned int cpu=dev->id;
+@@ -209,14 +209,14 @@
+ define_one_ro(resources);
+
+ static struct attribute *default_attrs[] = {
+- &attr_call_start.attr,
+- &attr_virtual_to_phys.attr,
+- &attr_err_type_info.attr,
+- &attr_err_struct_info.attr,
+- &attr_err_data_buffer.attr,
+- &attr_status.attr,
+- &attr_capabilities.attr,
+- &attr_resources.attr,
++ &dev_attr_call_start.attr,
++ &dev_attr_virtual_to_phys.attr,
++ &dev_attr_err_type_info.attr,
++ &dev_attr_err_struct_info.attr,
++ &dev_attr_err_data_buffer.attr,
++ &dev_attr_status.attr,
++ &dev_attr_capabilities.attr,
++ &dev_attr_resources.attr,
+ NULL
+ };
+
+@@ -225,12 +225,12 @@
+ .name = "err_inject"
+ };
+ /* Add/Remove err_inject interface for CPU device */
+-static int __cpuinit err_inject_add_dev(struct sys_device * sys_dev)
++static int __cpuinit err_inject_add_dev(struct device * sys_dev)
+ {
+ return sysfs_create_group(&sys_dev->kobj, &err_inject_attr_group);
+ }
+
+-static int __cpuinit err_inject_remove_dev(struct sys_device * sys_dev)
++static int __cpuinit err_inject_remove_dev(struct device * sys_dev)
+ {
+ sysfs_remove_group(&sys_dev->kobj, &err_inject_attr_group);
+ return 0;
+@@ -239,9 +239,9 @@
+ unsigned long action, void *hcpu)
+ {
+ unsigned int cpu = (unsigned long)hcpu;
+- struct sys_device *sys_dev;
++ struct device *sys_dev;
+
+- sys_dev = get_cpu_sysdev(cpu);
++ sys_dev = get_cpu_device(cpu);
+ switch (action) {
+ case CPU_ONLINE:
+ case CPU_ONLINE_FROZEN:
+@@ -283,13 +283,13 @@
+ err_inject_exit(void)
+ {
+ int i;
+- struct sys_device *sys_dev;
++ struct device *sys_dev;
+
+ #ifdef ERR_INJ_DEBUG
+ printk(KERN_INFO "Exit error injection driver.\n");
+ #endif
+ for_each_online_cpu(i) {
+- sys_dev = get_cpu_sysdev(i);
++ sys_dev = get_cpu_device(i);
+ sysfs_remove_group(&sys_dev->kobj, &err_inject_attr_group);
+ }
+ unregister_hotcpu_notifier(&err_inject_cpu_notifier);
+--- a/arch/ia64/kernel/topology.c
++++ b/arch/ia64/kernel/topology.c
+@@ -350,7 +350,7 @@
+ }
+
+ /* Add cache interface for CPU device */
+-static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
++static int __cpuinit cache_add_dev(struct device * sys_dev)
+ {
+ unsigned int cpu = sys_dev->id;
+ unsigned long i, j;
+@@ -400,7 +400,7 @@
+ }
+
+ /* Remove cache interface for CPU device */
+-static int __cpuinit cache_remove_dev(struct sys_device * sys_dev)
++static int __cpuinit cache_remove_dev(struct device * sys_dev)
+ {
+ unsigned int cpu = sys_dev->id;
+ unsigned long i;
+@@ -428,9 +428,9 @@
+ unsigned long action, void *hcpu)
+ {
+ unsigned int cpu = (unsigned long)hcpu;
+- struct sys_device *sys_dev;
++ struct device *sys_dev;
+
+- sys_dev = get_cpu_sysdev(cpu);
++ sys_dev = get_cpu_device(cpu);
+ switch (action) {
+ case CPU_ONLINE:
+ case CPU_ONLINE_FROZEN:
+@@ -454,7 +454,7 @@
+ int i;
+
+ for_each_online_cpu(i) {
+- struct sys_device *sys_dev = get_cpu_sysdev((unsigned int)i);
++ struct device *sys_dev = get_cpu_device((unsigned int)i);
+ cache_add_dev(sys_dev);
+ }
+
+--- a/arch/powerpc/include/asm/spu.h
++++ b/arch/powerpc/include/asm/spu.h
+@@ -25,7 +25,7 @@
+ #ifdef __KERNEL__
+
+ #include <linux/workqueue.h>
+-#include <linux/sysdev.h>
++#include <linux/device.h>
+ #include <linux/mutex.h>
+
+ #define LS_SIZE (256 * 1024)
+@@ -166,7 +166,7 @@
+ /* beat only */
+ u64 shadow_int_mask_RW[3];
+
+- struct sys_device sysdev;
++ struct device dev;
+
+ int has_mem_affinity;
+ struct list_head aff_list;
+@@ -270,11 +270,11 @@
+ int register_spu_syscalls(struct spufs_calls *calls);
+ void unregister_spu_syscalls(struct spufs_calls *calls);
+
+-int spu_add_sysdev_attr(struct sysdev_attribute *attr);
+-void spu_remove_sysdev_attr(struct sysdev_attribute *attr);
++int spu_add_dev_attr(struct device_attribute *attr);
++void spu_remove_dev_attr(struct device_attribute *attr);
+
+-int spu_add_sysdev_attr_group(struct attribute_group *attrs);
+-void spu_remove_sysdev_attr_group(struct attribute_group *attrs);
++int spu_add_dev_attr_group(struct attribute_group *attrs);
++void spu_remove_dev_attr_group(struct attribute_group *attrs);
+
+ int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea,
+ unsigned long dsisr, unsigned *flt);
+--- a/arch/powerpc/include/asm/topology.h
++++ b/arch/powerpc/include/asm/topology.h
+@@ -3,7 +3,7 @@
+ #ifdef __KERNEL__
+
+
+-struct sys_device;
++struct device;
+ struct device_node;
+
+ #ifdef CONFIG_NUMA
+@@ -86,19 +86,19 @@
+
+ extern void __init dump_numa_cpu_topology(void);
+
+-extern int sysfs_add_device_to_node(struct sys_device *dev, int nid);
+-extern void sysfs_remove_device_from_node(struct sys_device *dev, int nid);
++extern int sysfs_add_device_to_node(struct device *dev, int nid);
++extern void sysfs_remove_device_from_node(struct device *dev, int nid);
+
+ #else
+
+ static inline void dump_numa_cpu_topology(void) {}
+
+-static inline int sysfs_add_device_to_node(struct sys_device *dev, int nid)
++static inline int sysfs_add_device_to_node(struct device *dev, int nid)
+ {
+ return 0;
+ }
+
+-static inline void sysfs_remove_device_from_node(struct sys_device *dev,
++static inline void sysfs_remove_device_from_node(struct device *dev,
+ int nid)
+ {
+ }
+--- a/arch/powerpc/kernel/cacheinfo.c
++++ b/arch/powerpc/kernel/cacheinfo.c
+@@ -451,15 +451,15 @@
+ static struct cache_dir *__cpuinit cacheinfo_create_cache_dir(unsigned int cpu_id)
+ {
+ struct cache_dir *cache_dir;
+- struct sys_device *sysdev;
++ struct device *dev;
+ struct kobject *kobj = NULL;
+
+- sysdev = get_cpu_sysdev(cpu_id);
+- WARN_ONCE(!sysdev, "no sysdev for CPU %i\n", cpu_id);
+- if (!sysdev)
++ dev = get_cpu_device(cpu_id);
++ WARN_ONCE(!dev, "no dev for CPU %i\n", cpu_id);
++ if (!dev)
+ goto err;
+
+- kobj = kobject_create_and_add("cache", &sysdev->kobj);
++ kobj = kobject_create_and_add("cache", &dev->kobj);
+ if (!kobj)
+ goto err;
+
+--- a/arch/powerpc/kernel/smp.c
++++ b/arch/powerpc/kernel/smp.c
+@@ -27,7 +27,7 @@
+ #include <linux/spinlock.h>
+ #include <linux/cache.h>
+ #include <linux/err.h>
+-#include <linux/sysdev.h>
++#include <linux/device.h>
+ #include <linux/cpu.h>
+ #include <linux/notifier.h>
+ #include <linux/topology.h>
+--- a/arch/powerpc/kernel/sysfs.c
++++ b/arch/powerpc/kernel/sysfs.c
+@@ -1,4 +1,4 @@
+-#include <linux/sysdev.h>
++#include <linux/device.h>
+ #include <linux/cpu.h>
+ #include <linux/smp.h>
+ #include <linux/percpu.h>
+@@ -37,12 +37,12 @@
+ /* Time in microseconds we delay before sleeping in the idle loop */
+ DEFINE_PER_CPU(long, smt_snooze_delay) = { 100 };
+
+-static ssize_t store_smt_snooze_delay(struct sys_device *dev,
+- struct sysdev_attribute *attr,
++static ssize_t store_smt_snooze_delay(struct device *dev,
++ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+ {
+- struct cpu *cpu = container_of(dev, struct cpu, sysdev);
++ struct cpu *cpu = container_of(dev, struct cpu, dev);
+ ssize_t ret;
+ long snooze;
+
+@@ -50,21 +50,21 @@
+ if (ret != 1)
+ return -EINVAL;
+
+- per_cpu(smt_snooze_delay, cpu->sysdev.id) = snooze;
++ per_cpu(smt_snooze_delay, cpu->dev.id) = snooze;
+
+ return count;
+ }
+
+-static ssize_t show_smt_snooze_delay(struct sys_device *dev,
+- struct sysdev_attribute *attr,
++static ssize_t show_smt_snooze_delay(struct device *dev,
++ struct device_attribute *attr,
+ char *buf)
+ {
+- struct cpu *cpu = container_of(dev, struct cpu, sysdev);
++ struct cpu *cpu = container_of(dev, struct cpu, dev);
+
+- return sprintf(buf, "%ld\n", per_cpu(smt_snooze_delay, cpu->sysdev.id));
++ return sprintf(buf, "%ld\n", per_cpu(smt_snooze_delay, cpu->dev.id));
+ }
+
+-static SYSDEV_ATTR(smt_snooze_delay, 0644, show_smt_snooze_delay,
++static DEVICE_ATTR(smt_snooze_delay, 0644, show_smt_snooze_delay,
+ store_smt_snooze_delay);
+
+ static int __init setup_smt_snooze_delay(char *str)
+@@ -117,25 +117,25 @@
+ ppc_enable_pmcs(); \
+ mtspr(ADDRESS, *(unsigned long *)val); \
+ } \
+-static ssize_t show_##NAME(struct sys_device *dev, \
+- struct sysdev_attribute *attr, \
++static ssize_t show_##NAME(struct device *dev, \
++ struct device_attribute *attr, \
+ char *buf) \
+ { \
+- struct cpu *cpu = container_of(dev, struct cpu, sysdev); \
++ struct cpu *cpu = container_of(dev, struct cpu, dev); \
+ unsigned long val; \
+- smp_call_function_single(cpu->sysdev.id, read_##NAME, &val, 1); \
++ smp_call_function_single(cpu->dev.id, read_##NAME, &val, 1); \
+ return sprintf(buf, "%lx\n", val); \
+ } \
+ static ssize_t __used \
+- store_##NAME(struct sys_device *dev, struct sysdev_attribute *attr, \
++ store_##NAME(struct device *dev, struct device_attribute *attr, \
+ const char *buf, size_t count) \
+ { \
+- struct cpu *cpu = container_of(dev, struct cpu, sysdev); \
++ struct cpu *cpu = container_of(dev, struct cpu, dev); \
+ unsigned long val; \
+ int ret = sscanf(buf, "%lx", &val); \
+ if (ret != 1) \
+ return -EINVAL; \
+- smp_call_function_single(cpu->sysdev.id, write_##NAME, &val, 1); \
++ smp_call_function_single(cpu->dev.id, write_##NAME, &val, 1); \
+ return count; \
+ }
+
+@@ -178,22 +178,22 @@
+ SYSFS_PMCSETUP(spurr, SPRN_SPURR);
+ SYSFS_PMCSETUP(dscr, SPRN_DSCR);
+
+-static SYSDEV_ATTR(mmcra, 0600, show_mmcra, store_mmcra);
+-static SYSDEV_ATTR(spurr, 0600, show_spurr, NULL);
+-static SYSDEV_ATTR(dscr, 0600, show_dscr, store_dscr);
+-static SYSDEV_ATTR(purr, 0600, show_purr, store_purr);
++static DEVICE_ATTR(mmcra, 0600, show_mmcra, store_mmcra);
++static DEVICE_ATTR(spurr, 0600, show_spurr, NULL);
++static DEVICE_ATTR(dscr, 0600, show_dscr, store_dscr);
++static DEVICE_ATTR(purr, 0600, show_purr, store_purr);
+
+ unsigned long dscr_default = 0;
+ EXPORT_SYMBOL(dscr_default);
+
+-static ssize_t show_dscr_default(struct sysdev_class *class,
+- struct sysdev_class_attribute *attr, char *buf)
++static ssize_t show_dscr_default(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+ return sprintf(buf, "%lx\n", dscr_default);
+ }
+
+-static ssize_t __used store_dscr_default(struct sysdev_class *class,
+- struct sysdev_class_attribute *attr, const char *buf,
++static ssize_t __used store_dscr_default(struct device *dev,
++ struct device_attribute *attr, const char *buf,
+ size_t count)
+ {
+ unsigned long val;
+@@ -207,15 +207,14 @@
+ return count;
+ }
+
+-static SYSDEV_CLASS_ATTR(dscr_default, 0600,
++static DEVICE_ATTR(dscr_default, 0600,
+ show_dscr_default, store_dscr_default);
+
+ static void sysfs_create_dscr_default(void)
+ {
+ int err = 0;
+ if (cpu_has_feature(CPU_FTR_DSCR))
+- err = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
+- &attr_dscr_default.attr);
++ err = device_create_file(cpu_subsys.dev_root, &dev_attr_dscr_default);
+ }
+ #endif /* CONFIG_PPC64 */
+
+@@ -259,72 +258,72 @@
+ #endif /* HAS_PPC_PMC_PA6T */
+
+ #ifdef HAS_PPC_PMC_IBM
+-static struct sysdev_attribute ibm_common_attrs[] = {
+- _SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0),
+- _SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1),
++static struct device_attribute ibm_common_attrs[] = {
++ __ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0),
++ __ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1),
+ };
+ #endif /* HAS_PPC_PMC_G4 */
+
+ #ifdef HAS_PPC_PMC_G4
+-static struct sysdev_attribute g4_common_attrs[] = {
+- _SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0),
+- _SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1),
+- _SYSDEV_ATTR(mmcr2, 0600, show_mmcr2, store_mmcr2),
++static struct device_attribute g4_common_attrs[] = {
++ __ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0),
++ __ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1),
++ __ATTR(mmcr2, 0600, show_mmcr2, store_mmcr2),
+ };
+ #endif /* HAS_PPC_PMC_G4 */
+
+-static struct sysdev_attribute classic_pmc_attrs[] = {
+- _SYSDEV_ATTR(pmc1, 0600, show_pmc1, store_pmc1),
+- _SYSDEV_ATTR(pmc2, 0600, show_pmc2, store_pmc2),
+- _SYSDEV_ATTR(pmc3, 0600, show_pmc3, store_pmc3),
+- _SYSDEV_ATTR(pmc4, 0600, show_pmc4, store_pmc4),
+- _SYSDEV_ATTR(pmc5, 0600, show_pmc5, store_pmc5),
+- _SYSDEV_ATTR(pmc6, 0600, show_pmc6, store_pmc6),
++static struct device_attribute classic_pmc_attrs[] = {
++ __ATTR(pmc1, 0600, show_pmc1, store_pmc1),
++ __ATTR(pmc2, 0600, show_pmc2, store_pmc2),
++ __ATTR(pmc3, 0600, show_pmc3, store_pmc3),
++ __ATTR(pmc4, 0600, show_pmc4, store_pmc4),
++ __ATTR(pmc5, 0600, show_pmc5, store_pmc5),
++ __ATTR(pmc6, 0600, show_pmc6, store_pmc6),
+ #ifdef CONFIG_PPC64
+- _SYSDEV_ATTR(pmc7, 0600, show_pmc7, store_pmc7),
+- _SYSDEV_ATTR(pmc8, 0600, show_pmc8, store_pmc8),
++ __ATTR(pmc7, 0600, show_pmc7, store_pmc7),
++ __ATTR(pmc8, 0600, show_pmc8, store_pmc8),
+ #endif
+ };
+
+ #ifdef HAS_PPC_PMC_PA6T
+-static struct sysdev_attribute pa6t_attrs[] = {
+- _SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0),
+- _SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1),
+- _SYSDEV_ATTR(pmc0, 0600, show_pa6t_pmc0, store_pa6t_pmc0),
+- _SYSDEV_ATTR(pmc1, 0600, show_pa6t_pmc1, store_pa6t_pmc1),
+- _SYSDEV_ATTR(pmc2, 0600, show_pa6t_pmc2, store_pa6t_pmc2),
+- _SYSDEV_ATTR(pmc3, 0600, show_pa6t_pmc3, store_pa6t_pmc3),
+- _SYSDEV_ATTR(pmc4, 0600, show_pa6t_pmc4, store_pa6t_pmc4),
+- _SYSDEV_ATTR(pmc5, 0600, show_pa6t_pmc5, store_pa6t_pmc5),
++static struct device_attribute pa6t_attrs[] = {
++ __ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0),
++ __ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1),
++ __ATTR(pmc0, 0600, show_pa6t_pmc0, store_pa6t_pmc0),
++ __ATTR(pmc1, 0600, show_pa6t_pmc1, store_pa6t_pmc1),
++ __ATTR(pmc2, 0600, show_pa6t_pmc2, store_pa6t_pmc2),
++ __ATTR(pmc3, 0600, show_pa6t_pmc3, store_pa6t_pmc3),
++ __ATTR(pmc4, 0600, show_pa6t_pmc4, store_pa6t_pmc4),
++ __ATTR(pmc5, 0600, show_pa6t_pmc5, store_pa6t_pmc5),
+ #ifdef CONFIG_DEBUG_KERNEL
+- _SYSDEV_ATTR(hid0, 0600, show_hid0, store_hid0),
+- _SYSDEV_ATTR(hid1, 0600, show_hid1, store_hid1),
+- _SYSDEV_ATTR(hid4, 0600, show_hid4, store_hid4),
+- _SYSDEV_ATTR(hid5, 0600, show_hid5, store_hid5),
+- _SYSDEV_ATTR(ima0, 0600, show_ima0, store_ima0),
+- _SYSDEV_ATTR(ima1, 0600, show_ima1, store_ima1),
+- _SYSDEV_ATTR(ima2, 0600, show_ima2, store_ima2),
+- _SYSDEV_ATTR(ima3, 0600, show_ima3, store_ima3),
+- _SYSDEV_ATTR(ima4, 0600, show_ima4, store_ima4),
+- _SYSDEV_ATTR(ima5, 0600, show_ima5, store_ima5),
+- _SYSDEV_ATTR(ima6, 0600, show_ima6, store_ima6),
+- _SYSDEV_ATTR(ima7, 0600, show_ima7, store_ima7),
+- _SYSDEV_ATTR(ima8, 0600, show_ima8, store_ima8),
+- _SYSDEV_ATTR(ima9, 0600, show_ima9, store_ima9),
+- _SYSDEV_ATTR(imaat, 0600, show_imaat, store_imaat),
+- _SYSDEV_ATTR(btcr, 0600, show_btcr, store_btcr),
+- _SYSDEV_ATTR(pccr, 0600, show_pccr, store_pccr),
+- _SYSDEV_ATTR(rpccr, 0600, show_rpccr, store_rpccr),
+- _SYSDEV_ATTR(der, 0600, show_der, store_der),
+- _SYSDEV_ATTR(mer, 0600, show_mer, store_mer),
+- _SYSDEV_ATTR(ber, 0600, show_ber, store_ber),
+- _SYSDEV_ATTR(ier, 0600, show_ier, store_ier),
+- _SYSDEV_ATTR(sier, 0600, show_sier, store_sier),
+- _SYSDEV_ATTR(siar, 0600, show_siar, store_siar),
+- _SYSDEV_ATTR(tsr0, 0600, show_tsr0, store_tsr0),
+- _SYSDEV_ATTR(tsr1, 0600, show_tsr1, store_tsr1),
+- _SYSDEV_ATTR(tsr2, 0600, show_tsr2, store_tsr2),
+- _SYSDEV_ATTR(tsr3, 0600, show_tsr3, store_tsr3),
++ __ATTR(hid0, 0600, show_hid0, store_hid0),
++ __ATTR(hid1, 0600, show_hid1, store_hid1),
++ __ATTR(hid4, 0600, show_hid4, store_hid4),
++ __ATTR(hid5, 0600, show_hid5, store_hid5),
++ __ATTR(ima0, 0600, show_ima0, store_ima0),
++ __ATTR(ima1, 0600, show_ima1, store_ima1),
++ __ATTR(ima2, 0600, show_ima2, store_ima2),
++ __ATTR(ima3, 0600, show_ima3, store_ima3),
++ __ATTR(ima4, 0600, show_ima4, store_ima4),
++ __ATTR(ima5, 0600, show_ima5, store_ima5),
++ __ATTR(ima6, 0600, show_ima6, store_ima6),
++ __ATTR(ima7, 0600, show_ima7, store_ima7),
++ __ATTR(ima8, 0600, show_ima8, store_ima8),
++ __ATTR(ima9, 0600, show_ima9, store_ima9),
++ __ATTR(imaat, 0600, show_imaat, store_imaat),
++ __ATTR(btcr, 0600, show_btcr, store_btcr),
++ __ATTR(pccr, 0600, show_pccr, store_pccr),
++ __ATTR(rpccr, 0600, show_rpccr, store_rpccr),
++ __ATTR(der, 0600, show_der, store_der),
++ __ATTR(mer, 0600, show_mer, store_mer),
++ __ATTR(ber, 0600, show_ber, store_ber),
++ __ATTR(ier, 0600, show_ier, store_ier),
++ __ATTR(sier, 0600, show_sier, store_sier),
++ __ATTR(siar, 0600, show_siar, store_siar),
++ __ATTR(tsr0, 0600, show_tsr0, store_tsr0),
++ __ATTR(tsr1, 0600, show_tsr1, store_tsr1),
++ __ATTR(tsr2, 0600, show_tsr2, store_tsr2),
++ __ATTR(tsr3, 0600, show_tsr3, store_tsr3),
+ #endif /* CONFIG_DEBUG_KERNEL */
+ };
+ #endif /* HAS_PPC_PMC_PA6T */
+@@ -333,14 +332,14 @@
+ static void __cpuinit register_cpu_online(unsigned int cpu)
+ {
+ struct cpu *c = &per_cpu(cpu_devices, cpu);
+- struct sys_device *s = &c->sysdev;
+- struct sysdev_attribute *attrs, *pmc_attrs;
++ struct device *s = &c->dev;
++ struct device_attribute *attrs, *pmc_attrs;
+ int i, nattrs;
+
+ #ifdef CONFIG_PPC64
+ if (!firmware_has_feature(FW_FEATURE_ISERIES) &&
+ cpu_has_feature(CPU_FTR_SMT))
+- sysdev_create_file(s, &attr_smt_snooze_delay);
++ device_create_file(s, &dev_attr_smt_snooze_delay);
+ #endif
+
+ /* PMC stuff */
+@@ -348,14 +347,14 @@
+ #ifdef HAS_PPC_PMC_IBM
+ case PPC_PMC_IBM:
+ attrs = ibm_common_attrs;
+- nattrs = sizeof(ibm_common_attrs) / sizeof(struct sysdev_attribute);
++ nattrs = sizeof(ibm_common_attrs) / sizeof(struct device_attribute);
+ pmc_attrs = classic_pmc_attrs;
+ break;
+ #endif /* HAS_PPC_PMC_IBM */
+ #ifdef HAS_PPC_PMC_G4
+ case PPC_PMC_G4:
+ attrs = g4_common_attrs;
+- nattrs = sizeof(g4_common_attrs) / sizeof(struct sysdev_attribute);
++ nattrs = sizeof(g4_common_attrs) / sizeof(struct device_attribute);
+ pmc_attrs = classic_pmc_attrs;
+ break;
+ #endif /* HAS_PPC_PMC_G4 */
+@@ -363,7 +362,7 @@
+ case PPC_PMC_PA6T:
+ /* PA Semi starts counting at PMC0 */
+ attrs = pa6t_attrs;
+- nattrs = sizeof(pa6t_attrs) / sizeof(struct sysdev_attribute);
++ nattrs = sizeof(pa6t_attrs) / sizeof(struct device_attribute);
+ pmc_attrs = NULL;
+ break;
+ #endif /* HAS_PPC_PMC_PA6T */
+@@ -374,24 +373,24 @@
+ }
+
+ for (i = 0; i < nattrs; i++)
+- sysdev_create_file(s, &attrs[i]);
++ device_create_file(s, &attrs[i]);
+
+ if (pmc_attrs)
+ for (i = 0; i < cur_cpu_spec->num_pmcs; i++)
+- sysdev_create_file(s, &pmc_attrs[i]);
++ device_create_file(s, &pmc_attrs[i]);
+
+ #ifdef CONFIG_PPC64
+ if (cpu_has_feature(CPU_FTR_MMCRA))
+- sysdev_create_file(s, &attr_mmcra);
++ device_create_file(s, &dev_attr_mmcra);
+
+ if (cpu_has_feature(CPU_FTR_PURR))
+- sysdev_create_file(s, &attr_purr);
++ device_create_file(s, &dev_attr_purr);
+
+ if (cpu_has_feature(CPU_FTR_SPURR))
+- sysdev_create_file(s, &attr_spurr);
++ device_create_file(s, &dev_attr_spurr);
+
+ if (cpu_has_feature(CPU_FTR_DSCR))
+- sysdev_create_file(s, &attr_dscr);
++ device_create_file(s, &dev_attr_dscr);
+ #endif /* CONFIG_PPC64 */
+
+ cacheinfo_cpu_online(cpu);
+@@ -401,8 +400,8 @@
+ static void unregister_cpu_online(unsigned int cpu)
+ {
+ struct cpu *c = &per_cpu(cpu_devices, cpu);
+- struct sys_device *s = &c->sysdev;
+- struct sysdev_attribute *attrs, *pmc_attrs;
++ struct device *s = &c->dev;
++ struct device_attribute *attrs, *pmc_attrs;
+ int i, nattrs;
+
+ BUG_ON(!c->hotpluggable);
+@@ -410,7 +409,7 @@
+ #ifdef CONFIG_PPC64
+ if (!firmware_has_feature(FW_FEATURE_ISERIES) &&
+ cpu_has_feature(CPU_FTR_SMT))
+- sysdev_remove_file(s, &attr_smt_snooze_delay);
++ device_remove_file(s, &dev_attr_smt_snooze_delay);
+ #endif
+
+ /* PMC stuff */
+@@ -418,14 +417,14 @@
+ #ifdef HAS_PPC_PMC_IBM
+ case PPC_PMC_IBM:
+ attrs = ibm_common_attrs;
+- nattrs = sizeof(ibm_common_attrs) / sizeof(struct sysdev_attribute);
++ nattrs = sizeof(ibm_common_attrs) / sizeof(struct device_attribute);
+ pmc_attrs = classic_pmc_attrs;
+ break;
+ #endif /* HAS_PPC_PMC_IBM */
+ #ifdef HAS_PPC_PMC_G4
+ case PPC_PMC_G4:
+ attrs = g4_common_attrs;
+- nattrs = sizeof(g4_common_attrs) / sizeof(struct sysdev_attribute);
++ nattrs = sizeof(g4_common_attrs) / sizeof(struct device_attribute);
+ pmc_attrs = classic_pmc_attrs;
+ break;
+ #endif /* HAS_PPC_PMC_G4 */
+@@ -433,7 +432,7 @@
+ case PPC_PMC_PA6T:
+ /* PA Semi starts counting at PMC0 */
+ attrs = pa6t_attrs;
+- nattrs = sizeof(pa6t_attrs) / sizeof(struct sysdev_attribute);
++ nattrs = sizeof(pa6t_attrs) / sizeof(struct device_attribute);
+ pmc_attrs = NULL;
+ break;
+ #endif /* HAS_PPC_PMC_PA6T */
+@@ -444,24 +443,24 @@
+ }
+
+ for (i = 0; i < nattrs; i++)
+- sysdev_remove_file(s, &attrs[i]);
++ device_remove_file(s, &attrs[i]);
+
+ if (pmc_attrs)
+ for (i = 0; i < cur_cpu_spec->num_pmcs; i++)
+- sysdev_remove_file(s, &pmc_attrs[i]);
++ device_remove_file(s, &pmc_attrs[i]);
+
+ #ifdef CONFIG_PPC64
+ if (cpu_has_feature(CPU_FTR_MMCRA))
+- sysdev_remove_file(s, &attr_mmcra);
++ device_remove_file(s, &dev_attr_mmcra);
+
+ if (cpu_has_feature(CPU_FTR_PURR))
+- sysdev_remove_file(s, &attr_purr);
++ device_remove_file(s, &dev_attr_purr);
+
+ if (cpu_has_feature(CPU_FTR_SPURR))
+- sysdev_remove_file(s, &attr_spurr);
++ device_remove_file(s, &dev_attr_spurr);
+
+ if (cpu_has_feature(CPU_FTR_DSCR))
+- sysdev_remove_file(s, &attr_dscr);
++ device_remove_file(s, &dev_attr_dscr);
+ #endif /* CONFIG_PPC64 */
+
+ cacheinfo_cpu_offline(cpu);
+@@ -513,70 +512,70 @@
+
+ static DEFINE_MUTEX(cpu_mutex);
+
+-int cpu_add_sysdev_attr(struct sysdev_attribute *attr)
++int cpu_add_dev_attr(struct device_attribute *attr)
+ {
+ int cpu;
+
+ mutex_lock(&cpu_mutex);
+
+ for_each_possible_cpu(cpu) {
+- sysdev_create_file(get_cpu_sysdev(cpu), attr);
++ device_create_file(get_cpu_device(cpu), attr);
+ }
+
+ mutex_unlock(&cpu_mutex);
+ return 0;
+ }
+-EXPORT_SYMBOL_GPL(cpu_add_sysdev_attr);
++EXPORT_SYMBOL_GPL(cpu_add_dev_attr);
+
+-int cpu_add_sysdev_attr_group(struct attribute_group *attrs)
++int cpu_add_dev_attr_group(struct attribute_group *attrs)
+ {
+ int cpu;
+- struct sys_device *sysdev;
++ struct device *dev;
+ int ret;
+
+ mutex_lock(&cpu_mutex);
+
+ for_each_possible_cpu(cpu) {
+- sysdev = get_cpu_sysdev(cpu);
+- ret = sysfs_create_group(&sysdev->kobj, attrs);
++ dev = get_cpu_device(cpu);
++ ret = sysfs_create_group(&dev->kobj, attrs);
+ WARN_ON(ret != 0);
+ }
+
+ mutex_unlock(&cpu_mutex);
+ return 0;
+ }
+-EXPORT_SYMBOL_GPL(cpu_add_sysdev_attr_group);
++EXPORT_SYMBOL_GPL(cpu_add_dev_attr_group);
+
+
+-void cpu_remove_sysdev_attr(struct sysdev_attribute *attr)
++void cpu_remove_dev_attr(struct device_attribute *attr)
+ {
+ int cpu;
+
+ mutex_lock(&cpu_mutex);
+
+ for_each_possible_cpu(cpu) {
+- sysdev_remove_file(get_cpu_sysdev(cpu), attr);
++ device_remove_file(get_cpu_device(cpu), attr);
+ }
+
+ mutex_unlock(&cpu_mutex);
+ }
+-EXPORT_SYMBOL_GPL(cpu_remove_sysdev_attr);
++EXPORT_SYMBOL_GPL(cpu_remove_dev_attr);
+
+-void cpu_remove_sysdev_attr_group(struct attribute_group *attrs)
++void cpu_remove_dev_attr_group(struct attribute_group *attrs)
+ {
+ int cpu;
+- struct sys_device *sysdev;
++ struct device *dev;
+
+ mutex_lock(&cpu_mutex);
+
+ for_each_possible_cpu(cpu) {
+- sysdev = get_cpu_sysdev(cpu);
+- sysfs_remove_group(&sysdev->kobj, attrs);
++ dev = get_cpu_device(cpu);
++ sysfs_remove_group(&dev->kobj, attrs);
+ }
+
+ mutex_unlock(&cpu_mutex);
+ }
+-EXPORT_SYMBOL_GPL(cpu_remove_sysdev_attr_group);
++EXPORT_SYMBOL_GPL(cpu_remove_dev_attr_group);
+
+
+ /* NUMA stuff */
+@@ -590,7 +589,7 @@
+ register_one_node(i);
+ }
+
+-int sysfs_add_device_to_node(struct sys_device *dev, int nid)
++int sysfs_add_device_to_node(struct device *dev, int nid)
+ {
+ struct node *node = &node_devices[nid];
+ return sysfs_create_link(&node->sysdev.kobj, &dev->kobj,
+@@ -598,7 +597,7 @@
+ }
+ EXPORT_SYMBOL_GPL(sysfs_add_device_to_node);
+
+-void sysfs_remove_device_from_node(struct sys_device *dev, int nid)
++void sysfs_remove_device_from_node(struct device *dev, int nid)
+ {
+ struct node *node = &node_devices[nid];
+ sysfs_remove_link(&node->sysdev.kobj, kobject_name(&dev->kobj));
+@@ -614,14 +613,14 @@
+ #endif
+
+ /* Only valid if CPU is present. */
+-static ssize_t show_physical_id(struct sys_device *dev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t show_physical_id(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+- struct cpu *cpu = container_of(dev, struct cpu, sysdev);
++ struct cpu *cpu = container_of(dev, struct cpu, dev);
+
+- return sprintf(buf, "%d\n", get_hard_smp_processor_id(cpu->sysdev.id));
++ return sprintf(buf, "%d\n", get_hard_smp_processor_id(cpu->dev.id));
+ }
+-static SYSDEV_ATTR(physical_id, 0444, show_physical_id, NULL);
++static DEVICE_ATTR(physical_id, 0444, show_physical_id, NULL);
+
+ static int __init topology_init(void)
+ {
+@@ -646,7 +645,7 @@
+ if (cpu_online(cpu) || c->hotpluggable) {
+ register_cpu(c, cpu);
+
+- sysdev_create_file(&c->sysdev, &attr_physical_id);
++ device_create_file(&c->dev, &dev_attr_physical_id);
+ }
+
+ if (cpu_online(cpu))
+--- a/arch/powerpc/mm/numa.c
++++ b/arch/powerpc/mm/numa.c
+@@ -1462,7 +1462,7 @@
+ {
+ int cpu, nid, old_nid;
+ unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0};
+- struct sys_device *sysdev;
++ struct device *dev;
+
+ for_each_cpu(cpu,&cpu_associativity_changes_mask) {
+ vphn_get_associativity(cpu, associativity);
+@@ -1483,9 +1483,9 @@
+ register_cpu_under_node(cpu, nid);
+ put_online_cpus();
+
+- sysdev = get_cpu_sysdev(cpu);
+- if (sysdev)
+- kobject_uevent(&sysdev->kobj, KOBJ_CHANGE);
++ dev = get_cpu_device(cpu);
++ if (dev)
++ kobject_uevent(&dev->kobj, KOBJ_CHANGE);
+ }
+
+ return 1;
+--- a/arch/powerpc/platforms/cell/cbe_thermal.c
++++ b/arch/powerpc/platforms/cell/cbe_thermal.c
+@@ -46,7 +46,7 @@
+ */
+
+ #include <linux/module.h>
+-#include <linux/sysdev.h>
++#include <linux/device.h>
+ #include <linux/kernel.h>
+ #include <linux/cpu.h>
+ #include <asm/spu.h>
+@@ -59,8 +59,8 @@
+ #define TEMP_MIN 65
+ #define TEMP_MAX 125
+
+-#define SYSDEV_PREFIX_ATTR(_prefix,_name,_mode) \
+-struct sysdev_attribute attr_ ## _prefix ## _ ## _name = { \
++#define DEVICE_PREFIX_ATTR(_prefix,_name,_mode) \
++struct device_attribute attr_ ## _prefix ## _ ## _name = { \
+ .attr = { .name = __stringify(_name), .mode = _mode }, \
+ .show = _prefix ## _show_ ## _name, \
+ .store = _prefix ## _store_ ## _name, \
+@@ -76,36 +76,36 @@
+ return ((temp - TEMP_MIN) >> 1) & 0x3f;
+ }
+
+-static struct cbe_pmd_regs __iomem *get_pmd_regs(struct sys_device *sysdev)
++static struct cbe_pmd_regs __iomem *get_pmd_regs(struct device *dev)
+ {
+ struct spu *spu;
+
+- spu = container_of(sysdev, struct spu, sysdev);
++ spu = container_of(dev, struct spu, dev);
+
+ return cbe_get_pmd_regs(spu_devnode(spu));
+ }
+
+ /* returns the value for a given spu in a given register */
+-static u8 spu_read_register_value(struct sys_device *sysdev, union spe_reg __iomem *reg)
++static u8 spu_read_register_value(struct device *dev, union spe_reg __iomem *reg)
+ {
+ union spe_reg value;
+ struct spu *spu;
+
+- spu = container_of(sysdev, struct spu, sysdev);
++ spu = container_of(dev, struct spu, dev);
+ value.val = in_be64(®->val);
+
+ return value.spe[spu->spe_id];
+ }
+
+-static ssize_t spu_show_temp(struct sys_device *sysdev, struct sysdev_attribute *attr,
++static ssize_t spu_show_temp(struct device *dev, struct device_attribute *attr,
+ char *buf)
+ {
+ u8 value;
+ struct cbe_pmd_regs __iomem *pmd_regs;
+
+- pmd_regs = get_pmd_regs(sysdev);
++ pmd_regs = get_pmd_regs(dev);
+
+- value = spu_read_register_value(sysdev, &pmd_regs->ts_ctsr1);
++ value = spu_read_register_value(dev, &pmd_regs->ts_ctsr1);
+
+ return sprintf(buf, "%d\n", reg_to_temp(value));
+ }
+@@ -147,48 +147,48 @@
+ return size;
+ }
+
+-static ssize_t spu_show_throttle_end(struct sys_device *sysdev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t spu_show_throttle_end(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+- return show_throttle(get_pmd_regs(sysdev), buf, 0);
++ return show_throttle(get_pmd_regs(dev), buf, 0);
+ }
+
+-static ssize_t spu_show_throttle_begin(struct sys_device *sysdev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t spu_show_throttle_begin(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+- return show_throttle(get_pmd_regs(sysdev), buf, 8);
++ return show_throttle(get_pmd_regs(dev), buf, 8);
+ }
+
+-static ssize_t spu_show_throttle_full_stop(struct sys_device *sysdev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t spu_show_throttle_full_stop(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+- return show_throttle(get_pmd_regs(sysdev), buf, 16);
++ return show_throttle(get_pmd_regs(dev), buf, 16);
+ }
+
+-static ssize_t spu_store_throttle_end(struct sys_device *sysdev,
+- struct sysdev_attribute *attr, const char *buf, size_t size)
++static ssize_t spu_store_throttle_end(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t size)
+ {
+- return store_throttle(get_pmd_regs(sysdev), buf, size, 0);
++ return store_throttle(get_pmd_regs(dev), buf, size, 0);
+ }
+
+-static ssize_t spu_store_throttle_begin(struct sys_device *sysdev,
+- struct sysdev_attribute *attr, const char *buf, size_t size)
++static ssize_t spu_store_throttle_begin(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t size)
+ {
+- return store_throttle(get_pmd_regs(sysdev), buf, size, 8);
++ return store_throttle(get_pmd_regs(dev), buf, size, 8);
+ }
+
+-static ssize_t spu_store_throttle_full_stop(struct sys_device *sysdev,
+- struct sysdev_attribute *attr, const char *buf, size_t size)
++static ssize_t spu_store_throttle_full_stop(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t size)
+ {
+- return store_throttle(get_pmd_regs(sysdev), buf, size, 16);
++ return store_throttle(get_pmd_regs(dev), buf, size, 16);
+ }
+
+-static ssize_t ppe_show_temp(struct sys_device *sysdev, char *buf, int pos)
++static ssize_t ppe_show_temp(struct device *dev, char *buf, int pos)
+ {
+ struct cbe_pmd_regs __iomem *pmd_regs;
+ u64 value;
+
+- pmd_regs = cbe_get_cpu_pmd_regs(sysdev->id);
++ pmd_regs = cbe_get_cpu_pmd_regs(dev->id);
+ value = in_be64(&pmd_regs->ts_ctsr2);
+
+ value = (value >> pos) & 0x3f;
+@@ -199,64 +199,64 @@
+
+ /* shows the temperature of the DTS on the PPE,
+ * located near the linear thermal sensor */
+-static ssize_t ppe_show_temp0(struct sys_device *sysdev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t ppe_show_temp0(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+- return ppe_show_temp(sysdev, buf, 32);
++ return ppe_show_temp(dev, buf, 32);
+ }
+
+ /* shows the temperature of the second DTS on the PPE */
+-static ssize_t ppe_show_temp1(struct sys_device *sysdev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t ppe_show_temp1(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+- return ppe_show_temp(sysdev, buf, 0);
++ return ppe_show_temp(dev, buf, 0);
+ }
+
+-static ssize_t ppe_show_throttle_end(struct sys_device *sysdev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t ppe_show_throttle_end(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+- return show_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, 32);
++ return show_throttle(cbe_get_cpu_pmd_regs(dev->id), buf, 32);
+ }
+
+-static ssize_t ppe_show_throttle_begin(struct sys_device *sysdev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t ppe_show_throttle_begin(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+- return show_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, 40);
++ return show_throttle(cbe_get_cpu_pmd_regs(dev->id), buf, 40);
+ }
+
+-static ssize_t ppe_show_throttle_full_stop(struct sys_device *sysdev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t ppe_show_throttle_full_stop(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+- return show_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, 48);
++ return show_throttle(cbe_get_cpu_pmd_regs(dev->id), buf, 48);
+ }
+
+-static ssize_t ppe_store_throttle_end(struct sys_device *sysdev,
+- struct sysdev_attribute *attr, const char *buf, size_t size)
++static ssize_t ppe_store_throttle_end(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t size)
+ {
+- return store_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, size, 32);
++ return store_throttle(cbe_get_cpu_pmd_regs(dev->id), buf, size, 32);
+ }
+
+-static ssize_t ppe_store_throttle_begin(struct sys_device *sysdev,
+- struct sysdev_attribute *attr, const char *buf, size_t size)
++static ssize_t ppe_store_throttle_begin(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t size)
+ {
+- return store_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, size, 40);
++ return store_throttle(cbe_get_cpu_pmd_regs(dev->id), buf, size, 40);
+ }
+
+-static ssize_t ppe_store_throttle_full_stop(struct sys_device *sysdev,
+- struct sysdev_attribute *attr, const char *buf, size_t size)
++static ssize_t ppe_store_throttle_full_stop(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t size)
+ {
+- return store_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, size, 48);
++ return store_throttle(cbe_get_cpu_pmd_regs(dev->id), buf, size, 48);
+ }
+
+
+-static struct sysdev_attribute attr_spu_temperature = {
++static struct device_attribute attr_spu_temperature = {
+ .attr = {.name = "temperature", .mode = 0400 },
+ .show = spu_show_temp,
+ };
+
+-static SYSDEV_PREFIX_ATTR(spu, throttle_end, 0600);
+-static SYSDEV_PREFIX_ATTR(spu, throttle_begin, 0600);
+-static SYSDEV_PREFIX_ATTR(spu, throttle_full_stop, 0600);
++static DEVICE_PREFIX_ATTR(spu, throttle_end, 0600);
++static DEVICE_PREFIX_ATTR(spu, throttle_begin, 0600);
++static DEVICE_PREFIX_ATTR(spu, throttle_full_stop, 0600);
+
+
+ static struct attribute *spu_attributes[] = {
+@@ -272,19 +272,19 @@
+ .attrs = spu_attributes,
+ };
+
+-static struct sysdev_attribute attr_ppe_temperature0 = {
++static struct device_attribute attr_ppe_temperature0 = {
+ .attr = {.name = "temperature0", .mode = 0400 },
+ .show = ppe_show_temp0,
+ };
+
+-static struct sysdev_attribute attr_ppe_temperature1 = {
++static struct device_attribute attr_ppe_temperature1 = {
+ .attr = {.name = "temperature1", .mode = 0400 },
+ .show = ppe_show_temp1,
+ };
+
+-static SYSDEV_PREFIX_ATTR(ppe, throttle_end, 0600);
+-static SYSDEV_PREFIX_ATTR(ppe, throttle_begin, 0600);
+-static SYSDEV_PREFIX_ATTR(ppe, throttle_full_stop, 0600);
++static DEVICE_PREFIX_ATTR(ppe, throttle_end, 0600);
++static DEVICE_PREFIX_ATTR(ppe, throttle_begin, 0600);
++static DEVICE_PREFIX_ATTR(ppe, throttle_full_stop, 0600);
+
+ static struct attribute *ppe_attributes[] = {
+ &attr_ppe_temperature0.attr,
+@@ -307,7 +307,7 @@
+ {
+ int cpu;
+ struct cbe_pmd_regs __iomem *pmd_regs;
+- struct sys_device *sysdev;
++ struct device *dev;
+ union ppe_spe_reg tpr;
+ union spe_reg str1;
+ u64 str2;
+@@ -349,14 +349,14 @@
+
+ for_each_possible_cpu (cpu) {
+ pr_debug("processing cpu %d\n", cpu);
+- sysdev = get_cpu_sysdev(cpu);
++ dev = get_cpu_device(cpu);
+
+- if (!sysdev) {
+- pr_info("invalid sysdev pointer for cbe_thermal\n");
++ if (!dev) {
++ pr_info("invalid dev pointer for cbe_thermal\n");
+ return -EINVAL;
+ }
+
+- pmd_regs = cbe_get_cpu_pmd_regs(sysdev->id);
++ pmd_regs = cbe_get_cpu_pmd_regs(dev->id);
+
+ if (!pmd_regs) {
+ pr_info("invalid CBE regs pointer for cbe_thermal\n");
+@@ -379,8 +379,8 @@
+ int rc = init_default_values();
+
+ if (rc == 0) {
+- spu_add_sysdev_attr_group(&spu_attribute_group);
+- cpu_add_sysdev_attr_group(&ppe_attribute_group);
++ spu_add_dev_attr_group(&spu_attribute_group);
++ cpu_add_dev_attr_group(&ppe_attribute_group);
+ }
+
+ return rc;
+@@ -389,8 +389,8 @@
+
+ static void __exit thermal_exit(void)
+ {
+- spu_remove_sysdev_attr_group(&spu_attribute_group);
+- cpu_remove_sysdev_attr_group(&ppe_attribute_group);
++ spu_remove_dev_attr_group(&spu_attribute_group);
++ cpu_remove_dev_attr_group(&ppe_attribute_group);
+ }
+ module_exit(thermal_exit);
+
+--- a/arch/powerpc/platforms/cell/spu_base.c
++++ b/arch/powerpc/platforms/cell/spu_base.c
+@@ -519,31 +519,32 @@
+ }
+ EXPORT_SYMBOL_GPL(spu_init_channels);
+
+-static struct sysdev_class spu_sysdev_class = {
++static struct bus_type spu_subsys = {
+ .name = "spu",
++ .dev_name = "spu",
+ };
+
+-int spu_add_sysdev_attr(struct sysdev_attribute *attr)
++int spu_add_dev_attr(struct device_attribute *attr)
+ {
+ struct spu *spu;
+
+ mutex_lock(&spu_full_list_mutex);
+ list_for_each_entry(spu, &spu_full_list, full_list)
+- sysdev_create_file(&spu->sysdev, attr);
++ device_create_file(&spu->dev, attr);
+ mutex_unlock(&spu_full_list_mutex);
+
+ return 0;
+ }
+-EXPORT_SYMBOL_GPL(spu_add_sysdev_attr);
++EXPORT_SYMBOL_GPL(spu_add_dev_attr);
+
+-int spu_add_sysdev_attr_group(struct attribute_group *attrs)
++int spu_add_dev_attr_group(struct attribute_group *attrs)
+ {
+ struct spu *spu;
+ int rc = 0;
+
+ mutex_lock(&spu_full_list_mutex);
+ list_for_each_entry(spu, &spu_full_list, full_list) {
+- rc = sysfs_create_group(&spu->sysdev.kobj, attrs);
++ rc = sysfs_create_group(&spu->dev.kobj, attrs);
+
+ /* we're in trouble here, but try unwinding anyway */
+ if (rc) {
+@@ -552,7 +553,7 @@
+
+ list_for_each_entry_continue_reverse(spu,
+ &spu_full_list, full_list)
+- sysfs_remove_group(&spu->sysdev.kobj, attrs);
++ sysfs_remove_group(&spu->dev.kobj, attrs);
+ break;
+ }
+ }
+@@ -561,45 +562,45 @@
+
+ return rc;
+ }
+-EXPORT_SYMBOL_GPL(spu_add_sysdev_attr_group);
++EXPORT_SYMBOL_GPL(spu_add_dev_attr_group);
+
+
+-void spu_remove_sysdev_attr(struct sysdev_attribute *attr)
++void spu_remove_dev_attr(struct device_attribute *attr)
+ {
+ struct spu *spu;
+
+ mutex_lock(&spu_full_list_mutex);
+ list_for_each_entry(spu, &spu_full_list, full_list)
+- sysdev_remove_file(&spu->sysdev, attr);
++ device_remove_file(&spu->dev, attr);
+ mutex_unlock(&spu_full_list_mutex);
+ }
+-EXPORT_SYMBOL_GPL(spu_remove_sysdev_attr);
++EXPORT_SYMBOL_GPL(spu_remove_dev_attr);
+
+-void spu_remove_sysdev_attr_group(struct attribute_group *attrs)
++void spu_remove_dev_attr_group(struct attribute_group *attrs)
+ {
+ struct spu *spu;
+
+ mutex_lock(&spu_full_list_mutex);
+ list_for_each_entry(spu, &spu_full_list, full_list)
+- sysfs_remove_group(&spu->sysdev.kobj, attrs);
++ sysfs_remove_group(&spu->dev.kobj, attrs);
+ mutex_unlock(&spu_full_list_mutex);
+ }
+-EXPORT_SYMBOL_GPL(spu_remove_sysdev_attr_group);
++EXPORT_SYMBOL_GPL(spu_remove_dev_attr_group);
+
+-static int spu_create_sysdev(struct spu *spu)
++static int spu_create_dev(struct spu *spu)
+ {
+ int ret;
+
+- spu->sysdev.id = spu->number;
+- spu->sysdev.cls = &spu_sysdev_class;
+- ret = sysdev_register(&spu->sysdev);
++ spu->dev.id = spu->number;
++ spu->dev.bus = &spu_subsys;
++ ret = device_register(&spu->dev);
+ if (ret) {
+ printk(KERN_ERR "Can't register SPU %d with sysfs\n",
+ spu->number);
+ return ret;
+ }
+
+- sysfs_add_device_to_node(&spu->sysdev, spu->node);
++ sysfs_add_device_to_node(&spu->dev, spu->node);
+
+ return 0;
+ }
+@@ -635,7 +636,7 @@
+ if (ret)
+ goto out_destroy;
+
+- ret = spu_create_sysdev(spu);
++ ret = spu_create_dev(spu);
+ if (ret)
+ goto out_free_irqs;
+
+@@ -692,10 +693,10 @@
+ }
+
+
+-static ssize_t spu_stat_show(struct sys_device *sysdev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t spu_stat_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+- struct spu *spu = container_of(sysdev, struct spu, sysdev);
++ struct spu *spu = container_of(dev, struct spu, dev);
+
+ return sprintf(buf, "%s %llu %llu %llu %llu "
+ "%llu %llu %llu %llu %llu %llu %llu %llu\n",
+@@ -714,7 +715,7 @@
+ spu->stats.libassist);
+ }
+
+-static SYSDEV_ATTR(stat, 0644, spu_stat_show, NULL);
++static DEVICE_ATTR(stat, 0644, spu_stat_show, NULL);
+
+ #ifdef CONFIG_KEXEC
+
+@@ -813,8 +814,8 @@
+ if (!spu_management_ops)
+ goto out;
+
+- /* create sysdev class for spus */
+- ret = sysdev_class_register(&spu_sysdev_class);
++ /* create system subsystem for spus */
++ ret = subsys_system_register(&spu_subsys, NULL);
+ if (ret)
+ goto out;
+
+@@ -823,7 +824,7 @@
+ if (ret < 0) {
+ printk(KERN_WARNING "%s: Error initializing spus\n",
+ __func__);
+- goto out_unregister_sysdev_class;
++ goto out_unregister_subsys;
+ }
+
+ if (ret > 0)
+@@ -833,15 +834,15 @@
+ xmon_register_spus(&spu_full_list);
+ crash_register_spus(&spu_full_list);
+ mutex_unlock(&spu_full_list_mutex);
+- spu_add_sysdev_attr(&attr_stat);
++ spu_add_dev_attr(&dev_attr_stat);
+ register_syscore_ops(&spu_syscore_ops);
+
+ spu_init_affinity();
+
+ return 0;
+
+- out_unregister_sysdev_class:
+- sysdev_class_unregister(&spu_sysdev_class);
++ out_unregister_subsys:
++ bus_unregister(&spu_subsys);
+ out:
+ return ret;
+ }
+--- a/arch/powerpc/platforms/pseries/pseries_energy.c
++++ b/arch/powerpc/platforms/pseries/pseries_energy.c
+@@ -15,7 +15,7 @@
+ #include <linux/errno.h>
+ #include <linux/init.h>
+ #include <linux/seq_file.h>
+-#include <linux/sysdev.h>
++#include <linux/device.h>
+ #include <linux/cpu.h>
+ #include <linux/of.h>
+ #include <asm/cputhreads.h>
+@@ -184,7 +184,7 @@
+ return s-page;
+ }
+
+-static ssize_t get_best_energy_data(struct sys_device *dev,
++static ssize_t get_best_energy_data(struct device *dev,
+ char *page, int activate)
+ {
+ int rc;
+@@ -207,26 +207,26 @@
+
+ /* Wrapper functions */
+
+-static ssize_t cpu_activate_hint_list_show(struct sysdev_class *class,
+- struct sysdev_class_attribute *attr, char *page)
++static ssize_t cpu_activate_hint_list_show(struct device *dev,
++ struct device_attribute *attr, char *page)
+ {
+ return get_best_energy_list(page, 1);
+ }
+
+-static ssize_t cpu_deactivate_hint_list_show(struct sysdev_class *class,
+- struct sysdev_class_attribute *attr, char *page)
++static ssize_t cpu_deactivate_hint_list_show(struct device *dev,
++ struct device_attribute *attr, char *page)
+ {
+ return get_best_energy_list(page, 0);
+ }
+
+-static ssize_t percpu_activate_hint_show(struct sys_device *dev,
+- struct sysdev_attribute *attr, char *page)
++static ssize_t percpu_activate_hint_show(struct device *dev,
++ struct device_attribute *attr, char *page)
+ {
+ return get_best_energy_data(dev, page, 1);
+ }
+
+-static ssize_t percpu_deactivate_hint_show(struct sys_device *dev,
+- struct sysdev_attribute *attr, char *page)
++static ssize_t percpu_deactivate_hint_show(struct device *dev,
++ struct device_attribute *attr, char *page)
+ {
+ return get_best_energy_data(dev, page, 0);
+ }
+@@ -241,48 +241,48 @@
+ * Per-cpu value of the hint
+ */
+
+-struct sysdev_class_attribute attr_cpu_activate_hint_list =
+- _SYSDEV_CLASS_ATTR(pseries_activate_hint_list, 0444,
++struct device_attribute attr_cpu_activate_hint_list =
++ __ATTR(pseries_activate_hint_list, 0444,
+ cpu_activate_hint_list_show, NULL);
+
+-struct sysdev_class_attribute attr_cpu_deactivate_hint_list =
+- _SYSDEV_CLASS_ATTR(pseries_deactivate_hint_list, 0444,
++struct device_attribute attr_cpu_deactivate_hint_list =
++ __ATTR(pseries_deactivate_hint_list, 0444,
+ cpu_deactivate_hint_list_show, NULL);
+
+-struct sysdev_attribute attr_percpu_activate_hint =
+- _SYSDEV_ATTR(pseries_activate_hint, 0444,
++struct device_attribute attr_percpu_activate_hint =
++ __ATTR(pseries_activate_hint, 0444,
+ percpu_activate_hint_show, NULL);
+
+-struct sysdev_attribute attr_percpu_deactivate_hint =
+- _SYSDEV_ATTR(pseries_deactivate_hint, 0444,
++struct device_attribute attr_percpu_deactivate_hint =
++ __ATTR(pseries_deactivate_hint, 0444,
+ percpu_deactivate_hint_show, NULL);
+
+ static int __init pseries_energy_init(void)
+ {
+ int cpu, err;
+- struct sys_device *cpu_sys_dev;
++ struct device *cpu_dev;
+
+ if (!check_for_h_best_energy()) {
+ printk(KERN_INFO "Hypercall H_BEST_ENERGY not supported\n");
+ return 0;
+ }
+ /* Create the sysfs files */
+- err = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
+- &attr_cpu_activate_hint_list.attr);
++ err = device_create_file(cpu_subsys.dev_root,
++ &attr_cpu_activate_hint_list);
+ if (!err)
+- err = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
+- &attr_cpu_deactivate_hint_list.attr);
++ err = device_create_file(cpu_subsys.dev_root,
++ &attr_cpu_deactivate_hint_list);
+
+ if (err)
+ return err;
+ for_each_possible_cpu(cpu) {
+- cpu_sys_dev = get_cpu_sysdev(cpu);
+- err = sysfs_create_file(&cpu_sys_dev->kobj,
+- &attr_percpu_activate_hint.attr);
++ cpu_dev = get_cpu_device(cpu);
++ err = device_create_file(cpu_dev,
++ &attr_percpu_activate_hint);
+ if (err)
+ break;
+- err = sysfs_create_file(&cpu_sys_dev->kobj,
+- &attr_percpu_deactivate_hint.attr);
++ err = device_create_file(cpu_dev,
++ &attr_percpu_deactivate_hint);
+ if (err)
+ break;
+ }
+@@ -298,23 +298,20 @@
+ static void __exit pseries_energy_cleanup(void)
+ {
+ int cpu;
+- struct sys_device *cpu_sys_dev;
++ struct device *cpu_dev;
+
+ if (!sysfs_entries)
+ return;
+
+ /* Remove the sysfs files */
+- sysfs_remove_file(&cpu_sysdev_class.kset.kobj,
+- &attr_cpu_activate_hint_list.attr);
+-
+- sysfs_remove_file(&cpu_sysdev_class.kset.kobj,
+- &attr_cpu_deactivate_hint_list.attr);
++ device_remove_file(cpu_subsys.dev_root, &attr_cpu_activate_hint_list);
++ device_remove_file(cpu_subsys.dev_root, &attr_cpu_deactivate_hint_list);
+
+ for_each_possible_cpu(cpu) {
+- cpu_sys_dev = get_cpu_sysdev(cpu);
+- sysfs_remove_file(&cpu_sys_dev->kobj,
++ cpu_dev = get_cpu_device(cpu);
++ sysfs_remove_file(&cpu_dev->kobj,
+ &attr_percpu_activate_hint.attr);
+- sysfs_remove_file(&cpu_sys_dev->kobj,
++ sysfs_remove_file(&cpu_dev->kobj,
+ &attr_percpu_deactivate_hint.attr);
+ }
+ }
+--- a/arch/powerpc/sysdev/ppc4xx_cpm.c
++++ b/arch/powerpc/sysdev/ppc4xx_cpm.c
+@@ -179,12 +179,12 @@
+
+ static void cpm_idle_config_sysfs(void)
+ {
+- struct sys_device *sys_dev;
++ struct device *dev;
+ unsigned long ret;
+
+- sys_dev = get_cpu_sysdev(0);
++ dev = get_cpu_device(0);
+
+- ret = sysfs_create_file(&sys_dev->kobj,
++ ret = sysfs_create_file(&dev->kobj,
+ &cpm_idle_attr.attr);
+ if (ret)
+ printk(KERN_WARNING
+--- a/arch/s390/kernel/smp.c
++++ b/arch/s390/kernel/smp.c
+@@ -831,8 +831,8 @@
+ }
+
+ #ifdef CONFIG_HOTPLUG_CPU
+-static ssize_t cpu_configure_show(struct sys_device *dev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t cpu_configure_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+ ssize_t count;
+
+@@ -842,8 +842,8 @@
+ return count;
+ }
+
+-static ssize_t cpu_configure_store(struct sys_device *dev,
+- struct sysdev_attribute *attr,
++static ssize_t cpu_configure_store(struct device *dev,
++ struct device_attribute *attr,
+ const char *buf, size_t count)
+ {
+ int cpu = dev->id;
+@@ -889,11 +889,11 @@
+ put_online_cpus();
+ return rc ? rc : count;
+ }
+-static SYSDEV_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store);
++static DEVICE_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store);
+ #endif /* CONFIG_HOTPLUG_CPU */
+
+-static ssize_t cpu_polarization_show(struct sys_device *dev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t cpu_polarization_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+ int cpu = dev->id;
+ ssize_t count;
+@@ -919,22 +919,22 @@
+ mutex_unlock(&smp_cpu_state_mutex);
+ return count;
+ }
+-static SYSDEV_ATTR(polarization, 0444, cpu_polarization_show, NULL);
++static DEVICE_ATTR(polarization, 0444, cpu_polarization_show, NULL);
+
+-static ssize_t show_cpu_address(struct sys_device *dev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t show_cpu_address(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+ return sprintf(buf, "%d\n", __cpu_logical_map[dev->id]);
+ }
+-static SYSDEV_ATTR(address, 0444, show_cpu_address, NULL);
++static DEVICE_ATTR(address, 0444, show_cpu_address, NULL);
+
+
+ static struct attribute *cpu_common_attrs[] = {
+ #ifdef CONFIG_HOTPLUG_CPU
+- &attr_configure.attr,
++ &dev_attr_configure.attr,
+ #endif
+- &attr_address.attr,
+- &attr_polarization.attr,
++ &dev_attr_address.attr,
++ &dev_attr_polarization.attr,
+ NULL,
+ };
+
+@@ -942,8 +942,8 @@
+ .attrs = cpu_common_attrs,
+ };
+
+-static ssize_t show_capability(struct sys_device *dev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t show_capability(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+ unsigned int capability;
+ int rc;
+@@ -953,10 +953,10 @@
+ return rc;
+ return sprintf(buf, "%u\n", capability);
+ }
+-static SYSDEV_ATTR(capability, 0444, show_capability, NULL);
++static DEVICE_ATTR(capability, 0444, show_capability, NULL);
+
+-static ssize_t show_idle_count(struct sys_device *dev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t show_idle_count(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+ struct s390_idle_data *idle;
+ unsigned long long idle_count;
+@@ -976,10 +976,10 @@
+ goto repeat;
+ return sprintf(buf, "%llu\n", idle_count);
+ }
+-static SYSDEV_ATTR(idle_count, 0444, show_idle_count, NULL);
++static DEVICE_ATTR(idle_count, 0444, show_idle_count, NULL);
+
+-static ssize_t show_idle_time(struct sys_device *dev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t show_idle_time(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+ struct s390_idle_data *idle;
+ unsigned long long now, idle_time, idle_enter;
+@@ -1001,12 +1001,12 @@
+ goto repeat;
+ return sprintf(buf, "%llu\n", idle_time >> 12);
+ }
+-static SYSDEV_ATTR(idle_time_us, 0444, show_idle_time, NULL);
++static DEVICE_ATTR(idle_time_us, 0444, show_idle_time, NULL);
+
+ static struct attribute *cpu_online_attrs[] = {
+- &attr_capability.attr,
+- &attr_idle_count.attr,
+- &attr_idle_time_us.attr,
++ &dev_attr_capability.attr,
++ &dev_attr_idle_count.attr,
++ &dev_attr_idle_time_us.attr,
+ NULL,
+ };
+
+@@ -1019,7 +1019,7 @@
+ {
+ unsigned int cpu = (unsigned int)(long)hcpu;
+ struct cpu *c = &per_cpu(cpu_devices, cpu);
+- struct sys_device *s = &c->sysdev;
++ struct device *s = &c->dev;
+ struct s390_idle_data *idle;
+ int err = 0;
+
+@@ -1045,7 +1045,7 @@
+ static int __devinit smp_add_present_cpu(int cpu)
+ {
+ struct cpu *c = &per_cpu(cpu_devices, cpu);
+- struct sys_device *s = &c->sysdev;
++ struct device *s = &c->dev;
+ int rc;
+
+ c->hotpluggable = 1;
+@@ -1098,8 +1098,8 @@
+ return rc;
+ }
+
+-static ssize_t __ref rescan_store(struct sysdev_class *class,
+- struct sysdev_class_attribute *attr,
++static ssize_t __ref rescan_store(struct device *dev,
++ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+ {
+@@ -1108,11 +1108,11 @@
+ rc = smp_rescan_cpus();
+ return rc ? rc : count;
+ }
+-static SYSDEV_CLASS_ATTR(rescan, 0200, NULL, rescan_store);
++static DEVICE_ATTR(rescan, 0200, NULL, rescan_store);
+ #endif /* CONFIG_HOTPLUG_CPU */
+
+-static ssize_t dispatching_show(struct sysdev_class *class,
+- struct sysdev_class_attribute *attr,
++static ssize_t dispatching_show(struct device *dev,
++ struct device_attribute *attr,
+ char *buf)
+ {
+ ssize_t count;
+@@ -1123,8 +1123,8 @@
+ return count;
+ }
+
+-static ssize_t dispatching_store(struct sysdev_class *dev,
+- struct sysdev_class_attribute *attr,
++static ssize_t dispatching_store(struct device *dev,
++ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+ {
+@@ -1148,7 +1148,7 @@
+ put_online_cpus();
+ return rc ? rc : count;
+ }
+-static SYSDEV_CLASS_ATTR(dispatching, 0644, dispatching_show,
++static DEVICE_ATTR(dispatching, 0644, dispatching_show,
+ dispatching_store);
+
+ static int __init topology_init(void)
+@@ -1159,11 +1159,11 @@
+ register_cpu_notifier(&smp_cpu_nb);
+
+ #ifdef CONFIG_HOTPLUG_CPU
+- rc = sysdev_class_create_file(&cpu_sysdev_class, &attr_rescan);
++ rc = device_create_file(cpu_subsys.dev_root, &dev_attr_rescan);
+ if (rc)
+ return rc;
+ #endif
+- rc = sysdev_class_create_file(&cpu_sysdev_class, &attr_dispatching);
++ rc = device_create_file(cpu_subsys.dev_root, &dev_attr_dispatching);
+ if (rc)
+ return rc;
+ for_each_present_cpu(cpu) {
+--- a/arch/s390/kernel/topology.c
++++ b/arch/s390/kernel/topology.c
+@@ -261,7 +261,7 @@
+ int arch_update_cpu_topology(void)
+ {
+ struct sysinfo_15_1_x *info = tl_info;
+- struct sys_device *sysdev;
++ struct device *dev;
+ int cpu;
+
+ if (!MACHINE_HAS_TOPOLOGY) {
+@@ -273,8 +273,8 @@
+ tl_to_cores(info);
+ update_cpu_core_map();
+ for_each_online_cpu(cpu) {
+- sysdev = get_cpu_sysdev(cpu);
+- kobject_uevent(&sysdev->kobj, KOBJ_CHANGE);
++ dev = get_cpu_device(cpu);
++ kobject_uevent(&dev->kobj, KOBJ_CHANGE);
+ }
+ return 1;
+ }
+--- a/arch/sh/kernel/cpu/sh4/sq.c
++++ b/arch/sh/kernel/cpu/sh4/sq.c
+@@ -13,7 +13,7 @@
+ #include <linux/init.h>
+ #include <linux/cpu.h>
+ #include <linux/bitmap.h>
+-#include <linux/sysdev.h>
++#include <linux/device.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
+@@ -337,9 +337,9 @@
+ .default_attrs = sq_sysfs_attrs,
+ };
+
+-static int __devinit sq_sysdev_add(struct sys_device *sysdev)
++static int __devinit sq_dev_add(struct device *dev)
+ {
+- unsigned int cpu = sysdev->id;
++ unsigned int cpu = dev->id;
+ struct kobject *kobj;
+ int error;
+
+@@ -348,25 +348,27 @@
+ return -ENOMEM;
+
+ kobj = sq_kobject[cpu];
+- error = kobject_init_and_add(kobj, &ktype_percpu_entry, &sysdev->kobj,
++ error = kobject_init_and_add(kobj, &ktype_percpu_entry, &dev->kobj,
+ "%s", "sq");
+ if (!error)
+ kobject_uevent(kobj, KOBJ_ADD);
+ return error;
+ }
+
+-static int __devexit sq_sysdev_remove(struct sys_device *sysdev)
++static int __devexit sq_dev_remove(struct device *dev)
+ {
+- unsigned int cpu = sysdev->id;
++ unsigned int cpu = dev->id;
+ struct kobject *kobj = sq_kobject[cpu];
+
+ kobject_put(kobj);
+ return 0;
+ }
+
+-static struct sysdev_driver sq_sysdev_driver = {
+- .add = sq_sysdev_add,
+- .remove = __devexit_p(sq_sysdev_remove),
++static struct subsys_interface sq_interface = {
++ .name = "sq"
++ .subsys = &cpu_subsys,
++ .add_dev = sq_dev_add,
++ .remove_dev = __devexit_p(sq_dev_remove),
+ };
+
+ static int __init sq_api_init(void)
+@@ -386,7 +388,7 @@
+ if (unlikely(!sq_bitmap))
+ goto out;
+
+- ret = sysdev_driver_register(&cpu_sysdev_class, &sq_sysdev_driver);
++ ret = subsys_interface_register(&sq_interface);
+ if (unlikely(ret != 0))
+ goto out;
+
+@@ -401,7 +403,7 @@
+
+ static void __exit sq_api_exit(void)
+ {
+- sysdev_driver_unregister(&cpu_sysdev_class, &sq_sysdev_driver);
++ subsys_interface_unregister(&sq_interface);
+ kfree(sq_bitmap);
+ kmem_cache_destroy(sq_cache);
+ }
+--- a/arch/sparc/kernel/sysfs.c
++++ b/arch/sparc/kernel/sysfs.c
+@@ -3,7 +3,7 @@
+ * Copyright (C) 2007 David S. Miller <davem at davemloft.net>
+ */
+ #include <linux/sched.h>
+-#include <linux/sysdev.h>
++#include <linux/device.h>
+ #include <linux/cpu.h>
+ #include <linux/smp.h>
+ #include <linux/percpu.h>
+@@ -16,13 +16,13 @@
+ static DEFINE_PER_CPU(struct hv_mmu_statistics, mmu_stats) __attribute__((aligned(64)));
+
+ #define SHOW_MMUSTAT_ULONG(NAME) \
+-static ssize_t show_##NAME(struct sys_device *dev, \
+- struct sysdev_attribute *attr, char *buf) \
++static ssize_t show_##NAME(struct device *dev, \
++ struct device_attribute *attr, char *buf) \
+ { \
+ struct hv_mmu_statistics *p = &per_cpu(mmu_stats, dev->id); \
+ return sprintf(buf, "%lu\n", p->NAME); \
+ } \
+-static SYSDEV_ATTR(NAME, 0444, show_##NAME, NULL)
++static DEVICE_ATTR(NAME, 0444, show_##NAME, NULL)
+
+ SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctx0_8k_tte);
+ SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctx0_8k_tte);
+@@ -58,38 +58,38 @@
+ SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctxnon0_256mb_tte);
+
+ static struct attribute *mmu_stat_attrs[] = {
+- &attr_immu_tsb_hits_ctx0_8k_tte.attr,
+- &attr_immu_tsb_ticks_ctx0_8k_tte.attr,
+- &attr_immu_tsb_hits_ctx0_64k_tte.attr,
+- &attr_immu_tsb_ticks_ctx0_64k_tte.attr,
+- &attr_immu_tsb_hits_ctx0_4mb_tte.attr,
+- &attr_immu_tsb_ticks_ctx0_4mb_tte.attr,
+- &attr_immu_tsb_hits_ctx0_256mb_tte.attr,
+- &attr_immu_tsb_ticks_ctx0_256mb_tte.attr,
+- &attr_immu_tsb_hits_ctxnon0_8k_tte.attr,
+- &attr_immu_tsb_ticks_ctxnon0_8k_tte.attr,
+- &attr_immu_tsb_hits_ctxnon0_64k_tte.attr,
+- &attr_immu_tsb_ticks_ctxnon0_64k_tte.attr,
+- &attr_immu_tsb_hits_ctxnon0_4mb_tte.attr,
+- &attr_immu_tsb_ticks_ctxnon0_4mb_tte.attr,
+- &attr_immu_tsb_hits_ctxnon0_256mb_tte.attr,
+- &attr_immu_tsb_ticks_ctxnon0_256mb_tte.attr,
+- &attr_dmmu_tsb_hits_ctx0_8k_tte.attr,
+- &attr_dmmu_tsb_ticks_ctx0_8k_tte.attr,
+- &attr_dmmu_tsb_hits_ctx0_64k_tte.attr,
+- &attr_dmmu_tsb_ticks_ctx0_64k_tte.attr,
+- &attr_dmmu_tsb_hits_ctx0_4mb_tte.attr,
+- &attr_dmmu_tsb_ticks_ctx0_4mb_tte.attr,
+- &attr_dmmu_tsb_hits_ctx0_256mb_tte.attr,
+- &attr_dmmu_tsb_ticks_ctx0_256mb_tte.attr,
+- &attr_dmmu_tsb_hits_ctxnon0_8k_tte.attr,
+- &attr_dmmu_tsb_ticks_ctxnon0_8k_tte.attr,
+- &attr_dmmu_tsb_hits_ctxnon0_64k_tte.attr,
+- &attr_dmmu_tsb_ticks_ctxnon0_64k_tte.attr,
+- &attr_dmmu_tsb_hits_ctxnon0_4mb_tte.attr,
+- &attr_dmmu_tsb_ticks_ctxnon0_4mb_tte.attr,
+- &attr_dmmu_tsb_hits_ctxnon0_256mb_tte.attr,
+- &attr_dmmu_tsb_ticks_ctxnon0_256mb_tte.attr,
++ &dev_attr_immu_tsb_hits_ctx0_8k_tte.attr,
++ &dev_attr_immu_tsb_ticks_ctx0_8k_tte.attr,
++ &dev_attr_immu_tsb_hits_ctx0_64k_tte.attr,
++ &dev_attr_immu_tsb_ticks_ctx0_64k_tte.attr,
++ &dev_attr_immu_tsb_hits_ctx0_4mb_tte.attr,
++ &dev_attr_immu_tsb_ticks_ctx0_4mb_tte.attr,
++ &dev_attr_immu_tsb_hits_ctx0_256mb_tte.attr,
++ &dev_attr_immu_tsb_ticks_ctx0_256mb_tte.attr,
++ &dev_attr_immu_tsb_hits_ctxnon0_8k_tte.attr,
++ &dev_attr_immu_tsb_ticks_ctxnon0_8k_tte.attr,
++ &dev_attr_immu_tsb_hits_ctxnon0_64k_tte.attr,
++ &dev_attr_immu_tsb_ticks_ctxnon0_64k_tte.attr,
++ &dev_attr_immu_tsb_hits_ctxnon0_4mb_tte.attr,
++ &dev_attr_immu_tsb_ticks_ctxnon0_4mb_tte.attr,
++ &dev_attr_immu_tsb_hits_ctxnon0_256mb_tte.attr,
++ &dev_attr_immu_tsb_ticks_ctxnon0_256mb_tte.attr,
++ &dev_attr_dmmu_tsb_hits_ctx0_8k_tte.attr,
++ &dev_attr_dmmu_tsb_ticks_ctx0_8k_tte.attr,
++ &dev_attr_dmmu_tsb_hits_ctx0_64k_tte.attr,
++ &dev_attr_dmmu_tsb_ticks_ctx0_64k_tte.attr,
++ &dev_attr_dmmu_tsb_hits_ctx0_4mb_tte.attr,
++ &dev_attr_dmmu_tsb_ticks_ctx0_4mb_tte.attr,
++ &dev_attr_dmmu_tsb_hits_ctx0_256mb_tte.attr,
++ &dev_attr_dmmu_tsb_ticks_ctx0_256mb_tte.attr,
++ &dev_attr_dmmu_tsb_hits_ctxnon0_8k_tte.attr,
++ &dev_attr_dmmu_tsb_ticks_ctxnon0_8k_tte.attr,
++ &dev_attr_dmmu_tsb_hits_ctxnon0_64k_tte.attr,
++ &dev_attr_dmmu_tsb_ticks_ctxnon0_64k_tte.attr,
++ &dev_attr_dmmu_tsb_hits_ctxnon0_4mb_tte.attr,
++ &dev_attr_dmmu_tsb_ticks_ctxnon0_4mb_tte.attr,
++ &dev_attr_dmmu_tsb_hits_ctxnon0_256mb_tte.attr,
++ &dev_attr_dmmu_tsb_ticks_ctxnon0_256mb_tte.attr,
+ NULL,
+ };
+
+@@ -139,15 +139,15 @@
+ return sun4v_mmustat_conf(ra, &orig_ra);
+ }
+
+-static ssize_t show_mmustat_enable(struct sys_device *s,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t show_mmustat_enable(struct device *s,
++ struct device_attribute *attr, char *buf)
+ {
+ unsigned long val = run_on_cpu(s->id, read_mmustat_enable, 0);
+ return sprintf(buf, "%lx\n", val);
+ }
+
+-static ssize_t store_mmustat_enable(struct sys_device *s,
+- struct sysdev_attribute *attr, const char *buf,
++static ssize_t store_mmustat_enable(struct device *s,
++ struct device_attribute *attr, const char *buf,
+ size_t count)
+ {
+ unsigned long val, err;
+@@ -163,39 +163,39 @@
+ return count;
+ }
+
+-static SYSDEV_ATTR(mmustat_enable, 0644, show_mmustat_enable, store_mmustat_enable);
++static DEVICE_ATTR(mmustat_enable, 0644, show_mmustat_enable, store_mmustat_enable);
+
+ static int mmu_stats_supported;
+
+-static int register_mmu_stats(struct sys_device *s)
++static int register_mmu_stats(struct device *s)
+ {
+ if (!mmu_stats_supported)
+ return 0;
+- sysdev_create_file(s, &attr_mmustat_enable);
++ device_create_file(s, &dev_attr_mmustat_enable);
+ return sysfs_create_group(&s->kobj, &mmu_stat_group);
+ }
+
+ #ifdef CONFIG_HOTPLUG_CPU
+-static void unregister_mmu_stats(struct sys_device *s)
++static void unregister_mmu_stats(struct device *s)
+ {
+ if (!mmu_stats_supported)
+ return;
+ sysfs_remove_group(&s->kobj, &mmu_stat_group);
+- sysdev_remove_file(s, &attr_mmustat_enable);
++ device_remove_file(s, &dev_attr_mmustat_enable);
+ }
+ #endif
+
+ #define SHOW_CPUDATA_ULONG_NAME(NAME, MEMBER) \
+-static ssize_t show_##NAME(struct sys_device *dev, \
+- struct sysdev_attribute *attr, char *buf) \
++static ssize_t show_##NAME(struct device *dev, \
++ struct device_attribute *attr, char *buf) \
+ { \
+ cpuinfo_sparc *c = &cpu_data(dev->id); \
+ return sprintf(buf, "%lu\n", c->MEMBER); \
+ }
+
+ #define SHOW_CPUDATA_UINT_NAME(NAME, MEMBER) \
+-static ssize_t show_##NAME(struct sys_device *dev, \
+- struct sysdev_attribute *attr, char *buf) \
++static ssize_t show_##NAME(struct device *dev, \
++ struct device_attribute *attr, char *buf) \
+ { \
+ cpuinfo_sparc *c = &cpu_data(dev->id); \
+ return sprintf(buf, "%u\n", c->MEMBER); \
+@@ -209,14 +209,14 @@
+ SHOW_CPUDATA_UINT_NAME(l2_cache_size, ecache_size);
+ SHOW_CPUDATA_UINT_NAME(l2_cache_line_size, ecache_line_size);
+
+-static struct sysdev_attribute cpu_core_attrs[] = {
+- _SYSDEV_ATTR(clock_tick, 0444, show_clock_tick, NULL),
+- _SYSDEV_ATTR(l1_dcache_size, 0444, show_l1_dcache_size, NULL),
+- _SYSDEV_ATTR(l1_dcache_line_size, 0444, show_l1_dcache_line_size, NULL),
+- _SYSDEV_ATTR(l1_icache_size, 0444, show_l1_icache_size, NULL),
+- _SYSDEV_ATTR(l1_icache_line_size, 0444, show_l1_icache_line_size, NULL),
+- _SYSDEV_ATTR(l2_cache_size, 0444, show_l2_cache_size, NULL),
+- _SYSDEV_ATTR(l2_cache_line_size, 0444, show_l2_cache_line_size, NULL),
++static struct device_attribute cpu_core_attrs[] = {
++ __ATTR(clock_tick, 0444, show_clock_tick, NULL),
++ __ATTR(l1_dcache_size, 0444, show_l1_dcache_size, NULL),
++ __ATTR(l1_dcache_line_size, 0444, show_l1_dcache_line_size, NULL),
++ __ATTR(l1_icache_size, 0444, show_l1_icache_size, NULL),
++ __ATTR(l1_icache_line_size, 0444, show_l1_icache_line_size, NULL),
++ __ATTR(l2_cache_size, 0444, show_l2_cache_size, NULL),
++ __ATTR(l2_cache_line_size, 0444, show_l2_cache_line_size, NULL),
+ };
+
+ static DEFINE_PER_CPU(struct cpu, cpu_devices);
+@@ -224,11 +224,11 @@
+ static void register_cpu_online(unsigned int cpu)
+ {
+ struct cpu *c = &per_cpu(cpu_devices, cpu);
+- struct sys_device *s = &c->sysdev;
++ struct device *s = &c->dev;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cpu_core_attrs); i++)
+- sysdev_create_file(s, &cpu_core_attrs[i]);
++ device_create_file(s, &cpu_core_attrs[i]);
+
+ register_mmu_stats(s);
+ }
+@@ -237,12 +237,12 @@
+ static void unregister_cpu_online(unsigned int cpu)
+ {
+ struct cpu *c = &per_cpu(cpu_devices, cpu);
+- struct sys_device *s = &c->sysdev;
++ struct device *s = &c->dev;
+ int i;
+
+ unregister_mmu_stats(s);
+ for (i = 0; i < ARRAY_SIZE(cpu_core_attrs); i++)
+- sysdev_remove_file(s, &cpu_core_attrs[i]);
++ device_remove_file(s, &cpu_core_attrs[i]);
+ }
+ #endif
+
+--- a/arch/tile/kernel/sysfs.c
++++ b/arch/tile/kernel/sysfs.c
+@@ -14,7 +14,7 @@
+ * /sys entry support.
+ */
+
+-#include <linux/sysdev.h>
++#include <linux/device.h>
+ #include <linux/cpu.h>
+ #include <linux/slab.h>
+ #include <linux/smp.h>
+@@ -32,55 +32,55 @@
+ return n;
+ }
+
+-static ssize_t chip_width_show(struct sysdev_class *dev,
+- struct sysdev_class_attribute *attr,
++static ssize_t chip_width_show(struct device *dev,
++ struct device_attribute *attr,
+ char *page)
+ {
+ return sprintf(page, "%u\n", smp_width);
+ }
+-static SYSDEV_CLASS_ATTR(chip_width, 0444, chip_width_show, NULL);
++static DEVICE_ATTR(chip_width, 0444, chip_width_show, NULL);
+
+-static ssize_t chip_height_show(struct sysdev_class *dev,
+- struct sysdev_class_attribute *attr,
++static ssize_t chip_height_show(struct device *dev,
++ struct device_attribute *attr,
+ char *page)
+ {
+ return sprintf(page, "%u\n", smp_height);
+ }
+-static SYSDEV_CLASS_ATTR(chip_height, 0444, chip_height_show, NULL);
++static DEVICE_ATTR(chip_height, 0444, chip_height_show, NULL);
+
+-static ssize_t chip_serial_show(struct sysdev_class *dev,
+- struct sysdev_class_attribute *attr,
++static ssize_t chip_serial_show(struct device *dev,
++ struct device_attribute *attr,
+ char *page)
+ {
+ return get_hv_confstr(page, HV_CONFSTR_CHIP_SERIAL_NUM);
+ }
+-static SYSDEV_CLASS_ATTR(chip_serial, 0444, chip_serial_show, NULL);
++static DEVICE_ATTR(chip_serial, 0444, chip_serial_show, NULL);
+
+-static ssize_t chip_revision_show(struct sysdev_class *dev,
+- struct sysdev_class_attribute *attr,
++static ssize_t chip_revision_show(struct device *dev,
++ struct device_attribute *attr,
+ char *page)
+ {
+ return get_hv_confstr(page, HV_CONFSTR_CHIP_REV);
+ }
+-static SYSDEV_CLASS_ATTR(chip_revision, 0444, chip_revision_show, NULL);
++static DEVICE_ATTR(chip_revision, 0444, chip_revision_show, NULL);
+
+
+-static ssize_t type_show(struct sysdev_class *dev,
+- struct sysdev_class_attribute *attr,
++static ssize_t type_show(struct device *dev,
++ struct device_attribute *attr,
+ char *page)
+ {
+ return sprintf(page, "tilera\n");
+ }
+-static SYSDEV_CLASS_ATTR(type, 0444, type_show, NULL);
++static DEVICE_ATTR(type, 0444, type_show, NULL);
+
+ #define HV_CONF_ATTR(name, conf) \
+- static ssize_t name ## _show(struct sysdev_class *dev, \
+- struct sysdev_class_attribute *attr, \
++ static ssize_t name ## _show(struct device *dev, \
++ struct device_attribute *attr, \
+ char *page) \
+ { \
+ return get_hv_confstr(page, conf); \
+ } \
+- static SYSDEV_CLASS_ATTR(name, 0444, name ## _show, NULL);
++ static DEVICE_ATTR(name, 0444, name ## _show, NULL);
+
+ HV_CONF_ATTR(version, HV_CONFSTR_HV_SW_VER)
+ HV_CONF_ATTR(config_version, HV_CONFSTR_HV_CONFIG_VER)
+@@ -96,15 +96,15 @@
+ HV_CONF_ATTR(switch_control, HV_CONFSTR_SWITCH_CONTROL)
+
+ static struct attribute *board_attrs[] = {
+- &attr_board_part.attr,
+- &attr_board_serial.attr,
+- &attr_board_revision.attr,
+- &attr_board_description.attr,
+- &attr_mezz_part.attr,
+- &attr_mezz_serial.attr,
+- &attr_mezz_revision.attr,
+- &attr_mezz_description.attr,
+- &attr_switch_control.attr,
++ &dev_attr_board_part.attr,
++ &dev_attr_board_serial.attr,
++ &dev_attr_board_revision.attr,
++ &dev_attr_board_description.attr,
++ &dev_attr_mezz_part.attr,
++ &dev_attr_mezz_serial.attr,
++ &dev_attr_mezz_revision.attr,
++ &dev_attr_mezz_description.attr,
++ &dev_attr_switch_control.attr,
+ NULL
+ };
+
+@@ -151,12 +151,11 @@
+
+ static int __init create_sysfs_entries(void)
+ {
+- struct sysdev_class *cls = &cpu_sysdev_class;
+ int err = 0;
+
+ #define create_cpu_attr(name) \
+ if (!err) \
+- err = sysfs_create_file(&cls->kset.kobj, &attr_##name.attr);
++ err = device_create_file(cpu_subsys.dev_root, &dev_attr_##name);
+ create_cpu_attr(chip_width);
+ create_cpu_attr(chip_height);
+ create_cpu_attr(chip_serial);
+@@ -164,7 +163,7 @@
+
+ #define create_hv_attr(name) \
+ if (!err) \
+- err = sysfs_create_file(hypervisor_kobj, &attr_##name.attr);
++ err = sysfs_create_file(hypervisor_kobj, &dev_attr_##name);
+ create_hv_attr(type);
+ create_hv_attr(version);
+ create_hv_attr(config_version);
+--- a/arch/x86/include/asm/mce.h
++++ b/arch/x86/include/asm/mce.h
+@@ -149,7 +149,7 @@
+
+ void mce_setup(struct mce *m);
+ void mce_log(struct mce *m);
+-DECLARE_PER_CPU(struct sys_device, mce_sysdev);
++DECLARE_PER_CPU(struct device, mce_device);
+
+ /*
+ * Maximum banks number.
+--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
++++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
+@@ -872,8 +872,7 @@
+
+ #include <linux/kobject.h>
+ #include <linux/sysfs.h>
+-
+-extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */
++#include <linux/cpu.h>
+
+ /* pointer to kobject for cpuX/cache */
+ static DEFINE_PER_CPU(struct kobject *, ici_cache_kobject);
+@@ -1101,9 +1100,9 @@
+ static DECLARE_BITMAP(cache_dev_map, NR_CPUS);
+
+ /* Add/Remove cache interface for CPU device */
+-static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
++static int __cpuinit cache_add_dev(struct device *dev)
+ {
+- unsigned int cpu = sys_dev->id;
++ unsigned int cpu = dev->id;
+ unsigned long i, j;
+ struct _index_kobject *this_object;
+ struct _cpuid4_info *this_leaf;
+@@ -1115,7 +1114,7 @@
+
+ retval = kobject_init_and_add(per_cpu(ici_cache_kobject, cpu),
+ &ktype_percpu_entry,
+- &sys_dev->kobj, "%s", "cache");
++ &dev->kobj, "%s", "cache");
+ if (retval < 0) {
+ cpuid4_cache_sysfs_exit(cpu);
+ return retval;
+@@ -1152,9 +1151,9 @@
+ return 0;
+ }
+
+-static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
++static void __cpuinit cache_remove_dev(struct device *dev)
+ {
+- unsigned int cpu = sys_dev->id;
++ unsigned int cpu = dev->id;
+ unsigned long i;
+
+ if (per_cpu(ici_cpuid4_info, cpu) == NULL)
+@@ -1173,17 +1172,17 @@
+ unsigned long action, void *hcpu)
+ {
+ unsigned int cpu = (unsigned long)hcpu;
+- struct sys_device *sys_dev;
++ struct device *dev;
+
+- sys_dev = get_cpu_sysdev(cpu);
++ dev = get_cpu_device(cpu);
+ switch (action) {
+ case CPU_ONLINE:
+ case CPU_ONLINE_FROZEN:
+- cache_add_dev(sys_dev);
++ cache_add_dev(dev);
+ break;
+ case CPU_DEAD:
+ case CPU_DEAD_FROZEN:
+- cache_remove_dev(sys_dev);
++ cache_remove_dev(dev);
+ break;
+ }
+ return NOTIFY_OK;
+@@ -1202,9 +1201,9 @@
+
+ for_each_online_cpu(i) {
+ int err;
+- struct sys_device *sys_dev = get_cpu_sysdev(i);
++ struct device *dev = get_cpu_device(i);
+
+- err = cache_add_dev(sys_dev);
++ err = cache_add_dev(dev);
+ if (err)
+ return err;
+ }
+--- a/arch/x86/kernel/cpu/mcheck/mce-internal.h
++++ b/arch/x86/kernel/cpu/mcheck/mce-internal.h
+@@ -1,4 +1,4 @@
+-#include <linux/sysdev.h>
++#include <linux/device.h>
+ #include <asm/mce.h>
+
+ enum severity_level {
+@@ -17,7 +17,7 @@
+ struct mce_bank {
+ u64 ctl; /* subevents to enable */
+ unsigned char init; /* initialise bank? */
+- struct sysdev_attribute attr; /* sysdev attribute */
++ struct device_attribute attr; /* device attribute */
+ char attrname[ATTR_LEN]; /* attribute name */
+ };
+
+--- a/arch/x86/kernel/cpu/mcheck/mce.c
++++ b/arch/x86/kernel/cpu/mcheck/mce.c
+@@ -19,7 +19,7 @@
+ #include <linux/kernel.h>
+ #include <linux/percpu.h>
+ #include <linux/string.h>
+-#include <linux/sysdev.h>
++#include <linux/device.h>
+ #include <linux/syscore_ops.h>
+ #include <linux/delay.h>
+ #include <linux/ctype.h>
+@@ -1778,7 +1778,7 @@
+ };
+
+ /*
+- * mce_sysdev: Sysfs support
++ * mce_device: Sysfs support
+ */
+
+ static void mce_cpu_restart(void *data)
+@@ -1814,27 +1814,28 @@
+ __mcheck_cpu_init_timer();
+ }
+
+-static struct sysdev_class mce_sysdev_class = {
++static struct bus_type mce_subsys = {
+ .name = "machinecheck",
++ .dev_name = "machinecheck",
+ };
+
+-DEFINE_PER_CPU(struct sys_device, mce_sysdev);
++DEFINE_PER_CPU(struct device, mce_device);
+
+ __cpuinitdata
+ void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu);
+
+-static inline struct mce_bank *attr_to_bank(struct sysdev_attribute *attr)
++static inline struct mce_bank *attr_to_bank(struct device_attribute *attr)
+ {
+ return container_of(attr, struct mce_bank, attr);
+ }
+
+-static ssize_t show_bank(struct sys_device *s, struct sysdev_attribute *attr,
++static ssize_t show_bank(struct device *s, struct device_attribute *attr,
+ char *buf)
+ {
+ return sprintf(buf, "%llx\n", attr_to_bank(attr)->ctl);
+ }
+
+-static ssize_t set_bank(struct sys_device *s, struct sysdev_attribute *attr,
++static ssize_t set_bank(struct device *s, struct device_attribute *attr,
+ const char *buf, size_t size)
+ {
+ u64 new;
+@@ -1849,14 +1850,14 @@
+ }
+
+ static ssize_t
+-show_trigger(struct sys_device *s, struct sysdev_attribute *attr, char *buf)
++show_trigger(struct device *s, struct device_attribute *attr, char *buf)
+ {
+ strcpy(buf, mce_helper);
+ strcat(buf, "\n");
+ return strlen(mce_helper) + 1;
+ }
+
+-static ssize_t set_trigger(struct sys_device *s, struct sysdev_attribute *attr,
++static ssize_t set_trigger(struct device *s, struct device_attribute *attr,
+ const char *buf, size_t siz)
+ {
+ char *p;
+@@ -1871,8 +1872,8 @@
+ return strlen(mce_helper) + !!p;
+ }
+
+-static ssize_t set_ignore_ce(struct sys_device *s,
+- struct sysdev_attribute *attr,
++static ssize_t set_ignore_ce(struct device *s,
++ struct device_attribute *attr,
+ const char *buf, size_t size)
+ {
+ u64 new;
+@@ -1895,8 +1896,8 @@
+ return size;
+ }
+
+-static ssize_t set_cmci_disabled(struct sys_device *s,
+- struct sysdev_attribute *attr,
++static ssize_t set_cmci_disabled(struct device *s,
++ struct device_attribute *attr,
+ const char *buf, size_t size)
+ {
+ u64 new;
+@@ -1918,108 +1919,107 @@
+ return size;
+ }
+
+-static ssize_t store_int_with_restart(struct sys_device *s,
+- struct sysdev_attribute *attr,
++static ssize_t store_int_with_restart(struct device *s,
++ struct device_attribute *attr,
+ const char *buf, size_t size)
+ {
+- ssize_t ret = sysdev_store_int(s, attr, buf, size);
++ ssize_t ret = device_store_int(s, attr, buf, size);
+ mce_restart();
+ return ret;
+ }
+
+-static SYSDEV_ATTR(trigger, 0644, show_trigger, set_trigger);
+-static SYSDEV_INT_ATTR(tolerant, 0644, tolerant);
+-static SYSDEV_INT_ATTR(monarch_timeout, 0644, monarch_timeout);
+-static SYSDEV_INT_ATTR(dont_log_ce, 0644, mce_dont_log_ce);
+-
+-static struct sysdev_ext_attribute attr_check_interval = {
+- _SYSDEV_ATTR(check_interval, 0644, sysdev_show_int,
+- store_int_with_restart),
++static DEVICE_ATTR(trigger, 0644, show_trigger, set_trigger);
++static DEVICE_INT_ATTR(tolerant, 0644, tolerant);
++static DEVICE_INT_ATTR(monarch_timeout, 0644, monarch_timeout);
++static DEVICE_INT_ATTR(dont_log_ce, 0644, mce_dont_log_ce);
++
++static struct dev_ext_attribute dev_attr_check_interval = {
++ __ATTR(check_interval, 0644, device_show_int, store_int_with_restart),
+ &check_interval
+ };
+
+-static struct sysdev_ext_attribute attr_ignore_ce = {
+- _SYSDEV_ATTR(ignore_ce, 0644, sysdev_show_int, set_ignore_ce),
++static struct dev_ext_attribute dev_attr_ignore_ce = {
++ __ATTR(ignore_ce, 0644, device_show_int, set_ignore_ce),
+ &mce_ignore_ce
+ };
+
+-static struct sysdev_ext_attribute attr_cmci_disabled = {
+- _SYSDEV_ATTR(cmci_disabled, 0644, sysdev_show_int, set_cmci_disabled),
++static struct dev_ext_attribute dev_attr_cmci_disabled = {
++ __ATTR(cmci_disabled, 0644, device_show_int, set_cmci_disabled),
+ &mce_cmci_disabled
+ };
+
+-static struct sysdev_attribute *mce_sysdev_attrs[] = {
+- &attr_tolerant.attr,
+- &attr_check_interval.attr,
+- &attr_trigger,
+- &attr_monarch_timeout.attr,
+- &attr_dont_log_ce.attr,
+- &attr_ignore_ce.attr,
+- &attr_cmci_disabled.attr,
++static struct device_attribute *mce_device_attrs[] = {
++ &dev_attr_tolerant.attr,
++ &dev_attr_check_interval.attr,
++ &dev_attr_trigger,
++ &dev_attr_monarch_timeout.attr,
++ &dev_attr_dont_log_ce.attr,
++ &dev_attr_ignore_ce.attr,
++ &dev_attr_cmci_disabled.attr,
+ NULL
+ };
+
+-static cpumask_var_t mce_sysdev_initialized;
++static cpumask_var_t mce_device_initialized;
+
+-/* Per cpu sysdev init. All of the cpus still share the same ctrl bank: */
+-static __cpuinit int mce_sysdev_create(unsigned int cpu)
++/* Per cpu device init. All of the cpus still share the same ctrl bank: */
++static __cpuinit int mce_device_create(unsigned int cpu)
+ {
+- struct sys_device *sysdev = &per_cpu(mce_sysdev, cpu);
++ struct device *dev = &per_cpu(mce_device, cpu);
+ int err;
+ int i, j;
+
+ if (!mce_available(&boot_cpu_data))
+ return -EIO;
+
+- memset(&sysdev->kobj, 0, sizeof(struct kobject));
+- sysdev->id = cpu;
+- sysdev->cls = &mce_sysdev_class;
++ memset(&dev->kobj, 0, sizeof(struct kobject));
++ dev->id = cpu;
++ dev->bus = &mce_subsys;
+
+- err = sysdev_register(sysdev);
++ err = device_register(dev);
+ if (err)
+ return err;
+
+- for (i = 0; mce_sysdev_attrs[i]; i++) {
+- err = sysdev_create_file(sysdev, mce_sysdev_attrs[i]);
++ for (i = 0; mce_device_attrs[i]; i++) {
++ err = device_create_file(dev, mce_device_attrs[i]);
+ if (err)
+ goto error;
+ }
+ for (j = 0; j < banks; j++) {
+- err = sysdev_create_file(sysdev, &mce_banks[j].attr);
++ err = device_create_file(dev, &mce_banks[j].attr);
+ if (err)
+ goto error2;
+ }
+- cpumask_set_cpu(cpu, mce_sysdev_initialized);
++ cpumask_set_cpu(cpu, mce_device_initialized);
+
+ return 0;
+ error2:
+ while (--j >= 0)
+- sysdev_remove_file(sysdev, &mce_banks[j].attr);
++ device_remove_file(dev, &mce_banks[j].attr);
+ error:
+ while (--i >= 0)
+- sysdev_remove_file(sysdev, mce_sysdev_attrs[i]);
++ device_remove_file(dev, mce_device_attrs[i]);
+
+- sysdev_unregister(sysdev);
++ device_unregister(dev);
+
+ return err;
+ }
+
+-static __cpuinit void mce_sysdev_remove(unsigned int cpu)
++static __cpuinit void mce_device_remove(unsigned int cpu)
+ {
+- struct sys_device *sysdev = &per_cpu(mce_sysdev, cpu);
++ struct device *dev = &per_cpu(mce_device, cpu);
+ int i;
+
+- if (!cpumask_test_cpu(cpu, mce_sysdev_initialized))
++ if (!cpumask_test_cpu(cpu, mce_device_initialized))
+ return;
+
+- for (i = 0; mce_sysdev_attrs[i]; i++)
+- sysdev_remove_file(sysdev, mce_sysdev_attrs[i]);
++ for (i = 0; mce_device_attrs[i]; i++)
++ device_remove_file(dev, mce_device_attrs[i]);
+
+ for (i = 0; i < banks; i++)
+- sysdev_remove_file(sysdev, &mce_banks[i].attr);
++ device_remove_file(dev, &mce_banks[i].attr);
+
+- sysdev_unregister(sysdev);
+- cpumask_clear_cpu(cpu, mce_sysdev_initialized);
++ device_unregister(dev);
++ cpumask_clear_cpu(cpu, mce_device_initialized);
+ }
+
+ /* Make sure there are no machine checks on offlined CPUs. */
+@@ -2069,7 +2069,7 @@
+ switch (action) {
+ case CPU_ONLINE:
+ case CPU_ONLINE_FROZEN:
+- mce_sysdev_create(cpu);
++ mce_device_create(cpu);
+ if (threshold_cpu_callback)
+ threshold_cpu_callback(action, cpu);
+ break;
+@@ -2077,7 +2077,7 @@
+ case CPU_DEAD_FROZEN:
+ if (threshold_cpu_callback)
+ threshold_cpu_callback(action, cpu);
+- mce_sysdev_remove(cpu);
++ mce_device_remove(cpu);
+ break;
+ case CPU_DOWN_PREPARE:
+ case CPU_DOWN_PREPARE_FROZEN:
+@@ -2111,7 +2111,7 @@
+
+ for (i = 0; i < banks; i++) {
+ struct mce_bank *b = &mce_banks[i];
+- struct sysdev_attribute *a = &b->attr;
++ struct device_attribute *a = &b->attr;
+
+ sysfs_attr_init(&a->attr);
+ a->attr.name = b->attrname;
+@@ -2131,16 +2131,16 @@
+ if (!mce_available(&boot_cpu_data))
+ return -EIO;
+
+- zalloc_cpumask_var(&mce_sysdev_initialized, GFP_KERNEL);
++ zalloc_cpumask_var(&mce_device_initialized, GFP_KERNEL);
+
+ mce_init_banks();
+
+- err = sysdev_class_register(&mce_sysdev_class);
++ err = subsys_system_register(&mce_subsys, NULL);
+ if (err)
+ return err;
+
+ for_each_online_cpu(i) {
+- err = mce_sysdev_create(i);
++ err = mce_device_create(i);
+ if (err)
+ return err;
+ }
+--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
++++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
+@@ -17,7 +17,6 @@
+ #include <linux/notifier.h>
+ #include <linux/kobject.h>
+ #include <linux/percpu.h>
+-#include <linux/sysdev.h>
+ #include <linux/errno.h>
+ #include <linux/sched.h>
+ #include <linux/sysfs.h>
+@@ -548,7 +547,7 @@
+ if (!b)
+ goto out;
+
+- err = sysfs_create_link(&per_cpu(mce_sysdev, cpu).kobj,
++ err = sysfs_create_link(&per_cpu(mce_device, cpu).kobj,
+ b->kobj, name);
+ if (err)
+ goto out;
+@@ -571,7 +570,7 @@
+ goto out;
+ }
+
+- b->kobj = kobject_create_and_add(name, &per_cpu(mce_sysdev, cpu).kobj);
++ b->kobj = kobject_create_and_add(name, &per_cpu(mce_device, cpu).kobj);
+ if (!b->kobj)
+ goto out_free;
+
+@@ -591,7 +590,7 @@
+ if (i == cpu)
+ continue;
+
+- err = sysfs_create_link(&per_cpu(mce_sysdev, i).kobj,
++ err = sysfs_create_link(&per_cpu(mce_device, i).kobj,
+ b->kobj, name);
+ if (err)
+ goto out;
+@@ -669,7 +668,7 @@
+ #ifdef CONFIG_SMP
+ /* sibling symlink */
+ if (shared_bank[bank] && b->blocks->cpu != cpu) {
+- sysfs_remove_link(&per_cpu(mce_sysdev, cpu).kobj, name);
++ sysfs_remove_link(&per_cpu(mce_device, cpu).kobj, name);
+ per_cpu(threshold_banks, cpu)[bank] = NULL;
+
+ return;
+@@ -681,7 +680,7 @@
+ if (i == cpu)
+ continue;
+
+- sysfs_remove_link(&per_cpu(mce_sysdev, i).kobj, name);
++ sysfs_remove_link(&per_cpu(mce_device, i).kobj, name);
+ per_cpu(threshold_banks, i)[bank] = NULL;
+ }
+
+--- a/arch/x86/kernel/cpu/mcheck/therm_throt.c
++++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c
+@@ -19,7 +19,6 @@
+ #include <linux/kernel.h>
+ #include <linux/percpu.h>
+ #include <linux/export.h>
+-#include <linux/sysdev.h>
+ #include <linux/types.h>
+ #include <linux/init.h>
+ #include <linux/smp.h>
+@@ -69,16 +68,16 @@
+ static u32 lvtthmr_init __read_mostly;
+
+ #ifdef CONFIG_SYSFS
+-#define define_therm_throt_sysdev_one_ro(_name) \
+- static SYSDEV_ATTR(_name, 0444, \
+- therm_throt_sysdev_show_##_name, \
++#define define_therm_throt_device_one_ro(_name) \
++ static DEVICE_ATTR(_name, 0444, \
++ therm_throt_device_show_##_name, \
+ NULL) \
+
+-#define define_therm_throt_sysdev_show_func(event, name) \
++#define define_therm_throt_device_show_func(event, name) \
+ \
+-static ssize_t therm_throt_sysdev_show_##event##_##name( \
+- struct sys_device *dev, \
+- struct sysdev_attribute *attr, \
++static ssize_t therm_throt_device_show_##event##_##name( \
++ struct device *dev, \
++ struct device_attribute *attr, \
+ char *buf) \
+ { \
+ unsigned int cpu = dev->id; \
+@@ -95,20 +94,20 @@
+ return ret; \
+ }
+
+-define_therm_throt_sysdev_show_func(core_throttle, count);
+-define_therm_throt_sysdev_one_ro(core_throttle_count);
++define_therm_throt_device_show_func(core_throttle, count);
++define_therm_throt_device_one_ro(core_throttle_count);
+
+-define_therm_throt_sysdev_show_func(core_power_limit, count);
+-define_therm_throt_sysdev_one_ro(core_power_limit_count);
++define_therm_throt_device_show_func(core_power_limit, count);
++define_therm_throt_device_one_ro(core_power_limit_count);
+
+-define_therm_throt_sysdev_show_func(package_throttle, count);
+-define_therm_throt_sysdev_one_ro(package_throttle_count);
++define_therm_throt_device_show_func(package_throttle, count);
++define_therm_throt_device_one_ro(package_throttle_count);
+
+-define_therm_throt_sysdev_show_func(package_power_limit, count);
+-define_therm_throt_sysdev_one_ro(package_power_limit_count);
++define_therm_throt_device_show_func(package_power_limit, count);
++define_therm_throt_device_one_ro(package_power_limit_count);
+
+ static struct attribute *thermal_throttle_attrs[] = {
+- &attr_core_throttle_count.attr,
++ &dev_attr_core_throttle_count.attr,
+ NULL
+ };
+
+@@ -223,36 +222,36 @@
+
+ #ifdef CONFIG_SYSFS
+ /* Add/Remove thermal_throttle interface for CPU device: */
+-static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev,
++static __cpuinit int thermal_throttle_add_dev(struct device *dev,
+ unsigned int cpu)
+ {
+ int err;
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
+
+- err = sysfs_create_group(&sys_dev->kobj, &thermal_attr_group);
++ err = sysfs_create_group(&dev->kobj, &thermal_attr_group);
+ if (err)
+ return err;
+
+ if (cpu_has(c, X86_FEATURE_PLN))
+- err = sysfs_add_file_to_group(&sys_dev->kobj,
+- &attr_core_power_limit_count.attr,
++ err = sysfs_add_file_to_group(&dev->kobj,
++ &dev_attr_core_power_limit_count.attr,
+ thermal_attr_group.name);
+ if (cpu_has(c, X86_FEATURE_PTS)) {
+- err = sysfs_add_file_to_group(&sys_dev->kobj,
+- &attr_package_throttle_count.attr,
++ err = sysfs_add_file_to_group(&dev->kobj,
++ &dev_attr_package_throttle_count.attr,
+ thermal_attr_group.name);
+ if (cpu_has(c, X86_FEATURE_PLN))
+- err = sysfs_add_file_to_group(&sys_dev->kobj,
+- &attr_package_power_limit_count.attr,
++ err = sysfs_add_file_to_group(&dev->kobj,
++ &dev_attr_package_power_limit_count.attr,
+ thermal_attr_group.name);
+ }
+
+ return err;
+ }
+
+-static __cpuinit void thermal_throttle_remove_dev(struct sys_device *sys_dev)
++static __cpuinit void thermal_throttle_remove_dev(struct device *dev)
+ {
+- sysfs_remove_group(&sys_dev->kobj, &thermal_attr_group);
++ sysfs_remove_group(&dev->kobj, &thermal_attr_group);
+ }
+
+ /* Mutex protecting device creation against CPU hotplug: */
+@@ -265,16 +264,16 @@
+ void *hcpu)
+ {
+ unsigned int cpu = (unsigned long)hcpu;
+- struct sys_device *sys_dev;
++ struct device *dev;
+ int err = 0;
+
+- sys_dev = get_cpu_sysdev(cpu);
++ dev = get_cpu_device(cpu);
+
+ switch (action) {
+ case CPU_UP_PREPARE:
+ case CPU_UP_PREPARE_FROZEN:
+ mutex_lock(&therm_cpu_lock);
+- err = thermal_throttle_add_dev(sys_dev, cpu);
++ err = thermal_throttle_add_dev(dev, cpu);
+ mutex_unlock(&therm_cpu_lock);
+ WARN_ON(err);
+ break;
+@@ -283,7 +282,7 @@
+ case CPU_DEAD:
+ case CPU_DEAD_FROZEN:
+ mutex_lock(&therm_cpu_lock);
+- thermal_throttle_remove_dev(sys_dev);
++ thermal_throttle_remove_dev(dev);
+ mutex_unlock(&therm_cpu_lock);
+ break;
+ }
+@@ -310,7 +309,7 @@
+ #endif
+ /* connect live CPUs to sysfs */
+ for_each_online_cpu(cpu) {
+- err = thermal_throttle_add_dev(get_cpu_sysdev(cpu), cpu);
++ err = thermal_throttle_add_dev(get_cpu_device(cpu), cpu);
+ WARN_ON(err);
+ }
+ #ifdef CONFIG_HOTPLUG_CPU
+--- a/arch/x86/kernel/microcode_core.c
++++ b/arch/x86/kernel/microcode_core.c
+@@ -292,8 +292,8 @@
+ return err;
+ }
+
+-static ssize_t reload_store(struct sys_device *dev,
+- struct sysdev_attribute *attr,
++static ssize_t reload_store(struct device *dev,
++ struct device_attribute *attr,
+ const char *buf, size_t size)
+ {
+ unsigned long val;
+@@ -318,30 +318,30 @@
+ return ret;
+ }
+
+-static ssize_t version_show(struct sys_device *dev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t version_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+ struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
+
+ return sprintf(buf, "0x%x\n", uci->cpu_sig.rev);
+ }
+
+-static ssize_t pf_show(struct sys_device *dev,
+- struct sysdev_attribute *attr, char *buf)
++static ssize_t pf_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+ struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
+
+ return sprintf(buf, "0x%x\n", uci->cpu_sig.pf);
+ }
+
+-static SYSDEV_ATTR(reload, 0200, NULL, reload_store);
+-static SYSDEV_ATTR(version, 0400, version_show, NULL);
+-static SYSDEV_ATTR(processor_flags, 0400, pf_show, NULL);
++static DEVICE_ATTR(reload, 0200, NULL, reload_store);
++static DEVICE_ATTR(version, 0400, version_show, NULL);
++static DEVICE_ATTR(processor_flags, 0400, pf_show, NULL);
+
+ static struct attribute *mc_default_attrs[] = {
+- &attr_reload.attr,
+- &attr_version.attr,
+- &attr_processor_flags.attr,
++ &dev_attr_reload.attr,
++ &dev_attr_version.attr,
++ &dev_attr_processor_flags.attr,
+ NULL
+ };
+
+@@ -405,16 +405,16 @@
+ return ustate;
+ }
+
+-static int mc_sysdev_add(struct sys_device *sys_dev)
++static int mc_device_add(struct device *dev, struct subsys_interface *sif)
+ {
+- int err, cpu = sys_dev->id;
++ int err, cpu = dev->id;
+
+ if (!cpu_online(cpu))
+ return 0;
+
+ pr_debug("CPU%d added\n", cpu);
+
+- err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group);
++ err = sysfs_create_group(&dev->kobj, &mc_attr_group);
+ if (err)
+ return err;
+
+@@ -424,22 +424,24 @@
+ return err;
+ }
+
+-static int mc_sysdev_remove(struct sys_device *sys_dev)
++static int mc_device_remove(struct device *dev, struct subsys_interface *sif)
+ {
+- int cpu = sys_dev->id;
++ int cpu = dev->id;
+
+ if (!cpu_online(cpu))
+ return 0;
+
+ pr_debug("CPU%d removed\n", cpu);
+ microcode_fini_cpu(cpu);
+- sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
++ sysfs_remove_group(&dev->kobj, &mc_attr_group);
+ return 0;
+ }
+
+-static struct sysdev_driver mc_sysdev_driver = {
+- .add = mc_sysdev_add,
+- .remove = mc_sysdev_remove,
++static struct subsys_interface mc_cpu_interface = {
++ .name = "microcode",
++ .subsys = &cpu_subsys,
++ .add_dev = mc_device_add,
++ .remove_dev = mc_device_remove,
+ };
+
+ /**
+@@ -462,9 +464,9 @@
+ mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu)
+ {
+ unsigned int cpu = (unsigned long)hcpu;
+- struct sys_device *sys_dev;
++ struct device *dev;
+
+- sys_dev = get_cpu_sysdev(cpu);
++ dev = get_cpu_device(cpu);
+ switch (action) {
+ case CPU_ONLINE:
+ case CPU_ONLINE_FROZEN:
+@@ -472,13 +474,13 @@
+ case CPU_DOWN_FAILED:
+ case CPU_DOWN_FAILED_FROZEN:
+ pr_debug("CPU%d added\n", cpu);
+- if (sysfs_create_group(&sys_dev->kobj, &mc_attr_group))
++ if (sysfs_create_group(&dev->kobj, &mc_attr_group))
+ pr_err("Failed to create group for CPU%d\n", cpu);
+ break;
+ case CPU_DOWN_PREPARE:
+ case CPU_DOWN_PREPARE_FROZEN:
+ /* Suspend is in progress, only remove the interface */
+- sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
++ sysfs_remove_group(&dev->kobj, &mc_attr_group);
+ pr_debug("CPU%d removed\n", cpu);
+ break;
+
+@@ -523,7 +525,7 @@
+ get_online_cpus();
+ mutex_lock(µcode_mutex);
+
+- error = sysdev_driver_register(&cpu_sysdev_class, &mc_sysdev_driver);
++ error = subsys_interface_register(&mc_cpu_interface);
+
+ mutex_unlock(µcode_mutex);
+ put_online_cpus();
+@@ -533,7 +535,7 @@
+
+ error = microcode_dev_init();
+ if (error)
+- goto out_sysdev_driver;
++ goto out_driver;
+
+ register_syscore_ops(&mc_syscore_ops);
+ register_hotcpu_notifier(&mc_cpu_notifier);
+@@ -543,11 +545,11 @@
+
+ return 0;
+
+-out_sysdev_driver:
++out_driver:
+ get_online_cpus();
+ mutex_lock(µcode_mutex);
+
+- sysdev_driver_unregister(&cpu_sysdev_class, &mc_sysdev_driver);
++ subsys_interface_unregister(&mc_cpu_interface);
+
+ mutex_unlock(µcode_mutex);
+ put_online_cpus();
+@@ -569,7 +571,7 @@
+ get_online_cpus();
+ mutex_lock(µcode_mutex);
+
+- sysdev_driver_unregister(&cpu_sysdev_class, &mc_sysdev_driver);
++ subsys_interface_unregister(&mc_cpu_interface);
+
+ mutex_unlock(µcode_mutex);
+ put_online_cpus();
+--- a/drivers/acpi/processor_driver.c
++++ b/drivers/acpi/processor_driver.c
+@@ -446,7 +446,7 @@
+ {
+ struct acpi_processor *pr = NULL;
+ int result = 0;
+- struct sys_device *sysdev;
++ struct device *dev;
+
+ pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
+ if (!pr)
+@@ -491,8 +491,8 @@
+
+ per_cpu(processors, pr->id) = pr;
+
+- sysdev = get_cpu_sysdev(pr->id);
+- if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) {
++ dev = get_cpu_device(pr->id);
++ if (sysfs_create_link(&device->dev.kobj, &dev->kobj, "sysdev")) {
+ result = -EFAULT;
+ goto err_free_cpumask;
+ }
+--- a/drivers/acpi/processor_thermal.c
++++ b/drivers/acpi/processor_thermal.c
+@@ -30,7 +30,6 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/cpufreq.h>
+-#include <linux/sysdev.h>
+
+ #include <asm/uaccess.h>
+
+--- a/drivers/base/cpu.c
++++ b/drivers/base/cpu.c
+@@ -1,8 +1,7 @@
+ /*
+- * drivers/base/cpu.c - basic CPU class support
++ * CPU subsystem support
+ */
+
+-#include <linux/sysdev.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/sched.h>
+@@ -14,40 +13,40 @@
+
+ #include "base.h"
+
+-static struct sysdev_class_attribute *cpu_sysdev_class_attrs[];
+-
+-struct sysdev_class cpu_sysdev_class = {
++struct bus_type cpu_subsys = {
+ .name = "cpu",
+- .attrs = cpu_sysdev_class_attrs,
++ .dev_name = "cpu",
+ };
+-EXPORT_SYMBOL(cpu_sysdev_class);
++EXPORT_SYMBOL_GPL(cpu_subsys);
+
+-static DEFINE_PER_CPU(struct sys_device *, cpu_sys_devices);
++static DEFINE_PER_CPU(struct device *, cpu_sys_devices);
+
+ #ifdef CONFIG_HOTPLUG_CPU
+-static ssize_t show_online(struct sys_device *dev, struct sysdev_attribute *attr,
++static ssize_t show_online(struct device *dev,
++ struct device_attribute *attr,
+ char *buf)
+ {
+- struct cpu *cpu = container_of(dev, struct cpu, sysdev);
++ struct cpu *cpu = container_of(dev, struct cpu, dev);
+
+- return sprintf(buf, "%u\n", !!cpu_online(cpu->sysdev.id));
++ return sprintf(buf, "%u\n", !!cpu_online(cpu->dev.id));
+ }
+
+-static ssize_t __ref store_online(struct sys_device *dev, struct sysdev_attribute *attr,
+- const char *buf, size_t count)
++static ssize_t __ref store_online(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
+ {
+- struct cpu *cpu = container_of(dev, struct cpu, sysdev);
++ struct cpu *cpu = container_of(dev, struct cpu, dev);
+ ssize_t ret;
+
+ cpu_hotplug_driver_lock();
+ switch (buf[0]) {
+ case '0':
+- ret = cpu_down(cpu->sysdev.id);
++ ret = cpu_down(cpu->dev.id);
+ if (!ret)
+ kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
+ break;
+ case '1':
+- ret = cpu_up(cpu->sysdev.id);
++ ret = cpu_up(cpu->dev.id);
+ if (!ret)
+ kobject_uevent(&dev->kobj, KOBJ_ONLINE);
+ break;
+@@ -60,44 +59,44 @@
+ ret = count;
+ return ret;
+ }
+-static SYSDEV_ATTR(online, 0644, show_online, store_online);
++static DEVICE_ATTR(online, 0644, show_online, store_online);
+
+ static void __cpuinit register_cpu_control(struct cpu *cpu)
+ {
+- sysdev_create_file(&cpu->sysdev, &attr_online);
++ device_create_file(&cpu->dev, &dev_attr_online);
+ }
+ void unregister_cpu(struct cpu *cpu)
+ {
+- int logical_cpu = cpu->sysdev.id;
++ int logical_cpu = cpu->dev.id;
+
+ unregister_cpu_under_node(logical_cpu, cpu_to_node(logical_cpu));
+
+- sysdev_remove_file(&cpu->sysdev, &attr_online);
++ device_remove_file(&cpu->dev, &dev_attr_online);
+
+- sysdev_unregister(&cpu->sysdev);
++ device_unregister(&cpu->dev);
+ per_cpu(cpu_sys_devices, logical_cpu) = NULL;
+ return;
+ }
+
+ #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
+-static ssize_t cpu_probe_store(struct sysdev_class *class,
+- struct sysdev_class_attribute *attr,
++static ssize_t cpu_probe_store(struct device *dev,
++ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+ {
+ return arch_cpu_probe(buf, count);
+ }
+
+-static ssize_t cpu_release_store(struct sysdev_class *class,
+- struct sysdev_class_attribute *attr,
++static ssize_t cpu_release_store(struct device *dev,
++ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+ {
+ return arch_cpu_release(buf, count);
+ }
+
+-static SYSDEV_CLASS_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
+-static SYSDEV_CLASS_ATTR(release, S_IWUSR, NULL, cpu_release_store);
++static DEVICE_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
++static DEVICE_ATTR(release, S_IWUSR, NULL, cpu_release_store);
+ #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
+
+ #else /* ... !CONFIG_HOTPLUG_CPU */
+@@ -109,15 +108,15 @@
+ #ifdef CONFIG_KEXEC
+ #include <linux/kexec.h>
+
+-static ssize_t show_crash_notes(struct sys_device *dev, struct sysdev_attribute *attr,
++static ssize_t show_crash_notes(struct device *dev, struct device_attribute *attr,
+ char *buf)
+ {
+- struct cpu *cpu = container_of(dev, struct cpu, sysdev);
++ struct cpu *cpu = container_of(dev, struct cpu, dev);
+ ssize_t rc;
+ unsigned long long addr;
+ int cpunum;
+
+- cpunum = cpu->sysdev.id;
++ cpunum = cpu->dev.id;
+
+ /*
+ * Might be reading other cpu's data based on which cpu read thread
+@@ -129,7 +128,7 @@
+ rc = sprintf(buf, "%Lx\n", addr);
+ return rc;
+ }
+-static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL);
++static DEVICE_ATTR(crash_notes, 0400, show_crash_notes, NULL);
+ #endif
+
+ /*
+@@ -137,12 +136,12 @@
+ */
+
+ struct cpu_attr {
+- struct sysdev_class_attribute attr;
++ struct device_attribute attr;
+ const struct cpumask *const * const map;
+ };
+
+-static ssize_t show_cpus_attr(struct sysdev_class *class,
+- struct sysdev_class_attribute *attr,
++static ssize_t show_cpus_attr(struct device *dev,
++ struct device_attribute *attr,
+ char *buf)
+ {
+ struct cpu_attr *ca = container_of(attr, struct cpu_attr, attr);
+@@ -153,10 +152,10 @@
+ return n;
+ }
+
+-#define _CPU_ATTR(name, map) \
+- { _SYSDEV_CLASS_ATTR(name, 0444, show_cpus_attr, NULL), map }
++#define _CPU_ATTR(name, map) \
++ { __ATTR(name, 0444, show_cpus_attr, NULL), map }
+
+-/* Keep in sync with cpu_sysdev_class_attrs */
++/* Keep in sync with cpu_subsys_attrs */
+ static struct cpu_attr cpu_attrs[] = {
+ _CPU_ATTR(online, &cpu_online_mask),
+ _CPU_ATTR(possible, &cpu_possible_mask),
+@@ -166,19 +165,19 @@
+ /*
+ * Print values for NR_CPUS and offlined cpus
+ */
+-static ssize_t print_cpus_kernel_max(struct sysdev_class *class,
+- struct sysdev_class_attribute *attr, char *buf)
++static ssize_t print_cpus_kernel_max(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+ int n = snprintf(buf, PAGE_SIZE-2, "%d\n", NR_CPUS - 1);
+ return n;
+ }
+-static SYSDEV_CLASS_ATTR(kernel_max, 0444, print_cpus_kernel_max, NULL);
++static DEVICE_ATTR(kernel_max, 0444, print_cpus_kernel_max, NULL);
+
+ /* arch-optional setting to enable display of offline cpus >= nr_cpu_ids */
+ unsigned int total_cpus;
+
+-static ssize_t print_cpus_offline(struct sysdev_class *class,
+- struct sysdev_class_attribute *attr, char *buf)
++static ssize_t print_cpus_offline(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+ int n = 0, len = PAGE_SIZE-2;
+ cpumask_var_t offline;
+@@ -205,7 +204,7 @@
+ n += snprintf(&buf[n], len - n, "\n");
+ return n;
+ }
+-static SYSDEV_CLASS_ATTR(offline, 0444, print_cpus_offline, NULL);
++static DEVICE_ATTR(offline, 0444, print_cpus_offline, NULL);
+
+ /*
+ * register_cpu - Setup a sysfs device for a CPU.
+@@ -218,57 +217,66 @@
+ int __cpuinit register_cpu(struct cpu *cpu, int num)
+ {
+ int error;
+- cpu->node_id = cpu_to_node(num);
+- cpu->sysdev.id = num;
+- cpu->sysdev.cls = &cpu_sysdev_class;
+-
+- error = sysdev_register(&cpu->sysdev);
+
++ cpu->node_id = cpu_to_node(num);
++ cpu->dev.id = num;
++ cpu->dev.bus = &cpu_subsys;
++ error = device_register(&cpu->dev);
+ if (!error && cpu->hotpluggable)
+ register_cpu_control(cpu);
+ if (!error)
+- per_cpu(cpu_sys_devices, num) = &cpu->sysdev;
++ per_cpu(cpu_sys_devices, num) = &cpu->dev;
+ if (!error)
+ register_cpu_under_node(num, cpu_to_node(num));
+
+ #ifdef CONFIG_KEXEC
+ if (!error)
+- error = sysdev_create_file(&cpu->sysdev, &attr_crash_notes);
++ error = device_create_file(&cpu->dev, &dev_attr_crash_notes);
+ #endif
+ return error;
+ }
+
+-struct sys_device *get_cpu_sysdev(unsigned cpu)
++struct device *get_cpu_device(unsigned cpu)
+ {
+ if (cpu < nr_cpu_ids && cpu_possible(cpu))
+ return per_cpu(cpu_sys_devices, cpu);
+ else
+ return NULL;
+ }
+-EXPORT_SYMBOL_GPL(get_cpu_sysdev);
++EXPORT_SYMBOL_GPL(get_cpu_device);
++
++static struct attribute *cpu_root_attrs[] = {
++#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
++ &dev_attr_probe.attr,
++ &dev_attr_release.attr,
++#endif
++ &cpu_attrs[0].attr.attr,
++ &cpu_attrs[1].attr.attr,
++ &cpu_attrs[2].attr.attr,
++ &dev_attr_kernel_max.attr,
++ &dev_attr_offline.attr,
++ NULL
++};
++
++static struct attribute_group cpu_root_attr_group = {
++ .attrs = cpu_root_attrs,
++};
++
++static const struct attribute_group *cpu_root_attr_groups[] = {
++ &cpu_root_attr_group,
++ NULL,
++};
+
+ int __init cpu_dev_init(void)
+ {
+ int err;
+
+- err = sysdev_class_register(&cpu_sysdev_class);
++ err = subsys_system_register(&cpu_subsys, cpu_root_attr_groups);
++ if (err)
++ return err;
++
+ #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
+- if (!err)
+- err = sched_create_sysfs_power_savings_entries(&cpu_sysdev_class);
++ err = sched_create_sysfs_power_savings_entries(cpu_subsys.dev_root);
+ #endif
+-
+ return err;
+ }
+-
+-static struct sysdev_class_attribute *cpu_sysdev_class_attrs[] = {
+-#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
+- &attr_probe,
+- &attr_release,
+-#endif
+- &cpu_attrs[0].attr,
+- &cpu_attrs[1].attr,
+- &cpu_attrs[2].attr,
+- &attr_kernel_max,
+- &attr_offline,
+- NULL
+-};
+--- a/drivers/base/node.c
++++ b/drivers/base/node.c
+@@ -317,12 +317,12 @@
+ int register_cpu_under_node(unsigned int cpu, unsigned int nid)
+ {
+ int ret;
+- struct sys_device *obj;
++ struct device *obj;
+
+ if (!node_online(nid))
+ return 0;
+
+- obj = get_cpu_sysdev(cpu);
++ obj = get_cpu_device(cpu);
+ if (!obj)
+ return 0;
+
+@@ -339,12 +339,12 @@
+
+ int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
+ {
+- struct sys_device *obj;
++ struct device *obj;
+
+ if (!node_online(nid))
+ return 0;
+
+- obj = get_cpu_sysdev(cpu);
++ obj = get_cpu_device(cpu);
+ if (!obj)
+ return 0;
+
+--- a/drivers/base/topology.c
++++ b/drivers/base/topology.c
+@@ -23,7 +23,6 @@
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+-#include <linux/sysdev.h>
+ #include <linux/init.h>
+ #include <linux/mm.h>
+ #include <linux/cpu.h>
+@@ -32,14 +31,14 @@
+ #include <linux/topology.h>
+
+ #define define_one_ro_named(_name, _func) \
+-static SYSDEV_ATTR(_name, 0444, _func, NULL)
++ static DEVICE_ATTR(_name, 0444, _func, NULL)
+
+ #define define_one_ro(_name) \
+-static SYSDEV_ATTR(_name, 0444, show_##_name, NULL)
++ static DEVICE_ATTR(_name, 0444, show_##_name, NULL)
+
+ #define define_id_show_func(name) \
+-static ssize_t show_##name(struct sys_device *dev, \
+- struct sysdev_attribute *attr, char *buf) \
++static ssize_t show_##name(struct device *dev, \
++ struct device_attribute *attr, char *buf) \
+ { \
+ unsigned int cpu = dev->id; \
+ return sprintf(buf, "%d\n", topology_##name(cpu)); \
+@@ -65,16 +64,16 @@
+
+ #ifdef arch_provides_topology_pointers
+ #define define_siblings_show_map(name) \
+-static ssize_t show_##name(struct sys_device *dev, \
+- struct sysdev_attribute *attr, char *buf) \
++static ssize_t show_##name(struct device *dev, \
++ struct device_attribute *attr, char *buf) \
+ { \
+ unsigned int cpu = dev->id; \
+ return show_cpumap(0, topology_##name(cpu), buf); \
+ }
+
+ #define define_siblings_show_list(name) \
+-static ssize_t show_##name##_list(struct sys_device *dev, \
+- struct sysdev_attribute *attr, \
++static ssize_t show_##name##_list(struct device *dev, \
++ struct device_attribute *attr, \
+ char *buf) \
+ { \
+ unsigned int cpu = dev->id; \
+@@ -83,15 +82,15 @@
+
+ #else
+ #define define_siblings_show_map(name) \
+-static ssize_t show_##name(struct sys_device *dev, \
+- struct sysdev_attribute *attr, char *buf) \
++static ssize_t show_##name(struct device *dev, \
++ struct device_attribute *attr, char *buf) \
+ { \
+ return show_cpumap(0, topology_##name(dev->id), buf); \
+ }
+
+ #define define_siblings_show_list(name) \
+-static ssize_t show_##name##_list(struct sys_device *dev, \
+- struct sysdev_attribute *attr, \
++static ssize_t show_##name##_list(struct device *dev, \
++ struct device_attribute *attr, \
+ char *buf) \
+ { \
+ return show_cpumap(1, topology_##name(dev->id), buf); \
+@@ -124,16 +123,16 @@
+ #endif
+
+ static struct attribute *default_attrs[] = {
+- &attr_physical_package_id.attr,
+- &attr_core_id.attr,
+- &attr_thread_siblings.attr,
+- &attr_thread_siblings_list.attr,
+- &attr_core_siblings.attr,
+- &attr_core_siblings_list.attr,
++ &dev_attr_physical_package_id.attr,
++ &dev_attr_core_id.attr,
++ &dev_attr_thread_siblings.attr,
++ &dev_attr_thread_siblings_list.attr,
++ &dev_attr_core_siblings.attr,
++ &dev_attr_core_siblings_list.attr,
+ #ifdef CONFIG_SCHED_BOOK
+- &attr_book_id.attr,
+- &attr_book_siblings.attr,
+- &attr_book_siblings_list.attr,
++ &dev_attr_book_id.attr,
++ &dev_attr_book_siblings.attr,
++ &dev_attr_book_siblings_list.attr,
+ #endif
+ NULL
+ };
+@@ -146,16 +145,16 @@
+ /* Add/Remove cpu_topology interface for CPU device */
+ static int __cpuinit topology_add_dev(unsigned int cpu)
+ {
+- struct sys_device *sys_dev = get_cpu_sysdev(cpu);
++ struct device *dev = get_cpu_device(cpu);
+
+- return sysfs_create_group(&sys_dev->kobj, &topology_attr_group);
++ return sysfs_create_group(&dev->kobj, &topology_attr_group);
+ }
+
+ static void __cpuinit topology_remove_dev(unsigned int cpu)
+ {
+- struct sys_device *sys_dev = get_cpu_sysdev(cpu);
++ struct device *dev = get_cpu_device(cpu);
+
+- sysfs_remove_group(&sys_dev->kobj, &topology_attr_group);
++ sysfs_remove_group(&dev->kobj, &topology_attr_group);
+ }
+
+ static int __cpuinit topology_cpu_callback(struct notifier_block *nfb,
+--- a/drivers/cpufreq/cpufreq.c
++++ b/drivers/cpufreq/cpufreq.c
+@@ -679,7 +679,7 @@
+ */
+ static int cpufreq_add_dev_policy(unsigned int cpu,
+ struct cpufreq_policy *policy,
+- struct sys_device *sys_dev)
++ struct device *dev)
+ {
+ int ret = 0;
+ #ifdef CONFIG_SMP
+@@ -728,7 +728,7 @@
+ spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+
+ pr_debug("CPU already managed, adding link\n");
+- ret = sysfs_create_link(&sys_dev->kobj,
++ ret = sysfs_create_link(&dev->kobj,
+ &managed_policy->kobj,
+ "cpufreq");
+ if (ret)
+@@ -761,7 +761,7 @@
+
+ for_each_cpu(j, policy->cpus) {
+ struct cpufreq_policy *managed_policy;
+- struct sys_device *cpu_sys_dev;
++ struct device *cpu_dev;
+
+ if (j == cpu)
+ continue;
+@@ -770,8 +770,8 @@
+
+ pr_debug("CPU %u already managed, adding link\n", j);
+ managed_policy = cpufreq_cpu_get(cpu);
+- cpu_sys_dev = get_cpu_sysdev(j);
+- ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj,
++ cpu_dev = get_cpu_device(j);
++ ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
+ "cpufreq");
+ if (ret) {
+ cpufreq_cpu_put(managed_policy);
+@@ -783,7 +783,7 @@
+
+ static int cpufreq_add_dev_interface(unsigned int cpu,
+ struct cpufreq_policy *policy,
+- struct sys_device *sys_dev)
++ struct device *dev)
+ {
+ struct cpufreq_policy new_policy;
+ struct freq_attr **drv_attr;
+@@ -793,7 +793,7 @@
+
+ /* prepare interface data */
+ ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
+- &sys_dev->kobj, "cpufreq");
++ &dev->kobj, "cpufreq");
+ if (ret)
+ return ret;
+
+@@ -866,9 +866,9 @@
+ * with with cpu hotplugging and all hell will break loose. Tried to clean this
+ * mess up, but more thorough testing is needed. - Mathieu
+ */
+-static int cpufreq_add_dev(struct sys_device *sys_dev)
++static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
+ {
+- unsigned int cpu = sys_dev->id;
++ unsigned int cpu = dev->id;
+ int ret = 0, found = 0;
+ struct cpufreq_policy *policy;
+ unsigned long flags;
+@@ -947,7 +947,7 @@
+ blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
+ CPUFREQ_START, policy);
+
+- ret = cpufreq_add_dev_policy(cpu, policy, sys_dev);
++ ret = cpufreq_add_dev_policy(cpu, policy, dev);
+ if (ret) {
+ if (ret > 0)
+ /* This is a managed cpu, symlink created,
+@@ -956,7 +956,7 @@
+ goto err_unlock_policy;
+ }
+
+- ret = cpufreq_add_dev_interface(cpu, policy, sys_dev);
++ ret = cpufreq_add_dev_interface(cpu, policy, dev);
+ if (ret)
+ goto err_out_unregister;
+
+@@ -999,15 +999,15 @@
+ * Caller should already have policy_rwsem in write mode for this CPU.
+ * This routine frees the rwsem before returning.
+ */
+-static int __cpufreq_remove_dev(struct sys_device *sys_dev)
++static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
+ {
+- unsigned int cpu = sys_dev->id;
++ unsigned int cpu = dev->id;
+ unsigned long flags;
+ struct cpufreq_policy *data;
+ struct kobject *kobj;
+ struct completion *cmp;
+ #ifdef CONFIG_SMP
+- struct sys_device *cpu_sys_dev;
++ struct device *cpu_dev;
+ unsigned int j;
+ #endif
+
+@@ -1032,7 +1032,7 @@
+ pr_debug("removing link\n");
+ cpumask_clear_cpu(cpu, data->cpus);
+ spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+- kobj = &sys_dev->kobj;
++ kobj = &dev->kobj;
+ cpufreq_cpu_put(data);
+ unlock_policy_rwsem_write(cpu);
+ sysfs_remove_link(kobj, "cpufreq");
+@@ -1071,8 +1071,8 @@
+ strncpy(per_cpu(cpufreq_cpu_governor, j),
+ data->governor->name, CPUFREQ_NAME_LEN);
+ #endif
+- cpu_sys_dev = get_cpu_sysdev(j);
+- kobj = &cpu_sys_dev->kobj;
++ cpu_dev = get_cpu_device(j);
++ kobj = &cpu_dev->kobj;
+ unlock_policy_rwsem_write(cpu);
+ sysfs_remove_link(kobj, "cpufreq");
+ lock_policy_rwsem_write(cpu);
+@@ -1112,11 +1112,11 @@
+ if (unlikely(cpumask_weight(data->cpus) > 1)) {
+ /* first sibling now owns the new sysfs dir */
+ cpumask_clear_cpu(cpu, data->cpus);
+- cpufreq_add_dev(get_cpu_sysdev(cpumask_first(data->cpus)));
++ cpufreq_add_dev(get_cpu_device(cpumask_first(data->cpus)), NULL);
+
+ /* finally remove our own symlink */
+ lock_policy_rwsem_write(cpu);
+- __cpufreq_remove_dev(sys_dev);
++ __cpufreq_remove_dev(dev, sif);
+ }
+ #endif
+
+@@ -1128,9 +1128,9 @@
+ }
+
+
+-static int cpufreq_remove_dev(struct sys_device *sys_dev)
++static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
+ {
+- unsigned int cpu = sys_dev->id;
++ unsigned int cpu = dev->id;
+ int retval;
+
+ if (cpu_is_offline(cpu))
+@@ -1139,7 +1139,7 @@
+ if (unlikely(lock_policy_rwsem_write(cpu)))
+ BUG();
+
+- retval = __cpufreq_remove_dev(sys_dev);
++ retval = __cpufreq_remove_dev(dev, sif);
+ return retval;
+ }
+
+@@ -1271,9 +1271,11 @@
+ }
+ EXPORT_SYMBOL(cpufreq_get);
+
+-static struct sysdev_driver cpufreq_sysdev_driver = {
+- .add = cpufreq_add_dev,
+- .remove = cpufreq_remove_dev,
++static struct subsys_interface cpufreq_interface = {
++ .name = "cpufreq",
++ .subsys = &cpu_subsys,
++ .add_dev = cpufreq_add_dev,
++ .remove_dev = cpufreq_remove_dev,
+ };
+
+
+@@ -1765,25 +1767,25 @@
+ unsigned long action, void *hcpu)
+ {
+ unsigned int cpu = (unsigned long)hcpu;
+- struct sys_device *sys_dev;
++ struct device *dev;
+
+- sys_dev = get_cpu_sysdev(cpu);
+- if (sys_dev) {
++ dev = get_cpu_device(cpu);
++ if (dev) {
+ switch (action) {
+ case CPU_ONLINE:
+ case CPU_ONLINE_FROZEN:
+- cpufreq_add_dev(sys_dev);
++ cpufreq_add_dev(dev, NULL);
+ break;
+ case CPU_DOWN_PREPARE:
+ case CPU_DOWN_PREPARE_FROZEN:
+ if (unlikely(lock_policy_rwsem_write(cpu)))
+ BUG();
+
+- __cpufreq_remove_dev(sys_dev);
++ __cpufreq_remove_dev(dev, NULL);
+ break;
+ case CPU_DOWN_FAILED:
+ case CPU_DOWN_FAILED_FROZEN:
+- cpufreq_add_dev(sys_dev);
++ cpufreq_add_dev(dev, NULL);
+ break;
+ }
+ }
+@@ -1830,8 +1832,7 @@
+ cpufreq_driver = driver_data;
+ spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+
+- ret = sysdev_driver_register(&cpu_sysdev_class,
+- &cpufreq_sysdev_driver);
++ ret = subsys_interface_register(&cpufreq_interface);
+ if (ret)
+ goto err_null_driver;
+
+@@ -1850,7 +1851,7 @@
+ if (ret) {
+ pr_debug("no CPU initialized for driver %s\n",
+ driver_data->name);
+- goto err_sysdev_unreg;
++ goto err_if_unreg;
+ }
+ }
+
+@@ -1858,9 +1859,8 @@
+ pr_debug("driver %s up and running\n", driver_data->name);
+
+ return 0;
+-err_sysdev_unreg:
+- sysdev_driver_unregister(&cpu_sysdev_class,
+- &cpufreq_sysdev_driver);
++err_if_unreg:
++ subsys_interface_unregister(&cpufreq_interface);
+ err_null_driver:
+ spin_lock_irqsave(&cpufreq_driver_lock, flags);
+ cpufreq_driver = NULL;
+@@ -1887,7 +1887,7 @@
+
+ pr_debug("unregistering driver %s\n", driver->name);
+
+- sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver);
++ subsys_interface_unregister(&cpufreq_interface);
+ unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
+
+ spin_lock_irqsave(&cpufreq_driver_lock, flags);
+@@ -1907,8 +1907,7 @@
+ init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
+ }
+
+- cpufreq_global_kobject = kobject_create_and_add("cpufreq",
+- &cpu_sysdev_class.kset.kobj);
++ cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
+ BUG_ON(!cpufreq_global_kobject);
+ register_syscore_ops(&cpufreq_syscore_ops);
+
+--- a/drivers/cpufreq/cpufreq_stats.c
++++ b/drivers/cpufreq/cpufreq_stats.c
+@@ -11,7 +11,6 @@
+
+ #include <linux/kernel.h>
+ #include <linux/slab.h>
+-#include <linux/sysdev.h>
+ #include <linux/cpu.h>
+ #include <linux/sysfs.h>
+ #include <linux/cpufreq.h>
+--- a/drivers/cpuidle/cpuidle.c
++++ b/drivers/cpuidle/cpuidle.c
+@@ -291,10 +291,10 @@
+ static int __cpuidle_register_device(struct cpuidle_device *dev)
+ {
+ int ret;
+- struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu);
++ struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu);
+ struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver();
+
+- if (!sys_dev)
++ if (!dev)
+ return -EINVAL;
+ if (!try_module_get(cpuidle_driver->owner))
+ return -EINVAL;
+@@ -303,7 +303,7 @@
+
+ per_cpu(cpuidle_devices, dev->cpu) = dev;
+ list_add(&dev->device_list, &cpuidle_detected_devices);
+- if ((ret = cpuidle_add_sysfs(sys_dev))) {
++ if ((ret = cpuidle_add_sysfs(cpu_dev))) {
+ module_put(cpuidle_driver->owner);
+ return ret;
+ }
+@@ -344,7 +344,7 @@
+ */
+ void cpuidle_unregister_device(struct cpuidle_device *dev)
+ {
+- struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu);
++ struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu);
+ struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver();
+
+ if (dev->registered == 0)
+@@ -354,7 +354,7 @@
+
+ cpuidle_disable_device(dev);
+
+- cpuidle_remove_sysfs(sys_dev);
++ cpuidle_remove_sysfs(cpu_dev);
+ list_del(&dev->device_list);
+ wait_for_completion(&dev->kobj_unregister);
+ per_cpu(cpuidle_devices, dev->cpu) = NULL;
+@@ -411,7 +411,7 @@
+ if (cpuidle_disabled())
+ return -ENODEV;
+
+- ret = cpuidle_add_class_sysfs(&cpu_sysdev_class);
++ ret = cpuidle_add_interface(cpu_subsys.dev_root);
+ if (ret)
+ return ret;
+
+--- a/drivers/cpuidle/cpuidle.h
++++ b/drivers/cpuidle/cpuidle.h
+@@ -5,7 +5,7 @@
+ #ifndef __DRIVER_CPUIDLE_H
+ #define __DRIVER_CPUIDLE_H
+
+-#include <linux/sysdev.h>
++#include <linux/device.h>
+
+ /* For internal use only */
+ extern struct cpuidle_governor *cpuidle_curr_governor;
+@@ -23,11 +23,11 @@
+ extern int cpuidle_switch_governor(struct cpuidle_governor *gov);
+
+ /* sysfs */
+-extern int cpuidle_add_class_sysfs(struct sysdev_class *cls);
+-extern void cpuidle_remove_class_sysfs(struct sysdev_class *cls);
++extern int cpuidle_add_interface(struct device *dev);
++extern void cpuidle_remove_interface(struct device *dev);
+ extern int cpuidle_add_state_sysfs(struct cpuidle_device *device);
+ extern void cpuidle_remove_state_sysfs(struct cpuidle_device *device);
+-extern int cpuidle_add_sysfs(struct sys_device *sysdev);
+-extern void cpuidle_remove_sysfs(struct sys_device *sysdev);
++extern int cpuidle_add_sysfs(struct device *dev);
++extern void cpuidle_remove_sysfs(struct device *dev);
+
+ #endif /* __DRIVER_CPUIDLE_H */
+--- a/drivers/cpuidle/sysfs.c
++++ b/drivers/cpuidle/sysfs.c
+@@ -22,8 +22,8 @@
+ }
+ __setup("cpuidle_sysfs_switch", cpuidle_sysfs_setup);
+
+-static ssize_t show_available_governors(struct sysdev_class *class,
+- struct sysdev_class_attribute *attr,
++static ssize_t show_available_governors(struct device *dev,
++ struct device_attribute *attr,
+ char *buf)
+ {
+ ssize_t i = 0;
+@@ -42,8 +42,8 @@
+ return i;
+ }
+
+-static ssize_t show_current_driver(struct sysdev_class *class,
+- struct sysdev_class_attribute *attr,
++static ssize_t show_current_driver(struct device *dev,
++ struct device_attribute *attr,
+ char *buf)
+ {
+ ssize_t ret;
+@@ -59,8 +59,8 @@
+ return ret;
+ }
+
+-static ssize_t show_current_governor(struct sysdev_class *class,
+- struct sysdev_class_attribute *attr,
++static ssize_t show_current_governor(struct device *dev,
++ struct device_attribute *attr,
+ char *buf)
+ {
+ ssize_t ret;
+@@ -75,8 +75,8 @@
+ return ret;
+ }
+
+-static ssize_t store_current_governor(struct sysdev_class *class,
+- struct sysdev_class_attribute *attr,
++static ssize_t store_current_governor(struct device *dev,
++ struct device_attribute *attr,
+ const char *buf, size_t count)
+ {
+ char gov_name[CPUIDLE_NAME_LEN];
+@@ -109,50 +109,48 @@
+ return count;
+ }
+
+-static SYSDEV_CLASS_ATTR(current_driver, 0444, show_current_driver, NULL);
+-static SYSDEV_CLASS_ATTR(current_governor_ro, 0444, show_current_governor,
+- NULL);
+-
+-static struct attribute *cpuclass_default_attrs[] = {
+- &attr_current_driver.attr,
+- &attr_current_governor_ro.attr,
++static DEVICE_ATTR(current_driver, 0444, show_current_driver, NULL);
++static DEVICE_ATTR(current_governor_ro, 0444, show_current_governor, NULL);
++
++static struct attribute *cpuidle_default_attrs[] = {
++ &dev_attr_current_driver.attr,
++ &dev_attr_current_governor_ro.attr,
+ NULL
+ };
+
+-static SYSDEV_CLASS_ATTR(available_governors, 0444, show_available_governors,
+- NULL);
+-static SYSDEV_CLASS_ATTR(current_governor, 0644, show_current_governor,
+- store_current_governor);
+-
+-static struct attribute *cpuclass_switch_attrs[] = {
+- &attr_available_governors.attr,
+- &attr_current_driver.attr,
+- &attr_current_governor.attr,
++static DEVICE_ATTR(available_governors, 0444, show_available_governors, NULL);
++static DEVICE_ATTR(current_governor, 0644, show_current_governor,
++ store_current_governor);
++
++static struct attribute *cpuidle_switch_attrs[] = {
++ &dev_attr_available_governors.attr,
++ &dev_attr_current_driver.attr,
++ &dev_attr_current_governor.attr,
+ NULL
+ };
+
+-static struct attribute_group cpuclass_attr_group = {
+- .attrs = cpuclass_default_attrs,
++static struct attribute_group cpuidle_attr_group = {
++ .attrs = cpuidle_default_attrs,
+ .name = "cpuidle",
+ };
+
+ /**
+- * cpuidle_add_class_sysfs - add CPU global sysfs attributes
++ * cpuidle_add_interface - add CPU global sysfs attributes
+ */
+-int cpuidle_add_class_sysfs(struct sysdev_class *cls)
++int cpuidle_add_interface(struct device *dev)
+ {
+ if (sysfs_switch)
+- cpuclass_attr_group.attrs = cpuclass_switch_attrs;
++ cpuidle_attr_group.attrs = cpuidle_switch_attrs;
+
+- return sysfs_create_group(&cls->kset.kobj, &cpuclass_attr_group);
++ return sysfs_create_group(&dev->kobj, &cpuidle_attr_group);
+ }
+
+ /**
+- * cpuidle_remove_class_sysfs - remove CPU global sysfs attributes
++ * cpuidle_remove_interface - remove CPU global sysfs attributes
+ */
+-void cpuidle_remove_class_sysfs(struct sysdev_class *cls)
++void cpuidle_remove_interface(struct device *dev)
+ {
+- sysfs_remove_group(&cls->kset.kobj, &cpuclass_attr_group);
++ sysfs_remove_group(&dev->kobj, &cpuidle_attr_group);
+ }
+
+ struct cpuidle_attr {
+@@ -365,16 +363,16 @@
+
+ /**
+ * cpuidle_add_sysfs - creates a sysfs instance for the target device
+- * @sysdev: the target device
++ * @dev: the target device
+ */
+-int cpuidle_add_sysfs(struct sys_device *sysdev)
++int cpuidle_add_sysfs(struct device *cpu_dev)
+ {
+- int cpu = sysdev->id;
++ int cpu = cpu_dev->id;
+ struct cpuidle_device *dev;
+ int error;
+
+ dev = per_cpu(cpuidle_devices, cpu);
+- error = kobject_init_and_add(&dev->kobj, &ktype_cpuidle, &sysdev->kobj,
++ error = kobject_init_and_add(&dev->kobj, &ktype_cpuidle, &cpu_dev->kobj,
+ "cpuidle");
+ if (!error)
+ kobject_uevent(&dev->kobj, KOBJ_ADD);
+@@ -383,11 +381,11 @@
+
+ /**
+ * cpuidle_remove_sysfs - deletes a sysfs instance on the target device
+- * @sysdev: the target device
++ * @dev: the target device
+ */
+-void cpuidle_remove_sysfs(struct sys_device *sysdev)
++void cpuidle_remove_sysfs(struct device *cpu_dev)
+ {
+- int cpu = sysdev->id;
++ int cpu = cpu_dev->id;
+ struct cpuidle_device *dev;
+
+ dev = per_cpu(cpuidle_devices, cpu);
+--- a/drivers/s390/char/sclp_config.c
++++ b/drivers/s390/char/sclp_config.c
+@@ -11,7 +11,7 @@
+ #include <linux/init.h>
+ #include <linux/errno.h>
+ #include <linux/cpu.h>
+-#include <linux/sysdev.h>
++#include <linux/device.h>
+ #include <linux/workqueue.h>
+ #include <asm/smp.h>
+
+@@ -31,14 +31,14 @@
+ static void sclp_cpu_capability_notify(struct work_struct *work)
+ {
+ int cpu;
+- struct sys_device *sysdev;
++ struct device *dev;
+
+ s390_adjust_jiffies();
+ pr_warning("cpu capability changed.\n");
+ get_online_cpus();
+ for_each_online_cpu(cpu) {
+- sysdev = get_cpu_sysdev(cpu);
+- kobject_uevent(&sysdev->kobj, KOBJ_CHANGE);
++ dev = get_cpu_device(cpu);
++ kobject_uevent(&dev->kobj, KOBJ_CHANGE);
+ }
+ put_online_cpus();
+ }
+--- a/include/linux/cpu.h
++++ b/include/linux/cpu.h
+@@ -14,7 +14,7 @@
+ #ifndef _LINUX_CPU_H_
+ #define _LINUX_CPU_H_
+
+-#include <linux/sysdev.h>
++#include <linux/device.h>
+ #include <linux/node.h>
+ #include <linux/compiler.h>
+ #include <linux/cpumask.h>
+@@ -22,19 +22,19 @@
+ struct cpu {
+ int node_id; /* The node which contains the CPU */
+ int hotpluggable; /* creates sysfs control file if hotpluggable */
+- struct sys_device sysdev;
++ struct device dev;
+ };
+
+ extern int register_cpu(struct cpu *cpu, int num);
+-extern struct sys_device *get_cpu_sysdev(unsigned cpu);
++extern struct device *get_cpu_device(unsigned cpu);
+
+-extern int cpu_add_sysdev_attr(struct sysdev_attribute *attr);
+-extern void cpu_remove_sysdev_attr(struct sysdev_attribute *attr);
++extern int cpu_add_dev_attr(struct device_attribute *attr);
++extern void cpu_remove_dev_attr(struct device_attribute *attr);
+
+-extern int cpu_add_sysdev_attr_group(struct attribute_group *attrs);
+-extern void cpu_remove_sysdev_attr_group(struct attribute_group *attrs);
++extern int cpu_add_dev_attr_group(struct attribute_group *attrs);
++extern void cpu_remove_dev_attr_group(struct attribute_group *attrs);
+
+-extern int sched_create_sysfs_power_savings_entries(struct sysdev_class *cls);
++extern int sched_create_sysfs_power_savings_entries(struct device *dev);
+
+ #ifdef CONFIG_HOTPLUG_CPU
+ extern void unregister_cpu(struct cpu *cpu);
+@@ -160,7 +160,7 @@
+ }
+
+ #endif /* CONFIG_SMP */
+-extern struct sysdev_class cpu_sysdev_class;
++extern struct bus_type cpu_subsys;
+
+ #ifdef CONFIG_HOTPLUG_CPU
+ /* Stop CPUs going up and down. */
+--- a/kernel/sched.c
++++ b/kernel/sched.c
+@@ -7949,54 +7949,52 @@
+ }
+
+ #ifdef CONFIG_SCHED_MC
+-static ssize_t sched_mc_power_savings_show(struct sysdev_class *class,
+- struct sysdev_class_attribute *attr,
+- char *page)
++static ssize_t sched_mc_power_savings_show(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
+ {
+- return sprintf(page, "%u\n", sched_mc_power_savings);
++ return sprintf(buf, "%u\n", sched_mc_power_savings);
+ }
+-static ssize_t sched_mc_power_savings_store(struct sysdev_class *class,
+- struct sysdev_class_attribute *attr,
++static ssize_t sched_mc_power_savings_store(struct device *dev,
++ struct device_attribute *attr,
+ const char *buf, size_t count)
+ {
+ return sched_power_savings_store(buf, count, 0);
+ }
+-static SYSDEV_CLASS_ATTR(sched_mc_power_savings, 0644,
+- sched_mc_power_savings_show,
+- sched_mc_power_savings_store);
++static DEVICE_ATTR(sched_mc_power_savings, 0644,
++ sched_mc_power_savings_show,
++ sched_mc_power_savings_store);
+ #endif
+
+ #ifdef CONFIG_SCHED_SMT
+-static ssize_t sched_smt_power_savings_show(struct sysdev_class *dev,
+- struct sysdev_class_attribute *attr,
+- char *page)
++static ssize_t sched_smt_power_savings_show(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
+ {
+- return sprintf(page, "%u\n", sched_smt_power_savings);
++ return sprintf(buf, "%u\n", sched_smt_power_savings);
+ }
+-static ssize_t sched_smt_power_savings_store(struct sysdev_class *dev,
+- struct sysdev_class_attribute *attr,
++static ssize_t sched_smt_power_savings_store(struct device *dev,
++ struct device_attribute *attr,
+ const char *buf, size_t count)
+ {
+ return sched_power_savings_store(buf, count, 1);
+ }
+-static SYSDEV_CLASS_ATTR(sched_smt_power_savings, 0644,
++static DEVICE_ATTR(sched_smt_power_savings, 0644,
+ sched_smt_power_savings_show,
+ sched_smt_power_savings_store);
+ #endif
+
+-int __init sched_create_sysfs_power_savings_entries(struct sysdev_class *cls)
++int __init sched_create_sysfs_power_savings_entries(struct device *dev)
+ {
+ int err = 0;
+
+ #ifdef CONFIG_SCHED_SMT
+ if (smt_capable())
+- err = sysfs_create_file(&cls->kset.kobj,
+- &attr_sched_smt_power_savings.attr);
++ err = device_create_file(dev, &dev_attr_sched_smt_power_savings);
+ #endif
+ #ifdef CONFIG_SCHED_MC
+ if (!err && mc_capable())
+- err = sysfs_create_file(&cls->kset.kobj,
+- &attr_sched_mc_power_savings.attr);
++ err = device_create_file(dev, &dev_attr_sched_mc_power_savings);
+ #endif
+ return err;
+ }
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/cpufreq-Add-support-for-x86-cpuinfo-auto-loading-v4.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/cpufreq-Add-support-for-x86-cpuinfo-auto-loading-v4.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,596 @@
+From: Andi Kleen <ak at linux.intel.com>
+Date: Thu, 26 Jan 2012 00:09:12 +0100
+Subject: cpufreq: Add support for x86 cpuinfo auto loading v4
+
+commit fa8031aefec0cf7ea6c2387c93610d99d9659aa2 upstream.
+
+This marks all the x86 cpuinfo tables to the CPU specific device drivers,
+to allow auto loading by udev. This should simplify the distribution
+startup scripts for this greatly.
+
+I didn't add MODULE_DEVICE_IDs to the centrino and p4-clockmod drivers,
+because those probably shouldn't be auto loaded and the acpi driver
+be used instead (not fully sure on that, would appreciate feedback)
+
+The old nforce drivers autoload based on the PCI ID.
+
+ACPI cpufreq is autoloaded in another patch.
+
+v3: Autoload gx based on PCI IDs only. Remove cpu check (Dave Jones)
+v4: Use newly introduce HW_PSTATE feature for powernow-k8 loading
+
+Cc: Dave Jones <davej at redhat.com>
+Cc: Kay Sievers <kay.sievers at vrfy.org>
+Signed-off-by: Andi Kleen <ak at linux.intel.com>
+Signed-off-by: Thomas Renninger <trenn at suse.de>
+Acked-by: H. Peter Anvin <hpa at zytor.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+---
+ drivers/cpufreq/cpufreq-nforce2.c | 8 ++++++++
+ drivers/cpufreq/e_powersaver.c | 20 +++++++++++---------
+ drivers/cpufreq/elanfreq.c | 14 +++++++-------
+ drivers/cpufreq/gx-suspmod.c | 9 ++-------
+ drivers/cpufreq/longhaul.c | 8 +++++++-
+ drivers/cpufreq/longrun.c | 13 ++++++++-----
+ drivers/cpufreq/p4-clockmod.c | 17 +++++++++++------
+ drivers/cpufreq/powernow-k6.c | 12 ++++++++----
+ drivers/cpufreq/powernow-k7.c | 14 ++++++++------
+ drivers/cpufreq/powernow-k8.c | 19 +++++++++++++------
+ drivers/cpufreq/sc520_freq.c | 14 ++++++++------
+ drivers/cpufreq/speedstep-centrino.c | 24 ++++++++++++++++++++----
+ drivers/cpufreq/speedstep-ich.c | 15 +++++++++++++++
+ drivers/cpufreq/speedstep-lib.c | 1 +
+ drivers/cpufreq/speedstep-smi.c | 15 +++++++++++++++
+ 15 files changed, 142 insertions(+), 61 deletions(-)
+
+diff --git a/drivers/cpufreq/cpufreq-nforce2.c b/drivers/cpufreq/cpufreq-nforce2.c
+index 7bac808..13d311e 100644
+--- a/drivers/cpufreq/cpufreq-nforce2.c
++++ b/drivers/cpufreq/cpufreq-nforce2.c
+@@ -385,6 +385,14 @@ static struct cpufreq_driver nforce2_driver = {
+ .owner = THIS_MODULE,
+ };
+
++#ifdef MODULE
++static DEFINE_PCI_DEVICE_TABLE(nforce2_ids) = {
++ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2 },
++ {}
++};
++MODULE_DEVICE_TABLE(pci, nforce2_ids);
++#endif
++
+ /**
+ * nforce2_detect_chipset - detect the Southbridge which contains FSB PLL logic
+ *
+diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c
+index 4bd6815..3fffbe6 100644
+--- a/drivers/cpufreq/e_powersaver.c
++++ b/drivers/cpufreq/e_powersaver.c
+@@ -16,6 +16,7 @@
+ #include <linux/io.h>
+ #include <linux/delay.h>
+
++#include <asm/cpu_device_id.h>
+ #include <asm/msr.h>
+ #include <asm/tsc.h>
+
+@@ -437,18 +438,19 @@ static struct cpufreq_driver eps_driver = {
+ .attr = eps_attr,
+ };
+
++
++/* This driver will work only on Centaur C7 processors with
++ * Enhanced SpeedStep/PowerSaver registers */
++static const struct x86_cpu_id eps_cpu_id[] = {
++ { X86_VENDOR_CENTAUR, 6, X86_MODEL_ANY, X86_FEATURE_EST },
++ {}
++};
++MODULE_DEVICE_TABLE(x86cpu, eps_cpu_id);
++
+ static int __init eps_init(void)
+ {
+- struct cpuinfo_x86 *c = &cpu_data(0);
+-
+- /* This driver will work only on Centaur C7 processors with
+- * Enhanced SpeedStep/PowerSaver registers */
+- if (c->x86_vendor != X86_VENDOR_CENTAUR
+- || c->x86 != 6 || c->x86_model < 10)
+- return -ENODEV;
+- if (!cpu_has(c, X86_FEATURE_EST))
++ if (!x86_match_cpu(eps_cpu_id) || boot_cpu_data.x86_model < 10)
+ return -ENODEV;
+-
+ if (cpufreq_register_driver(&eps_driver))
+ return -EINVAL;
+ return 0;
+diff --git a/drivers/cpufreq/elanfreq.c b/drivers/cpufreq/elanfreq.c
+index c587db4..960671f 100644
+--- a/drivers/cpufreq/elanfreq.c
++++ b/drivers/cpufreq/elanfreq.c
+@@ -23,6 +23,7 @@
+ #include <linux/delay.h>
+ #include <linux/cpufreq.h>
+
++#include <asm/cpu_device_id.h>
+ #include <asm/msr.h>
+ #include <linux/timex.h>
+ #include <linux/io.h>
+@@ -277,17 +278,16 @@ static struct cpufreq_driver elanfreq_driver = {
+ .attr = elanfreq_attr,
+ };
+
++static const struct x86_cpu_id elan_id[] = {
++ { X86_VENDOR_AMD, 4, 10, },
++ {}
++};
++MODULE_DEVICE_TABLE(x86cpu, elan_id);
+
+ static int __init elanfreq_init(void)
+ {
+- struct cpuinfo_x86 *c = &cpu_data(0);
+-
+- /* Test if we have the right hardware */
+- if ((c->x86_vendor != X86_VENDOR_AMD) ||
+- (c->x86 != 4) || (c->x86_model != 10)) {
+- printk(KERN_INFO "elanfreq: error: no Elan processor found!\n");
++ if (!x86_match_cpu(elan_id))
+ return -ENODEV;
+- }
+ return cpufreq_register_driver(&elanfreq_driver);
+ }
+
+diff --git a/drivers/cpufreq/gx-suspmod.c b/drivers/cpufreq/gx-suspmod.c
+index ffe1f2c..5a06c0b 100644
+--- a/drivers/cpufreq/gx-suspmod.c
++++ b/drivers/cpufreq/gx-suspmod.c
+@@ -82,6 +82,7 @@
+ #include <linux/errno.h>
+ #include <linux/slab.h>
+
++#include <asm/cpu_device_id.h>
+ #include <asm/processor-cyrix.h>
+
+ /* PCI config registers, all at F0 */
+@@ -171,6 +172,7 @@ static struct pci_device_id gx_chipset_tbl[] __initdata = {
+ { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), },
+ { 0, },
+ };
++MODULE_DEVICE_TABLE(gx_chipset_tbl);
+
+ static void gx_write_byte(int reg, int value)
+ {
+@@ -185,13 +187,6 @@ static __init struct pci_dev *gx_detect_chipset(void)
+ {
+ struct pci_dev *gx_pci = NULL;
+
+- /* check if CPU is a MediaGX or a Geode. */
+- if ((boot_cpu_data.x86_vendor != X86_VENDOR_NSC) &&
+- (boot_cpu_data.x86_vendor != X86_VENDOR_CYRIX)) {
+- pr_debug("error: no MediaGX/Geode processor found!\n");
+- return NULL;
+- }
+-
+ /* detect which companion chip is used */
+ for_each_pci_dev(gx_pci) {
+ if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL)
+diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c
+index f47d26e..53ddbc7 100644
+--- a/drivers/cpufreq/longhaul.c
++++ b/drivers/cpufreq/longhaul.c
+@@ -35,6 +35,7 @@
+ #include <linux/acpi.h>
+
+ #include <asm/msr.h>
++#include <asm/cpu_device_id.h>
+ #include <acpi/processor.h>
+
+ #include "longhaul.h"
+@@ -951,12 +952,17 @@ static struct cpufreq_driver longhaul_driver = {
+ .attr = longhaul_attr,
+ };
+
++static const struct x86_cpu_id longhaul_id[] = {
++ { X86_VENDOR_CENTAUR, 6 },
++ {}
++};
++MODULE_DEVICE_TABLE(x86cpu, longhaul_id);
+
+ static int __init longhaul_init(void)
+ {
+ struct cpuinfo_x86 *c = &cpu_data(0);
+
+- if (c->x86_vendor != X86_VENDOR_CENTAUR || c->x86 != 6)
++ if (!x86_match_cpu(longhaul_id))
+ return -ENODEV;
+
+ #ifdef CONFIG_SMP
+diff --git a/drivers/cpufreq/longrun.c b/drivers/cpufreq/longrun.c
+index 34ea359..8bc9f5f 100644
+--- a/drivers/cpufreq/longrun.c
++++ b/drivers/cpufreq/longrun.c
+@@ -14,6 +14,7 @@
+
+ #include <asm/msr.h>
+ #include <asm/processor.h>
++#include <asm/cpu_device_id.h>
+
+ static struct cpufreq_driver longrun_driver;
+
+@@ -288,6 +289,12 @@ static struct cpufreq_driver longrun_driver = {
+ .owner = THIS_MODULE,
+ };
+
++static const struct x86_cpu_id longrun_ids[] = {
++ { X86_VENDOR_TRANSMETA, X86_FAMILY_ANY, X86_MODEL_ANY,
++ X86_FEATURE_LONGRUN },
++ {}
++};
++MODULE_DEVICE_TABLE(x86cpu, longrun_ids);
+
+ /**
+ * longrun_init - initializes the Transmeta Crusoe LongRun CPUFreq driver
+@@ -296,12 +303,8 @@ static struct cpufreq_driver longrun_driver = {
+ */
+ static int __init longrun_init(void)
+ {
+- struct cpuinfo_x86 *c = &cpu_data(0);
+-
+- if (c->x86_vendor != X86_VENDOR_TRANSMETA ||
+- !cpu_has(c, X86_FEATURE_LONGRUN))
++ if (!x86_match_cpu(longrun_ids))
+ return -ENODEV;
+-
+ return cpufreq_register_driver(&longrun_driver);
+ }
+
+diff --git a/drivers/cpufreq/p4-clockmod.c b/drivers/cpufreq/p4-clockmod.c
+index 6be3e07..827629c9 100644
+--- a/drivers/cpufreq/p4-clockmod.c
++++ b/drivers/cpufreq/p4-clockmod.c
+@@ -31,6 +31,7 @@
+ #include <asm/processor.h>
+ #include <asm/msr.h>
+ #include <asm/timer.h>
++#include <asm/cpu_device_id.h>
+
+ #include "speedstep-lib.h"
+
+@@ -289,21 +290,25 @@ static struct cpufreq_driver p4clockmod_driver = {
+ .attr = p4clockmod_attr,
+ };
+
++static const struct x86_cpu_id cpufreq_p4_id[] = {
++ { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_ACC },
++ {}
++};
++
++/*
++ * Intentionally no MODULE_DEVICE_TABLE here: this driver should not
++ * be auto loaded. Please don't add one.
++ */
+
+ static int __init cpufreq_p4_init(void)
+ {
+- struct cpuinfo_x86 *c = &cpu_data(0);
+ int ret;
+
+ /*
+ * THERM_CONTROL is architectural for IA32 now, so
+ * we can rely on the capability checks
+ */
+- if (c->x86_vendor != X86_VENDOR_INTEL)
+- return -ENODEV;
+-
+- if (!test_cpu_cap(c, X86_FEATURE_ACPI) ||
+- !test_cpu_cap(c, X86_FEATURE_ACC))
++ if (!x86_match_cpu(cpufreq_p4_id) || !boot_cpu_has(X86_FEATURE_ACPI))
+ return -ENODEV;
+
+ ret = cpufreq_register_driver(&p4clockmod_driver);
+diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c
+index b3379d6..54dd031 100644
+--- a/drivers/cpufreq/powernow-k6.c
++++ b/drivers/cpufreq/powernow-k6.c
+@@ -16,6 +16,7 @@
+ #include <linux/timex.h>
+ #include <linux/io.h>
+
++#include <asm/cpu_device_id.h>
+ #include <asm/msr.h>
+
+ #define POWERNOW_IOPORT 0xfff0 /* it doesn't matter where, as long
+@@ -210,6 +211,12 @@ static struct cpufreq_driver powernow_k6_driver = {
+ .attr = powernow_k6_attr,
+ };
+
++static const struct x86_cpu_id powernow_k6_ids[] = {
++ { X86_VENDOR_AMD, 5, 12 },
++ { X86_VENDOR_AMD, 5, 13 },
++ {}
++};
++
+
+ /**
+ * powernow_k6_init - initializes the k6 PowerNow! CPUFreq driver
+@@ -220,10 +227,7 @@ static struct cpufreq_driver powernow_k6_driver = {
+ */
+ static int __init powernow_k6_init(void)
+ {
+- struct cpuinfo_x86 *c = &cpu_data(0);
+-
+- if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) ||
+- ((c->x86_model != 12) && (c->x86_model != 13)))
++ if (!x86_match_cpu(powernow_k6_ids))
+ return -ENODEV;
+
+ if (!request_region(POWERNOW_IOPORT, 16, "PowerNow!")) {
+diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c
+index d71d9f3..501d167 100644
+--- a/drivers/cpufreq/powernow-k7.c
++++ b/drivers/cpufreq/powernow-k7.c
+@@ -28,6 +28,7 @@
+ #include <asm/timer.h> /* Needed for recalibrate_cpu_khz() */
+ #include <asm/msr.h>
+ #include <asm/system.h>
++#include <asm/cpu_device_id.h>
+
+ #ifdef CONFIG_X86_POWERNOW_K7_ACPI
+ #include <linux/acpi.h>
+@@ -110,18 +111,19 @@ static int check_fsb(unsigned int fsbspeed)
+ return delta < 5;
+ }
+
++static const struct x86_cpu_id powernow_k7_cpuids[] = {
++ { X86_VENDOR_AMD, 7, },
++ {}
++};
++MODULE_DEVICE_TABLE(x86cpu, powernow_k7_cpuids);
++
+ static int check_powernow(void)
+ {
+ struct cpuinfo_x86 *c = &cpu_data(0);
+ unsigned int maxei, eax, ebx, ecx, edx;
+
+- if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 6)) {
+-#ifdef MODULE
+- printk(KERN_INFO PFX "This module only works with "
+- "AMD K7 CPUs\n");
+-#endif
++ if (!x86_match_cpu(powernow_k7_cpuids))
+ return 0;
+- }
+
+ /* Get maximum capabilities */
+ maxei = cpuid_eax(0x80000000);
+diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
+index 8f9b2ce..c0e8164 100644
+--- a/drivers/cpufreq/powernow-k8.c
++++ b/drivers/cpufreq/powernow-k8.c
+@@ -40,6 +40,7 @@
+ #include <linux/delay.h>
+
+ #include <asm/msr.h>
++#include <asm/cpu_device_id.h>
+
+ #include <linux/acpi.h>
+ #include <linux/mutex.h>
+@@ -520,6 +521,15 @@ static int core_voltage_post_transition(struct powernow_k8_data *data,
+ return 0;
+ }
+
++static const struct x86_cpu_id powernow_k8_ids[] = {
++ /* IO based frequency switching */
++ { X86_VENDOR_AMD, 0xf },
++ /* MSR based frequency switching supported */
++ X86_FEATURE_MATCH(X86_FEATURE_HW_PSTATE),
++ {}
++};
++MODULE_DEVICE_TABLE(x86cpu, powernow_k8_ids);
++
+ static void check_supported_cpu(void *_rc)
+ {
+ u32 eax, ebx, ecx, edx;
+@@ -527,13 +537,7 @@ static void check_supported_cpu(void *_rc)
+
+ *rc = -ENODEV;
+
+- if (__this_cpu_read(cpu_info.x86_vendor) != X86_VENDOR_AMD)
+- return;
+-
+ eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
+- if (((eax & CPUID_XFAM) != CPUID_XFAM_K8) &&
+- ((eax & CPUID_XFAM) < CPUID_XFAM_10H))
+- return;
+
+ if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) {
+ if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
+@@ -1553,6 +1557,9 @@ static int __cpuinit powernowk8_init(void)
+ unsigned int i, supported_cpus = 0, cpu;
+ int rv;
+
++ if (!x86_match_cpu(powernow_k8_ids))
++ return -ENODEV;
++
+ for_each_online_cpu(i) {
+ int rc;
+ smp_call_function_single(i, check_supported_cpu, &rc, 1);
+diff --git a/drivers/cpufreq/sc520_freq.c b/drivers/cpufreq/sc520_freq.c
+index 1e205e6..e42e073 100644
+--- a/drivers/cpufreq/sc520_freq.c
++++ b/drivers/cpufreq/sc520_freq.c
+@@ -22,6 +22,7 @@
+ #include <linux/timex.h>
+ #include <linux/io.h>
+
++#include <asm/cpu_device_id.h>
+ #include <asm/msr.h>
+
+ #define MMCR_BASE 0xfffef000 /* The default base address */
+@@ -150,18 +151,19 @@ static struct cpufreq_driver sc520_freq_driver = {
+ .attr = sc520_freq_attr,
+ };
+
++static const struct x86_cpu_id sc520_ids[] = {
++ { X86_VENDOR_AMD, 4, 9 },
++ {}
++};
++MODULE_DEVICE_TABLE(x86cpu, sc520_ids);
+
+ static int __init sc520_freq_init(void)
+ {
+- struct cpuinfo_x86 *c = &cpu_data(0);
+ int err;
+
+- /* Test if we have the right hardware */
+- if (c->x86_vendor != X86_VENDOR_AMD ||
+- c->x86 != 4 || c->x86_model != 9) {
+- pr_debug("no Elan SC520 processor found!\n");
++ if (!x86_match_cpu(sc520_ids))
+ return -ENODEV;
+- }
++
+ cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1);
+ if (!cpuctl) {
+ printk(KERN_ERR "sc520_freq: error: failed to remap memory\n");
+diff --git a/drivers/cpufreq/speedstep-centrino.c b/drivers/cpufreq/speedstep-centrino.c
+index 6ea3455..3a953d5 100644
+--- a/drivers/cpufreq/speedstep-centrino.c
++++ b/drivers/cpufreq/speedstep-centrino.c
+@@ -25,6 +25,7 @@
+ #include <asm/msr.h>
+ #include <asm/processor.h>
+ #include <asm/cpufeature.h>
++#include <asm/cpu_device_id.h>
+
+ #define PFX "speedstep-centrino: "
+ #define MAINTAINER "cpufreq at vger.kernel.org"
+@@ -595,6 +596,24 @@ static struct cpufreq_driver centrino_driver = {
+ .owner = THIS_MODULE,
+ };
+
++/*
++ * This doesn't replace the detailed checks above because
++ * the generic CPU IDs don't have a way to match for steppings
++ * or ASCII model IDs.
++ */
++static const struct x86_cpu_id centrino_ids[] = {
++ { X86_VENDOR_INTEL, 6, 9, X86_FEATURE_EST },
++ { X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST },
++ { X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST },
++ { X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST },
++ { X86_VENDOR_INTEL, 15, 3, X86_FEATURE_EST },
++ { X86_VENDOR_INTEL, 15, 4, X86_FEATURE_EST },
++ {}
++};
++#if 0
++/* Autoload or not? Do not for now. */
++MODULE_DEVICE_TABLE(x86cpu, centrino_ids);
++#endif
+
+ /**
+ * centrino_init - initializes the Enhanced SpeedStep CPUFreq driver
+@@ -612,11 +631,8 @@ static struct cpufreq_driver centrino_driver = {
+ */
+ static int __init centrino_init(void)
+ {
+- struct cpuinfo_x86 *cpu = &cpu_data(0);
+-
+- if (!cpu_has(cpu, X86_FEATURE_EST))
++ if (!x86_match_cpu(centrino_ids))
+ return -ENODEV;
+-
+ return cpufreq_register_driver(¢rino_driver);
+ }
+
+diff --git a/drivers/cpufreq/speedstep-ich.c b/drivers/cpufreq/speedstep-ich.c
+index a748ce7..7432b3a 100644
+--- a/drivers/cpufreq/speedstep-ich.c
++++ b/drivers/cpufreq/speedstep-ich.c
+@@ -25,6 +25,8 @@
+ #include <linux/pci.h>
+ #include <linux/sched.h>
+
++#include <asm/cpu_device_id.h>
++
+ #include "speedstep-lib.h"
+
+
+@@ -388,6 +390,16 @@ static struct cpufreq_driver speedstep_driver = {
+ .attr = speedstep_attr,
+ };
+
++static const struct x86_cpu_id ss_smi_ids[] = {
++ { X86_VENDOR_INTEL, 6, 0xb, },
++ { X86_VENDOR_INTEL, 6, 0x8, },
++ { X86_VENDOR_INTEL, 15, 2 },
++ {}
++};
++#if 0
++/* Autoload or not? Do not for now. */
++MODULE_DEVICE_TABLE(x86cpu, ss_smi_ids);
++#endif
+
+ /**
+ * speedstep_init - initializes the SpeedStep CPUFreq driver
+@@ -398,6 +410,9 @@ static struct cpufreq_driver speedstep_driver = {
+ */
+ static int __init speedstep_init(void)
+ {
++ if (!x86_match_cpu(ss_smi_ids))
++ return -ENODEV;
++
+ /* detect processor */
+ speedstep_processor = speedstep_detect_processor();
+ if (!speedstep_processor) {
+diff --git a/drivers/cpufreq/speedstep-lib.c b/drivers/cpufreq/speedstep-lib.c
+index 8af2d2f..7047821 100644
+--- a/drivers/cpufreq/speedstep-lib.c
++++ b/drivers/cpufreq/speedstep-lib.c
+@@ -249,6 +249,7 @@ EXPORT_SYMBOL_GPL(speedstep_get_frequency);
+ * DETECT SPEEDSTEP-CAPABLE PROCESSOR *
+ *********************************************************************/
+
++/* Keep in sync with the x86_cpu_id tables in the different modules */
+ unsigned int speedstep_detect_processor(void)
+ {
+ struct cpuinfo_x86 *c = &cpu_data(0);
+diff --git a/drivers/cpufreq/speedstep-smi.c b/drivers/cpufreq/speedstep-smi.c
+index c76ead3..6a457fc 100644
+--- a/drivers/cpufreq/speedstep-smi.c
++++ b/drivers/cpufreq/speedstep-smi.c
+@@ -20,6 +20,7 @@
+ #include <linux/delay.h>
+ #include <linux/io.h>
+ #include <asm/ist.h>
++#include <asm/cpu_device_id.h>
+
+ #include "speedstep-lib.h"
+
+@@ -379,6 +380,17 @@ static struct cpufreq_driver speedstep_driver = {
+ .attr = speedstep_attr,
+ };
+
++static const struct x86_cpu_id ss_smi_ids[] = {
++ { X86_VENDOR_INTEL, 6, 0xb, },
++ { X86_VENDOR_INTEL, 6, 0x8, },
++ { X86_VENDOR_INTEL, 15, 2 },
++ {}
++};
++#if 0
++/* Not auto loaded currently */
++MODULE_DEVICE_TABLE(x86cpu, ss_smi_ids);
++#endif
++
+ /**
+ * speedstep_init - initializes the SpeedStep CPUFreq driver
+ *
+@@ -388,6 +400,9 @@ static struct cpufreq_driver speedstep_driver = {
+ */
+ static int __init speedstep_init(void)
+ {
++ if (!x86_match_cpu(ss_smi_ids))
++ return -ENODEV;
++
+ speedstep_processor = speedstep_detect_processor();
+
+ switch (speedstep_processor) {
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/crypto-Add-support-for-x86-cpuid-auto-loading-for-x8.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/crypto-Add-support-for-x86-cpuid-auto-loading-for-x8.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,215 @@
+From: Andi Kleen <ak at linux.intel.com>
+Date: Thu, 26 Jan 2012 00:09:06 +0100
+Subject: crypto: Add support for x86 cpuid auto loading for x86 crypto
+ drivers
+
+commit 3bd391f056df61e928de1680ff4a3e7e07e5b399 upstream.
+
+Add support for auto-loading of crypto drivers based on cpuid features.
+This enables auto-loading of the VIA and Intel specific drivers
+for AES, hashing and CRCs.
+
+Requires the earlier infrastructure patch to add x86 modinfo.
+I kept it all in a single patch for now.
+
+I dropped the printks when the driver cpuid doesn't match (imho
+drivers never should print anything in such a case)
+
+One drawback is that udev doesn't know if the drivers are used or not,
+so they will be unconditionally loaded at boot up. That's better
+than not loading them at all, like it often happens.
+
+Cc: Dave Jones <davej at redhat.com>
+Cc: Kay Sievers <kay.sievers at vrfy.org>
+Cc: Jen Axboe <axboe at kernel.dk>
+Cc: Herbert Xu <herbert at gondor.apana.org.au>
+Cc: Huang Ying <ying.huang at intel.com>
+Signed-off-by: Andi Kleen <ak at linux.intel.com>
+Signed-off-by: Thomas Renninger <trenn at suse.de>
+Acked-by: H. Peter Anvin <hpa at zytor.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+---
+ arch/x86/crypto/aesni-intel_glue.c | 12 +++++++++---
+ arch/x86/crypto/crc32c-intel.c | 11 ++++++++---
+ arch/x86/crypto/ghash-clmulni-intel_glue.c | 12 ++++++++----
+ drivers/crypto/padlock-aes.c | 9 ++++++++-
+ drivers/crypto/padlock-sha.c | 16 ++++++++--------
+ 5 files changed, 41 insertions(+), 19 deletions(-)
+
+diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
+index 545d0ce..b3350bd 100644
+--- a/arch/x86/crypto/aesni-intel_glue.c
++++ b/arch/x86/crypto/aesni-intel_glue.c
+@@ -28,6 +28,7 @@
+ #include <crypto/aes.h>
+ #include <crypto/cryptd.h>
+ #include <crypto/ctr.h>
++#include <asm/cpu_device_id.h>
+ #include <asm/i387.h>
+ #include <asm/aes.h>
+ #include <crypto/scatterwalk.h>
+@@ -1253,14 +1254,19 @@ static struct crypto_alg __rfc4106_alg = {
+ };
+ #endif
+
++
++static const struct x86_cpu_id aesni_cpu_id[] = {
++ X86_FEATURE_MATCH(X86_FEATURE_AES),
++ {}
++};
++MODULE_DEVICE_TABLE(x86cpu, aesni_cpu_id);
++
+ static int __init aesni_init(void)
+ {
+ int err;
+
+- if (!cpu_has_aes) {
+- printk(KERN_INFO "Intel AES-NI instructions are not detected.\n");
++ if (!x86_match_cpu(aesni_cpu_id))
+ return -ENODEV;
+- }
+
+ if ((err = crypto_fpu_init()))
+ goto fpu_err;
+diff --git a/arch/x86/crypto/crc32c-intel.c b/arch/x86/crypto/crc32c-intel.c
+index b9d0026..493f959 100644
+--- a/arch/x86/crypto/crc32c-intel.c
++++ b/arch/x86/crypto/crc32c-intel.c
+@@ -31,6 +31,7 @@
+ #include <crypto/internal/hash.h>
+
+ #include <asm/cpufeature.h>
++#include <asm/cpu_device_id.h>
+
+ #define CHKSUM_BLOCK_SIZE 1
+ #define CHKSUM_DIGEST_SIZE 4
+@@ -173,13 +174,17 @@ static struct shash_alg alg = {
+ }
+ };
+
++static const struct x86_cpu_id crc32c_cpu_id[] = {
++ X86_FEATURE_MATCH(X86_FEATURE_XMM4_2),
++ {}
++};
++MODULE_DEVICE_TABLE(x86cpu, crc32c_cpu_id);
+
+ static int __init crc32c_intel_mod_init(void)
+ {
+- if (cpu_has_xmm4_2)
+- return crypto_register_shash(&alg);
+- else
++ if (!x86_match_cpu(crc32c_cpu_id))
+ return -ENODEV;
++ return crypto_register_shash(&alg);
+ }
+
+ static void __exit crc32c_intel_mod_fini(void)
+diff --git a/arch/x86/crypto/ghash-clmulni-intel_glue.c b/arch/x86/crypto/ghash-clmulni-intel_glue.c
+index 976aa64..b4bf0a6 100644
+--- a/arch/x86/crypto/ghash-clmulni-intel_glue.c
++++ b/arch/x86/crypto/ghash-clmulni-intel_glue.c
+@@ -20,6 +20,7 @@
+ #include <crypto/gf128mul.h>
+ #include <crypto/internal/hash.h>
+ #include <asm/i387.h>
++#include <asm/cpu_device_id.h>
+
+ #define GHASH_BLOCK_SIZE 16
+ #define GHASH_DIGEST_SIZE 16
+@@ -294,15 +295,18 @@ static struct ahash_alg ghash_async_alg = {
+ },
+ };
+
++static const struct x86_cpu_id pcmul_cpu_id[] = {
++ X86_FEATURE_MATCH(X86_FEATURE_PCLMULQDQ), /* Pickle-Mickle-Duck */
++ {}
++};
++MODULE_DEVICE_TABLE(x86cpu, pcmul_cpu_id);
++
+ static int __init ghash_pclmulqdqni_mod_init(void)
+ {
+ int err;
+
+- if (!cpu_has_pclmulqdq) {
+- printk(KERN_INFO "Intel PCLMULQDQ-NI instructions are not"
+- " detected.\n");
++ if (!x86_match_cpu(pcmul_cpu_id))
+ return -ENODEV;
+- }
+
+ err = crypto_register_shash(&ghash_alg);
+ if (err)
+diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c
+index 29b9469..37b2e94 100644
+--- a/drivers/crypto/padlock-aes.c
++++ b/drivers/crypto/padlock-aes.c
+@@ -19,6 +19,7 @@
+ #include <linux/percpu.h>
+ #include <linux/smp.h>
+ #include <linux/slab.h>
++#include <asm/cpu_device_id.h>
+ #include <asm/byteorder.h>
+ #include <asm/processor.h>
+ #include <asm/i387.h>
+@@ -503,12 +504,18 @@ static struct crypto_alg cbc_aes_alg = {
+ }
+ };
+
++static struct x86_cpu_id padlock_cpu_id[] = {
++ X86_FEATURE_MATCH(X86_FEATURE_XCRYPT),
++ {}
++};
++MODULE_DEVICE_TABLE(x86cpu, padlock_cpu_id);
++
+ static int __init padlock_init(void)
+ {
+ int ret;
+ struct cpuinfo_x86 *c = &cpu_data(0);
+
+- if (!cpu_has_xcrypt)
++ if (!x86_match_cpu(padlock_cpu_id))
+ return -ENODEV;
+
+ if (!cpu_has_xcrypt_enabled) {
+diff --git a/drivers/crypto/padlock-sha.c b/drivers/crypto/padlock-sha.c
+index 06bdb4b..9266c0e 100644
+--- a/drivers/crypto/padlock-sha.c
++++ b/drivers/crypto/padlock-sha.c
+@@ -22,6 +22,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/kernel.h>
+ #include <linux/scatterlist.h>
++#include <asm/cpu_device_id.h>
+ #include <asm/i387.h>
+
+ struct padlock_sha_desc {
+@@ -526,6 +527,12 @@ static struct shash_alg sha256_alg_nano = {
+ }
+ };
+
++static struct x86_cpu_id padlock_sha_ids[] = {
++ X86_FEATURE_MATCH(X86_FEATURE_PHE),
++ {}
++};
++MODULE_DEVICE_TABLE(x86cpu, padlock_sha_ids);
++
+ static int __init padlock_init(void)
+ {
+ int rc = -ENODEV;
+@@ -533,15 +540,8 @@ static int __init padlock_init(void)
+ struct shash_alg *sha1;
+ struct shash_alg *sha256;
+
+- if (!cpu_has_phe) {
+- printk(KERN_NOTICE PFX "VIA PadLock Hash Engine not detected.\n");
+- return -ENODEV;
+- }
+-
+- if (!cpu_has_phe_enabled) {
+- printk(KERN_NOTICE PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n");
++ if (!x86_match_cpu(padlock_sha_ids) || !cpu_has_phe_enabled)
+ return -ENODEV;
+- }
+
+ /* Register the newly added algorithm module if on *
+ * VIA Nano processor, or else just do as before */
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/driver-core-cpu-fix-kobject-warning-when-hotplugging.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/driver-core-cpu-fix-kobject-warning-when-hotplugging.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,31 @@
+From: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+Date: Wed, 8 Feb 2012 15:11:17 -0800
+Subject: driver-core: cpu: fix kobject warning when hotplugging a cpu
+
+commit 29bb5d4fd3140a7d5d02d858118c74a45f15c296 upstream.
+
+Due to the sysdev conversion to struct device, the cpu objects get
+reused when adding a cpu after offlining it, which causes a big warning
+that the kobject portion is not properly initialized.
+
+So clear out the object before we register it again, so all is quiet.
+
+Reported-by: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
+Tested-by: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ drivers/base/cpu.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
+index 23f2c4c..4dabf50 100644
+--- a/drivers/base/cpu.c
++++ b/drivers/base/cpu.c
+@@ -240,6 +240,7 @@ int __cpuinit register_cpu(struct cpu *cpu, int num)
+ int error;
+
+ cpu->node_id = cpu_to_node(num);
++ memset(&cpu->dev, 0x00, sizeof(struct device));
+ cpu->dev.id = num;
+ cpu->dev.bus = &cpu_subsys;
+ cpu->dev.release = cpu_device_release;
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/driver-core-cpu-remove-kernel-warning-when-removing-.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/driver-core-cpu-remove-kernel-warning-when-removing-.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,59 @@
+From: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+Date: Thu, 2 Feb 2012 10:36:33 -0800
+Subject: driver core: cpu: remove kernel warning when removing a cpu
+
+commit 2885e25c422fb68208f677f944a45fce8eda2a3c upstream.
+
+With the movement of the cpu sysdev code to be real stuct devices, now
+when we remove a cpu from the system, the driver core rightfully
+complains that there is not a release method for this device.
+
+For now, paper over this issue by quieting the driver core, but comment
+this in detail. This will be resolved in future kernels to be solved
+properly.
+
+Reported-by: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
+Tested-by: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+[bwh: Adjust context for textual conflict with commit
+ fad12ac8c8c2591c7f4e61d19b6a9d76cd49fafa]
+---
+ drivers/base/cpu.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+--- a/drivers/base/cpu.c
++++ b/drivers/base/cpu.c
+@@ -209,6 +209,25 @@
+ }
+ static DEVICE_ATTR(offline, 0444, print_cpus_offline, NULL);
+
++static void cpu_device_release(struct device *dev)
++{
++ /*
++ * This is an empty function to prevent the driver core from spitting a
++ * warning at us. Yes, I know this is directly opposite of what the
++ * documentation for the driver core and kobjects say, and the author
++ * of this code has already been publically ridiculed for doing
++ * something as foolish as this. However, at this point in time, it is
++ * the only way to handle the issue of statically allocated cpu
++ * devices. The different architectures will have their cpu device
++ * code reworked to properly handle this in the near future, so this
++ * function will then be changed to correctly free up the memory held
++ * by the cpu device.
++ *
++ * Never copy this way of doing things, or you too will be made fun of
++ * on the linux-kerenl list, you have been warned.
++ */
++}
++
+ /*
+ * register_cpu - Setup a sysfs device for a CPU.
+ * @cpu - cpu->hotpluggable field set to 1 will generate a control file in
+@@ -224,6 +243,7 @@
+ cpu->node_id = cpu_to_node(num);
+ cpu->dev.id = num;
+ cpu->dev.bus = &cpu_subsys;
++ cpu->dev.release = cpu_device_release;
+ #ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
+ cpu->dev.bus->uevent = arch_cpu_uevent;
+ #endif
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/driver-core-implement-sysdev-functionality-for-regul.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/driver-core-implement-sysdev-functionality-for-regul.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,884 @@
+From: Kay Sievers <kay.sievers at vrfy.org>
+Date: Wed, 14 Dec 2011 14:29:38 -0800
+Subject: driver-core: implement 'sysdev' functionality for regular devices
+ and buses
+
+commit ca22e56debc57b47c422b749c93217ba62644be2 upstream.
+
+All sysdev classes and sysdev devices will converted to regular devices
+and buses to properly hook userspace into the event processing.
+
+There is no interesting difference between a 'sysdev' and 'device' which
+would justify to roll an entire own subsystem with different userspace
+export semantics. Userspace relies on events and generic sysfs subsystem
+infrastructure from sysdev devices, which are currently not properly
+available.
+
+Every converted sysdev class will create a regular device with the class
+name in /sys/devices/system and all registered devices will becom a children
+of theses devices.
+
+For compatibility reasons, the sysdev class-wide attributes are created
+at this parent device. (Do not copy that logic for anything new, subsystem-
+wide properties belong to the subsystem, not to some fake parent device
+created in /sys/devices.)
+
+Every sysdev driver is implemented as a simple subsystem interface now,
+and no longer called a driver.
+
+After all sysdev classes are ported to regular driver core entities, the
+sysdev implementation will be entirely removed from the kernel.
+
+Signed-off-by: Kay Sievers <kay.sievers at vrfy.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+---
+ drivers/base/base.h | 12 +-
+ drivers/base/bus.c | 293 ++++++++++++++++++++++++++++++++++++++++++++----
+ drivers/base/class.c | 14 +--
+ drivers/base/core.c | 85 +++++++++++---
+ drivers/base/init.c | 1 -
+ drivers/base/sys.c | 10 +-
+ include/linux/device.h | 78 ++++++++++++-
+ 7 files changed, 431 insertions(+), 62 deletions(-)
+
+diff --git a/drivers/base/base.h b/drivers/base/base.h
+index 21c1b96..7a6ae42 100644
+--- a/drivers/base/base.h
++++ b/drivers/base/base.h
+@@ -4,7 +4,9 @@
+ * struct subsys_private - structure to hold the private to the driver core portions of the bus_type/class structure.
+ *
+ * @subsys - the struct kset that defines this subsystem
+- * @devices_kset - the list of devices associated
++ * @devices_kset - the subsystem's 'devices' directory
++ * @interfaces - list of subsystem interfaces associated
++ * @mutex - protect the devices, and interfaces lists.
+ *
+ * @drivers_kset - the list of drivers associated
+ * @klist_devices - the klist to iterate over the @devices_kset
+@@ -14,10 +16,8 @@
+ * @bus - pointer back to the struct bus_type that this structure is associated
+ * with.
+ *
+- * @class_interfaces - list of class_interfaces associated
+ * @glue_dirs - "glue" directory to put in-between the parent device to
+ * avoid namespace conflicts
+- * @class_mutex - mutex to protect the children, devices, and interfaces lists.
+ * @class - pointer back to the struct class that this structure is associated
+ * with.
+ *
+@@ -28,6 +28,8 @@
+ struct subsys_private {
+ struct kset subsys;
+ struct kset *devices_kset;
++ struct list_head interfaces;
++ struct mutex mutex;
+
+ struct kset *drivers_kset;
+ struct klist klist_devices;
+@@ -36,9 +38,7 @@ struct subsys_private {
+ unsigned int drivers_autoprobe:1;
+ struct bus_type *bus;
+
+- struct list_head class_interfaces;
+ struct kset glue_dirs;
+- struct mutex class_mutex;
+ struct class *class;
+ };
+ #define to_subsys_private(obj) container_of(obj, struct subsys_private, subsys.kobj)
+@@ -94,7 +94,6 @@ extern int hypervisor_init(void);
+ static inline int hypervisor_init(void) { return 0; }
+ #endif
+ extern int platform_bus_init(void);
+-extern int system_bus_init(void);
+ extern int cpu_dev_init(void);
+
+ extern int bus_add_device(struct device *dev);
+@@ -116,6 +115,7 @@ extern char *make_class_name(const char *name, struct kobject *kobj);
+
+ extern int devres_release_all(struct device *dev);
+
++/* /sys/devices directory */
+ extern struct kset *devices_kset;
+
+ #if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS)
+diff --git a/drivers/base/bus.c b/drivers/base/bus.c
+index 000e7b2..99dc592 100644
+--- a/drivers/base/bus.c
++++ b/drivers/base/bus.c
+@@ -16,9 +16,14 @@
+ #include <linux/slab.h>
+ #include <linux/init.h>
+ #include <linux/string.h>
++#include <linux/mutex.h>
+ #include "base.h"
+ #include "power/power.h"
+
++/* /sys/devices/system */
++/* FIXME: make static after drivers/base/sys.c is deleted */
++struct kset *system_kset;
++
+ #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr)
+
+ /*
+@@ -360,6 +365,47 @@ struct device *bus_find_device_by_name(struct bus_type *bus,
+ }
+ EXPORT_SYMBOL_GPL(bus_find_device_by_name);
+
++/**
++ * subsys_find_device_by_id - find a device with a specific enumeration number
++ * @subsys: subsystem
++ * @id: index 'id' in struct device
++ * @hint: device to check first
++ *
++ * Check the hint's next object and if it is a match return it directly,
++ * otherwise, fall back to a full list search. Either way a reference for
++ * the returned object is taken.
++ */
++struct device *subsys_find_device_by_id(struct bus_type *subsys, unsigned int id,
++ struct device *hint)
++{
++ struct klist_iter i;
++ struct device *dev;
++
++ if (!subsys)
++ return NULL;
++
++ if (hint) {
++ klist_iter_init_node(&subsys->p->klist_devices, &i, &hint->p->knode_bus);
++ dev = next_device(&i);
++ if (dev && dev->id == id && get_device(dev)) {
++ klist_iter_exit(&i);
++ return dev;
++ }
++ klist_iter_exit(&i);
++ }
++
++ klist_iter_init_node(&subsys->p->klist_devices, &i, NULL);
++ while ((dev = next_device(&i))) {
++ if (dev->id == id && get_device(dev)) {
++ klist_iter_exit(&i);
++ return dev;
++ }
++ }
++ klist_iter_exit(&i);
++ return NULL;
++}
++EXPORT_SYMBOL_GPL(subsys_find_device_by_id);
++
+ static struct device_driver *next_driver(struct klist_iter *i)
+ {
+ struct klist_node *n = klist_next(i);
+@@ -487,38 +533,59 @@ out_put:
+ void bus_probe_device(struct device *dev)
+ {
+ struct bus_type *bus = dev->bus;
++ struct subsys_interface *sif;
+ int ret;
+
+- if (bus && bus->p->drivers_autoprobe) {
++ if (!bus)
++ return;
++
++ if (bus->p->drivers_autoprobe) {
+ ret = device_attach(dev);
+ WARN_ON(ret < 0);
+ }
++
++ mutex_lock(&bus->p->mutex);
++ list_for_each_entry(sif, &bus->p->interfaces, node)
++ if (sif->add_dev)
++ sif->add_dev(dev, sif);
++ mutex_unlock(&bus->p->mutex);
+ }
+
+ /**
+ * bus_remove_device - remove device from bus
+ * @dev: device to be removed
+ *
+- * - Remove symlink from bus's directory.
++ * - Remove device from all interfaces.
++ * - Remove symlink from bus' directory.
+ * - Delete device from bus's list.
+ * - Detach from its driver.
+ * - Drop reference taken in bus_add_device().
+ */
+ void bus_remove_device(struct device *dev)
+ {
+- if (dev->bus) {
+- sysfs_remove_link(&dev->kobj, "subsystem");
+- sysfs_remove_link(&dev->bus->p->devices_kset->kobj,
+- dev_name(dev));
+- device_remove_attrs(dev->bus, dev);
+- if (klist_node_attached(&dev->p->knode_bus))
+- klist_del(&dev->p->knode_bus);
+-
+- pr_debug("bus: '%s': remove device %s\n",
+- dev->bus->name, dev_name(dev));
+- device_release_driver(dev);
+- bus_put(dev->bus);
+- }
++ struct bus_type *bus = dev->bus;
++ struct subsys_interface *sif;
++
++ if (!bus)
++ return;
++
++ mutex_lock(&bus->p->mutex);
++ list_for_each_entry(sif, &bus->p->interfaces, node)
++ if (sif->remove_dev)
++ sif->remove_dev(dev, sif);
++ mutex_unlock(&bus->p->mutex);
++
++ sysfs_remove_link(&dev->kobj, "subsystem");
++ sysfs_remove_link(&dev->bus->p->devices_kset->kobj,
++ dev_name(dev));
++ device_remove_attrs(dev->bus, dev);
++ if (klist_node_attached(&dev->p->knode_bus))
++ klist_del(&dev->p->knode_bus);
++
++ pr_debug("bus: '%s': remove device %s\n",
++ dev->bus->name, dev_name(dev));
++ device_release_driver(dev);
++ bus_put(dev->bus);
+ }
+
+ static int driver_add_attrs(struct bus_type *bus, struct device_driver *drv)
+@@ -847,14 +914,14 @@ static ssize_t bus_uevent_store(struct bus_type *bus,
+ static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store);
+
+ /**
+- * bus_register - register a bus with the system.
++ * __bus_register - register a driver-core subsystem
+ * @bus: bus.
+ *
+ * Once we have that, we registered the bus with the kobject
+ * infrastructure, then register the children subsystems it has:
+- * the devices and drivers that belong to the bus.
++ * the devices and drivers that belong to the subsystem.
+ */
+-int bus_register(struct bus_type *bus)
++int __bus_register(struct bus_type *bus, struct lock_class_key *key)
+ {
+ int retval;
+ struct subsys_private *priv;
+@@ -898,6 +965,8 @@ int bus_register(struct bus_type *bus)
+ goto bus_drivers_fail;
+ }
+
++ INIT_LIST_HEAD(&priv->interfaces);
++ __mutex_init(&priv->mutex, "subsys mutex", key);
+ klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);
+ klist_init(&priv->klist_drivers, NULL, NULL);
+
+@@ -927,7 +996,7 @@ out:
+ bus->p = NULL;
+ return retval;
+ }
+-EXPORT_SYMBOL_GPL(bus_register);
++EXPORT_SYMBOL_GPL(__bus_register);
+
+ /**
+ * bus_unregister - remove a bus from the system
+@@ -939,6 +1008,8 @@ EXPORT_SYMBOL_GPL(bus_register);
+ void bus_unregister(struct bus_type *bus)
+ {
+ pr_debug("bus: '%s': unregistering\n", bus->name);
++ if (bus->dev_root)
++ device_unregister(bus->dev_root);
+ bus_remove_attrs(bus);
+ remove_probe_files(bus);
+ kset_unregister(bus->p->drivers_kset);
+@@ -1028,10 +1099,194 @@ void bus_sort_breadthfirst(struct bus_type *bus,
+ }
+ EXPORT_SYMBOL_GPL(bus_sort_breadthfirst);
+
++/**
++ * subsys_dev_iter_init - initialize subsys device iterator
++ * @iter: subsys iterator to initialize
++ * @subsys: the subsys we wanna iterate over
++ * @start: the device to start iterating from, if any
++ * @type: device_type of the devices to iterate over, NULL for all
++ *
++ * Initialize subsys iterator @iter such that it iterates over devices
++ * of @subsys. If @start is set, the list iteration will start there,
++ * otherwise if it is NULL, the iteration starts at the beginning of
++ * the list.
++ */
++void subsys_dev_iter_init(struct subsys_dev_iter *iter, struct bus_type *subsys,
++ struct device *start, const struct device_type *type)
++{
++ struct klist_node *start_knode = NULL;
++
++ if (start)
++ start_knode = &start->p->knode_bus;
++ klist_iter_init_node(&subsys->p->klist_devices, &iter->ki, start_knode);
++ iter->type = type;
++}
++EXPORT_SYMBOL_GPL(subsys_dev_iter_init);
++
++/**
++ * subsys_dev_iter_next - iterate to the next device
++ * @iter: subsys iterator to proceed
++ *
++ * Proceed @iter to the next device and return it. Returns NULL if
++ * iteration is complete.
++ *
++ * The returned device is referenced and won't be released till
++ * iterator is proceed to the next device or exited. The caller is
++ * free to do whatever it wants to do with the device including
++ * calling back into subsys code.
++ */
++struct device *subsys_dev_iter_next(struct subsys_dev_iter *iter)
++{
++ struct klist_node *knode;
++ struct device *dev;
++
++ for (;;) {
++ knode = klist_next(&iter->ki);
++ if (!knode)
++ return NULL;
++ dev = container_of(knode, struct device_private, knode_bus)->device;
++ if (!iter->type || iter->type == dev->type)
++ return dev;
++ }
++}
++EXPORT_SYMBOL_GPL(subsys_dev_iter_next);
++
++/**
++ * subsys_dev_iter_exit - finish iteration
++ * @iter: subsys iterator to finish
++ *
++ * Finish an iteration. Always call this function after iteration is
++ * complete whether the iteration ran till the end or not.
++ */
++void subsys_dev_iter_exit(struct subsys_dev_iter *iter)
++{
++ klist_iter_exit(&iter->ki);
++}
++EXPORT_SYMBOL_GPL(subsys_dev_iter_exit);
++
++int subsys_interface_register(struct subsys_interface *sif)
++{
++ struct bus_type *subsys;
++ struct subsys_dev_iter iter;
++ struct device *dev;
++
++ if (!sif || !sif->subsys)
++ return -ENODEV;
++
++ subsys = bus_get(sif->subsys);
++ if (!subsys)
++ return -EINVAL;
++
++ mutex_lock(&subsys->p->mutex);
++ list_add_tail(&sif->node, &subsys->p->interfaces);
++ if (sif->add_dev) {
++ subsys_dev_iter_init(&iter, subsys, NULL, NULL);
++ while ((dev = subsys_dev_iter_next(&iter)))
++ sif->add_dev(dev, sif);
++ subsys_dev_iter_exit(&iter);
++ }
++ mutex_unlock(&subsys->p->mutex);
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(subsys_interface_register);
++
++void subsys_interface_unregister(struct subsys_interface *sif)
++{
++ struct bus_type *subsys = sif->subsys;
++ struct subsys_dev_iter iter;
++ struct device *dev;
++
++ if (!sif)
++ return;
++
++ mutex_lock(&subsys->p->mutex);
++ list_del_init(&sif->node);
++ if (sif->remove_dev) {
++ subsys_dev_iter_init(&iter, subsys, NULL, NULL);
++ while ((dev = subsys_dev_iter_next(&iter)))
++ sif->remove_dev(dev, sif);
++ subsys_dev_iter_exit(&iter);
++ }
++ mutex_unlock(&subsys->p->mutex);
++
++ bus_put(subsys);
++}
++EXPORT_SYMBOL_GPL(subsys_interface_unregister);
++
++static void system_root_device_release(struct device *dev)
++{
++ kfree(dev);
++}
++/**
++ * subsys_system_register - register a subsystem at /sys/devices/system/
++ * @subsys - system subsystem
++ * @groups - default attributes for the root device
++ *
++ * All 'system' subsystems have a /sys/devices/system/<name> root device
++ * with the name of the subsystem. The root device can carry subsystem-
++ * wide attributes. All registered devices are below this single root
++ * device and are named after the subsystem with a simple enumeration
++ * number appended. The registered devices are not explicitely named;
++ * only 'id' in the device needs to be set.
++ *
++ * Do not use this interface for anything new, it exists for compatibility
++ * with bad ideas only. New subsystems should use plain subsystems; and
++ * add the subsystem-wide attributes should be added to the subsystem
++ * directory itself and not some create fake root-device placed in
++ * /sys/devices/system/<name>.
++ */
++int subsys_system_register(struct bus_type *subsys,
++ const struct attribute_group **groups)
++{
++ struct device *dev;
++ int err;
++
++ err = bus_register(subsys);
++ if (err < 0)
++ return err;
++
++ dev = kzalloc(sizeof(struct device), GFP_KERNEL);
++ if (!dev) {
++ err = -ENOMEM;
++ goto err_dev;
++ }
++
++ err = dev_set_name(dev, "%s", subsys->name);
++ if (err < 0)
++ goto err_name;
++
++ dev->kobj.parent = &system_kset->kobj;
++ dev->groups = groups;
++ dev->release = system_root_device_release;
++
++ err = device_register(dev);
++ if (err < 0)
++ goto err_dev_reg;
++
++ subsys->dev_root = dev;
++ return 0;
++
++err_dev_reg:
++ put_device(dev);
++ dev = NULL;
++err_name:
++ kfree(dev);
++err_dev:
++ bus_unregister(subsys);
++ return err;
++}
++EXPORT_SYMBOL_GPL(subsys_system_register);
++
+ int __init buses_init(void)
+ {
+ bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);
+ if (!bus_kset)
+ return -ENOMEM;
++
++ system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj);
++ if (!system_kset)
++ return -ENOMEM;
++
+ return 0;
+ }
+diff --git a/drivers/base/class.c b/drivers/base/class.c
+index b80d91c..03243d4 100644
+--- a/drivers/base/class.c
++++ b/drivers/base/class.c
+@@ -184,9 +184,9 @@ int __class_register(struct class *cls, struct lock_class_key *key)
+ if (!cp)
+ return -ENOMEM;
+ klist_init(&cp->klist_devices, klist_class_dev_get, klist_class_dev_put);
+- INIT_LIST_HEAD(&cp->class_interfaces);
++ INIT_LIST_HEAD(&cp->interfaces);
+ kset_init(&cp->glue_dirs);
+- __mutex_init(&cp->class_mutex, "struct class mutex", key);
++ __mutex_init(&cp->mutex, "subsys mutex", key);
+ error = kobject_set_name(&cp->subsys.kobj, "%s", cls->name);
+ if (error) {
+ kfree(cp);
+@@ -460,15 +460,15 @@ int class_interface_register(struct class_interface *class_intf)
+ if (!parent)
+ return -EINVAL;
+
+- mutex_lock(&parent->p->class_mutex);
+- list_add_tail(&class_intf->node, &parent->p->class_interfaces);
++ mutex_lock(&parent->p->mutex);
++ list_add_tail(&class_intf->node, &parent->p->interfaces);
+ if (class_intf->add_dev) {
+ class_dev_iter_init(&iter, parent, NULL, NULL);
+ while ((dev = class_dev_iter_next(&iter)))
+ class_intf->add_dev(dev, class_intf);
+ class_dev_iter_exit(&iter);
+ }
+- mutex_unlock(&parent->p->class_mutex);
++ mutex_unlock(&parent->p->mutex);
+
+ return 0;
+ }
+@@ -482,7 +482,7 @@ void class_interface_unregister(struct class_interface *class_intf)
+ if (!parent)
+ return;
+
+- mutex_lock(&parent->p->class_mutex);
++ mutex_lock(&parent->p->mutex);
+ list_del_init(&class_intf->node);
+ if (class_intf->remove_dev) {
+ class_dev_iter_init(&iter, parent, NULL, NULL);
+@@ -490,7 +490,7 @@ void class_interface_unregister(struct class_interface *class_intf)
+ class_intf->remove_dev(dev, class_intf);
+ class_dev_iter_exit(&iter);
+ }
+- mutex_unlock(&parent->p->class_mutex);
++ mutex_unlock(&parent->p->mutex);
+
+ class_put(parent);
+ }
+diff --git a/drivers/base/core.c b/drivers/base/core.c
+index 82c8654..a31ea19 100644
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -117,6 +117,56 @@ static const struct sysfs_ops dev_sysfs_ops = {
+ .store = dev_attr_store,
+ };
+
++#define to_ext_attr(x) container_of(x, struct dev_ext_attribute, attr)
++
++ssize_t device_store_ulong(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t size)
++{
++ struct dev_ext_attribute *ea = to_ext_attr(attr);
++ char *end;
++ unsigned long new = simple_strtoul(buf, &end, 0);
++ if (end == buf)
++ return -EINVAL;
++ *(unsigned long *)(ea->var) = new;
++ /* Always return full write size even if we didn't consume all */
++ return size;
++}
++EXPORT_SYMBOL_GPL(device_store_ulong);
++
++ssize_t device_show_ulong(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ struct dev_ext_attribute *ea = to_ext_attr(attr);
++ return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var));
++}
++EXPORT_SYMBOL_GPL(device_show_ulong);
++
++ssize_t device_store_int(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t size)
++{
++ struct dev_ext_attribute *ea = to_ext_attr(attr);
++ char *end;
++ long new = simple_strtol(buf, &end, 0);
++ if (end == buf || new > INT_MAX || new < INT_MIN)
++ return -EINVAL;
++ *(int *)(ea->var) = new;
++ /* Always return full write size even if we didn't consume all */
++ return size;
++}
++EXPORT_SYMBOL_GPL(device_store_int);
++
++ssize_t device_show_int(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ struct dev_ext_attribute *ea = to_ext_attr(attr);
++
++ return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var));
++}
++EXPORT_SYMBOL_GPL(device_show_int);
+
+ /**
+ * device_release - free device structure.
+@@ -463,7 +513,7 @@ static ssize_t show_dev(struct device *dev, struct device_attribute *attr,
+ static struct device_attribute devt_attr =
+ __ATTR(dev, S_IRUGO, show_dev, NULL);
+
+-/* kset to create /sys/devices/ */
++/* /sys/devices/ */
+ struct kset *devices_kset;
+
+ /**
+@@ -710,6 +760,10 @@ static struct kobject *get_device_parent(struct device *dev,
+ return k;
+ }
+
++ /* subsystems can specify a default root directory for their devices */
++ if (!parent && dev->bus && dev->bus->dev_root)
++ return &dev->bus->dev_root->kobj;
++
+ if (parent)
+ return &parent->kobj;
+ return NULL;
+@@ -730,14 +784,6 @@ static void cleanup_device_parent(struct device *dev)
+ cleanup_glue_dir(dev, dev->kobj.parent);
+ }
+
+-static void setup_parent(struct device *dev, struct device *parent)
+-{
+- struct kobject *kobj;
+- kobj = get_device_parent(dev, parent);
+- if (kobj)
+- dev->kobj.parent = kobj;
+-}
+-
+ static int device_add_class_symlinks(struct device *dev)
+ {
+ int error;
+@@ -890,6 +936,7 @@ int device_private_init(struct device *dev)
+ int device_add(struct device *dev)
+ {
+ struct device *parent = NULL;
++ struct kobject *kobj;
+ struct class_interface *class_intf;
+ int error = -EINVAL;
+
+@@ -913,6 +960,10 @@ int device_add(struct device *dev)
+ dev->init_name = NULL;
+ }
+
++ /* subsystems can specify simple device enumeration */
++ if (!dev_name(dev) && dev->bus && dev->bus->dev_name)
++ dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id);
++
+ if (!dev_name(dev)) {
+ error = -EINVAL;
+ goto name_error;
+@@ -921,7 +972,9 @@ int device_add(struct device *dev)
+ pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
+
+ parent = get_device(dev->parent);
+- setup_parent(dev, parent);
++ kobj = get_device_parent(dev, parent);
++ if (kobj)
++ dev->kobj.parent = kobj;
+
+ /* use parent numa_node */
+ if (parent)
+@@ -981,17 +1034,17 @@ int device_add(struct device *dev)
+ &parent->p->klist_children);
+
+ if (dev->class) {
+- mutex_lock(&dev->class->p->class_mutex);
++ mutex_lock(&dev->class->p->mutex);
+ /* tie the class to the device */
+ klist_add_tail(&dev->knode_class,
+ &dev->class->p->klist_devices);
+
+ /* notify any interfaces that the device is here */
+ list_for_each_entry(class_intf,
+- &dev->class->p->class_interfaces, node)
++ &dev->class->p->interfaces, node)
+ if (class_intf->add_dev)
+ class_intf->add_dev(dev, class_intf);
+- mutex_unlock(&dev->class->p->class_mutex);
++ mutex_unlock(&dev->class->p->mutex);
+ }
+ done:
+ put_device(dev);
+@@ -1106,15 +1159,15 @@ void device_del(struct device *dev)
+ if (dev->class) {
+ device_remove_class_symlinks(dev);
+
+- mutex_lock(&dev->class->p->class_mutex);
++ mutex_lock(&dev->class->p->mutex);
+ /* notify any interfaces that the device is now gone */
+ list_for_each_entry(class_intf,
+- &dev->class->p->class_interfaces, node)
++ &dev->class->p->interfaces, node)
+ if (class_intf->remove_dev)
+ class_intf->remove_dev(dev, class_intf);
+ /* remove the device from the class list */
+ klist_del(&dev->knode_class);
+- mutex_unlock(&dev->class->p->class_mutex);
++ mutex_unlock(&dev->class->p->mutex);
+ }
+ device_remove_file(dev, &uevent_attr);
+ device_remove_attrs(dev);
+diff --git a/drivers/base/init.c b/drivers/base/init.c
+index c8a934e..c16f0b8 100644
+--- a/drivers/base/init.c
++++ b/drivers/base/init.c
+@@ -31,7 +31,6 @@ void __init driver_init(void)
+ * core core pieces.
+ */
+ platform_bus_init();
+- system_bus_init();
+ cpu_dev_init();
+ memory_dev_init();
+ }
+diff --git a/drivers/base/sys.c b/drivers/base/sys.c
+index 9dff77b..409f5ce 100644
+--- a/drivers/base/sys.c
++++ b/drivers/base/sys.c
+@@ -126,7 +126,7 @@ void sysdev_class_remove_file(struct sysdev_class *c,
+ }
+ EXPORT_SYMBOL_GPL(sysdev_class_remove_file);
+
+-static struct kset *system_kset;
++extern struct kset *system_kset;
+
+ int sysdev_class_register(struct sysdev_class *cls)
+ {
+@@ -331,14 +331,6 @@ void sysdev_unregister(struct sys_device *sysdev)
+ EXPORT_SYMBOL_GPL(sysdev_register);
+ EXPORT_SYMBOL_GPL(sysdev_unregister);
+
+-int __init system_bus_init(void)
+-{
+- system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj);
+- if (!system_kset)
+- return -ENOMEM;
+- return 0;
+-}
+-
+ #define to_ext_attr(x) container_of(x, struct sysdev_ext_attribute, attr)
+
+ ssize_t sysdev_store_ulong(struct sys_device *sysdev,
+diff --git a/include/linux/device.h b/include/linux/device.h
+index 341fb74..7f9fc15 100644
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -53,6 +53,8 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
+ * struct bus_type - The bus type of the device
+ *
+ * @name: The name of the bus.
++ * @dev_name: Used for subsystems to enumerate devices like ("foo%u", dev->id).
++ * @dev_root: Default device to use as the parent.
+ * @bus_attrs: Default attributes of the bus.
+ * @dev_attrs: Default attributes of the devices on the bus.
+ * @drv_attrs: Default attributes of the device drivers on the bus.
+@@ -86,6 +88,8 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
+ */
+ struct bus_type {
+ const char *name;
++ const char *dev_name;
++ struct device *dev_root;
+ struct bus_attribute *bus_attrs;
+ struct device_attribute *dev_attrs;
+ struct driver_attribute *drv_attrs;
+@@ -106,12 +110,30 @@ struct bus_type {
+ struct subsys_private *p;
+ };
+
+-extern int __must_check bus_register(struct bus_type *bus);
++/* This is a #define to keep the compiler from merging different
++ * instances of the __key variable */
++#define bus_register(subsys) \
++({ \
++ static struct lock_class_key __key; \
++ __bus_register(subsys, &__key); \
++})
++extern int __must_check __bus_register(struct bus_type *bus,
++ struct lock_class_key *key);
+ extern void bus_unregister(struct bus_type *bus);
+
+ extern int __must_check bus_rescan_devices(struct bus_type *bus);
+
+ /* iterator helpers for buses */
++struct subsys_dev_iter {
++ struct klist_iter ki;
++ const struct device_type *type;
++};
++void subsys_dev_iter_init(struct subsys_dev_iter *iter,
++ struct bus_type *subsys,
++ struct device *start,
++ const struct device_type *type);
++struct device *subsys_dev_iter_next(struct subsys_dev_iter *iter);
++void subsys_dev_iter_exit(struct subsys_dev_iter *iter);
+
+ int bus_for_each_dev(struct bus_type *bus, struct device *start, void *data,
+ int (*fn)(struct device *dev, void *data));
+@@ -121,10 +143,10 @@ struct device *bus_find_device(struct bus_type *bus, struct device *start,
+ struct device *bus_find_device_by_name(struct bus_type *bus,
+ struct device *start,
+ const char *name);
+-
++struct device *subsys_find_device_by_id(struct bus_type *bus, unsigned int id,
++ struct device *hint);
+ int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
+ void *data, int (*fn)(struct device_driver *, void *));
+-
+ void bus_sort_breadthfirst(struct bus_type *bus,
+ int (*compare)(const struct device *a,
+ const struct device *b));
+@@ -256,6 +278,33 @@ struct device *driver_find_device(struct device_driver *drv,
+ int (*match)(struct device *dev, void *data));
+
+ /**
++ * struct subsys_interface - interfaces to device functions
++ * @name name of the device function
++ * @subsystem subsytem of the devices to attach to
++ * @node the list of functions registered at the subsystem
++ * @add device hookup to device function handler
++ * @remove device hookup to device function handler
++ *
++ * Simple interfaces attached to a subsystem. Multiple interfaces can
++ * attach to a subsystem and its devices. Unlike drivers, they do not
++ * exclusively claim or control devices. Interfaces usually represent
++ * a specific functionality of a subsystem/class of devices.
++ */
++struct subsys_interface {
++ const char *name;
++ struct bus_type *subsys;
++ struct list_head node;
++ int (*add_dev)(struct device *dev, struct subsys_interface *sif);
++ int (*remove_dev)(struct device *dev, struct subsys_interface *sif);
++};
++
++int subsys_interface_register(struct subsys_interface *sif);
++void subsys_interface_unregister(struct subsys_interface *sif);
++
++int subsys_system_register(struct bus_type *subsys,
++ const struct attribute_group **groups);
++
++/**
+ * struct class - device classes
+ * @name: Name of the class.
+ * @owner: The module owner.
+@@ -438,8 +487,28 @@ struct device_attribute {
+ const char *buf, size_t count);
+ };
+
++struct dev_ext_attribute {
++ struct device_attribute attr;
++ void *var;
++};
++
++ssize_t device_show_ulong(struct device *dev, struct device_attribute *attr,
++ char *buf);
++ssize_t device_store_ulong(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count);
++ssize_t device_show_int(struct device *dev, struct device_attribute *attr,
++ char *buf);
++ssize_t device_store_int(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count);
++
+ #define DEVICE_ATTR(_name, _mode, _show, _store) \
+-struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
++ struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
++#define DEVICE_ULONG_ATTR(_name, _mode, _var) \
++ struct dev_ext_attribute dev_attr_##_name = \
++ { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) }
++#define DEVICE_INT_ATTR(_name, _mode, _var) \
++ struct dev_ext_attribute dev_attr_##_name = \
++ { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) }
+
+ extern int __must_check device_create_file(struct device *device,
+ const struct device_attribute *entry);
+@@ -603,6 +672,7 @@ struct device {
+ struct device_node *of_node; /* associated device tree node */
+
+ dev_t devt; /* dev_t, creates the sysfs "dev" */
++ u32 id; /* device instance */
+
+ spinlock_t devres_lock;
+ struct list_head devres_head;
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/intel-idle-convert-to-x86_cpu_id-auto-probing.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/intel-idle-convert-to-x86_cpu_id-auto-probing.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,196 @@
+From: Andi Kleen <ak at linux.intel.com>
+Date: Thu, 26 Jan 2012 00:09:07 +0100
+Subject: intel-idle: convert to x86_cpu_id auto probing
+
+commit b66b8b9a4a79087dde1b358a016e5c8739ccf186 upstream.
+
+With this it should be automatically loaded on suitable systems by
+udev.
+
+The old switch () is replaced with a table based approach, this
+also cleans up the code.
+
+Cc: Len Brown <lenb at kernel.org>
+Signed-off-by: Andi Kleen <ak at linux.intel.com>
+Signed-off-by: Thomas Renninger <trenn at suse.de>
+Acked-by: H. Peter Anvin <hpa at zytor.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+[bwh: Backported to 3.2: one less instance of auto_demotion_disable_flags]
+---
+ drivers/idle/intel_idle.c | 116 ++++++++++++++++++++++++++-------------------
+ 1 file changed, 66 insertions(+), 50 deletions(-)
+
+--- a/drivers/idle/intel_idle.c
++++ b/drivers/idle/intel_idle.c
+@@ -62,6 +62,7 @@
+ #include <linux/notifier.h>
+ #include <linux/cpu.h>
+ #include <linux/module.h>
++#include <asm/cpu_device_id.h>
+ #include <asm/mwait.h>
+ #include <asm/msr.h>
+
+@@ -81,6 +82,17 @@
+ /* Reliable LAPIC Timer States, bit 1 for C1 etc. */
+ static unsigned int lapic_timer_reliable_states = (1 << 1); /* Default to only C1 */
+
++struct idle_cpu {
++ struct cpuidle_state *state_table;
++
++ /*
++ * Hardware C-state auto-demotion may not always be optimal.
++ * Indicate which enable bits to clear here.
++ */
++ unsigned long auto_demotion_disable_flags;
++};
++
++static const struct idle_cpu *icpu;
+ static struct cpuidle_device __percpu *intel_idle_cpuidle_devices;
+ static int intel_idle(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index);
+@@ -88,12 +100,6 @@
+ static struct cpuidle_state *cpuidle_state_table;
+
+ /*
+- * Hardware C-state auto-demotion may not always be optimal.
+- * Indicate which enable bits to clear here.
+- */
+-static unsigned long long auto_demotion_disable_flags;
+-
+-/*
+ * Set this flag for states where the HW flushes the TLB for us
+ * and so we don't need cross-calls to keep it consistent.
+ * If this flag is set, SW flushes the TLB, so even if the
+@@ -320,27 +326,72 @@
+ unsigned long long msr_bits;
+
+ rdmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits);
+- msr_bits &= ~auto_demotion_disable_flags;
++ msr_bits &= ~(icpu->auto_demotion_disable_flags);
+ wrmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits);
+ }
+
++static const struct idle_cpu idle_cpu_nehalem = {
++ .state_table = nehalem_cstates,
++};
++
++static const struct idle_cpu idle_cpu_westmere = {
++ .state_table = nehalem_cstates,
++ .auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE,
++};
++
++static const struct idle_cpu idle_cpu_atom = {
++ .state_table = atom_cstates,
++};
++
++static const struct idle_cpu idle_cpu_lincroft = {
++ .state_table = atom_cstates,
++ .auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE,
++};
++
++static const struct idle_cpu idle_cpu_snb = {
++ .state_table = snb_cstates,
++};
++
++#define ICPU(model, cpu) \
++ { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu }
++
++static const struct x86_cpu_id intel_idle_ids[] = {
++ ICPU(0x1a, idle_cpu_nehalem),
++ ICPU(0x1e, idle_cpu_nehalem),
++ ICPU(0x1f, idle_cpu_nehalem),
++ ICPU(0x25, idle_cpu_westmere),
++ ICPU(0x2c, idle_cpu_westmere),
++ ICPU(0x2f, idle_cpu_westmere),
++ ICPU(0x1c, idle_cpu_atom),
++ ICPU(0x26, idle_cpu_lincroft),
++ ICPU(0x2f, idle_cpu_westmere),
++ ICPU(0x2a, idle_cpu_snb),
++ ICPU(0x2d, idle_cpu_snb),
++ {}
++};
++MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids);
++
+ /*
+ * intel_idle_probe()
+ */
+ static int intel_idle_probe(void)
+ {
+ unsigned int eax, ebx, ecx;
++ const struct x86_cpu_id *id;
+
+ if (max_cstate == 0) {
+ pr_debug(PREFIX "disabled\n");
+ return -EPERM;
+ }
+
+- if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+- return -ENODEV;
+-
+- if (!boot_cpu_has(X86_FEATURE_MWAIT))
++ id = x86_match_cpu(intel_idle_ids);
++ if (!id) {
++ if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
++ boot_cpu_data.x86 == 6)
++ pr_debug(PREFIX "does not run on family %d model %d\n",
++ boot_cpu_data.x86, boot_cpu_data.x86_model);
+ return -ENODEV;
++ }
+
+ if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF)
+ return -ENODEV;
+@@ -354,43 +405,8 @@
+
+ pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates);
+
+-
+- if (boot_cpu_data.x86 != 6) /* family 6 */
+- return -ENODEV;
+-
+- switch (boot_cpu_data.x86_model) {
+-
+- case 0x1A: /* Core i7, Xeon 5500 series */
+- case 0x1E: /* Core i7 and i5 Processor - Lynnfield Jasper Forest */
+- case 0x1F: /* Core i7 and i5 Processor - Nehalem */
+- case 0x2E: /* Nehalem-EX Xeon */
+- case 0x2F: /* Westmere-EX Xeon */
+- case 0x25: /* Westmere */
+- case 0x2C: /* Westmere */
+- cpuidle_state_table = nehalem_cstates;
+- auto_demotion_disable_flags =
+- (NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE);
+- break;
+-
+- case 0x1C: /* 28 - Atom Processor */
+- cpuidle_state_table = atom_cstates;
+- break;
+-
+- case 0x26: /* 38 - Lincroft Atom Processor */
+- cpuidle_state_table = atom_cstates;
+- auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE;
+- break;
+-
+- case 0x2A: /* SNB */
+- case 0x2D: /* SNB Xeon */
+- cpuidle_state_table = snb_cstates;
+- break;
+-
+- default:
+- pr_debug(PREFIX "does not run on family %d model %d\n",
+- boot_cpu_data.x86, boot_cpu_data.x86_model);
+- return -ENODEV;
+- }
++ icpu = (const struct idle_cpu *)id->driver_data;
++ cpuidle_state_table = icpu->state_table;
+
+ if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */
+ lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE;
+@@ -471,7 +487,7 @@
+ drv->state_count += 1;
+ }
+
+- if (auto_demotion_disable_flags)
++ if (icpu->auto_demotion_disable_flags)
+ on_each_cpu(auto_demotion_disable, NULL, 1);
+
+ return 0;
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/intel_idle-Fix-ID-for-Nehalem-EX-Xeon-in-device-ID-t.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/intel_idle-Fix-ID-for-Nehalem-EX-Xeon-in-device-ID-t.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,32 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Sat, 11 Feb 2012 22:57:38 +0000
+Subject: intel_idle: Fix ID for Nehalem-EX Xeon in device ID table
+
+commit e668505c9811411c6096888b43ba104f35c9e9c3 upstream.
+
+Commit b66b8b9a4a79087dde1b358a016e5c8739ccf186 ('intel-idle: convert
+to x86_cpu_id auto probing') put two entries for model 0x2f
+(Westmere-EX Xeon) in the device ID table and left out model 0x2e
+(Nehalem-EX Xeon).
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+Acked-by: Thomas Renninger <trenn at suse.de>
+Acked-by: H. Peter Anvin <hpa at zytor.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ drivers/idle/intel_idle.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
+index 237fe57..a238649 100644
+--- a/drivers/idle/intel_idle.c
++++ b/drivers/idle/intel_idle.c
+@@ -360,7 +360,7 @@ static const struct x86_cpu_id intel_idle_ids[] = {
+ ICPU(0x1f, idle_cpu_nehalem),
+ ICPU(0x25, idle_cpu_westmere),
+ ICPU(0x2c, idle_cpu_westmere),
+- ICPU(0x2f, idle_cpu_westmere),
++ ICPU(0x2e, idle_cpu_westmere),
+ ICPU(0x1c, idle_cpu_atom),
+ ICPU(0x26, idle_cpu_lincroft),
+ ICPU(0x2f, idle_cpu_westmere),
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/intel_idle-Revert-change-of-auto_demotion_disable_fl.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/intel_idle-Revert-change-of-auto_demotion_disable_fl.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,52 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Thu, 16 Feb 2012 04:13:14 +0000
+Subject: intel_idle: Revert change of auto_demotion_disable_flags for Nehalem
+
+commit 8bf11938459ff8ceb8643258d0a35e0f2bc9be17 upstream.
+
+Commit b66b8b9a4a79087dde1b358a016e5c8739ccf186 ('intel-idle: convert
+to x86_cpu_id auto probing') added a distinction between Nehalem and
+Westemere processors and changed auto_demotion_disable_flags for the
+former to 0. This was not explained in the commit message, so change
+it back.
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+Acked-by: Thomas Renninger <trenn at suse.de>
+Acked-by: H. Peter Anvin <hpa at zytor.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ drivers/idle/intel_idle.c | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
+index a238649..1c15e9b 100644
+--- a/drivers/idle/intel_idle.c
++++ b/drivers/idle/intel_idle.c
+@@ -331,10 +331,6 @@ static void auto_demotion_disable(void *dummy)
+
+ static const struct idle_cpu idle_cpu_nehalem = {
+ .state_table = nehalem_cstates,
+-};
+-
+-static const struct idle_cpu idle_cpu_westmere = {
+- .state_table = nehalem_cstates,
+ .auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE,
+ };
+
+@@ -358,12 +354,12 @@ static const struct x86_cpu_id intel_idle_ids[] = {
+ ICPU(0x1a, idle_cpu_nehalem),
+ ICPU(0x1e, idle_cpu_nehalem),
+ ICPU(0x1f, idle_cpu_nehalem),
+- ICPU(0x25, idle_cpu_westmere),
+- ICPU(0x2c, idle_cpu_westmere),
+- ICPU(0x2e, idle_cpu_westmere),
++ ICPU(0x25, idle_cpu_nehalem),
++ ICPU(0x2c, idle_cpu_nehalem),
++ ICPU(0x2e, idle_cpu_nehalem),
+ ICPU(0x1c, idle_cpu_atom),
+ ICPU(0x26, idle_cpu_lincroft),
+- ICPU(0x2f, idle_cpu_westmere),
++ ICPU(0x2f, idle_cpu_nehalem),
+ ICPU(0x2a, idle_cpu_snb),
+ ICPU(0x2d, idle_cpu_snb),
+ {}
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/powernow-k6-Really-enable-auto-loading.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/powernow-k6-Really-enable-auto-loading.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,31 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Sat, 11 Feb 2012 23:04:12 +0000
+Subject: powernow-k6: Really enable auto-loading
+
+commit b4d2d23148b446f6853e711eb31c533c7385eba5 upstream.
+
+Commit fa8031aefec0cf7ea6c2387c93610d99d9659aa2 ('cpufreq: Add support
+for x86 cpuinfo auto loading v4') added a device ID table to this
+driver, but didn't declare it as the module device ID table.
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+Acked-by: Thomas Renninger <trenn at suse.de>
+Acked-by: H. Peter Anvin <hpa at zytor.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ drivers/cpufreq/powernow-k6.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c
+index 54dd031..af23e0b 100644
+--- a/drivers/cpufreq/powernow-k6.c
++++ b/drivers/cpufreq/powernow-k6.c
+@@ -216,7 +216,7 @@ static const struct x86_cpu_id powernow_k6_ids[] = {
+ { X86_VENDOR_AMD, 5, 13 },
+ {}
+ };
+-
++MODULE_DEVICE_TABLE(x86cpu, powernow_k6_ids);
+
+ /**
+ * powernow_k6_init - initializes the k6 PowerNow! CPUFreq driver
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/powernow-k7-Fix-CPU-family-number.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/powernow-k7-Fix-CPU-family-number.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,31 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Sat, 11 Feb 2012 22:58:14 +0000
+Subject: powernow-k7: Fix CPU family number
+
+commit 30bcfff9bd41db5edab6420d0ae2e435609eb083 upstream.
+
+Commit fa8031aefec0cf7ea6c2387c93610d99d9659aa2 ('cpufreq: Add support
+for x86 cpuinfo auto loading v4') seems to have inadvertently changed
+the matched CPU family number from 6 to 7. Change it back.
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+Acked-by: Thomas Renninger <trenn at suse.de>
+Acked-by: H. Peter Anvin <hpa at zytor.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ drivers/cpufreq/powernow-k7.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c
+index 501d167..cf7e1ee 100644
+--- a/drivers/cpufreq/powernow-k7.c
++++ b/drivers/cpufreq/powernow-k7.c
+@@ -112,7 +112,7 @@ static int check_fsb(unsigned int fsbspeed)
+ }
+
+ static const struct x86_cpu_id powernow_k7_cpuids[] = {
+- { X86_VENDOR_AMD, 7, },
++ { X86_VENDOR_AMD, 6, },
+ {}
+ };
+ MODULE_DEVICE_TABLE(x86cpu, powernow_k7_cpuids);
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/topology-Provide-CPU-topology-in-sysfs-in-SMP-configura.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/topology-Provide-CPU-topology-in-sysfs-in-SMP-configura.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,44 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Thu, 24 Nov 2011 07:04:39 +0000
+Subject: [PATCH] topology: Provide CPU topology in sysfs in !SMP
+ configurations
+
+commit ccbc60d3e19a1b6ae66ca0d89b3da02dde62088b upstream.
+
+We should provide topology information to userland even if it's not
+very interesting. The current code appears to work properly for !SMP
+(tested on i386).
+
+Reference: http://bugs.debian.org/649216
+Reported-by: Marcus Osdoba <marcus.osdoba at googlemail.com>
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+---
+ drivers/base/Makefile | 4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/base/Makefile b/drivers/base/Makefile
+index 99a375a..1334d89 100644
+--- a/drivers/base/Makefile
++++ b/drivers/base/Makefile
+@@ -3,7 +3,8 @@
+ obj-y := core.o sys.o bus.o dd.o syscore.o \
+ driver.o class.o platform.o \
+ cpu.o firmware.o init.o map.o devres.o \
+- attribute_container.o transport_class.o
++ attribute_container.o transport_class.o \
++ topology.o
+ obj-$(CONFIG_DEVTMPFS) += devtmpfs.o
+ obj-y += power/
+ obj-$(CONFIG_HAS_DMA) += dma-mapping.o
+@@ -12,7 +13,6 @@ obj-$(CONFIG_ISA) += isa.o
+ obj-$(CONFIG_FW_LOADER) += firmware_class.o
+ obj-$(CONFIG_NUMA) += node.o
+ obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o
+-obj-$(CONFIG_SMP) += topology.o
+ ifeq ($(CONFIG_SYSFS),y)
+ obj-$(CONFIG_MODULES) += module.o
+ endif
+--
+1.7.7.3
+
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/x86-cpu-Clean-up-modalias-feature-matching.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/x86-cpu-Clean-up-modalias-feature-matching.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,57 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Sat, 11 Feb 2012 22:57:19 +0000
+Subject: x86/cpu: Clean up modalias feature matching
+
+commit 5467bdda4a326513c2f14b712a22d59115b7ae94 upstream.
+
+We currently include commas on both sides of the feature ID in a
+modalias, but this prevents the lowest numbered feature of a CPU from
+being matched. Since all feature IDs have the same length, we do not
+need to worry about substring matches, so omit commas from the
+modalias entirely.
+
+Avoid generating multiple adjacent wildcards when there is no
+feature ID to match.
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+Acked-by: Thomas Renninger <trenn at suse.de>
+Acked-by: H. Peter Anvin <hpa at zytor.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ arch/x86/kernel/cpu/match.c | 3 +--
+ scripts/mod/file2alias.c | 5 +++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/arch/x86/kernel/cpu/match.c
++++ b/arch/x86/kernel/cpu/match.c
+@@ -63,7 +63,7 @@
+ boot_cpu_data.x86_model);
+ size -= n;
+ buf += n;
+- size -= 2;
++ size -= 1;
+ for (i = 0; i < NCAPINTS*32; i++) {
+ if (boot_cpu_has(i)) {
+ n = snprintf(buf, size, ",%04X", i);
+@@ -75,7 +75,6 @@
+ buf += n;
+ }
+ }
+- *buf++ = ',';
+ *buf++ = '\n';
+ return buf - bufptr;
+ }
+--- a/scripts/mod/file2alias.c
++++ b/scripts/mod/file2alias.c
+@@ -898,8 +898,9 @@
+ ADD(alias, "vendor:", id->vendor != X86_VENDOR_ANY, id->vendor);
+ ADD(alias, ":family:", id->family != X86_FAMILY_ANY, id->family);
+ ADD(alias, ":model:", id->model != X86_MODEL_ANY, id->model);
+- ADD(alias, ":feature:*,", id->feature != X86_FEATURE_ANY, id->feature);
+- strcat(alias, ",*");
++ strcat(alias, ":feature:*");
++ if (id->feature != X86_FEATURE_ANY)
++ sprintf(alias + strlen(alias), "%04X*", id->feature);
+ return 1;
+ }
+
Added: dists/sid/linux/debian/patches/features/all/cpu-devices/x86-cpu-Fix-overrun-check-in-arch_print_cpu_modalias.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/cpu-devices/x86-cpu-Fix-overrun-check-in-arch_print_cpu_modalias.patch Mon Jun 18 05:14:25 2012 (r19164)
@@ -0,0 +1,29 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Sat, 11 Feb 2012 22:56:59 +0000
+Subject: x86/cpu: Fix overrun check in arch_print_cpu_modalias()
+
+commit 70142a9dd154f54f7409871ead86f7d77f2c6576 upstream.
+
+snprintf() does not return a negative value when truncating.
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+Acked-by: Thomas Renninger <trenn at suse.de>
+Acked-by: H. Peter Anvin <hpa at zytor.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ arch/x86/kernel/cpu/match.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c
+index 940e2d4..2dfa52b 100644
+--- a/arch/x86/kernel/cpu/match.c
++++ b/arch/x86/kernel/cpu/match.c
+@@ -67,7 +67,7 @@ ssize_t arch_print_cpu_modalias(struct device *dev,
+ for (i = 0; i < NCAPINTS*32; i++) {
+ if (boot_cpu_has(i)) {
+ n = snprintf(buf, size, ",%04X", i);
+- if (n < 0) {
++ if (n >= size) {
+ WARN(1, "x86 features overflow page\n");
+ break;
+ }
Modified: dists/sid/linux/debian/patches/series
==============================================================================
--- dists/sid/linux/debian/patches/series Sun Jun 17 19:52:06 2012 (r19163)
+++ dists/sid/linux/debian/patches/series Mon Jun 18 05:14:25 2012 (r19164)
@@ -47,9 +47,6 @@
bugfix/all/0004-media-staging-lirc_serial-Fix-bogus-error-codes.patch
-features/all/topology-Provide-CPU-topology-in-sysfs-in-SMP-configura.patch
-bugfix/all/cpu-Do-not-return-errors-from-cpu_dev_init-which-wil.patch
-bugfix/all/cpu-Register-a-generic-CPU-device-on-architectures-t.patch
debian/x86-memtest-WARN-if-bad-RAM-found.patch
bugfix/all/snapshot-Implement-compat_ioctl.patch
debian/ARM-Remove-use-of-possibly-undefined-BUILD_BUG_ON-in.patch
@@ -327,3 +324,28 @@
bugfix/all/KVM-Fix-buffer-overflow-in-kvm_set_irq.patch
bugfix/all/ethtool-allow-ETHTOOL_GSSET_INFO-for-users.patch
+
+# CPU sysdev removal from 3.3 and x86 CPU auto-loading from 3.4
+features/all/cpu-devices/driver-core-implement-sysdev-functionality-for-regul.patch
+features/all/cpu-devices/cpu-convert-cpu-and-machinecheck-sysdev_class-to-a-r.patch
+features/all/cpu-devices/topology-Provide-CPU-topology-in-sysfs-in-SMP-configura.patch
+features/all/cpu-devices/cpu-Do-not-return-errors-from-cpu_dev_init-which-wil.patch
+features/all/cpu-devices/cpu-Register-a-generic-CPU-device-on-architectures-t.patch
+features/all/cpu-devices/Add-driver-auto-probing-for-x86-features-v4.patch
+features/all/cpu-devices/CPU-Introduce-ARCH_HAS_CPU_AUTOPROBE-and-X86-parts.patch
+features/all/cpu-devices/driver-core-cpu-remove-kernel-warning-when-removing-.patch
+features/all/cpu-devices/driver-core-cpu-fix-kobject-warning-when-hotplugging.patch
+features/all/cpu-devices/crypto-Add-support-for-x86-cpuid-auto-loading-for-x8.patch
+features/all/cpu-devices/intel-idle-convert-to-x86_cpu_id-auto-probing.patch
+features/all/cpu-devices/ACPI-Load-acpi-cpufreq-from-processor-driver-automat.patch
+features/all/cpu-devices/HWMON-Convert-via-cputemp-to-x86-cpuid-autoprobing.patch
+features/all/cpu-devices/HWMON-Convert-coretemp-to-x86-cpuid-autoprobing.patch
+features/all/cpu-devices/X86-Introduce-HW-Pstate-scattered-cpuid-feature.patch
+features/all/cpu-devices/cpufreq-Add-support-for-x86-cpuinfo-auto-loading-v4.patch
+features/all/cpu-devices/x86-cpu-Fix-overrun-check-in-arch_print_cpu_modalias.patch
+features/all/cpu-devices/x86-cpu-Clean-up-modalias-feature-matching.patch
+features/all/cpu-devices/intel_idle-Fix-ID-for-Nehalem-EX-Xeon-in-device-ID-t.patch
+features/all/cpu-devices/powernow-k7-Fix-CPU-family-number.patch
+features/all/cpu-devices/powernow-k6-Really-enable-auto-loading.patch
+features/all/cpu-devices/intel_idle-Revert-change-of-auto_demotion_disable_fl.patch
+features/all/cpu-devices/Partially-revert-cpufreq-Add-support-for-x86-cpuinfo.patch
More information about the Kernel-svn-changes
mailing list