diff --git a/debian/changelog b/debian/changelog index d6c08fc3c..4cf4e3c20 100644 --- a/debian/changelog +++ b/debian/changelog @@ -6,7 +6,16 @@ linux (3.2.20-2) UNRELEASED; urgency=low * [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. diff --git a/debian/patches/features/all/cpu-devices/ACPI-Load-acpi-cpufreq-from-processor-driver-automat.patch b/debian/patches/features/all/cpu-devices/ACPI-Load-acpi-cpufreq-from-processor-driver-automat.patch new file mode 100644 index 000000000..5d6757122 --- /dev/null +++ b/debian/patches/features/all/cpu-devices/ACPI-Load-acpi-cpufreq-from-processor-driver-automat.patch @@ -0,0 +1,81 @@ +From: Andi Kleen +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 +Signed-off-by: Andi Kleen +Signed-off-by: Thomas Renninger +Acked-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman +--- + 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); diff --git a/debian/patches/features/all/cpu-devices/Add-driver-auto-probing-for-x86-features-v4.patch b/debian/patches/features/all/cpu-devices/Add-driver-auto-probing-for-x86-features-v4.patch new file mode 100644 index 000000000..983c7b53f --- /dev/null +++ b/debian/patches/features/all/cpu-devices/Add-driver-auto-probing-for-x86-features-v4.patch @@ -0,0 +1,313 @@ +From: Andi Kleen +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@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 +Cc: Kay Sievers +Cc: Jen Axboe +Cc: Herbert Xu +Cc: Huang Ying +Cc: Len Brown +Signed-off-by: Andi Kleen +Signed-off-by: Thomas Renninger +Acked-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman +[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 ++ ++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 ++#include ++#include ++#include ++ ++/** ++ * 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 + #include + #include ++#include + + #include + #include +@@ -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); + } + diff --git a/debian/patches/features/all/cpu-devices/CPU-Introduce-ARCH_HAS_CPU_AUTOPROBE-and-X86-parts.patch b/debian/patches/features/all/cpu-devices/CPU-Introduce-ARCH_HAS_CPU_AUTOPROBE-and-X86-parts.patch new file mode 100644 index 000000000..1195c0320 --- /dev/null +++ b/debian/patches/features/all/cpu-devices/CPU-Introduce-ARCH_HAS_CPU_AUTOPROBE-and-X86-parts.patch @@ -0,0 +1,266 @@ +From: Thomas Renninger +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 +Cc: Dave Jones +Cc: Jens Axboe +Cc: Herbert Xu +Cc: Huang Ying +Cc: Len Brown +Acked-by: Andi Kleen +Signed-off-by: Thomas Renninger +Acked-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + #include ++#include + + /** + * 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 + #include + #include +-#include + + #include + #include +@@ -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 + #include + #include ++#include + #include + + #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. + */ diff --git a/debian/patches/features/all/cpu-devices/HWMON-Convert-coretemp-to-x86-cpuid-autoprobing.patch b/debian/patches/features/all/cpu-devices/HWMON-Convert-coretemp-to-x86-cpuid-autoprobing.patch new file mode 100644 index 000000000..1fd0acee7 --- /dev/null +++ b/debian/patches/features/all/cpu-devices/HWMON-Convert-coretemp-to-x86-cpuid-autoprobing.patch @@ -0,0 +1,59 @@ +From: Andi Kleen +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 +Cc: Jean Delvare +Cc: Guenter Roeck +Signed-off-by: Andi Kleen +Signed-off-by: Thomas Renninger +Acked-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + #include ++#include + + #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) diff --git a/debian/patches/features/all/cpu-devices/HWMON-Convert-via-cputemp-to-x86-cpuid-autoprobing.patch b/debian/patches/features/all/cpu-devices/HWMON-Convert-via-cputemp-to-x86-cpuid-autoprobing.patch new file mode 100644 index 000000000..2e95c6f7f --- /dev/null +++ b/debian/patches/features/all/cpu-devices/HWMON-Convert-via-cputemp-to-x86-cpuid-autoprobing.patch @@ -0,0 +1,56 @@ +From: Andi Kleen +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 +Cc: Guenter Roeck +Signed-off-by: Andi Kleen +Signed-off-by: Thomas Renninger +Acked-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + #include ++#include + + #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) diff --git a/debian/patches/features/all/cpu-devices/Partially-revert-cpufreq-Add-support-for-x86-cpuinfo.patch b/debian/patches/features/all/cpu-devices/Partially-revert-cpufreq-Add-support-for-x86-cpuinfo.patch new file mode 100644 index 000000000..73bacc01f --- /dev/null +++ b/debian/patches/features/all/cpu-devices/Partially-revert-cpufreq-Add-support-for-x86-cpuinfo.patch @@ -0,0 +1,55 @@ +From: Ben Hutchings +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 + #include + +-#include + #include + #include + +@@ -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; diff --git a/debian/patches/features/all/cpu-devices/X86-Introduce-HW-Pstate-scattered-cpuid-feature.patch b/debian/patches/features/all/cpu-devices/X86-Introduce-HW-Pstate-scattered-cpuid-feature.patch new file mode 100644 index 000000000..ece442c08 --- /dev/null +++ b/debian/patches/features/all/cpu-devices/X86-Introduce-HW-Pstate-scattered-cpuid-feature.patch @@ -0,0 +1,48 @@ +From: Thomas Renninger +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 +Cc: Dave Jones +Cc: Borislav Petkov +Signed-off-by: Thomas Renninger +Acked-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman +--- + 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 }, diff --git a/debian/patches/bugfix/all/cpu-Do-not-return-errors-from-cpu_dev_init-which-wil.patch b/debian/patches/features/all/cpu-devices/cpu-Do-not-return-errors-from-cpu_dev_init-which-wil.patch similarity index 63% rename from debian/patches/bugfix/all/cpu-Do-not-return-errors-from-cpu_dev_init-which-wil.patch rename to debian/patches/features/all/cpu-devices/cpu-Do-not-return-errors-from-cpu_dev_init-which-wil.patch index dae191c0e..9196a6742 100644 --- a/debian/patches/bugfix/all/cpu-Do-not-return-errors-from-cpu_dev_init-which-wil.patch +++ b/debian/patches/features/all/cpu-devices/cpu-Do-not-return-errors-from-cpu_dev_init-which-wil.patch @@ -1,7 +1,6 @@ From: Ben Hutchings Date: Tue, 10 Jan 2012 02:59:49 +0000 -Subject: [PATCH 1/2] cpu: Do not return errors from cpu_dev_init() which will - be ignored +Subject: cpu: Do not return errors from cpu_dev_init() which will be ignored commit 024f78462c3da710642a54939888a92e28704653 upstream. @@ -15,14 +14,17 @@ contained, so ignore this (as before). Signed-off-by: Ben Hutchings Signed-off-by: Linus Torvalds -[bwh: Backport to 3.2] --- + 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 -@@ -95,7 +95,7 @@ extern int hypervisor_init(void); +@@ -94,7 +94,7 @@ + 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 void cpu_dev_init(void); @@ -31,33 +33,31 @@ Signed-off-by: Linus Torvalds --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -2,6 +2,7 @@ - * drivers/base/cpu.c - basic CPU class support + * CPU subsystem support */ +#include - #include #include #include -@@ -247,17 +248,14 @@ bool cpu_is_hotpluggable(unsigned cpu) - } - EXPORT_SYMBOL_GPL(get_cpu_sysdev); + #include +@@ -267,16 +268,12 @@ + NULL, + }; -int __init cpu_dev_init(void) +void __init cpu_dev_init(void) { - int err; - -- err = sysdev_class_register(&cpu_sysdev_class); -+ if (sysdev_class_register(&cpu_sysdev_class)) +- 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) -- if (!err) -- err = sched_create_sysfs_power_savings_entries(&cpu_sysdev_class); -+ sched_create_sysfs_power_savings_entries(&cpu_sysdev_class); +- err = sched_create_sysfs_power_savings_entries(cpu_subsys.dev_root); ++ sched_create_sysfs_power_savings_entries(cpu_subsys.dev_root); #endif -- - return err; } - - static struct sysdev_class_attribute *cpu_sysdev_class_attrs[] = { diff --git a/debian/patches/bugfix/all/cpu-Register-a-generic-CPU-device-on-architectures-t.patch b/debian/patches/features/all/cpu-devices/cpu-Register-a-generic-CPU-device-on-architectures-t.patch similarity index 83% rename from debian/patches/bugfix/all/cpu-Register-a-generic-CPU-device-on-architectures-t.patch rename to debian/patches/features/all/cpu-devices/cpu-Register-a-generic-CPU-device-on-architectures-t.patch index 7af8c0fa3..68dc3536c 100644 --- a/debian/patches/bugfix/all/cpu-Register-a-generic-CPU-device-on-architectures-t.patch +++ b/debian/patches/features/all/cpu-devices/cpu-Register-a-generic-CPU-device-on-architectures-t.patch @@ -1,7 +1,7 @@ From: Ben Hutchings Date: Tue, 10 Jan 2012 03:04:32 +0000 -Subject: [PATCH 2/2] cpu: Register a generic CPU device on architectures that - currently do not +Subject: cpu: Register a generic CPU device on architectures that currently + do not commit 9f13a1fd452f11c18004ba2422a6384b424ec8a9 upstream. @@ -15,8 +15,19 @@ per_cpu. Signed-off-by: Ben Hutchings Signed-off-by: Linus Torvalds -[bwh: Backport to 3.2] --- + 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 @@ @@ -112,7 +123,7 @@ Signed-off-by: Linus Torvalds endmenu --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c -@@ -12,6 +12,7 @@ +@@ -11,6 +11,7 @@ #include #include #include @@ -120,9 +131,9 @@ Signed-off-by: Linus Torvalds #include "base.h" -@@ -248,11 +249,29 @@ - } - EXPORT_SYMBOL_GPL(get_cpu_sysdev); +@@ -268,11 +269,29 @@ + NULL, + }; +#ifdef CONFIG_GENERIC_CPU_DEVICES +static DEFINE_PER_CPU(struct cpu, cpu_devices); @@ -142,11 +153,11 @@ Signed-off-by: Linus Torvalds + void __init cpu_dev_init(void) { - if (sysdev_class_register(&cpu_sysdev_class)) + 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_sysdev_class); + sched_create_sysfs_power_savings_entries(cpu_subsys.dev_root); #endif diff --git a/debian/patches/features/all/cpu-devices/cpu-convert-cpu-and-machinecheck-sysdev_class-to-a-r.patch b/debian/patches/features/all/cpu-devices/cpu-convert-cpu-and-machinecheck-sysdev_class-to-a-r.patch new file mode 100644 index 000000000..176bf00ce --- /dev/null +++ b/debian/patches/features/all/cpu-devices/cpu-convert-cpu-and-machinecheck-sysdev_class-to-a-r.patch @@ -0,0 +1,4365 @@ +From: Kay Sievers +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 +Cc: Hans-Christian Egtvedt +Cc: Tony Luck +Cc: Fenghua Yu +Cc: Arnd Bergmann +Cc: Benjamin Herrenschmidt +Cc: Paul Mackerras +Cc: Martin Schwidefsky +Cc: Heiko Carstens +Cc: Paul Mundt +Cc: "David S. Miller" +Cc: Chris Metcalf +Cc: Thomas Gleixner +Cc: Ingo Molnar +Cc: "H. Peter Anvin" +Cc: Borislav Petkov +Cc: Tigran Aivazian +Cc: Len Brown +Cc: Zhang Rui +Cc: Dave Jones +Cc: Peter Zijlstra +Cc: Russell King +Cc: Andrew Morton +Cc: Arjan van de Ven +Cc: "Rafael J. Wysocki" +Cc: "Srivatsa S. Bhat" +Signed-off-by: Kay Sievers +Signed-off-by: Greg Kroah-Hartman +[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 +-#include ++#include + #include + #include + #include +@@ -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 ++#include + #include + #include + #include +@@ -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 +-#include ++#include + #include + + #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 + #include + #include +-#include ++#include + #include + #include + #include +--- a/arch/powerpc/kernel/sysfs.c ++++ b/arch/powerpc/kernel/sysfs.c +@@ -1,4 +1,4 @@ +-#include ++#include + #include + #include + #include +@@ -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 +-#include ++#include + #include + #include + #include +@@ -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 + #include + #include +-#include ++#include + #include + #include + #include +@@ -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 + #include + #include +-#include ++#include + #include + #include + #include +@@ -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 + */ + #include +-#include ++#include + #include + #include + #include +@@ -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 ++#include + #include + #include + #include +@@ -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 + #include +- +-extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */ ++#include + + /* 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 ++#include + #include + + 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 + #include + #include +-#include ++#include + #include + #include + #include +@@ -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 + #include + #include +-#include + #include + #include + #include +@@ -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 + #include + #include +-#include + #include + #include + #include +@@ -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 + #include + #include +-#include + + #include + +--- 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 + #include + #include + #include +@@ -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 + +-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 + #include + #include + #include +@@ -32,14 +31,14 @@ + #include + + #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 + #include +-#include + #include + #include + #include +--- 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 ++#include + + /* 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 + #include + #include +-#include ++#include + #include + #include + +@@ -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 ++#include + #include + #include + #include +@@ -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; + } diff --git a/debian/patches/features/all/cpu-devices/cpufreq-Add-support-for-x86-cpuinfo-auto-loading-v4.patch b/debian/patches/features/all/cpu-devices/cpufreq-Add-support-for-x86-cpuinfo-auto-loading-v4.patch new file mode 100644 index 000000000..06607f97e --- /dev/null +++ b/debian/patches/features/all/cpu-devices/cpufreq-Add-support-for-x86-cpuinfo-auto-loading-v4.patch @@ -0,0 +1,596 @@ +From: Andi Kleen +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 +Cc: Kay Sievers +Signed-off-by: Andi Kleen +Signed-off-by: Thomas Renninger +Acked-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + ++#include + #include + #include + +@@ -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 + #include + ++#include + #include + #include + #include +@@ -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 + #include + ++#include + #include + + /* 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 + + #include ++#include + #include + + #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 + #include ++#include + + 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 + #include + #include ++#include + + #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 + #include + ++#include + #include + + #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 /* Needed for recalibrate_cpu_khz() */ + #include + #include ++#include + + #ifdef CONFIG_X86_POWERNOW_K7_ACPI + #include +@@ -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 + + #include ++#include + + #include + #include +@@ -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 + #include + ++#include + #include + + #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 + #include + #include ++#include + + #define PFX "speedstep-centrino: " + #define MAINTAINER "cpufreq@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 + #include + ++#include ++ + #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 + #include + #include ++#include + + #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) { diff --git a/debian/patches/features/all/cpu-devices/crypto-Add-support-for-x86-cpuid-auto-loading-for-x8.patch b/debian/patches/features/all/cpu-devices/crypto-Add-support-for-x86-cpuid-auto-loading-for-x8.patch new file mode 100644 index 000000000..38c9f8272 --- /dev/null +++ b/debian/patches/features/all/cpu-devices/crypto-Add-support-for-x86-cpuid-auto-loading-for-x8.patch @@ -0,0 +1,215 @@ +From: Andi Kleen +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 +Cc: Kay Sievers +Cc: Jen Axboe +Cc: Herbert Xu +Cc: Huang Ying +Signed-off-by: Andi Kleen +Signed-off-by: Thomas Renninger +Acked-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + #include ++#include + #include + #include + #include +@@ -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 + + #include ++#include + + #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 + #include + #include ++#include + + #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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + #include + + 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 */ diff --git a/debian/patches/features/all/cpu-devices/driver-core-cpu-fix-kobject-warning-when-hotplugging.patch b/debian/patches/features/all/cpu-devices/driver-core-cpu-fix-kobject-warning-when-hotplugging.patch new file mode 100644 index 000000000..4bcc54fd5 --- /dev/null +++ b/debian/patches/features/all/cpu-devices/driver-core-cpu-fix-kobject-warning-when-hotplugging.patch @@ -0,0 +1,31 @@ +From: Greg Kroah-Hartman +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 +Tested-by: Konrad Rzeszutek Wilk +Signed-off-by: Greg Kroah-Hartman +--- + 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; diff --git a/debian/patches/features/all/cpu-devices/driver-core-cpu-remove-kernel-warning-when-removing-.patch b/debian/patches/features/all/cpu-devices/driver-core-cpu-remove-kernel-warning-when-removing-.patch new file mode 100644 index 000000000..cb0b8dddd --- /dev/null +++ b/debian/patches/features/all/cpu-devices/driver-core-cpu-remove-kernel-warning-when-removing-.patch @@ -0,0 +1,59 @@ +From: Greg Kroah-Hartman +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 +Tested-by: Konrad Rzeszutek Wilk +Signed-off-by: Greg Kroah-Hartman +[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 diff --git a/debian/patches/features/all/cpu-devices/driver-core-implement-sysdev-functionality-for-regul.patch b/debian/patches/features/all/cpu-devices/driver-core-implement-sysdev-functionality-for-regul.patch new file mode 100644 index 000000000..9ccad0c7d --- /dev/null +++ b/debian/patches/features/all/cpu-devices/driver-core-implement-sysdev-functionality-for-regul.patch @@ -0,0 +1,884 @@ +From: Kay Sievers +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + #include ++#include + #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/ 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/. ++ */ ++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; diff --git a/debian/patches/features/all/cpu-devices/intel-idle-convert-to-x86_cpu_id-auto-probing.patch b/debian/patches/features/all/cpu-devices/intel-idle-convert-to-x86_cpu_id-auto-probing.patch new file mode 100644 index 000000000..20a9442c9 --- /dev/null +++ b/debian/patches/features/all/cpu-devices/intel-idle-convert-to-x86_cpu_id-auto-probing.patch @@ -0,0 +1,196 @@ +From: Andi Kleen +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 +Signed-off-by: Andi Kleen +Signed-off-by: Thomas Renninger +Acked-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman +[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 + #include + #include ++#include + #include + #include + +@@ -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; diff --git a/debian/patches/features/all/cpu-devices/intel_idle-Fix-ID-for-Nehalem-EX-Xeon-in-device-ID-t.patch b/debian/patches/features/all/cpu-devices/intel_idle-Fix-ID-for-Nehalem-EX-Xeon-in-device-ID-t.patch new file mode 100644 index 000000000..ee0546ed5 --- /dev/null +++ b/debian/patches/features/all/cpu-devices/intel_idle-Fix-ID-for-Nehalem-EX-Xeon-in-device-ID-t.patch @@ -0,0 +1,32 @@ +From: Ben Hutchings +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 +Acked-by: Thomas Renninger +Acked-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman +--- + 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), diff --git a/debian/patches/features/all/cpu-devices/intel_idle-Revert-change-of-auto_demotion_disable_fl.patch b/debian/patches/features/all/cpu-devices/intel_idle-Revert-change-of-auto_demotion_disable_fl.patch new file mode 100644 index 000000000..7da98a367 --- /dev/null +++ b/debian/patches/features/all/cpu-devices/intel_idle-Revert-change-of-auto_demotion_disable_fl.patch @@ -0,0 +1,52 @@ +From: Ben Hutchings +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 +Acked-by: Thomas Renninger +Acked-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman +--- + 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), + {} diff --git a/debian/patches/features/all/cpu-devices/powernow-k6-Really-enable-auto-loading.patch b/debian/patches/features/all/cpu-devices/powernow-k6-Really-enable-auto-loading.patch new file mode 100644 index 000000000..db4e0b8e3 --- /dev/null +++ b/debian/patches/features/all/cpu-devices/powernow-k6-Really-enable-auto-loading.patch @@ -0,0 +1,31 @@ +From: Ben Hutchings +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 +Acked-by: Thomas Renninger +Acked-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman +--- + 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 diff --git a/debian/patches/features/all/cpu-devices/powernow-k7-Fix-CPU-family-number.patch b/debian/patches/features/all/cpu-devices/powernow-k7-Fix-CPU-family-number.patch new file mode 100644 index 000000000..52a067e8a --- /dev/null +++ b/debian/patches/features/all/cpu-devices/powernow-k7-Fix-CPU-family-number.patch @@ -0,0 +1,31 @@ +From: Ben Hutchings +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 +Acked-by: Thomas Renninger +Acked-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman +--- + 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); diff --git a/debian/patches/features/all/topology-Provide-CPU-topology-in-sysfs-in-SMP-configura.patch b/debian/patches/features/all/cpu-devices/topology-Provide-CPU-topology-in-sysfs-in-SMP-configura.patch similarity index 100% rename from debian/patches/features/all/topology-Provide-CPU-topology-in-sysfs-in-SMP-configura.patch rename to debian/patches/features/all/cpu-devices/topology-Provide-CPU-topology-in-sysfs-in-SMP-configura.patch diff --git a/debian/patches/features/all/cpu-devices/x86-cpu-Clean-up-modalias-feature-matching.patch b/debian/patches/features/all/cpu-devices/x86-cpu-Clean-up-modalias-feature-matching.patch new file mode 100644 index 000000000..e65ef5b55 --- /dev/null +++ b/debian/patches/features/all/cpu-devices/x86-cpu-Clean-up-modalias-feature-matching.patch @@ -0,0 +1,57 @@ +From: Ben Hutchings +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 +Acked-by: Thomas Renninger +Acked-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman +--- + 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; + } + diff --git a/debian/patches/features/all/cpu-devices/x86-cpu-Fix-overrun-check-in-arch_print_cpu_modalias.patch b/debian/patches/features/all/cpu-devices/x86-cpu-Fix-overrun-check-in-arch_print_cpu_modalias.patch new file mode 100644 index 000000000..fffa8876b --- /dev/null +++ b/debian/patches/features/all/cpu-devices/x86-cpu-Fix-overrun-check-in-arch_print_cpu_modalias.patch @@ -0,0 +1,29 @@ +From: Ben Hutchings +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 +Acked-by: Thomas Renninger +Acked-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman +--- + 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; + } diff --git a/debian/patches/series b/debian/patches/series index 28bfd24b0..84a30dfeb 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -47,9 +47,6 @@ debian/bcma-Do-not-claim-PCI-device-IDs-also-claimed-by-brc.patch 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/macvtap-zerocopy-validate-vectors-before-building-sk.patch 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