CPU sysdev removal from 3.3 and x86 CPU auto-loading from 3.4
* cpu: Convert 'cpu' and 'machinecheck' sysdev_class to a regular subsystem * [x86] Add driver auto probing for x86 features - crypto: Add support for x86 cpuid auto loading for x86 crypto drivers (Closes: #568008) - intel-idle: convert to x86_cpu_id auto probing - HWMON: Convert coretemp to x86 cpuid autoprobing - HWMON: Convert via-cputemp to x86 cpuid autoprobing - cpufreq: Add support for x86 cpuinfo auto loading (Closes: #664813) * [x86] ACPI: Load acpi-cpufreq from processor driver automatically svn path=/dists/sid/linux/; revision=19164
This commit is contained in:
parent
2a7ca38f68
commit
650c4637a3
|
@ -6,6 +6,15 @@ 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.
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
From: Andi Kleen <ak@linux.intel.com>
|
||||
Date: Thu, 26 Jan 2012 00:09:08 +0100
|
||||
Subject: ACPI: Load acpi-cpufreq from processor driver automatically
|
||||
|
||||
commit 9061e0e16700ef228837e96987ff51794c956197 upstream.
|
||||
|
||||
The only left over hole in automatic cpufreq driver loading was the loading
|
||||
of ACPI cpufreq. This driver should be loaded when ACPI supports a _PDC
|
||||
method and the CPU vendor wants to use acpi cpufreq.
|
||||
|
||||
Simply add a request module call to the acpi processor core driver
|
||||
when this is true. This seems like the simplest solution for this.
|
||||
|
||||
Cc: Len Brown <lenb@kernel.org>
|
||||
Signed-off-by: Andi Kleen <ak@linux.intel.com>
|
||||
Signed-off-by: Thomas Renninger <trenn@suse.de>
|
||||
Acked-by: H. Peter Anvin <hpa@zytor.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/acpi/processor_driver.c | 1 +
|
||||
drivers/acpi/processor_perflib.c | 22 ++++++++++++++++++++++
|
||||
include/acpi/processor.h | 1 +
|
||||
3 files changed, 24 insertions(+)
|
||||
|
||||
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
|
||||
index 0034ede..e6920d0 100644
|
||||
--- a/drivers/acpi/processor_driver.c
|
||||
+++ b/drivers/acpi/processor_driver.c
|
||||
@@ -497,6 +497,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
|
||||
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
acpi_processor_ppc_has_changed(pr, 0);
|
||||
+ acpi_processor_load_module(pr);
|
||||
#endif
|
||||
acpi_processor_get_throttling_info(pr);
|
||||
acpi_processor_get_limit_info(pr);
|
||||
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
|
||||
index 85b3237..0af48a8 100644
|
||||
--- a/drivers/acpi/processor_perflib.c
|
||||
+++ b/drivers/acpi/processor_perflib.c
|
||||
@@ -240,6 +240,28 @@ void acpi_processor_ppc_exit(void)
|
||||
acpi_processor_ppc_status &= ~PPC_REGISTERED;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Do a quick check if the systems looks like it should use ACPI
|
||||
+ * cpufreq. We look at a _PCT method being available, but don't
|
||||
+ * do a whole lot of sanity checks.
|
||||
+ */
|
||||
+void acpi_processor_load_module(struct acpi_processor *pr)
|
||||
+{
|
||||
+ static int requested;
|
||||
+ acpi_status status = 0;
|
||||
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
+
|
||||
+ if (!arch_has_acpi_pdc() || requested)
|
||||
+ return;
|
||||
+ status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer);
|
||||
+ if (!ACPI_FAILURE(status)) {
|
||||
+ printk(KERN_INFO PREFIX "Requesting acpi_cpufreq\n");
|
||||
+ request_module_nowait("acpi_cpufreq");
|
||||
+ requested = 1;
|
||||
+ }
|
||||
+ kfree(buffer.pointer);
|
||||
+}
|
||||
+
|
||||
static int acpi_processor_get_performance_control(struct acpi_processor *pr)
|
||||
{
|
||||
int result = 0;
|
||||
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
|
||||
index 610f6fb..da57fdc 100644
|
||||
--- a/include/acpi/processor.h
|
||||
+++ b/include/acpi/processor.h
|
||||
@@ -224,6 +224,7 @@ struct acpi_processor_errata {
|
||||
} piix4;
|
||||
};
|
||||
|
||||
+extern void acpi_processor_load_module(struct acpi_processor *pr);
|
||||
extern int acpi_processor_preregister_performance(struct
|
||||
acpi_processor_performance
|
||||
__percpu *performance);
|
313
debian/patches/features/all/cpu-devices/Add-driver-auto-probing-for-x86-features-v4.patch
vendored
Normal file
313
debian/patches/features/all/cpu-devices/Add-driver-auto-probing-for-x86-features-v4.patch
vendored
Normal file
|
@ -0,0 +1,313 @@
|
|||
From: Andi Kleen <ak@linux.intel.com>
|
||||
Date: Thu, 26 Jan 2012 00:09:05 +0100
|
||||
Subject: Add driver auto probing for x86 features v4
|
||||
|
||||
commit 644e9cbbe3fc032cc92d0936057e166a994dc246 upstream.
|
||||
|
||||
There's a growing number of drivers that support a specific x86 feature
|
||||
or CPU. Currently loading these drivers currently on a generic
|
||||
distribution requires various driver specific hacks and it often
|
||||
doesn't work.
|
||||
|
||||
This patch adds auto probing for drivers based on the x86 cpuid
|
||||
information, in particular based on vendor/family/model number
|
||||
and also based on CPUID feature bits.
|
||||
|
||||
For example a common issue is not loading the SSE 4.2 accelerated
|
||||
CRC module: this can significantly lower the performance of BTRFS
|
||||
which relies on fast CRC.
|
||||
|
||||
Another issue is loading the right CPUFREQ driver for the current CPU.
|
||||
Currently distributions often try all all possible driver until
|
||||
one sticks, which is not really a good way to do this.
|
||||
|
||||
It works with existing udev without any changes. The code
|
||||
exports the x86 information as a generic string in sysfs
|
||||
that can be matched by udev's pattern matching.
|
||||
|
||||
This scheme does not support numeric ranges, so if you want to
|
||||
handle e.g. ranges of model numbers they have to be encoded
|
||||
in ASCII or simply all models or families listed. Fixing
|
||||
that would require changing udev.
|
||||
|
||||
Another issue is that udev will happily load all drivers that match,
|
||||
there is currently no nice way to stop a specific driver from
|
||||
being loaded if it's not needed (e.g. if you don't need fast CRC)
|
||||
But there are not that many cpu specific drivers around and they're
|
||||
all not that bloated, so this isn't a particularly serious issue.
|
||||
|
||||
Originally this patch added the modalias to the normal cpu
|
||||
sysdevs. However sysdevs don't have all the infrastructure
|
||||
needed for udev, so it couldn't really autoload drivers.
|
||||
This patch instead adds the CPU modaliases to the cpuid devices,
|
||||
which are real devices with full support for udev. This implies
|
||||
that the cpuid driver has to be loaded to use this.
|
||||
|
||||
This patch just adds infrastructure, some driver conversions
|
||||
in followups.
|
||||
|
||||
Thanks to Kay for helping with some sysfs magic.
|
||||
|
||||
v2: Constifcation, some updates
|
||||
v4: (trenn@suse.de):
|
||||
- Use kzalloc instead of kmalloc to terminate modalias buffer
|
||||
- Use uppercase hex values to match correctly against hex values containing
|
||||
letters
|
||||
|
||||
Cc: Dave Jones <davej@redhat.com>
|
||||
Cc: Kay Sievers <kay.sievers@vrfy.org>
|
||||
Cc: Jen Axboe <axboe@kernel.dk>
|
||||
Cc: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
Cc: Huang Ying <ying.huang@intel.com>
|
||||
Cc: Len Brown <lenb@kernel.org>
|
||||
Signed-off-by: Andi Kleen <ak@linux.intel.com>
|
||||
Signed-off-by: Thomas Renninger <trenn@suse.de>
|
||||
Acked-by: H. Peter Anvin <hpa@zytor.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
[bwh: Backported to 3.2:
|
||||
- adjust context
|
||||
- make do without ADD_TO_DEVTABLE in file2alias]
|
||||
---
|
||||
--- /dev/null
|
||||
+++ b/arch/x86/include/asm/cpu_device_id.h
|
||||
@@ -0,0 +1,13 @@
|
||||
+#ifndef _CPU_DEVICE_ID
|
||||
+#define _CPU_DEVICE_ID 1
|
||||
+
|
||||
+/*
|
||||
+ * Declare drivers belonging to specific x86 CPUs
|
||||
+ * Similar in spirit to pci_device_id and related PCI functions
|
||||
+ */
|
||||
+
|
||||
+#include <linux/mod_devicetable.h>
|
||||
+
|
||||
+extern const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match);
|
||||
+
|
||||
+#endif
|
||||
--- a/arch/x86/kernel/cpu/Makefile
|
||||
+++ b/arch/x86/kernel/cpu/Makefile
|
||||
@@ -16,6 +16,7 @@
|
||||
obj-y += proc.o capflags.o powerflags.o common.o
|
||||
obj-y += vmware.o hypervisor.o sched.o mshyperv.o
|
||||
obj-y += rdrand.o
|
||||
+obj-y += match.o
|
||||
|
||||
obj-$(CONFIG_X86_32) += bugs.o
|
||||
obj-$(CONFIG_X86_64) += bugs_64.o
|
||||
--- /dev/null
|
||||
+++ b/arch/x86/kernel/cpu/match.c
|
||||
@@ -0,0 +1,48 @@
|
||||
+#include <asm/cpu_device_id.h>
|
||||
+#include <asm/processor.h>
|
||||
+#include <linux/cpu.h>
|
||||
+#include <linux/module.h>
|
||||
+
|
||||
+/**
|
||||
+ * x86_match_cpu - match current CPU again an array of x86_cpu_ids
|
||||
+ * @match: Pointer to array of x86_cpu_ids. Last entry terminated with
|
||||
+ * {}.
|
||||
+ *
|
||||
+ * Return the entry if the current CPU matches the entries in the
|
||||
+ * passed x86_cpu_id match table. Otherwise NULL. The match table
|
||||
+ * contains vendor (X86_VENDOR_*), family, model and feature bits or
|
||||
+ * respective wildcard entries.
|
||||
+ *
|
||||
+ * A typical table entry would be to match a specific CPU
|
||||
+ * { X86_VENDOR_INTEL, 6, 0x12 }
|
||||
+ * or to match a specific CPU feature
|
||||
+ * { X86_FEATURE_MATCH(X86_FEATURE_FOOBAR) }
|
||||
+ *
|
||||
+ * Fields can be wildcarded with %X86_VENDOR_ANY, %X86_FAMILY_ANY,
|
||||
+ * %X86_MODEL_ANY, %X86_FEATURE_ANY or 0 (except for vendor)
|
||||
+ *
|
||||
+ * Arrays used to match for this should also be declared using
|
||||
+ * MODULE_DEVICE_TABLE(x86_cpu, ...)
|
||||
+ *
|
||||
+ * This always matches against the boot cpu, assuming models and features are
|
||||
+ * consistent over all CPUs.
|
||||
+ */
|
||||
+const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match)
|
||||
+{
|
||||
+ const struct x86_cpu_id *m;
|
||||
+ struct cpuinfo_x86 *c = &boot_cpu_data;
|
||||
+
|
||||
+ for (m = match; m->vendor | m->family | m->model | m->feature; m++) {
|
||||
+ if (m->vendor != X86_VENDOR_ANY && c->x86_vendor != m->vendor)
|
||||
+ continue;
|
||||
+ if (m->family != X86_FAMILY_ANY && c->x86 != m->family)
|
||||
+ continue;
|
||||
+ if (m->model != X86_MODEL_ANY && c->x86_model != m->model)
|
||||
+ continue;
|
||||
+ if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature))
|
||||
+ continue;
|
||||
+ return m;
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+EXPORT_SYMBOL(x86_match_cpu);
|
||||
--- a/arch/x86/kernel/cpuid.c
|
||||
+++ b/arch/x86/kernel/cpuid.c
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/gfp.h>
|
||||
+#include <linux/slab.h>
|
||||
|
||||
#include <asm/processor.h>
|
||||
#include <asm/msr.h>
|
||||
@@ -138,13 +139,57 @@
|
||||
.open = cpuid_open,
|
||||
};
|
||||
|
||||
+static ssize_t print_cpu_modalias(struct device *dev,
|
||||
+ struct device_attribute *attr,
|
||||
+ char *bufptr)
|
||||
+{
|
||||
+ int size = PAGE_SIZE;
|
||||
+ int i, n;
|
||||
+ char *buf = bufptr;
|
||||
+
|
||||
+ n = snprintf(buf, size, "x86cpu:vendor:%04X:family:"
|
||||
+ "%04X:model:%04X:feature:",
|
||||
+ boot_cpu_data.x86_vendor,
|
||||
+ boot_cpu_data.x86,
|
||||
+ boot_cpu_data.x86_model);
|
||||
+ size -= n;
|
||||
+ buf += n;
|
||||
+ size -= 2;
|
||||
+ for (i = 0; i < NCAPINTS*32; i++) {
|
||||
+ if (boot_cpu_has(i)) {
|
||||
+ n = snprintf(buf, size, ",%04X", i);
|
||||
+ if (n < 0) {
|
||||
+ WARN(1, "x86 features overflow page\n");
|
||||
+ break;
|
||||
+ }
|
||||
+ size -= n;
|
||||
+ buf += n;
|
||||
+ }
|
||||
+ }
|
||||
+ *buf++ = ',';
|
||||
+ *buf++ = '\n';
|
||||
+ return buf - bufptr;
|
||||
+}
|
||||
+
|
||||
+static DEVICE_ATTR(modalias, 0444, print_cpu_modalias, NULL);
|
||||
+
|
||||
static __cpuinit int cpuid_device_create(int cpu)
|
||||
{
|
||||
struct device *dev;
|
||||
+ int err;
|
||||
|
||||
dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu), NULL,
|
||||
"cpu%d", cpu);
|
||||
- return IS_ERR(dev) ? PTR_ERR(dev) : 0;
|
||||
+ if (IS_ERR(dev))
|
||||
+ return PTR_ERR(dev);
|
||||
+
|
||||
+ err = device_create_file(dev, &dev_attr_modalias);
|
||||
+ if (err) {
|
||||
+ /* keep device around on error. attribute is optional. */
|
||||
+ err = 0;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void cpuid_device_destroy(int cpu)
|
||||
@@ -182,6 +227,17 @@
|
||||
return kasprintf(GFP_KERNEL, "cpu/%u/cpuid", MINOR(dev->devt));
|
||||
}
|
||||
|
||||
+static int cpuid_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
+{
|
||||
+ char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
+ if (buf) {
|
||||
+ print_cpu_modalias(NULL, NULL, buf);
|
||||
+ add_uevent_var(env, "MODALIAS=%s", buf);
|
||||
+ kfree(buf);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int __init cpuid_init(void)
|
||||
{
|
||||
int i, err = 0;
|
||||
@@ -200,6 +256,7 @@
|
||||
goto out_chrdev;
|
||||
}
|
||||
cpuid_class->devnode = cpuid_devnode;
|
||||
+ cpuid_class->dev_uevent = cpuid_dev_uevent;
|
||||
for_each_online_cpu(i) {
|
||||
err = cpuid_device_create(i);
|
||||
if (err != 0)
|
||||
--- a/include/linux/mod_devicetable.h
|
||||
+++ b/include/linux/mod_devicetable.h
|
||||
@@ -542,4 +542,25 @@
|
||||
kernel_ulong_t driver_data; /* data private to the driver */
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * Match x86 CPUs for CPU specific drivers.
|
||||
+ * See documentation of "x86_match_cpu" for details.
|
||||
+ */
|
||||
+
|
||||
+struct x86_cpu_id {
|
||||
+ __u16 vendor;
|
||||
+ __u16 family;
|
||||
+ __u16 model;
|
||||
+ __u16 feature; /* bit index */
|
||||
+ kernel_ulong_t driver_data;
|
||||
+};
|
||||
+
|
||||
+#define X86_FEATURE_MATCH(x) \
|
||||
+ { X86_VENDOR_ANY, X86_FAMILY_ANY, X86_MODEL_ANY, x }
|
||||
+
|
||||
+#define X86_VENDOR_ANY 0xffff
|
||||
+#define X86_FAMILY_ANY 0
|
||||
+#define X86_MODEL_ANY 0
|
||||
+#define X86_FEATURE_ANY 0 /* Same as FPU, you can't test for that */
|
||||
+
|
||||
#endif /* LINUX_MOD_DEVICETABLE_H */
|
||||
--- a/scripts/mod/file2alias.c
|
||||
+++ b/scripts/mod/file2alias.c
|
||||
@@ -880,6 +880,29 @@
|
||||
return 1;
|
||||
}
|
||||
|
||||
+/* LOOKS like x86cpu:vendor:VVVV:family:FFFF:model:MMMM:feature:*,FEAT,*
|
||||
+ * All fields are numbers. It would be nicer to use strings for vendor
|
||||
+ * and feature, but getting those out of the build system here is too
|
||||
+ * complicated.
|
||||
+ */
|
||||
+
|
||||
+static int do_x86cpu_entry(const char *filename, struct x86_cpu_id *id,
|
||||
+ char *alias)
|
||||
+{
|
||||
+ id->feature = TO_NATIVE(id->feature);
|
||||
+ id->family = TO_NATIVE(id->family);
|
||||
+ id->model = TO_NATIVE(id->model);
|
||||
+ id->vendor = TO_NATIVE(id->vendor);
|
||||
+
|
||||
+ strcpy(alias, "x86cpu:");
|
||||
+ ADD(alias, "vendor:", id->vendor != X86_VENDOR_ANY, id->vendor);
|
||||
+ ADD(alias, ":family:", id->family != X86_FAMILY_ANY, id->family);
|
||||
+ ADD(alias, ":model:", id->model != X86_MODEL_ANY, id->model);
|
||||
+ ADD(alias, ":feature:*,", id->feature != X86_FEATURE_ANY, id->feature);
|
||||
+ strcat(alias, ",*");
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
/* Ignore any prefix, eg. some architectures prepend _ */
|
||||
static inline int sym_is(const char *symbol, const char *name)
|
||||
{
|
||||
@@ -1051,6 +1074,10 @@
|
||||
do_table(symval, sym->st_size,
|
||||
sizeof(struct isapnp_device_id), "isa",
|
||||
do_isapnp_entry, mod);
|
||||
+ else if (sym_is(symname, "__mod_x86cpu_device_table"))
|
||||
+ do_table(symval, sym->st_size,
|
||||
+ sizeof(struct x86_cpu_id), "x86cpu",
|
||||
+ do_x86cpu_entry, mod);
|
||||
free(zeros);
|
||||
}
|
||||
|
266
debian/patches/features/all/cpu-devices/CPU-Introduce-ARCH_HAS_CPU_AUTOPROBE-and-X86-parts.patch
vendored
Normal file
266
debian/patches/features/all/cpu-devices/CPU-Introduce-ARCH_HAS_CPU_AUTOPROBE-and-X86-parts.patch
vendored
Normal file
|
@ -0,0 +1,266 @@
|
|||
From: Thomas Renninger <trenn@suse.de>
|
||||
Date: Thu, 26 Jan 2012 00:09:14 +0100
|
||||
Subject: CPU: Introduce ARCH_HAS_CPU_AUTOPROBE and X86 parts
|
||||
|
||||
commit fad12ac8c8c2591c7f4e61d19b6a9d76cd49fafa upstream.
|
||||
|
||||
This patch is based on Andi Kleen's work:
|
||||
Implement autoprobing/loading of modules serving CPU
|
||||
specific features (x86cpu autoloading).
|
||||
|
||||
And Kay Siever's work to get rid of sysdev cpu structures
|
||||
and making use of struct device instead.
|
||||
|
||||
Before, the cpuid driver had to be loaded to get the x86cpu
|
||||
autoloading feature. With this patch autoloading works through
|
||||
the /sys/devices/system/cpu object
|
||||
|
||||
Cc: Kay Sievers <kay.sievers@vrfy.org>
|
||||
Cc: Dave Jones <davej@redhat.com>
|
||||
Cc: Jens Axboe <axboe@kernel.dk>
|
||||
Cc: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
Cc: Huang Ying <ying.huang@intel.com>
|
||||
Cc: Len Brown <lenb@kernel.org>
|
||||
Acked-by: Andi Kleen <ak@linux.intel.com>
|
||||
Signed-off-by: Thomas Renninger <trenn@suse.de>
|
||||
Acked-by: H. Peter Anvin <hpa@zytor.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
arch/x86/Kconfig | 3 +++
|
||||
arch/x86/kernel/cpu/match.c | 44 ++++++++++++++++++++++++++++++++
|
||||
arch/x86/kernel/cpuid.c | 59 +------------------------------------------
|
||||
drivers/base/cpu.c | 11 ++++++++
|
||||
include/linux/cpu.h | 7 +++++
|
||||
5 files changed, 66 insertions(+), 58 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
|
||||
index 864cc6e..6baa1e6 100644
|
||||
--- a/arch/x86/Kconfig
|
||||
+++ b/arch/x86/Kconfig
|
||||
@@ -179,6 +179,9 @@ config ARCH_HAS_DEFAULT_IDLE
|
||||
config ARCH_HAS_CACHE_LINE_SIZE
|
||||
def_bool y
|
||||
|
||||
+config ARCH_HAS_CPU_AUTOPROBE
|
||||
+ def_bool y
|
||||
+
|
||||
config HAVE_SETUP_PER_CPU_AREA
|
||||
def_bool y
|
||||
|
||||
diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c
|
||||
index 7acc961..940e2d4 100644
|
||||
--- a/arch/x86/kernel/cpu/match.c
|
||||
+++ b/arch/x86/kernel/cpu/match.c
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <asm/processor.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/module.h>
|
||||
+#include <linux/slab.h>
|
||||
|
||||
/**
|
||||
* x86_match_cpu - match current CPU again an array of x86_cpu_ids
|
||||
@@ -46,3 +47,46 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match)
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(x86_match_cpu);
|
||||
+
|
||||
+ssize_t arch_print_cpu_modalias(struct device *dev,
|
||||
+ struct device_attribute *attr,
|
||||
+ char *bufptr)
|
||||
+{
|
||||
+ int size = PAGE_SIZE;
|
||||
+ int i, n;
|
||||
+ char *buf = bufptr;
|
||||
+
|
||||
+ n = snprintf(buf, size, "x86cpu:vendor:%04X:family:%04X:"
|
||||
+ "model:%04X:feature:",
|
||||
+ boot_cpu_data.x86_vendor,
|
||||
+ boot_cpu_data.x86,
|
||||
+ boot_cpu_data.x86_model);
|
||||
+ size -= n;
|
||||
+ buf += n;
|
||||
+ size -= 2;
|
||||
+ for (i = 0; i < NCAPINTS*32; i++) {
|
||||
+ if (boot_cpu_has(i)) {
|
||||
+ n = snprintf(buf, size, ",%04X", i);
|
||||
+ if (n < 0) {
|
||||
+ WARN(1, "x86 features overflow page\n");
|
||||
+ break;
|
||||
+ }
|
||||
+ size -= n;
|
||||
+ buf += n;
|
||||
+ }
|
||||
+ }
|
||||
+ *buf++ = ',';
|
||||
+ *buf++ = '\n';
|
||||
+ return buf - bufptr;
|
||||
+}
|
||||
+
|
||||
+int arch_cpu_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
+{
|
||||
+ char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
+ if (buf) {
|
||||
+ arch_print_cpu_modalias(NULL, NULL, buf);
|
||||
+ add_uevent_var(env, "MODALIAS=%s", buf);
|
||||
+ kfree(buf);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c
|
||||
index 7c89880..a524353 100644
|
||||
--- a/arch/x86/kernel/cpuid.c
|
||||
+++ b/arch/x86/kernel/cpuid.c
|
||||
@@ -40,7 +40,6 @@
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/gfp.h>
|
||||
-#include <linux/slab.h>
|
||||
|
||||
#include <asm/processor.h>
|
||||
#include <asm/msr.h>
|
||||
@@ -139,57 +138,13 @@ static const struct file_operations cpuid_fops = {
|
||||
.open = cpuid_open,
|
||||
};
|
||||
|
||||
-static ssize_t print_cpu_modalias(struct device *dev,
|
||||
- struct device_attribute *attr,
|
||||
- char *bufptr)
|
||||
-{
|
||||
- int size = PAGE_SIZE;
|
||||
- int i, n;
|
||||
- char *buf = bufptr;
|
||||
-
|
||||
- n = snprintf(buf, size, "x86cpu:vendor:%04X:family:"
|
||||
- "%04X:model:%04X:feature:",
|
||||
- boot_cpu_data.x86_vendor,
|
||||
- boot_cpu_data.x86,
|
||||
- boot_cpu_data.x86_model);
|
||||
- size -= n;
|
||||
- buf += n;
|
||||
- size -= 2;
|
||||
- for (i = 0; i < NCAPINTS*32; i++) {
|
||||
- if (boot_cpu_has(i)) {
|
||||
- n = snprintf(buf, size, ",%04X", i);
|
||||
- if (n < 0) {
|
||||
- WARN(1, "x86 features overflow page\n");
|
||||
- break;
|
||||
- }
|
||||
- size -= n;
|
||||
- buf += n;
|
||||
- }
|
||||
- }
|
||||
- *buf++ = ',';
|
||||
- *buf++ = '\n';
|
||||
- return buf - bufptr;
|
||||
-}
|
||||
-
|
||||
-static DEVICE_ATTR(modalias, 0444, print_cpu_modalias, NULL);
|
||||
-
|
||||
static __cpuinit int cpuid_device_create(int cpu)
|
||||
{
|
||||
struct device *dev;
|
||||
- int err;
|
||||
|
||||
dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu), NULL,
|
||||
"cpu%d", cpu);
|
||||
- if (IS_ERR(dev))
|
||||
- return PTR_ERR(dev);
|
||||
-
|
||||
- err = device_create_file(dev, &dev_attr_modalias);
|
||||
- if (err) {
|
||||
- /* keep device around on error. attribute is optional. */
|
||||
- err = 0;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
+ return IS_ERR(dev) ? PTR_ERR(dev) : 0;
|
||||
}
|
||||
|
||||
static void cpuid_device_destroy(int cpu)
|
||||
@@ -227,17 +182,6 @@ static char *cpuid_devnode(struct device *dev, umode_t *mode)
|
||||
return kasprintf(GFP_KERNEL, "cpu/%u/cpuid", MINOR(dev->devt));
|
||||
}
|
||||
|
||||
-static int cpuid_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
-{
|
||||
- char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
- if (buf) {
|
||||
- print_cpu_modalias(NULL, NULL, buf);
|
||||
- add_uevent_var(env, "MODALIAS=%s", buf);
|
||||
- kfree(buf);
|
||||
- }
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
static int __init cpuid_init(void)
|
||||
{
|
||||
int i, err = 0;
|
||||
@@ -256,7 +200,6 @@ static int __init cpuid_init(void)
|
||||
goto out_chrdev;
|
||||
}
|
||||
cpuid_class->devnode = cpuid_devnode;
|
||||
- cpuid_class->dev_uevent = cpuid_dev_uevent;
|
||||
for_each_online_cpu(i) {
|
||||
err = cpuid_device_create(i);
|
||||
if (err != 0)
|
||||
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
|
||||
index db87e78..2a0c670 100644
|
||||
--- a/drivers/base/cpu.c
|
||||
+++ b/drivers/base/cpu.c
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/node.h>
|
||||
#include <linux/gfp.h>
|
||||
+#include <linux/slab.h>
|
||||
#include <linux/percpu.h>
|
||||
|
||||
#include "base.h"
|
||||
@@ -223,6 +224,9 @@ int __cpuinit register_cpu(struct cpu *cpu, int num)
|
||||
cpu->node_id = cpu_to_node(num);
|
||||
cpu->dev.id = num;
|
||||
cpu->dev.bus = &cpu_subsys;
|
||||
+#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
|
||||
+ cpu->dev.bus->uevent = arch_cpu_uevent;
|
||||
+#endif
|
||||
error = device_register(&cpu->dev);
|
||||
if (!error && cpu->hotpluggable)
|
||||
register_cpu_control(cpu);
|
||||
@@ -247,6 +251,10 @@ struct device *get_cpu_device(unsigned cpu)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(get_cpu_device);
|
||||
|
||||
+#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
|
||||
+static DEVICE_ATTR(modalias, 0444, arch_print_cpu_modalias, NULL);
|
||||
+#endif
|
||||
+
|
||||
static struct attribute *cpu_root_attrs[] = {
|
||||
#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
|
||||
&dev_attr_probe.attr,
|
||||
@@ -257,6 +265,9 @@ static struct attribute *cpu_root_attrs[] = {
|
||||
&cpu_attrs[2].attr.attr,
|
||||
&dev_attr_kernel_max.attr,
|
||||
&dev_attr_offline.attr,
|
||||
+#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
|
||||
+ &dev_attr_modalias.attr,
|
||||
+#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
|
||||
index 1f65875..6e53b48 100644
|
||||
--- a/include/linux/cpu.h
|
||||
+++ b/include/linux/cpu.h
|
||||
@@ -44,6 +44,13 @@ extern ssize_t arch_cpu_release(const char *, size_t);
|
||||
#endif
|
||||
struct notifier_block;
|
||||
|
||||
+#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
|
||||
+extern int arch_cpu_uevent(struct device *dev, struct kobj_uevent_env *env);
|
||||
+extern ssize_t arch_print_cpu_modalias(struct device *dev,
|
||||
+ struct device_attribute *attr,
|
||||
+ char *bufptr);
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* CPU notifier priorities.
|
||||
*/
|
59
debian/patches/features/all/cpu-devices/HWMON-Convert-coretemp-to-x86-cpuid-autoprobing.patch
vendored
Normal file
59
debian/patches/features/all/cpu-devices/HWMON-Convert-coretemp-to-x86-cpuid-autoprobing.patch
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
From: Andi Kleen <ak@linux.intel.com>
|
||||
Date: Thu, 26 Jan 2012 00:09:10 +0100
|
||||
Subject: HWMON: Convert coretemp to x86 cpuid autoprobing
|
||||
|
||||
commit 9b38096fde5f9b93c3657911c3be7892cc155cbd upstream.
|
||||
|
||||
Use the new x86 cpuid autoprobe interface for the Intel coretemp
|
||||
driver.
|
||||
|
||||
Cc: Fenghua Yu <fenghua.yu@intel.com>
|
||||
Cc: Jean Delvare <khali@linux-fr.org>
|
||||
Cc: Guenter Roeck <guenter.roeck@ericsson.com>
|
||||
Signed-off-by: Andi Kleen <ak@linux.intel.com>
|
||||
Signed-off-by: Thomas Renninger <trenn@suse.de>
|
||||
Acked-by: H. Peter Anvin <hpa@zytor.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/hwmon/coretemp.c | 17 ++++++++++++++---
|
||||
1 file changed, 14 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
|
||||
index a6c6ec3..249ac46 100644
|
||||
--- a/drivers/hwmon/coretemp.c
|
||||
+++ b/drivers/hwmon/coretemp.c
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <linux/moduleparam.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/processor.h>
|
||||
+#include <asm/cpu_device_id.h>
|
||||
|
||||
#define DRVNAME "coretemp"
|
||||
|
||||
@@ -759,13 +760,23 @@ static struct notifier_block coretemp_cpu_notifier __refdata = {
|
||||
.notifier_call = coretemp_cpu_callback,
|
||||
};
|
||||
|
||||
+static const struct x86_cpu_id coretemp_ids[] = {
|
||||
+ { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTS },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(x86cpu, coretemp_ids);
|
||||
+
|
||||
static int __init coretemp_init(void)
|
||||
{
|
||||
int i, err = -ENODEV;
|
||||
|
||||
- /* quick check if we run Intel */
|
||||
- if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL)
|
||||
- goto exit;
|
||||
+ /*
|
||||
+ * CPUID.06H.EAX[0] indicates whether the CPU has thermal
|
||||
+ * sensors. We check this bit only, all the early CPUs
|
||||
+ * without thermal sensors will be filtered out.
|
||||
+ */
|
||||
+ if (!x86_match_cpu(coretemp_ids))
|
||||
+ return -ENODEV;
|
||||
|
||||
err = platform_driver_register(&coretemp_driver);
|
||||
if (err)
|
56
debian/patches/features/all/cpu-devices/HWMON-Convert-via-cputemp-to-x86-cpuid-autoprobing.patch
vendored
Normal file
56
debian/patches/features/all/cpu-devices/HWMON-Convert-via-cputemp-to-x86-cpuid-autoprobing.patch
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
From: Andi Kleen <ak@linux.intel.com>
|
||||
Date: Thu, 26 Jan 2012 00:09:09 +0100
|
||||
Subject: HWMON: Convert via-cputemp to x86 cpuid autoprobing
|
||||
|
||||
commit 267fc9788d0cdb77edafb506063f06961e1418f5 upstream.
|
||||
|
||||
Use the new x86 cpuid autoprobe interface.
|
||||
|
||||
Cc: Jean Delvare <khali@linux-fr.org>
|
||||
Cc: Guenter Roeck <guenter.roeck@ericsson.com>
|
||||
Signed-off-by: Andi Kleen <ak@linux.intel.com>
|
||||
Signed-off-by: Thomas Renninger <trenn@suse.de>
|
||||
Acked-by: H. Peter Anvin <hpa@zytor.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/hwmon/via-cputemp.c | 16 +++++++++++-----
|
||||
1 file changed, 11 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c
|
||||
index 8eac67d..8689664 100644
|
||||
--- a/drivers/hwmon/via-cputemp.c
|
||||
+++ b/drivers/hwmon/via-cputemp.c
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <linux/cpu.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/processor.h>
|
||||
+#include <asm/cpu_device_id.h>
|
||||
|
||||
#define DRVNAME "via_cputemp"
|
||||
|
||||
@@ -308,15 +309,20 @@ static struct notifier_block via_cputemp_cpu_notifier __refdata = {
|
||||
.notifier_call = via_cputemp_cpu_callback,
|
||||
};
|
||||
|
||||
+static const struct x86_cpu_id cputemp_ids[] = {
|
||||
+ { X86_VENDOR_CENTAUR, 6, 0xa, }, /* C7 A */
|
||||
+ { X86_VENDOR_CENTAUR, 6, 0xd, }, /* C7 D */
|
||||
+ { X86_VENDOR_CENTAUR, 6, 0xf, }, /* Nano */
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(x86cpu, cputemp_ids);
|
||||
+
|
||||
static int __init via_cputemp_init(void)
|
||||
{
|
||||
int i, err;
|
||||
|
||||
- if (cpu_data(0).x86_vendor != X86_VENDOR_CENTAUR) {
|
||||
- printk(KERN_DEBUG DRVNAME ": Not a VIA CPU\n");
|
||||
- err = -ENODEV;
|
||||
- goto exit;
|
||||
- }
|
||||
+ if (!x86_match_cpu(cputemp_ids))
|
||||
+ return -ENODEV;
|
||||
|
||||
err = platform_driver_register(&via_cputemp_driver);
|
||||
if (err)
|
|
@ -0,0 +1,55 @@
|
|||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Mon, 18 Jun 2012 02:56:40 +0100
|
||||
Subject: Partially revert "cpufreq: Add support for x86 cpuinfo auto loading
|
||||
v4"
|
||||
|
||||
This reverts commit fa8031aefec0cf7ea6c2387c93610d99d9659aa2 in
|
||||
drivers/cpufreq/e_powersaver.c only.
|
||||
|
||||
e_powersaver may cause the CPU to run too fast on some systems, and is
|
||||
therefore unsafe to auto-load.
|
||||
---
|
||||
drivers/cpufreq/e_powersaver.c | 20 +++++++++-----------
|
||||
1 file changed, 9 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c
|
||||
index 3fffbe6..4bd6815 100644
|
||||
--- a/drivers/cpufreq/e_powersaver.c
|
||||
+++ b/drivers/cpufreq/e_powersaver.c
|
||||
@@ -16,7 +16,6 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
-#include <asm/cpu_device_id.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/tsc.h>
|
||||
|
||||
@@ -438,19 +437,18 @@ static struct cpufreq_driver eps_driver = {
|
||||
.attr = eps_attr,
|
||||
};
|
||||
|
||||
-
|
||||
-/* This driver will work only on Centaur C7 processors with
|
||||
- * Enhanced SpeedStep/PowerSaver registers */
|
||||
-static const struct x86_cpu_id eps_cpu_id[] = {
|
||||
- { X86_VENDOR_CENTAUR, 6, X86_MODEL_ANY, X86_FEATURE_EST },
|
||||
- {}
|
||||
-};
|
||||
-MODULE_DEVICE_TABLE(x86cpu, eps_cpu_id);
|
||||
-
|
||||
static int __init eps_init(void)
|
||||
{
|
||||
- if (!x86_match_cpu(eps_cpu_id) || boot_cpu_data.x86_model < 10)
|
||||
+ struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
+
|
||||
+ /* This driver will work only on Centaur C7 processors with
|
||||
+ * Enhanced SpeedStep/PowerSaver registers */
|
||||
+ if (c->x86_vendor != X86_VENDOR_CENTAUR
|
||||
+ || c->x86 != 6 || c->x86_model < 10)
|
||||
+ return -ENODEV;
|
||||
+ if (!cpu_has(c, X86_FEATURE_EST))
|
||||
return -ENODEV;
|
||||
+
|
||||
if (cpufreq_register_driver(&eps_driver))
|
||||
return -EINVAL;
|
||||
return 0;
|
48
debian/patches/features/all/cpu-devices/X86-Introduce-HW-Pstate-scattered-cpuid-feature.patch
vendored
Normal file
48
debian/patches/features/all/cpu-devices/X86-Introduce-HW-Pstate-scattered-cpuid-feature.patch
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
From: Thomas Renninger <trenn@suse.de>
|
||||
Date: Thu, 26 Jan 2012 00:09:11 +0100
|
||||
Subject: X86: Introduce HW-Pstate scattered cpuid feature
|
||||
|
||||
commit 2f1e097e24defe64a86535b53768f5c8ab0368d1 upstream.
|
||||
|
||||
It is rather similar to CPB (boot capability) feature
|
||||
and exists since fam10h (can be looked up in AMD's BKDG).
|
||||
|
||||
The feature is needed for powernow-k8 to cleanup init functions and to
|
||||
provide proper autoloading matching with the new x86cpu modalias
|
||||
feature.
|
||||
|
||||
Cc: Kay Sievers <kay.sievers@vrfy.org>
|
||||
Cc: Dave Jones <davej@redhat.com>
|
||||
Cc: Borislav Petkov <bp@amd64.org>
|
||||
Signed-off-by: Thomas Renninger <trenn@suse.de>
|
||||
Acked-by: H. Peter Anvin <hpa@zytor.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
arch/x86/include/asm/cpufeature.h | 1 +
|
||||
arch/x86/kernel/cpu/scattered.c | 1 +
|
||||
2 files changed, 2 insertions(+)
|
||||
|
||||
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
|
||||
index 17c5d4b..67b0910 100644
|
||||
--- a/arch/x86/include/asm/cpufeature.h
|
||||
+++ b/arch/x86/include/asm/cpufeature.h
|
||||
@@ -176,6 +176,7 @@
|
||||
#define X86_FEATURE_PLN (7*32+ 5) /* Intel Power Limit Notification */
|
||||
#define X86_FEATURE_PTS (7*32+ 6) /* Intel Package Thermal Status */
|
||||
#define X86_FEATURE_DTS (7*32+ 7) /* Digital Thermal Sensor */
|
||||
+#define X86_FEATURE_HW_PSTATE (7*32+ 8) /* AMD HW-PState */
|
||||
|
||||
/* Virtualization flags: Linux defined, word 8 */
|
||||
#define X86_FEATURE_TPR_SHADOW (8*32+ 0) /* Intel TPR Shadow */
|
||||
diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c
|
||||
index c7f64e6..addf9e8 100644
|
||||
--- a/arch/x86/kernel/cpu/scattered.c
|
||||
+++ b/arch/x86/kernel/cpu/scattered.c
|
||||
@@ -40,6 +40,7 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
|
||||
{ X86_FEATURE_EPB, CR_ECX, 3, 0x00000006, 0 },
|
||||
{ X86_FEATURE_XSAVEOPT, CR_EAX, 0, 0x0000000d, 1 },
|
||||
{ X86_FEATURE_CPB, CR_EDX, 9, 0x80000007, 0 },
|
||||
+ { X86_FEATURE_HW_PSTATE, CR_EDX, 7, 0x80000007, 0 },
|
||||
{ X86_FEATURE_NPT, CR_EDX, 0, 0x8000000a, 0 },
|
||||
{ X86_FEATURE_LBRV, CR_EDX, 1, 0x8000000a, 0 },
|
||||
{ X86_FEATURE_SVML, CR_EDX, 2, 0x8000000a, 0 },
|
|
@ -1,7 +1,6 @@
|
|||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
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 <ben@decadent.org.uk>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
[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 <torvalds@linux-foundation.org>
|
|||
--- 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 <linux/kernel.h>
|
||||
#include <linux/sysdev.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
@@ -247,17 +248,14 @@ bool cpu_is_hotpluggable(unsigned cpu)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(get_cpu_sysdev);
|
||||
#include <linux/sched.h>
|
||||
@@ -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[] = {
|
|
@ -1,7 +1,7 @@
|
|||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
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 <ben@decadent.org.uk>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
[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 <torvalds@linux-foundation.org>
|
|||
endmenu
|
||||
--- a/drivers/base/cpu.c
|
||||
+++ b/drivers/base/cpu.c
|
||||
@@ -12,6 +12,7 @@
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/node.h>
|
||||
#include <linux/gfp.h>
|
||||
|
@ -120,9 +131,9 @@ Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
|||
|
||||
#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 <torvalds@linux-foundation.org>
|
|||
+
|
||||
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
|
4365
debian/patches/features/all/cpu-devices/cpu-convert-cpu-and-machinecheck-sysdev_class-to-a-r.patch
vendored
Normal file
4365
debian/patches/features/all/cpu-devices/cpu-convert-cpu-and-machinecheck-sysdev_class-to-a-r.patch
vendored
Normal file
File diff suppressed because it is too large
Load Diff
596
debian/patches/features/all/cpu-devices/cpufreq-Add-support-for-x86-cpuinfo-auto-loading-v4.patch
vendored
Normal file
596
debian/patches/features/all/cpu-devices/cpufreq-Add-support-for-x86-cpuinfo-auto-loading-v4.patch
vendored
Normal file
|
@ -0,0 +1,596 @@
|
|||
From: Andi Kleen <ak@linux.intel.com>
|
||||
Date: Thu, 26 Jan 2012 00:09:12 +0100
|
||||
Subject: cpufreq: Add support for x86 cpuinfo auto loading v4
|
||||
|
||||
commit fa8031aefec0cf7ea6c2387c93610d99d9659aa2 upstream.
|
||||
|
||||
This marks all the x86 cpuinfo tables to the CPU specific device drivers,
|
||||
to allow auto loading by udev. This should simplify the distribution
|
||||
startup scripts for this greatly.
|
||||
|
||||
I didn't add MODULE_DEVICE_IDs to the centrino and p4-clockmod drivers,
|
||||
because those probably shouldn't be auto loaded and the acpi driver
|
||||
be used instead (not fully sure on that, would appreciate feedback)
|
||||
|
||||
The old nforce drivers autoload based on the PCI ID.
|
||||
|
||||
ACPI cpufreq is autoloaded in another patch.
|
||||
|
||||
v3: Autoload gx based on PCI IDs only. Remove cpu check (Dave Jones)
|
||||
v4: Use newly introduce HW_PSTATE feature for powernow-k8 loading
|
||||
|
||||
Cc: Dave Jones <davej@redhat.com>
|
||||
Cc: Kay Sievers <kay.sievers@vrfy.org>
|
||||
Signed-off-by: Andi Kleen <ak@linux.intel.com>
|
||||
Signed-off-by: Thomas Renninger <trenn@suse.de>
|
||||
Acked-by: H. Peter Anvin <hpa@zytor.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/cpufreq/cpufreq-nforce2.c | 8 ++++++++
|
||||
drivers/cpufreq/e_powersaver.c | 20 +++++++++++---------
|
||||
drivers/cpufreq/elanfreq.c | 14 +++++++-------
|
||||
drivers/cpufreq/gx-suspmod.c | 9 ++-------
|
||||
drivers/cpufreq/longhaul.c | 8 +++++++-
|
||||
drivers/cpufreq/longrun.c | 13 ++++++++-----
|
||||
drivers/cpufreq/p4-clockmod.c | 17 +++++++++++------
|
||||
drivers/cpufreq/powernow-k6.c | 12 ++++++++----
|
||||
drivers/cpufreq/powernow-k7.c | 14 ++++++++------
|
||||
drivers/cpufreq/powernow-k8.c | 19 +++++++++++++------
|
||||
drivers/cpufreq/sc520_freq.c | 14 ++++++++------
|
||||
drivers/cpufreq/speedstep-centrino.c | 24 ++++++++++++++++++++----
|
||||
drivers/cpufreq/speedstep-ich.c | 15 +++++++++++++++
|
||||
drivers/cpufreq/speedstep-lib.c | 1 +
|
||||
drivers/cpufreq/speedstep-smi.c | 15 +++++++++++++++
|
||||
15 files changed, 142 insertions(+), 61 deletions(-)
|
||||
|
||||
diff --git a/drivers/cpufreq/cpufreq-nforce2.c b/drivers/cpufreq/cpufreq-nforce2.c
|
||||
index 7bac808..13d311e 100644
|
||||
--- a/drivers/cpufreq/cpufreq-nforce2.c
|
||||
+++ b/drivers/cpufreq/cpufreq-nforce2.c
|
||||
@@ -385,6 +385,14 @@ static struct cpufreq_driver nforce2_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
+#ifdef MODULE
|
||||
+static DEFINE_PCI_DEVICE_TABLE(nforce2_ids) = {
|
||||
+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2 },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(pci, nforce2_ids);
|
||||
+#endif
|
||||
+
|
||||
/**
|
||||
* nforce2_detect_chipset - detect the Southbridge which contains FSB PLL logic
|
||||
*
|
||||
diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c
|
||||
index 4bd6815..3fffbe6 100644
|
||||
--- a/drivers/cpufreq/e_powersaver.c
|
||||
+++ b/drivers/cpufreq/e_powersaver.c
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
+#include <asm/cpu_device_id.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/tsc.h>
|
||||
|
||||
@@ -437,18 +438,19 @@ static struct cpufreq_driver eps_driver = {
|
||||
.attr = eps_attr,
|
||||
};
|
||||
|
||||
+
|
||||
+/* This driver will work only on Centaur C7 processors with
|
||||
+ * Enhanced SpeedStep/PowerSaver registers */
|
||||
+static const struct x86_cpu_id eps_cpu_id[] = {
|
||||
+ { X86_VENDOR_CENTAUR, 6, X86_MODEL_ANY, X86_FEATURE_EST },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(x86cpu, eps_cpu_id);
|
||||
+
|
||||
static int __init eps_init(void)
|
||||
{
|
||||
- struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
-
|
||||
- /* This driver will work only on Centaur C7 processors with
|
||||
- * Enhanced SpeedStep/PowerSaver registers */
|
||||
- if (c->x86_vendor != X86_VENDOR_CENTAUR
|
||||
- || c->x86 != 6 || c->x86_model < 10)
|
||||
- return -ENODEV;
|
||||
- if (!cpu_has(c, X86_FEATURE_EST))
|
||||
+ if (!x86_match_cpu(eps_cpu_id) || boot_cpu_data.x86_model < 10)
|
||||
return -ENODEV;
|
||||
-
|
||||
if (cpufreq_register_driver(&eps_driver))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
diff --git a/drivers/cpufreq/elanfreq.c b/drivers/cpufreq/elanfreq.c
|
||||
index c587db4..960671f 100644
|
||||
--- a/drivers/cpufreq/elanfreq.c
|
||||
+++ b/drivers/cpufreq/elanfreq.c
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/cpufreq.h>
|
||||
|
||||
+#include <asm/cpu_device_id.h>
|
||||
#include <asm/msr.h>
|
||||
#include <linux/timex.h>
|
||||
#include <linux/io.h>
|
||||
@@ -277,17 +278,16 @@ static struct cpufreq_driver elanfreq_driver = {
|
||||
.attr = elanfreq_attr,
|
||||
};
|
||||
|
||||
+static const struct x86_cpu_id elan_id[] = {
|
||||
+ { X86_VENDOR_AMD, 4, 10, },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(x86cpu, elan_id);
|
||||
|
||||
static int __init elanfreq_init(void)
|
||||
{
|
||||
- struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
-
|
||||
- /* Test if we have the right hardware */
|
||||
- if ((c->x86_vendor != X86_VENDOR_AMD) ||
|
||||
- (c->x86 != 4) || (c->x86_model != 10)) {
|
||||
- printk(KERN_INFO "elanfreq: error: no Elan processor found!\n");
|
||||
+ if (!x86_match_cpu(elan_id))
|
||||
return -ENODEV;
|
||||
- }
|
||||
return cpufreq_register_driver(&elanfreq_driver);
|
||||
}
|
||||
|
||||
diff --git a/drivers/cpufreq/gx-suspmod.c b/drivers/cpufreq/gx-suspmod.c
|
||||
index ffe1f2c..5a06c0b 100644
|
||||
--- a/drivers/cpufreq/gx-suspmod.c
|
||||
+++ b/drivers/cpufreq/gx-suspmod.c
|
||||
@@ -82,6 +82,7 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
+#include <asm/cpu_device_id.h>
|
||||
#include <asm/processor-cyrix.h>
|
||||
|
||||
/* PCI config registers, all at F0 */
|
||||
@@ -171,6 +172,7 @@ static struct pci_device_id gx_chipset_tbl[] __initdata = {
|
||||
{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), },
|
||||
{ 0, },
|
||||
};
|
||||
+MODULE_DEVICE_TABLE(gx_chipset_tbl);
|
||||
|
||||
static void gx_write_byte(int reg, int value)
|
||||
{
|
||||
@@ -185,13 +187,6 @@ static __init struct pci_dev *gx_detect_chipset(void)
|
||||
{
|
||||
struct pci_dev *gx_pci = NULL;
|
||||
|
||||
- /* check if CPU is a MediaGX or a Geode. */
|
||||
- if ((boot_cpu_data.x86_vendor != X86_VENDOR_NSC) &&
|
||||
- (boot_cpu_data.x86_vendor != X86_VENDOR_CYRIX)) {
|
||||
- pr_debug("error: no MediaGX/Geode processor found!\n");
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
/* detect which companion chip is used */
|
||||
for_each_pci_dev(gx_pci) {
|
||||
if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL)
|
||||
diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c
|
||||
index f47d26e..53ddbc7 100644
|
||||
--- a/drivers/cpufreq/longhaul.c
|
||||
+++ b/drivers/cpufreq/longhaul.c
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <linux/acpi.h>
|
||||
|
||||
#include <asm/msr.h>
|
||||
+#include <asm/cpu_device_id.h>
|
||||
#include <acpi/processor.h>
|
||||
|
||||
#include "longhaul.h"
|
||||
@@ -951,12 +952,17 @@ static struct cpufreq_driver longhaul_driver = {
|
||||
.attr = longhaul_attr,
|
||||
};
|
||||
|
||||
+static const struct x86_cpu_id longhaul_id[] = {
|
||||
+ { X86_VENDOR_CENTAUR, 6 },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(x86cpu, longhaul_id);
|
||||
|
||||
static int __init longhaul_init(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
|
||||
- if (c->x86_vendor != X86_VENDOR_CENTAUR || c->x86 != 6)
|
||||
+ if (!x86_match_cpu(longhaul_id))
|
||||
return -ENODEV;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
diff --git a/drivers/cpufreq/longrun.c b/drivers/cpufreq/longrun.c
|
||||
index 34ea359..8bc9f5f 100644
|
||||
--- a/drivers/cpufreq/longrun.c
|
||||
+++ b/drivers/cpufreq/longrun.c
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <asm/msr.h>
|
||||
#include <asm/processor.h>
|
||||
+#include <asm/cpu_device_id.h>
|
||||
|
||||
static struct cpufreq_driver longrun_driver;
|
||||
|
||||
@@ -288,6 +289,12 @@ static struct cpufreq_driver longrun_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
+static const struct x86_cpu_id longrun_ids[] = {
|
||||
+ { X86_VENDOR_TRANSMETA, X86_FAMILY_ANY, X86_MODEL_ANY,
|
||||
+ X86_FEATURE_LONGRUN },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(x86cpu, longrun_ids);
|
||||
|
||||
/**
|
||||
* longrun_init - initializes the Transmeta Crusoe LongRun CPUFreq driver
|
||||
@@ -296,12 +303,8 @@ static struct cpufreq_driver longrun_driver = {
|
||||
*/
|
||||
static int __init longrun_init(void)
|
||||
{
|
||||
- struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
-
|
||||
- if (c->x86_vendor != X86_VENDOR_TRANSMETA ||
|
||||
- !cpu_has(c, X86_FEATURE_LONGRUN))
|
||||
+ if (!x86_match_cpu(longrun_ids))
|
||||
return -ENODEV;
|
||||
-
|
||||
return cpufreq_register_driver(&longrun_driver);
|
||||
}
|
||||
|
||||
diff --git a/drivers/cpufreq/p4-clockmod.c b/drivers/cpufreq/p4-clockmod.c
|
||||
index 6be3e07..827629c9 100644
|
||||
--- a/drivers/cpufreq/p4-clockmod.c
|
||||
+++ b/drivers/cpufreq/p4-clockmod.c
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <asm/processor.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/timer.h>
|
||||
+#include <asm/cpu_device_id.h>
|
||||
|
||||
#include "speedstep-lib.h"
|
||||
|
||||
@@ -289,21 +290,25 @@ static struct cpufreq_driver p4clockmod_driver = {
|
||||
.attr = p4clockmod_attr,
|
||||
};
|
||||
|
||||
+static const struct x86_cpu_id cpufreq_p4_id[] = {
|
||||
+ { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_ACC },
|
||||
+ {}
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * Intentionally no MODULE_DEVICE_TABLE here: this driver should not
|
||||
+ * be auto loaded. Please don't add one.
|
||||
+ */
|
||||
|
||||
static int __init cpufreq_p4_init(void)
|
||||
{
|
||||
- struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* THERM_CONTROL is architectural for IA32 now, so
|
||||
* we can rely on the capability checks
|
||||
*/
|
||||
- if (c->x86_vendor != X86_VENDOR_INTEL)
|
||||
- return -ENODEV;
|
||||
-
|
||||
- if (!test_cpu_cap(c, X86_FEATURE_ACPI) ||
|
||||
- !test_cpu_cap(c, X86_FEATURE_ACC))
|
||||
+ if (!x86_match_cpu(cpufreq_p4_id) || !boot_cpu_has(X86_FEATURE_ACPI))
|
||||
return -ENODEV;
|
||||
|
||||
ret = cpufreq_register_driver(&p4clockmod_driver);
|
||||
diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c
|
||||
index b3379d6..54dd031 100644
|
||||
--- a/drivers/cpufreq/powernow-k6.c
|
||||
+++ b/drivers/cpufreq/powernow-k6.c
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <linux/timex.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
+#include <asm/cpu_device_id.h>
|
||||
#include <asm/msr.h>
|
||||
|
||||
#define POWERNOW_IOPORT 0xfff0 /* it doesn't matter where, as long
|
||||
@@ -210,6 +211,12 @@ static struct cpufreq_driver powernow_k6_driver = {
|
||||
.attr = powernow_k6_attr,
|
||||
};
|
||||
|
||||
+static const struct x86_cpu_id powernow_k6_ids[] = {
|
||||
+ { X86_VENDOR_AMD, 5, 12 },
|
||||
+ { X86_VENDOR_AMD, 5, 13 },
|
||||
+ {}
|
||||
+};
|
||||
+
|
||||
|
||||
/**
|
||||
* powernow_k6_init - initializes the k6 PowerNow! CPUFreq driver
|
||||
@@ -220,10 +227,7 @@ static struct cpufreq_driver powernow_k6_driver = {
|
||||
*/
|
||||
static int __init powernow_k6_init(void)
|
||||
{
|
||||
- struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
-
|
||||
- if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) ||
|
||||
- ((c->x86_model != 12) && (c->x86_model != 13)))
|
||||
+ if (!x86_match_cpu(powernow_k6_ids))
|
||||
return -ENODEV;
|
||||
|
||||
if (!request_region(POWERNOW_IOPORT, 16, "PowerNow!")) {
|
||||
diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c
|
||||
index d71d9f3..501d167 100644
|
||||
--- a/drivers/cpufreq/powernow-k7.c
|
||||
+++ b/drivers/cpufreq/powernow-k7.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <asm/timer.h> /* Needed for recalibrate_cpu_khz() */
|
||||
#include <asm/msr.h>
|
||||
#include <asm/system.h>
|
||||
+#include <asm/cpu_device_id.h>
|
||||
|
||||
#ifdef CONFIG_X86_POWERNOW_K7_ACPI
|
||||
#include <linux/acpi.h>
|
||||
@@ -110,18 +111,19 @@ static int check_fsb(unsigned int fsbspeed)
|
||||
return delta < 5;
|
||||
}
|
||||
|
||||
+static const struct x86_cpu_id powernow_k7_cpuids[] = {
|
||||
+ { X86_VENDOR_AMD, 7, },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(x86cpu, powernow_k7_cpuids);
|
||||
+
|
||||
static int check_powernow(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
unsigned int maxei, eax, ebx, ecx, edx;
|
||||
|
||||
- if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 6)) {
|
||||
-#ifdef MODULE
|
||||
- printk(KERN_INFO PFX "This module only works with "
|
||||
- "AMD K7 CPUs\n");
|
||||
-#endif
|
||||
+ if (!x86_match_cpu(powernow_k7_cpuids))
|
||||
return 0;
|
||||
- }
|
||||
|
||||
/* Get maximum capabilities */
|
||||
maxei = cpuid_eax(0x80000000);
|
||||
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
|
||||
index 8f9b2ce..c0e8164 100644
|
||||
--- a/drivers/cpufreq/powernow-k8.c
|
||||
+++ b/drivers/cpufreq/powernow-k8.c
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/msr.h>
|
||||
+#include <asm/cpu_device_id.h>
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/mutex.h>
|
||||
@@ -520,6 +521,15 @@ static int core_voltage_post_transition(struct powernow_k8_data *data,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static const struct x86_cpu_id powernow_k8_ids[] = {
|
||||
+ /* IO based frequency switching */
|
||||
+ { X86_VENDOR_AMD, 0xf },
|
||||
+ /* MSR based frequency switching supported */
|
||||
+ X86_FEATURE_MATCH(X86_FEATURE_HW_PSTATE),
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(x86cpu, powernow_k8_ids);
|
||||
+
|
||||
static void check_supported_cpu(void *_rc)
|
||||
{
|
||||
u32 eax, ebx, ecx, edx;
|
||||
@@ -527,13 +537,7 @@ static void check_supported_cpu(void *_rc)
|
||||
|
||||
*rc = -ENODEV;
|
||||
|
||||
- if (__this_cpu_read(cpu_info.x86_vendor) != X86_VENDOR_AMD)
|
||||
- return;
|
||||
-
|
||||
eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
|
||||
- if (((eax & CPUID_XFAM) != CPUID_XFAM_K8) &&
|
||||
- ((eax & CPUID_XFAM) < CPUID_XFAM_10H))
|
||||
- return;
|
||||
|
||||
if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) {
|
||||
if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
|
||||
@@ -1553,6 +1557,9 @@ static int __cpuinit powernowk8_init(void)
|
||||
unsigned int i, supported_cpus = 0, cpu;
|
||||
int rv;
|
||||
|
||||
+ if (!x86_match_cpu(powernow_k8_ids))
|
||||
+ return -ENODEV;
|
||||
+
|
||||
for_each_online_cpu(i) {
|
||||
int rc;
|
||||
smp_call_function_single(i, check_supported_cpu, &rc, 1);
|
||||
diff --git a/drivers/cpufreq/sc520_freq.c b/drivers/cpufreq/sc520_freq.c
|
||||
index 1e205e6..e42e073 100644
|
||||
--- a/drivers/cpufreq/sc520_freq.c
|
||||
+++ b/drivers/cpufreq/sc520_freq.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <linux/timex.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
+#include <asm/cpu_device_id.h>
|
||||
#include <asm/msr.h>
|
||||
|
||||
#define MMCR_BASE 0xfffef000 /* The default base address */
|
||||
@@ -150,18 +151,19 @@ static struct cpufreq_driver sc520_freq_driver = {
|
||||
.attr = sc520_freq_attr,
|
||||
};
|
||||
|
||||
+static const struct x86_cpu_id sc520_ids[] = {
|
||||
+ { X86_VENDOR_AMD, 4, 9 },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(x86cpu, sc520_ids);
|
||||
|
||||
static int __init sc520_freq_init(void)
|
||||
{
|
||||
- struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
int err;
|
||||
|
||||
- /* Test if we have the right hardware */
|
||||
- if (c->x86_vendor != X86_VENDOR_AMD ||
|
||||
- c->x86 != 4 || c->x86_model != 9) {
|
||||
- pr_debug("no Elan SC520 processor found!\n");
|
||||
+ if (!x86_match_cpu(sc520_ids))
|
||||
return -ENODEV;
|
||||
- }
|
||||
+
|
||||
cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1);
|
||||
if (!cpuctl) {
|
||||
printk(KERN_ERR "sc520_freq: error: failed to remap memory\n");
|
||||
diff --git a/drivers/cpufreq/speedstep-centrino.c b/drivers/cpufreq/speedstep-centrino.c
|
||||
index 6ea3455..3a953d5 100644
|
||||
--- a/drivers/cpufreq/speedstep-centrino.c
|
||||
+++ b/drivers/cpufreq/speedstep-centrino.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <asm/msr.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/cpufeature.h>
|
||||
+#include <asm/cpu_device_id.h>
|
||||
|
||||
#define PFX "speedstep-centrino: "
|
||||
#define MAINTAINER "cpufreq@vger.kernel.org"
|
||||
@@ -595,6 +596,24 @@ static struct cpufreq_driver centrino_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * This doesn't replace the detailed checks above because
|
||||
+ * the generic CPU IDs don't have a way to match for steppings
|
||||
+ * or ASCII model IDs.
|
||||
+ */
|
||||
+static const struct x86_cpu_id centrino_ids[] = {
|
||||
+ { X86_VENDOR_INTEL, 6, 9, X86_FEATURE_EST },
|
||||
+ { X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST },
|
||||
+ { X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST },
|
||||
+ { X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST },
|
||||
+ { X86_VENDOR_INTEL, 15, 3, X86_FEATURE_EST },
|
||||
+ { X86_VENDOR_INTEL, 15, 4, X86_FEATURE_EST },
|
||||
+ {}
|
||||
+};
|
||||
+#if 0
|
||||
+/* Autoload or not? Do not for now. */
|
||||
+MODULE_DEVICE_TABLE(x86cpu, centrino_ids);
|
||||
+#endif
|
||||
|
||||
/**
|
||||
* centrino_init - initializes the Enhanced SpeedStep CPUFreq driver
|
||||
@@ -612,11 +631,8 @@ static struct cpufreq_driver centrino_driver = {
|
||||
*/
|
||||
static int __init centrino_init(void)
|
||||
{
|
||||
- struct cpuinfo_x86 *cpu = &cpu_data(0);
|
||||
-
|
||||
- if (!cpu_has(cpu, X86_FEATURE_EST))
|
||||
+ if (!x86_match_cpu(centrino_ids))
|
||||
return -ENODEV;
|
||||
-
|
||||
return cpufreq_register_driver(¢rino_driver);
|
||||
}
|
||||
|
||||
diff --git a/drivers/cpufreq/speedstep-ich.c b/drivers/cpufreq/speedstep-ich.c
|
||||
index a748ce7..7432b3a 100644
|
||||
--- a/drivers/cpufreq/speedstep-ich.c
|
||||
+++ b/drivers/cpufreq/speedstep-ich.c
|
||||
@@ -25,6 +25,8 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
+#include <asm/cpu_device_id.h>
|
||||
+
|
||||
#include "speedstep-lib.h"
|
||||
|
||||
|
||||
@@ -388,6 +390,16 @@ static struct cpufreq_driver speedstep_driver = {
|
||||
.attr = speedstep_attr,
|
||||
};
|
||||
|
||||
+static const struct x86_cpu_id ss_smi_ids[] = {
|
||||
+ { X86_VENDOR_INTEL, 6, 0xb, },
|
||||
+ { X86_VENDOR_INTEL, 6, 0x8, },
|
||||
+ { X86_VENDOR_INTEL, 15, 2 },
|
||||
+ {}
|
||||
+};
|
||||
+#if 0
|
||||
+/* Autoload or not? Do not for now. */
|
||||
+MODULE_DEVICE_TABLE(x86cpu, ss_smi_ids);
|
||||
+#endif
|
||||
|
||||
/**
|
||||
* speedstep_init - initializes the SpeedStep CPUFreq driver
|
||||
@@ -398,6 +410,9 @@ static struct cpufreq_driver speedstep_driver = {
|
||||
*/
|
||||
static int __init speedstep_init(void)
|
||||
{
|
||||
+ if (!x86_match_cpu(ss_smi_ids))
|
||||
+ return -ENODEV;
|
||||
+
|
||||
/* detect processor */
|
||||
speedstep_processor = speedstep_detect_processor();
|
||||
if (!speedstep_processor) {
|
||||
diff --git a/drivers/cpufreq/speedstep-lib.c b/drivers/cpufreq/speedstep-lib.c
|
||||
index 8af2d2f..7047821 100644
|
||||
--- a/drivers/cpufreq/speedstep-lib.c
|
||||
+++ b/drivers/cpufreq/speedstep-lib.c
|
||||
@@ -249,6 +249,7 @@ EXPORT_SYMBOL_GPL(speedstep_get_frequency);
|
||||
* DETECT SPEEDSTEP-CAPABLE PROCESSOR *
|
||||
*********************************************************************/
|
||||
|
||||
+/* Keep in sync with the x86_cpu_id tables in the different modules */
|
||||
unsigned int speedstep_detect_processor(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
diff --git a/drivers/cpufreq/speedstep-smi.c b/drivers/cpufreq/speedstep-smi.c
|
||||
index c76ead3..6a457fc 100644
|
||||
--- a/drivers/cpufreq/speedstep-smi.c
|
||||
+++ b/drivers/cpufreq/speedstep-smi.c
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/ist.h>
|
||||
+#include <asm/cpu_device_id.h>
|
||||
|
||||
#include "speedstep-lib.h"
|
||||
|
||||
@@ -379,6 +380,17 @@ static struct cpufreq_driver speedstep_driver = {
|
||||
.attr = speedstep_attr,
|
||||
};
|
||||
|
||||
+static const struct x86_cpu_id ss_smi_ids[] = {
|
||||
+ { X86_VENDOR_INTEL, 6, 0xb, },
|
||||
+ { X86_VENDOR_INTEL, 6, 0x8, },
|
||||
+ { X86_VENDOR_INTEL, 15, 2 },
|
||||
+ {}
|
||||
+};
|
||||
+#if 0
|
||||
+/* Not auto loaded currently */
|
||||
+MODULE_DEVICE_TABLE(x86cpu, ss_smi_ids);
|
||||
+#endif
|
||||
+
|
||||
/**
|
||||
* speedstep_init - initializes the SpeedStep CPUFreq driver
|
||||
*
|
||||
@@ -388,6 +400,9 @@ static struct cpufreq_driver speedstep_driver = {
|
||||
*/
|
||||
static int __init speedstep_init(void)
|
||||
{
|
||||
+ if (!x86_match_cpu(ss_smi_ids))
|
||||
+ return -ENODEV;
|
||||
+
|
||||
speedstep_processor = speedstep_detect_processor();
|
||||
|
||||
switch (speedstep_processor) {
|
215
debian/patches/features/all/cpu-devices/crypto-Add-support-for-x86-cpuid-auto-loading-for-x8.patch
vendored
Normal file
215
debian/patches/features/all/cpu-devices/crypto-Add-support-for-x86-cpuid-auto-loading-for-x8.patch
vendored
Normal file
|
@ -0,0 +1,215 @@
|
|||
From: Andi Kleen <ak@linux.intel.com>
|
||||
Date: Thu, 26 Jan 2012 00:09:06 +0100
|
||||
Subject: crypto: Add support for x86 cpuid auto loading for x86 crypto
|
||||
drivers
|
||||
|
||||
commit 3bd391f056df61e928de1680ff4a3e7e07e5b399 upstream.
|
||||
|
||||
Add support for auto-loading of crypto drivers based on cpuid features.
|
||||
This enables auto-loading of the VIA and Intel specific drivers
|
||||
for AES, hashing and CRCs.
|
||||
|
||||
Requires the earlier infrastructure patch to add x86 modinfo.
|
||||
I kept it all in a single patch for now.
|
||||
|
||||
I dropped the printks when the driver cpuid doesn't match (imho
|
||||
drivers never should print anything in such a case)
|
||||
|
||||
One drawback is that udev doesn't know if the drivers are used or not,
|
||||
so they will be unconditionally loaded at boot up. That's better
|
||||
than not loading them at all, like it often happens.
|
||||
|
||||
Cc: Dave Jones <davej@redhat.com>
|
||||
Cc: Kay Sievers <kay.sievers@vrfy.org>
|
||||
Cc: Jen Axboe <axboe@kernel.dk>
|
||||
Cc: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
Cc: Huang Ying <ying.huang@intel.com>
|
||||
Signed-off-by: Andi Kleen <ak@linux.intel.com>
|
||||
Signed-off-by: Thomas Renninger <trenn@suse.de>
|
||||
Acked-by: H. Peter Anvin <hpa@zytor.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
arch/x86/crypto/aesni-intel_glue.c | 12 +++++++++---
|
||||
arch/x86/crypto/crc32c-intel.c | 11 ++++++++---
|
||||
arch/x86/crypto/ghash-clmulni-intel_glue.c | 12 ++++++++----
|
||||
drivers/crypto/padlock-aes.c | 9 ++++++++-
|
||||
drivers/crypto/padlock-sha.c | 16 ++++++++--------
|
||||
5 files changed, 41 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
|
||||
index 545d0ce..b3350bd 100644
|
||||
--- a/arch/x86/crypto/aesni-intel_glue.c
|
||||
+++ b/arch/x86/crypto/aesni-intel_glue.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <crypto/aes.h>
|
||||
#include <crypto/cryptd.h>
|
||||
#include <crypto/ctr.h>
|
||||
+#include <asm/cpu_device_id.h>
|
||||
#include <asm/i387.h>
|
||||
#include <asm/aes.h>
|
||||
#include <crypto/scatterwalk.h>
|
||||
@@ -1253,14 +1254,19 @@ static struct crypto_alg __rfc4106_alg = {
|
||||
};
|
||||
#endif
|
||||
|
||||
+
|
||||
+static const struct x86_cpu_id aesni_cpu_id[] = {
|
||||
+ X86_FEATURE_MATCH(X86_FEATURE_AES),
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(x86cpu, aesni_cpu_id);
|
||||
+
|
||||
static int __init aesni_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
- if (!cpu_has_aes) {
|
||||
- printk(KERN_INFO "Intel AES-NI instructions are not detected.\n");
|
||||
+ if (!x86_match_cpu(aesni_cpu_id))
|
||||
return -ENODEV;
|
||||
- }
|
||||
|
||||
if ((err = crypto_fpu_init()))
|
||||
goto fpu_err;
|
||||
diff --git a/arch/x86/crypto/crc32c-intel.c b/arch/x86/crypto/crc32c-intel.c
|
||||
index b9d0026..493f959 100644
|
||||
--- a/arch/x86/crypto/crc32c-intel.c
|
||||
+++ b/arch/x86/crypto/crc32c-intel.c
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <crypto/internal/hash.h>
|
||||
|
||||
#include <asm/cpufeature.h>
|
||||
+#include <asm/cpu_device_id.h>
|
||||
|
||||
#define CHKSUM_BLOCK_SIZE 1
|
||||
#define CHKSUM_DIGEST_SIZE 4
|
||||
@@ -173,13 +174,17 @@ static struct shash_alg alg = {
|
||||
}
|
||||
};
|
||||
|
||||
+static const struct x86_cpu_id crc32c_cpu_id[] = {
|
||||
+ X86_FEATURE_MATCH(X86_FEATURE_XMM4_2),
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(x86cpu, crc32c_cpu_id);
|
||||
|
||||
static int __init crc32c_intel_mod_init(void)
|
||||
{
|
||||
- if (cpu_has_xmm4_2)
|
||||
- return crypto_register_shash(&alg);
|
||||
- else
|
||||
+ if (!x86_match_cpu(crc32c_cpu_id))
|
||||
return -ENODEV;
|
||||
+ return crypto_register_shash(&alg);
|
||||
}
|
||||
|
||||
static void __exit crc32c_intel_mod_fini(void)
|
||||
diff --git a/arch/x86/crypto/ghash-clmulni-intel_glue.c b/arch/x86/crypto/ghash-clmulni-intel_glue.c
|
||||
index 976aa64..b4bf0a6 100644
|
||||
--- a/arch/x86/crypto/ghash-clmulni-intel_glue.c
|
||||
+++ b/arch/x86/crypto/ghash-clmulni-intel_glue.c
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <crypto/gf128mul.h>
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <asm/i387.h>
|
||||
+#include <asm/cpu_device_id.h>
|
||||
|
||||
#define GHASH_BLOCK_SIZE 16
|
||||
#define GHASH_DIGEST_SIZE 16
|
||||
@@ -294,15 +295,18 @@ static struct ahash_alg ghash_async_alg = {
|
||||
},
|
||||
};
|
||||
|
||||
+static const struct x86_cpu_id pcmul_cpu_id[] = {
|
||||
+ X86_FEATURE_MATCH(X86_FEATURE_PCLMULQDQ), /* Pickle-Mickle-Duck */
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(x86cpu, pcmul_cpu_id);
|
||||
+
|
||||
static int __init ghash_pclmulqdqni_mod_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
- if (!cpu_has_pclmulqdq) {
|
||||
- printk(KERN_INFO "Intel PCLMULQDQ-NI instructions are not"
|
||||
- " detected.\n");
|
||||
+ if (!x86_match_cpu(pcmul_cpu_id))
|
||||
return -ENODEV;
|
||||
- }
|
||||
|
||||
err = crypto_register_shash(&ghash_alg);
|
||||
if (err)
|
||||
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c
|
||||
index 29b9469..37b2e94 100644
|
||||
--- a/drivers/crypto/padlock-aes.c
|
||||
+++ b/drivers/crypto/padlock-aes.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/slab.h>
|
||||
+#include <asm/cpu_device_id.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/i387.h>
|
||||
@@ -503,12 +504,18 @@ static struct crypto_alg cbc_aes_alg = {
|
||||
}
|
||||
};
|
||||
|
||||
+static struct x86_cpu_id padlock_cpu_id[] = {
|
||||
+ X86_FEATURE_MATCH(X86_FEATURE_XCRYPT),
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(x86cpu, padlock_cpu_id);
|
||||
+
|
||||
static int __init padlock_init(void)
|
||||
{
|
||||
int ret;
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
|
||||
- if (!cpu_has_xcrypt)
|
||||
+ if (!x86_match_cpu(padlock_cpu_id))
|
||||
return -ENODEV;
|
||||
|
||||
if (!cpu_has_xcrypt_enabled) {
|
||||
diff --git a/drivers/crypto/padlock-sha.c b/drivers/crypto/padlock-sha.c
|
||||
index 06bdb4b..9266c0e 100644
|
||||
--- a/drivers/crypto/padlock-sha.c
|
||||
+++ b/drivers/crypto/padlock-sha.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/scatterlist.h>
|
||||
+#include <asm/cpu_device_id.h>
|
||||
#include <asm/i387.h>
|
||||
|
||||
struct padlock_sha_desc {
|
||||
@@ -526,6 +527,12 @@ static struct shash_alg sha256_alg_nano = {
|
||||
}
|
||||
};
|
||||
|
||||
+static struct x86_cpu_id padlock_sha_ids[] = {
|
||||
+ X86_FEATURE_MATCH(X86_FEATURE_PHE),
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(x86cpu, padlock_sha_ids);
|
||||
+
|
||||
static int __init padlock_init(void)
|
||||
{
|
||||
int rc = -ENODEV;
|
||||
@@ -533,15 +540,8 @@ static int __init padlock_init(void)
|
||||
struct shash_alg *sha1;
|
||||
struct shash_alg *sha256;
|
||||
|
||||
- if (!cpu_has_phe) {
|
||||
- printk(KERN_NOTICE PFX "VIA PadLock Hash Engine not detected.\n");
|
||||
- return -ENODEV;
|
||||
- }
|
||||
-
|
||||
- if (!cpu_has_phe_enabled) {
|
||||
- printk(KERN_NOTICE PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n");
|
||||
+ if (!x86_match_cpu(padlock_sha_ids) || !cpu_has_phe_enabled)
|
||||
return -ENODEV;
|
||||
- }
|
||||
|
||||
/* Register the newly added algorithm module if on *
|
||||
* VIA Nano processor, or else just do as before */
|
|
@ -0,0 +1,31 @@
|
|||
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Date: Wed, 8 Feb 2012 15:11:17 -0800
|
||||
Subject: driver-core: cpu: fix kobject warning when hotplugging a cpu
|
||||
|
||||
commit 29bb5d4fd3140a7d5d02d858118c74a45f15c296 upstream.
|
||||
|
||||
Due to the sysdev conversion to struct device, the cpu objects get
|
||||
reused when adding a cpu after offlining it, which causes a big warning
|
||||
that the kobject portion is not properly initialized.
|
||||
|
||||
So clear out the object before we register it again, so all is quiet.
|
||||
|
||||
Reported-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
Tested-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/base/cpu.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
|
||||
index 23f2c4c..4dabf50 100644
|
||||
--- a/drivers/base/cpu.c
|
||||
+++ b/drivers/base/cpu.c
|
||||
@@ -240,6 +240,7 @@ int __cpuinit register_cpu(struct cpu *cpu, int num)
|
||||
int error;
|
||||
|
||||
cpu->node_id = cpu_to_node(num);
|
||||
+ memset(&cpu->dev, 0x00, sizeof(struct device));
|
||||
cpu->dev.id = num;
|
||||
cpu->dev.bus = &cpu_subsys;
|
||||
cpu->dev.release = cpu_device_release;
|
|
@ -0,0 +1,59 @@
|
|||
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Date: Thu, 2 Feb 2012 10:36:33 -0800
|
||||
Subject: driver core: cpu: remove kernel warning when removing a cpu
|
||||
|
||||
commit 2885e25c422fb68208f677f944a45fce8eda2a3c upstream.
|
||||
|
||||
With the movement of the cpu sysdev code to be real stuct devices, now
|
||||
when we remove a cpu from the system, the driver core rightfully
|
||||
complains that there is not a release method for this device.
|
||||
|
||||
For now, paper over this issue by quieting the driver core, but comment
|
||||
this in detail. This will be resolved in future kernels to be solved
|
||||
properly.
|
||||
|
||||
Reported-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
Tested-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
[bwh: Adjust context for textual conflict with commit
|
||||
fad12ac8c8c2591c7f4e61d19b6a9d76cd49fafa]
|
||||
---
|
||||
drivers/base/cpu.c | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
--- a/drivers/base/cpu.c
|
||||
+++ b/drivers/base/cpu.c
|
||||
@@ -209,6 +209,25 @@
|
||||
}
|
||||
static DEVICE_ATTR(offline, 0444, print_cpus_offline, NULL);
|
||||
|
||||
+static void cpu_device_release(struct device *dev)
|
||||
+{
|
||||
+ /*
|
||||
+ * This is an empty function to prevent the driver core from spitting a
|
||||
+ * warning at us. Yes, I know this is directly opposite of what the
|
||||
+ * documentation for the driver core and kobjects say, and the author
|
||||
+ * of this code has already been publically ridiculed for doing
|
||||
+ * something as foolish as this. However, at this point in time, it is
|
||||
+ * the only way to handle the issue of statically allocated cpu
|
||||
+ * devices. The different architectures will have their cpu device
|
||||
+ * code reworked to properly handle this in the near future, so this
|
||||
+ * function will then be changed to correctly free up the memory held
|
||||
+ * by the cpu device.
|
||||
+ *
|
||||
+ * Never copy this way of doing things, or you too will be made fun of
|
||||
+ * on the linux-kerenl list, you have been warned.
|
||||
+ */
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* register_cpu - Setup a sysfs device for a CPU.
|
||||
* @cpu - cpu->hotpluggable field set to 1 will generate a control file in
|
||||
@@ -224,6 +243,7 @@
|
||||
cpu->node_id = cpu_to_node(num);
|
||||
cpu->dev.id = num;
|
||||
cpu->dev.bus = &cpu_subsys;
|
||||
+ cpu->dev.release = cpu_device_release;
|
||||
#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
|
||||
cpu->dev.bus->uevent = arch_cpu_uevent;
|
||||
#endif
|
884
debian/patches/features/all/cpu-devices/driver-core-implement-sysdev-functionality-for-regul.patch
vendored
Normal file
884
debian/patches/features/all/cpu-devices/driver-core-implement-sysdev-functionality-for-regul.patch
vendored
Normal file
|
@ -0,0 +1,884 @@
|
|||
From: Kay Sievers <kay.sievers@vrfy.org>
|
||||
Date: Wed, 14 Dec 2011 14:29:38 -0800
|
||||
Subject: driver-core: implement 'sysdev' functionality for regular devices
|
||||
and buses
|
||||
|
||||
commit ca22e56debc57b47c422b749c93217ba62644be2 upstream.
|
||||
|
||||
All sysdev classes and sysdev devices will converted to regular devices
|
||||
and buses to properly hook userspace into the event processing.
|
||||
|
||||
There is no interesting difference between a 'sysdev' and 'device' which
|
||||
would justify to roll an entire own subsystem with different userspace
|
||||
export semantics. Userspace relies on events and generic sysfs subsystem
|
||||
infrastructure from sysdev devices, which are currently not properly
|
||||
available.
|
||||
|
||||
Every converted sysdev class will create a regular device with the class
|
||||
name in /sys/devices/system and all registered devices will becom a children
|
||||
of theses devices.
|
||||
|
||||
For compatibility reasons, the sysdev class-wide attributes are created
|
||||
at this parent device. (Do not copy that logic for anything new, subsystem-
|
||||
wide properties belong to the subsystem, not to some fake parent device
|
||||
created in /sys/devices.)
|
||||
|
||||
Every sysdev driver is implemented as a simple subsystem interface now,
|
||||
and no longer called a driver.
|
||||
|
||||
After all sysdev classes are ported to regular driver core entities, the
|
||||
sysdev implementation will be entirely removed from the kernel.
|
||||
|
||||
Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/base/base.h | 12 +-
|
||||
drivers/base/bus.c | 293 ++++++++++++++++++++++++++++++++++++++++++++----
|
||||
drivers/base/class.c | 14 +--
|
||||
drivers/base/core.c | 85 +++++++++++---
|
||||
drivers/base/init.c | 1 -
|
||||
drivers/base/sys.c | 10 +-
|
||||
include/linux/device.h | 78 ++++++++++++-
|
||||
7 files changed, 431 insertions(+), 62 deletions(-)
|
||||
|
||||
diff --git a/drivers/base/base.h b/drivers/base/base.h
|
||||
index 21c1b96..7a6ae42 100644
|
||||
--- a/drivers/base/base.h
|
||||
+++ b/drivers/base/base.h
|
||||
@@ -4,7 +4,9 @@
|
||||
* struct subsys_private - structure to hold the private to the driver core portions of the bus_type/class structure.
|
||||
*
|
||||
* @subsys - the struct kset that defines this subsystem
|
||||
- * @devices_kset - the list of devices associated
|
||||
+ * @devices_kset - the subsystem's 'devices' directory
|
||||
+ * @interfaces - list of subsystem interfaces associated
|
||||
+ * @mutex - protect the devices, and interfaces lists.
|
||||
*
|
||||
* @drivers_kset - the list of drivers associated
|
||||
* @klist_devices - the klist to iterate over the @devices_kset
|
||||
@@ -14,10 +16,8 @@
|
||||
* @bus - pointer back to the struct bus_type that this structure is associated
|
||||
* with.
|
||||
*
|
||||
- * @class_interfaces - list of class_interfaces associated
|
||||
* @glue_dirs - "glue" directory to put in-between the parent device to
|
||||
* avoid namespace conflicts
|
||||
- * @class_mutex - mutex to protect the children, devices, and interfaces lists.
|
||||
* @class - pointer back to the struct class that this structure is associated
|
||||
* with.
|
||||
*
|
||||
@@ -28,6 +28,8 @@
|
||||
struct subsys_private {
|
||||
struct kset subsys;
|
||||
struct kset *devices_kset;
|
||||
+ struct list_head interfaces;
|
||||
+ struct mutex mutex;
|
||||
|
||||
struct kset *drivers_kset;
|
||||
struct klist klist_devices;
|
||||
@@ -36,9 +38,7 @@ struct subsys_private {
|
||||
unsigned int drivers_autoprobe:1;
|
||||
struct bus_type *bus;
|
||||
|
||||
- struct list_head class_interfaces;
|
||||
struct kset glue_dirs;
|
||||
- struct mutex class_mutex;
|
||||
struct class *class;
|
||||
};
|
||||
#define to_subsys_private(obj) container_of(obj, struct subsys_private, subsys.kobj)
|
||||
@@ -94,7 +94,6 @@ extern int hypervisor_init(void);
|
||||
static inline int hypervisor_init(void) { return 0; }
|
||||
#endif
|
||||
extern int platform_bus_init(void);
|
||||
-extern int system_bus_init(void);
|
||||
extern int cpu_dev_init(void);
|
||||
|
||||
extern int bus_add_device(struct device *dev);
|
||||
@@ -116,6 +115,7 @@ extern char *make_class_name(const char *name, struct kobject *kobj);
|
||||
|
||||
extern int devres_release_all(struct device *dev);
|
||||
|
||||
+/* /sys/devices directory */
|
||||
extern struct kset *devices_kset;
|
||||
|
||||
#if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS)
|
||||
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
|
||||
index 000e7b2..99dc592 100644
|
||||
--- a/drivers/base/bus.c
|
||||
+++ b/drivers/base/bus.c
|
||||
@@ -16,9 +16,14 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/string.h>
|
||||
+#include <linux/mutex.h>
|
||||
#include "base.h"
|
||||
#include "power/power.h"
|
||||
|
||||
+/* /sys/devices/system */
|
||||
+/* FIXME: make static after drivers/base/sys.c is deleted */
|
||||
+struct kset *system_kset;
|
||||
+
|
||||
#define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr)
|
||||
|
||||
/*
|
||||
@@ -360,6 +365,47 @@ struct device *bus_find_device_by_name(struct bus_type *bus,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bus_find_device_by_name);
|
||||
|
||||
+/**
|
||||
+ * subsys_find_device_by_id - find a device with a specific enumeration number
|
||||
+ * @subsys: subsystem
|
||||
+ * @id: index 'id' in struct device
|
||||
+ * @hint: device to check first
|
||||
+ *
|
||||
+ * Check the hint's next object and if it is a match return it directly,
|
||||
+ * otherwise, fall back to a full list search. Either way a reference for
|
||||
+ * the returned object is taken.
|
||||
+ */
|
||||
+struct device *subsys_find_device_by_id(struct bus_type *subsys, unsigned int id,
|
||||
+ struct device *hint)
|
||||
+{
|
||||
+ struct klist_iter i;
|
||||
+ struct device *dev;
|
||||
+
|
||||
+ if (!subsys)
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (hint) {
|
||||
+ klist_iter_init_node(&subsys->p->klist_devices, &i, &hint->p->knode_bus);
|
||||
+ dev = next_device(&i);
|
||||
+ if (dev && dev->id == id && get_device(dev)) {
|
||||
+ klist_iter_exit(&i);
|
||||
+ return dev;
|
||||
+ }
|
||||
+ klist_iter_exit(&i);
|
||||
+ }
|
||||
+
|
||||
+ klist_iter_init_node(&subsys->p->klist_devices, &i, NULL);
|
||||
+ while ((dev = next_device(&i))) {
|
||||
+ if (dev->id == id && get_device(dev)) {
|
||||
+ klist_iter_exit(&i);
|
||||
+ return dev;
|
||||
+ }
|
||||
+ }
|
||||
+ klist_iter_exit(&i);
|
||||
+ return NULL;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(subsys_find_device_by_id);
|
||||
+
|
||||
static struct device_driver *next_driver(struct klist_iter *i)
|
||||
{
|
||||
struct klist_node *n = klist_next(i);
|
||||
@@ -487,38 +533,59 @@ out_put:
|
||||
void bus_probe_device(struct device *dev)
|
||||
{
|
||||
struct bus_type *bus = dev->bus;
|
||||
+ struct subsys_interface *sif;
|
||||
int ret;
|
||||
|
||||
- if (bus && bus->p->drivers_autoprobe) {
|
||||
+ if (!bus)
|
||||
+ return;
|
||||
+
|
||||
+ if (bus->p->drivers_autoprobe) {
|
||||
ret = device_attach(dev);
|
||||
WARN_ON(ret < 0);
|
||||
}
|
||||
+
|
||||
+ mutex_lock(&bus->p->mutex);
|
||||
+ list_for_each_entry(sif, &bus->p->interfaces, node)
|
||||
+ if (sif->add_dev)
|
||||
+ sif->add_dev(dev, sif);
|
||||
+ mutex_unlock(&bus->p->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* bus_remove_device - remove device from bus
|
||||
* @dev: device to be removed
|
||||
*
|
||||
- * - Remove symlink from bus's directory.
|
||||
+ * - Remove device from all interfaces.
|
||||
+ * - Remove symlink from bus' directory.
|
||||
* - Delete device from bus's list.
|
||||
* - Detach from its driver.
|
||||
* - Drop reference taken in bus_add_device().
|
||||
*/
|
||||
void bus_remove_device(struct device *dev)
|
||||
{
|
||||
- if (dev->bus) {
|
||||
- sysfs_remove_link(&dev->kobj, "subsystem");
|
||||
- sysfs_remove_link(&dev->bus->p->devices_kset->kobj,
|
||||
- dev_name(dev));
|
||||
- device_remove_attrs(dev->bus, dev);
|
||||
- if (klist_node_attached(&dev->p->knode_bus))
|
||||
- klist_del(&dev->p->knode_bus);
|
||||
-
|
||||
- pr_debug("bus: '%s': remove device %s\n",
|
||||
- dev->bus->name, dev_name(dev));
|
||||
- device_release_driver(dev);
|
||||
- bus_put(dev->bus);
|
||||
- }
|
||||
+ struct bus_type *bus = dev->bus;
|
||||
+ struct subsys_interface *sif;
|
||||
+
|
||||
+ if (!bus)
|
||||
+ return;
|
||||
+
|
||||
+ mutex_lock(&bus->p->mutex);
|
||||
+ list_for_each_entry(sif, &bus->p->interfaces, node)
|
||||
+ if (sif->remove_dev)
|
||||
+ sif->remove_dev(dev, sif);
|
||||
+ mutex_unlock(&bus->p->mutex);
|
||||
+
|
||||
+ sysfs_remove_link(&dev->kobj, "subsystem");
|
||||
+ sysfs_remove_link(&dev->bus->p->devices_kset->kobj,
|
||||
+ dev_name(dev));
|
||||
+ device_remove_attrs(dev->bus, dev);
|
||||
+ if (klist_node_attached(&dev->p->knode_bus))
|
||||
+ klist_del(&dev->p->knode_bus);
|
||||
+
|
||||
+ pr_debug("bus: '%s': remove device %s\n",
|
||||
+ dev->bus->name, dev_name(dev));
|
||||
+ device_release_driver(dev);
|
||||
+ bus_put(dev->bus);
|
||||
}
|
||||
|
||||
static int driver_add_attrs(struct bus_type *bus, struct device_driver *drv)
|
||||
@@ -847,14 +914,14 @@ static ssize_t bus_uevent_store(struct bus_type *bus,
|
||||
static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store);
|
||||
|
||||
/**
|
||||
- * bus_register - register a bus with the system.
|
||||
+ * __bus_register - register a driver-core subsystem
|
||||
* @bus: bus.
|
||||
*
|
||||
* Once we have that, we registered the bus with the kobject
|
||||
* infrastructure, then register the children subsystems it has:
|
||||
- * the devices and drivers that belong to the bus.
|
||||
+ * the devices and drivers that belong to the subsystem.
|
||||
*/
|
||||
-int bus_register(struct bus_type *bus)
|
||||
+int __bus_register(struct bus_type *bus, struct lock_class_key *key)
|
||||
{
|
||||
int retval;
|
||||
struct subsys_private *priv;
|
||||
@@ -898,6 +965,8 @@ int bus_register(struct bus_type *bus)
|
||||
goto bus_drivers_fail;
|
||||
}
|
||||
|
||||
+ INIT_LIST_HEAD(&priv->interfaces);
|
||||
+ __mutex_init(&priv->mutex, "subsys mutex", key);
|
||||
klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);
|
||||
klist_init(&priv->klist_drivers, NULL, NULL);
|
||||
|
||||
@@ -927,7 +996,7 @@ out:
|
||||
bus->p = NULL;
|
||||
return retval;
|
||||
}
|
||||
-EXPORT_SYMBOL_GPL(bus_register);
|
||||
+EXPORT_SYMBOL_GPL(__bus_register);
|
||||
|
||||
/**
|
||||
* bus_unregister - remove a bus from the system
|
||||
@@ -939,6 +1008,8 @@ EXPORT_SYMBOL_GPL(bus_register);
|
||||
void bus_unregister(struct bus_type *bus)
|
||||
{
|
||||
pr_debug("bus: '%s': unregistering\n", bus->name);
|
||||
+ if (bus->dev_root)
|
||||
+ device_unregister(bus->dev_root);
|
||||
bus_remove_attrs(bus);
|
||||
remove_probe_files(bus);
|
||||
kset_unregister(bus->p->drivers_kset);
|
||||
@@ -1028,10 +1099,194 @@ void bus_sort_breadthfirst(struct bus_type *bus,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bus_sort_breadthfirst);
|
||||
|
||||
+/**
|
||||
+ * subsys_dev_iter_init - initialize subsys device iterator
|
||||
+ * @iter: subsys iterator to initialize
|
||||
+ * @subsys: the subsys we wanna iterate over
|
||||
+ * @start: the device to start iterating from, if any
|
||||
+ * @type: device_type of the devices to iterate over, NULL for all
|
||||
+ *
|
||||
+ * Initialize subsys iterator @iter such that it iterates over devices
|
||||
+ * of @subsys. If @start is set, the list iteration will start there,
|
||||
+ * otherwise if it is NULL, the iteration starts at the beginning of
|
||||
+ * the list.
|
||||
+ */
|
||||
+void subsys_dev_iter_init(struct subsys_dev_iter *iter, struct bus_type *subsys,
|
||||
+ struct device *start, const struct device_type *type)
|
||||
+{
|
||||
+ struct klist_node *start_knode = NULL;
|
||||
+
|
||||
+ if (start)
|
||||
+ start_knode = &start->p->knode_bus;
|
||||
+ klist_iter_init_node(&subsys->p->klist_devices, &iter->ki, start_knode);
|
||||
+ iter->type = type;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(subsys_dev_iter_init);
|
||||
+
|
||||
+/**
|
||||
+ * subsys_dev_iter_next - iterate to the next device
|
||||
+ * @iter: subsys iterator to proceed
|
||||
+ *
|
||||
+ * Proceed @iter to the next device and return it. Returns NULL if
|
||||
+ * iteration is complete.
|
||||
+ *
|
||||
+ * The returned device is referenced and won't be released till
|
||||
+ * iterator is proceed to the next device or exited. The caller is
|
||||
+ * free to do whatever it wants to do with the device including
|
||||
+ * calling back into subsys code.
|
||||
+ */
|
||||
+struct device *subsys_dev_iter_next(struct subsys_dev_iter *iter)
|
||||
+{
|
||||
+ struct klist_node *knode;
|
||||
+ struct device *dev;
|
||||
+
|
||||
+ for (;;) {
|
||||
+ knode = klist_next(&iter->ki);
|
||||
+ if (!knode)
|
||||
+ return NULL;
|
||||
+ dev = container_of(knode, struct device_private, knode_bus)->device;
|
||||
+ if (!iter->type || iter->type == dev->type)
|
||||
+ return dev;
|
||||
+ }
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(subsys_dev_iter_next);
|
||||
+
|
||||
+/**
|
||||
+ * subsys_dev_iter_exit - finish iteration
|
||||
+ * @iter: subsys iterator to finish
|
||||
+ *
|
||||
+ * Finish an iteration. Always call this function after iteration is
|
||||
+ * complete whether the iteration ran till the end or not.
|
||||
+ */
|
||||
+void subsys_dev_iter_exit(struct subsys_dev_iter *iter)
|
||||
+{
|
||||
+ klist_iter_exit(&iter->ki);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(subsys_dev_iter_exit);
|
||||
+
|
||||
+int subsys_interface_register(struct subsys_interface *sif)
|
||||
+{
|
||||
+ struct bus_type *subsys;
|
||||
+ struct subsys_dev_iter iter;
|
||||
+ struct device *dev;
|
||||
+
|
||||
+ if (!sif || !sif->subsys)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ subsys = bus_get(sif->subsys);
|
||||
+ if (!subsys)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ mutex_lock(&subsys->p->mutex);
|
||||
+ list_add_tail(&sif->node, &subsys->p->interfaces);
|
||||
+ if (sif->add_dev) {
|
||||
+ subsys_dev_iter_init(&iter, subsys, NULL, NULL);
|
||||
+ while ((dev = subsys_dev_iter_next(&iter)))
|
||||
+ sif->add_dev(dev, sif);
|
||||
+ subsys_dev_iter_exit(&iter);
|
||||
+ }
|
||||
+ mutex_unlock(&subsys->p->mutex);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(subsys_interface_register);
|
||||
+
|
||||
+void subsys_interface_unregister(struct subsys_interface *sif)
|
||||
+{
|
||||
+ struct bus_type *subsys = sif->subsys;
|
||||
+ struct subsys_dev_iter iter;
|
||||
+ struct device *dev;
|
||||
+
|
||||
+ if (!sif)
|
||||
+ return;
|
||||
+
|
||||
+ mutex_lock(&subsys->p->mutex);
|
||||
+ list_del_init(&sif->node);
|
||||
+ if (sif->remove_dev) {
|
||||
+ subsys_dev_iter_init(&iter, subsys, NULL, NULL);
|
||||
+ while ((dev = subsys_dev_iter_next(&iter)))
|
||||
+ sif->remove_dev(dev, sif);
|
||||
+ subsys_dev_iter_exit(&iter);
|
||||
+ }
|
||||
+ mutex_unlock(&subsys->p->mutex);
|
||||
+
|
||||
+ bus_put(subsys);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(subsys_interface_unregister);
|
||||
+
|
||||
+static void system_root_device_release(struct device *dev)
|
||||
+{
|
||||
+ kfree(dev);
|
||||
+}
|
||||
+/**
|
||||
+ * subsys_system_register - register a subsystem at /sys/devices/system/
|
||||
+ * @subsys - system subsystem
|
||||
+ * @groups - default attributes for the root device
|
||||
+ *
|
||||
+ * All 'system' subsystems have a /sys/devices/system/<name> root device
|
||||
+ * with the name of the subsystem. The root device can carry subsystem-
|
||||
+ * wide attributes. All registered devices are below this single root
|
||||
+ * device and are named after the subsystem with a simple enumeration
|
||||
+ * number appended. The registered devices are not explicitely named;
|
||||
+ * only 'id' in the device needs to be set.
|
||||
+ *
|
||||
+ * Do not use this interface for anything new, it exists for compatibility
|
||||
+ * with bad ideas only. New subsystems should use plain subsystems; and
|
||||
+ * add the subsystem-wide attributes should be added to the subsystem
|
||||
+ * directory itself and not some create fake root-device placed in
|
||||
+ * /sys/devices/system/<name>.
|
||||
+ */
|
||||
+int subsys_system_register(struct bus_type *subsys,
|
||||
+ const struct attribute_group **groups)
|
||||
+{
|
||||
+ struct device *dev;
|
||||
+ int err;
|
||||
+
|
||||
+ err = bus_register(subsys);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+
|
||||
+ dev = kzalloc(sizeof(struct device), GFP_KERNEL);
|
||||
+ if (!dev) {
|
||||
+ err = -ENOMEM;
|
||||
+ goto err_dev;
|
||||
+ }
|
||||
+
|
||||
+ err = dev_set_name(dev, "%s", subsys->name);
|
||||
+ if (err < 0)
|
||||
+ goto err_name;
|
||||
+
|
||||
+ dev->kobj.parent = &system_kset->kobj;
|
||||
+ dev->groups = groups;
|
||||
+ dev->release = system_root_device_release;
|
||||
+
|
||||
+ err = device_register(dev);
|
||||
+ if (err < 0)
|
||||
+ goto err_dev_reg;
|
||||
+
|
||||
+ subsys->dev_root = dev;
|
||||
+ return 0;
|
||||
+
|
||||
+err_dev_reg:
|
||||
+ put_device(dev);
|
||||
+ dev = NULL;
|
||||
+err_name:
|
||||
+ kfree(dev);
|
||||
+err_dev:
|
||||
+ bus_unregister(subsys);
|
||||
+ return err;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(subsys_system_register);
|
||||
+
|
||||
int __init buses_init(void)
|
||||
{
|
||||
bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);
|
||||
if (!bus_kset)
|
||||
return -ENOMEM;
|
||||
+
|
||||
+ system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj);
|
||||
+ if (!system_kset)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
diff --git a/drivers/base/class.c b/drivers/base/class.c
|
||||
index b80d91c..03243d4 100644
|
||||
--- a/drivers/base/class.c
|
||||
+++ b/drivers/base/class.c
|
||||
@@ -184,9 +184,9 @@ int __class_register(struct class *cls, struct lock_class_key *key)
|
||||
if (!cp)
|
||||
return -ENOMEM;
|
||||
klist_init(&cp->klist_devices, klist_class_dev_get, klist_class_dev_put);
|
||||
- INIT_LIST_HEAD(&cp->class_interfaces);
|
||||
+ INIT_LIST_HEAD(&cp->interfaces);
|
||||
kset_init(&cp->glue_dirs);
|
||||
- __mutex_init(&cp->class_mutex, "struct class mutex", key);
|
||||
+ __mutex_init(&cp->mutex, "subsys mutex", key);
|
||||
error = kobject_set_name(&cp->subsys.kobj, "%s", cls->name);
|
||||
if (error) {
|
||||
kfree(cp);
|
||||
@@ -460,15 +460,15 @@ int class_interface_register(struct class_interface *class_intf)
|
||||
if (!parent)
|
||||
return -EINVAL;
|
||||
|
||||
- mutex_lock(&parent->p->class_mutex);
|
||||
- list_add_tail(&class_intf->node, &parent->p->class_interfaces);
|
||||
+ mutex_lock(&parent->p->mutex);
|
||||
+ list_add_tail(&class_intf->node, &parent->p->interfaces);
|
||||
if (class_intf->add_dev) {
|
||||
class_dev_iter_init(&iter, parent, NULL, NULL);
|
||||
while ((dev = class_dev_iter_next(&iter)))
|
||||
class_intf->add_dev(dev, class_intf);
|
||||
class_dev_iter_exit(&iter);
|
||||
}
|
||||
- mutex_unlock(&parent->p->class_mutex);
|
||||
+ mutex_unlock(&parent->p->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -482,7 +482,7 @@ void class_interface_unregister(struct class_interface *class_intf)
|
||||
if (!parent)
|
||||
return;
|
||||
|
||||
- mutex_lock(&parent->p->class_mutex);
|
||||
+ mutex_lock(&parent->p->mutex);
|
||||
list_del_init(&class_intf->node);
|
||||
if (class_intf->remove_dev) {
|
||||
class_dev_iter_init(&iter, parent, NULL, NULL);
|
||||
@@ -490,7 +490,7 @@ void class_interface_unregister(struct class_interface *class_intf)
|
||||
class_intf->remove_dev(dev, class_intf);
|
||||
class_dev_iter_exit(&iter);
|
||||
}
|
||||
- mutex_unlock(&parent->p->class_mutex);
|
||||
+ mutex_unlock(&parent->p->mutex);
|
||||
|
||||
class_put(parent);
|
||||
}
|
||||
diff --git a/drivers/base/core.c b/drivers/base/core.c
|
||||
index 82c8654..a31ea19 100644
|
||||
--- a/drivers/base/core.c
|
||||
+++ b/drivers/base/core.c
|
||||
@@ -117,6 +117,56 @@ static const struct sysfs_ops dev_sysfs_ops = {
|
||||
.store = dev_attr_store,
|
||||
};
|
||||
|
||||
+#define to_ext_attr(x) container_of(x, struct dev_ext_attribute, attr)
|
||||
+
|
||||
+ssize_t device_store_ulong(struct device *dev,
|
||||
+ struct device_attribute *attr,
|
||||
+ const char *buf, size_t size)
|
||||
+{
|
||||
+ struct dev_ext_attribute *ea = to_ext_attr(attr);
|
||||
+ char *end;
|
||||
+ unsigned long new = simple_strtoul(buf, &end, 0);
|
||||
+ if (end == buf)
|
||||
+ return -EINVAL;
|
||||
+ *(unsigned long *)(ea->var) = new;
|
||||
+ /* Always return full write size even if we didn't consume all */
|
||||
+ return size;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(device_store_ulong);
|
||||
+
|
||||
+ssize_t device_show_ulong(struct device *dev,
|
||||
+ struct device_attribute *attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ struct dev_ext_attribute *ea = to_ext_attr(attr);
|
||||
+ return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var));
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(device_show_ulong);
|
||||
+
|
||||
+ssize_t device_store_int(struct device *dev,
|
||||
+ struct device_attribute *attr,
|
||||
+ const char *buf, size_t size)
|
||||
+{
|
||||
+ struct dev_ext_attribute *ea = to_ext_attr(attr);
|
||||
+ char *end;
|
||||
+ long new = simple_strtol(buf, &end, 0);
|
||||
+ if (end == buf || new > INT_MAX || new < INT_MIN)
|
||||
+ return -EINVAL;
|
||||
+ *(int *)(ea->var) = new;
|
||||
+ /* Always return full write size even if we didn't consume all */
|
||||
+ return size;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(device_store_int);
|
||||
+
|
||||
+ssize_t device_show_int(struct device *dev,
|
||||
+ struct device_attribute *attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ struct dev_ext_attribute *ea = to_ext_attr(attr);
|
||||
+
|
||||
+ return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var));
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(device_show_int);
|
||||
|
||||
/**
|
||||
* device_release - free device structure.
|
||||
@@ -463,7 +513,7 @@ static ssize_t show_dev(struct device *dev, struct device_attribute *attr,
|
||||
static struct device_attribute devt_attr =
|
||||
__ATTR(dev, S_IRUGO, show_dev, NULL);
|
||||
|
||||
-/* kset to create /sys/devices/ */
|
||||
+/* /sys/devices/ */
|
||||
struct kset *devices_kset;
|
||||
|
||||
/**
|
||||
@@ -710,6 +760,10 @@ static struct kobject *get_device_parent(struct device *dev,
|
||||
return k;
|
||||
}
|
||||
|
||||
+ /* subsystems can specify a default root directory for their devices */
|
||||
+ if (!parent && dev->bus && dev->bus->dev_root)
|
||||
+ return &dev->bus->dev_root->kobj;
|
||||
+
|
||||
if (parent)
|
||||
return &parent->kobj;
|
||||
return NULL;
|
||||
@@ -730,14 +784,6 @@ static void cleanup_device_parent(struct device *dev)
|
||||
cleanup_glue_dir(dev, dev->kobj.parent);
|
||||
}
|
||||
|
||||
-static void setup_parent(struct device *dev, struct device *parent)
|
||||
-{
|
||||
- struct kobject *kobj;
|
||||
- kobj = get_device_parent(dev, parent);
|
||||
- if (kobj)
|
||||
- dev->kobj.parent = kobj;
|
||||
-}
|
||||
-
|
||||
static int device_add_class_symlinks(struct device *dev)
|
||||
{
|
||||
int error;
|
||||
@@ -890,6 +936,7 @@ int device_private_init(struct device *dev)
|
||||
int device_add(struct device *dev)
|
||||
{
|
||||
struct device *parent = NULL;
|
||||
+ struct kobject *kobj;
|
||||
struct class_interface *class_intf;
|
||||
int error = -EINVAL;
|
||||
|
||||
@@ -913,6 +960,10 @@ int device_add(struct device *dev)
|
||||
dev->init_name = NULL;
|
||||
}
|
||||
|
||||
+ /* subsystems can specify simple device enumeration */
|
||||
+ if (!dev_name(dev) && dev->bus && dev->bus->dev_name)
|
||||
+ dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id);
|
||||
+
|
||||
if (!dev_name(dev)) {
|
||||
error = -EINVAL;
|
||||
goto name_error;
|
||||
@@ -921,7 +972,9 @@ int device_add(struct device *dev)
|
||||
pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
|
||||
|
||||
parent = get_device(dev->parent);
|
||||
- setup_parent(dev, parent);
|
||||
+ kobj = get_device_parent(dev, parent);
|
||||
+ if (kobj)
|
||||
+ dev->kobj.parent = kobj;
|
||||
|
||||
/* use parent numa_node */
|
||||
if (parent)
|
||||
@@ -981,17 +1034,17 @@ int device_add(struct device *dev)
|
||||
&parent->p->klist_children);
|
||||
|
||||
if (dev->class) {
|
||||
- mutex_lock(&dev->class->p->class_mutex);
|
||||
+ mutex_lock(&dev->class->p->mutex);
|
||||
/* tie the class to the device */
|
||||
klist_add_tail(&dev->knode_class,
|
||||
&dev->class->p->klist_devices);
|
||||
|
||||
/* notify any interfaces that the device is here */
|
||||
list_for_each_entry(class_intf,
|
||||
- &dev->class->p->class_interfaces, node)
|
||||
+ &dev->class->p->interfaces, node)
|
||||
if (class_intf->add_dev)
|
||||
class_intf->add_dev(dev, class_intf);
|
||||
- mutex_unlock(&dev->class->p->class_mutex);
|
||||
+ mutex_unlock(&dev->class->p->mutex);
|
||||
}
|
||||
done:
|
||||
put_device(dev);
|
||||
@@ -1106,15 +1159,15 @@ void device_del(struct device *dev)
|
||||
if (dev->class) {
|
||||
device_remove_class_symlinks(dev);
|
||||
|
||||
- mutex_lock(&dev->class->p->class_mutex);
|
||||
+ mutex_lock(&dev->class->p->mutex);
|
||||
/* notify any interfaces that the device is now gone */
|
||||
list_for_each_entry(class_intf,
|
||||
- &dev->class->p->class_interfaces, node)
|
||||
+ &dev->class->p->interfaces, node)
|
||||
if (class_intf->remove_dev)
|
||||
class_intf->remove_dev(dev, class_intf);
|
||||
/* remove the device from the class list */
|
||||
klist_del(&dev->knode_class);
|
||||
- mutex_unlock(&dev->class->p->class_mutex);
|
||||
+ mutex_unlock(&dev->class->p->mutex);
|
||||
}
|
||||
device_remove_file(dev, &uevent_attr);
|
||||
device_remove_attrs(dev);
|
||||
diff --git a/drivers/base/init.c b/drivers/base/init.c
|
||||
index c8a934e..c16f0b8 100644
|
||||
--- a/drivers/base/init.c
|
||||
+++ b/drivers/base/init.c
|
||||
@@ -31,7 +31,6 @@ void __init driver_init(void)
|
||||
* core core pieces.
|
||||
*/
|
||||
platform_bus_init();
|
||||
- system_bus_init();
|
||||
cpu_dev_init();
|
||||
memory_dev_init();
|
||||
}
|
||||
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
|
||||
index 9dff77b..409f5ce 100644
|
||||
--- a/drivers/base/sys.c
|
||||
+++ b/drivers/base/sys.c
|
||||
@@ -126,7 +126,7 @@ void sysdev_class_remove_file(struct sysdev_class *c,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sysdev_class_remove_file);
|
||||
|
||||
-static struct kset *system_kset;
|
||||
+extern struct kset *system_kset;
|
||||
|
||||
int sysdev_class_register(struct sysdev_class *cls)
|
||||
{
|
||||
@@ -331,14 +331,6 @@ void sysdev_unregister(struct sys_device *sysdev)
|
||||
EXPORT_SYMBOL_GPL(sysdev_register);
|
||||
EXPORT_SYMBOL_GPL(sysdev_unregister);
|
||||
|
||||
-int __init system_bus_init(void)
|
||||
-{
|
||||
- system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj);
|
||||
- if (!system_kset)
|
||||
- return -ENOMEM;
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
#define to_ext_attr(x) container_of(x, struct sysdev_ext_attribute, attr)
|
||||
|
||||
ssize_t sysdev_store_ulong(struct sys_device *sysdev,
|
||||
diff --git a/include/linux/device.h b/include/linux/device.h
|
||||
index 341fb74..7f9fc15 100644
|
||||
--- a/include/linux/device.h
|
||||
+++ b/include/linux/device.h
|
||||
@@ -53,6 +53,8 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
|
||||
* struct bus_type - The bus type of the device
|
||||
*
|
||||
* @name: The name of the bus.
|
||||
+ * @dev_name: Used for subsystems to enumerate devices like ("foo%u", dev->id).
|
||||
+ * @dev_root: Default device to use as the parent.
|
||||
* @bus_attrs: Default attributes of the bus.
|
||||
* @dev_attrs: Default attributes of the devices on the bus.
|
||||
* @drv_attrs: Default attributes of the device drivers on the bus.
|
||||
@@ -86,6 +88,8 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
|
||||
*/
|
||||
struct bus_type {
|
||||
const char *name;
|
||||
+ const char *dev_name;
|
||||
+ struct device *dev_root;
|
||||
struct bus_attribute *bus_attrs;
|
||||
struct device_attribute *dev_attrs;
|
||||
struct driver_attribute *drv_attrs;
|
||||
@@ -106,12 +110,30 @@ struct bus_type {
|
||||
struct subsys_private *p;
|
||||
};
|
||||
|
||||
-extern int __must_check bus_register(struct bus_type *bus);
|
||||
+/* This is a #define to keep the compiler from merging different
|
||||
+ * instances of the __key variable */
|
||||
+#define bus_register(subsys) \
|
||||
+({ \
|
||||
+ static struct lock_class_key __key; \
|
||||
+ __bus_register(subsys, &__key); \
|
||||
+})
|
||||
+extern int __must_check __bus_register(struct bus_type *bus,
|
||||
+ struct lock_class_key *key);
|
||||
extern void bus_unregister(struct bus_type *bus);
|
||||
|
||||
extern int __must_check bus_rescan_devices(struct bus_type *bus);
|
||||
|
||||
/* iterator helpers for buses */
|
||||
+struct subsys_dev_iter {
|
||||
+ struct klist_iter ki;
|
||||
+ const struct device_type *type;
|
||||
+};
|
||||
+void subsys_dev_iter_init(struct subsys_dev_iter *iter,
|
||||
+ struct bus_type *subsys,
|
||||
+ struct device *start,
|
||||
+ const struct device_type *type);
|
||||
+struct device *subsys_dev_iter_next(struct subsys_dev_iter *iter);
|
||||
+void subsys_dev_iter_exit(struct subsys_dev_iter *iter);
|
||||
|
||||
int bus_for_each_dev(struct bus_type *bus, struct device *start, void *data,
|
||||
int (*fn)(struct device *dev, void *data));
|
||||
@@ -121,10 +143,10 @@ struct device *bus_find_device(struct bus_type *bus, struct device *start,
|
||||
struct device *bus_find_device_by_name(struct bus_type *bus,
|
||||
struct device *start,
|
||||
const char *name);
|
||||
-
|
||||
+struct device *subsys_find_device_by_id(struct bus_type *bus, unsigned int id,
|
||||
+ struct device *hint);
|
||||
int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
|
||||
void *data, int (*fn)(struct device_driver *, void *));
|
||||
-
|
||||
void bus_sort_breadthfirst(struct bus_type *bus,
|
||||
int (*compare)(const struct device *a,
|
||||
const struct device *b));
|
||||
@@ -256,6 +278,33 @@ struct device *driver_find_device(struct device_driver *drv,
|
||||
int (*match)(struct device *dev, void *data));
|
||||
|
||||
/**
|
||||
+ * struct subsys_interface - interfaces to device functions
|
||||
+ * @name name of the device function
|
||||
+ * @subsystem subsytem of the devices to attach to
|
||||
+ * @node the list of functions registered at the subsystem
|
||||
+ * @add device hookup to device function handler
|
||||
+ * @remove device hookup to device function handler
|
||||
+ *
|
||||
+ * Simple interfaces attached to a subsystem. Multiple interfaces can
|
||||
+ * attach to a subsystem and its devices. Unlike drivers, they do not
|
||||
+ * exclusively claim or control devices. Interfaces usually represent
|
||||
+ * a specific functionality of a subsystem/class of devices.
|
||||
+ */
|
||||
+struct subsys_interface {
|
||||
+ const char *name;
|
||||
+ struct bus_type *subsys;
|
||||
+ struct list_head node;
|
||||
+ int (*add_dev)(struct device *dev, struct subsys_interface *sif);
|
||||
+ int (*remove_dev)(struct device *dev, struct subsys_interface *sif);
|
||||
+};
|
||||
+
|
||||
+int subsys_interface_register(struct subsys_interface *sif);
|
||||
+void subsys_interface_unregister(struct subsys_interface *sif);
|
||||
+
|
||||
+int subsys_system_register(struct bus_type *subsys,
|
||||
+ const struct attribute_group **groups);
|
||||
+
|
||||
+/**
|
||||
* struct class - device classes
|
||||
* @name: Name of the class.
|
||||
* @owner: The module owner.
|
||||
@@ -438,8 +487,28 @@ struct device_attribute {
|
||||
const char *buf, size_t count);
|
||||
};
|
||||
|
||||
+struct dev_ext_attribute {
|
||||
+ struct device_attribute attr;
|
||||
+ void *var;
|
||||
+};
|
||||
+
|
||||
+ssize_t device_show_ulong(struct device *dev, struct device_attribute *attr,
|
||||
+ char *buf);
|
||||
+ssize_t device_store_ulong(struct device *dev, struct device_attribute *attr,
|
||||
+ const char *buf, size_t count);
|
||||
+ssize_t device_show_int(struct device *dev, struct device_attribute *attr,
|
||||
+ char *buf);
|
||||
+ssize_t device_store_int(struct device *dev, struct device_attribute *attr,
|
||||
+ const char *buf, size_t count);
|
||||
+
|
||||
#define DEVICE_ATTR(_name, _mode, _show, _store) \
|
||||
-struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
|
||||
+ struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
|
||||
+#define DEVICE_ULONG_ATTR(_name, _mode, _var) \
|
||||
+ struct dev_ext_attribute dev_attr_##_name = \
|
||||
+ { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) }
|
||||
+#define DEVICE_INT_ATTR(_name, _mode, _var) \
|
||||
+ struct dev_ext_attribute dev_attr_##_name = \
|
||||
+ { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) }
|
||||
|
||||
extern int __must_check device_create_file(struct device *device,
|
||||
const struct device_attribute *entry);
|
||||
@@ -603,6 +672,7 @@ struct device {
|
||||
struct device_node *of_node; /* associated device tree node */
|
||||
|
||||
dev_t devt; /* dev_t, creates the sysfs "dev" */
|
||||
+ u32 id; /* device instance */
|
||||
|
||||
spinlock_t devres_lock;
|
||||
struct list_head devres_head;
|
196
debian/patches/features/all/cpu-devices/intel-idle-convert-to-x86_cpu_id-auto-probing.patch
vendored
Normal file
196
debian/patches/features/all/cpu-devices/intel-idle-convert-to-x86_cpu_id-auto-probing.patch
vendored
Normal file
|
@ -0,0 +1,196 @@
|
|||
From: Andi Kleen <ak@linux.intel.com>
|
||||
Date: Thu, 26 Jan 2012 00:09:07 +0100
|
||||
Subject: intel-idle: convert to x86_cpu_id auto probing
|
||||
|
||||
commit b66b8b9a4a79087dde1b358a016e5c8739ccf186 upstream.
|
||||
|
||||
With this it should be automatically loaded on suitable systems by
|
||||
udev.
|
||||
|
||||
The old switch () is replaced with a table based approach, this
|
||||
also cleans up the code.
|
||||
|
||||
Cc: Len Brown <lenb@kernel.org>
|
||||
Signed-off-by: Andi Kleen <ak@linux.intel.com>
|
||||
Signed-off-by: Thomas Renninger <trenn@suse.de>
|
||||
Acked-by: H. Peter Anvin <hpa@zytor.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
[bwh: Backported to 3.2: one less instance of auto_demotion_disable_flags]
|
||||
---
|
||||
drivers/idle/intel_idle.c | 116 ++++++++++++++++++++++++++-------------------
|
||||
1 file changed, 66 insertions(+), 50 deletions(-)
|
||||
|
||||
--- a/drivers/idle/intel_idle.c
|
||||
+++ b/drivers/idle/intel_idle.c
|
||||
@@ -62,6 +62,7 @@
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/module.h>
|
||||
+#include <asm/cpu_device_id.h>
|
||||
#include <asm/mwait.h>
|
||||
#include <asm/msr.h>
|
||||
|
||||
@@ -81,6 +82,17 @@
|
||||
/* Reliable LAPIC Timer States, bit 1 for C1 etc. */
|
||||
static unsigned int lapic_timer_reliable_states = (1 << 1); /* Default to only C1 */
|
||||
|
||||
+struct idle_cpu {
|
||||
+ struct cpuidle_state *state_table;
|
||||
+
|
||||
+ /*
|
||||
+ * Hardware C-state auto-demotion may not always be optimal.
|
||||
+ * Indicate which enable bits to clear here.
|
||||
+ */
|
||||
+ unsigned long auto_demotion_disable_flags;
|
||||
+};
|
||||
+
|
||||
+static const struct idle_cpu *icpu;
|
||||
static struct cpuidle_device __percpu *intel_idle_cpuidle_devices;
|
||||
static int intel_idle(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv, int index);
|
||||
@@ -88,12 +100,6 @@
|
||||
static struct cpuidle_state *cpuidle_state_table;
|
||||
|
||||
/*
|
||||
- * Hardware C-state auto-demotion may not always be optimal.
|
||||
- * Indicate which enable bits to clear here.
|
||||
- */
|
||||
-static unsigned long long auto_demotion_disable_flags;
|
||||
-
|
||||
-/*
|
||||
* Set this flag for states where the HW flushes the TLB for us
|
||||
* and so we don't need cross-calls to keep it consistent.
|
||||
* If this flag is set, SW flushes the TLB, so even if the
|
||||
@@ -320,27 +326,72 @@
|
||||
unsigned long long msr_bits;
|
||||
|
||||
rdmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits);
|
||||
- msr_bits &= ~auto_demotion_disable_flags;
|
||||
+ msr_bits &= ~(icpu->auto_demotion_disable_flags);
|
||||
wrmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits);
|
||||
}
|
||||
|
||||
+static const struct idle_cpu idle_cpu_nehalem = {
|
||||
+ .state_table = nehalem_cstates,
|
||||
+};
|
||||
+
|
||||
+static const struct idle_cpu idle_cpu_westmere = {
|
||||
+ .state_table = nehalem_cstates,
|
||||
+ .auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE,
|
||||
+};
|
||||
+
|
||||
+static const struct idle_cpu idle_cpu_atom = {
|
||||
+ .state_table = atom_cstates,
|
||||
+};
|
||||
+
|
||||
+static const struct idle_cpu idle_cpu_lincroft = {
|
||||
+ .state_table = atom_cstates,
|
||||
+ .auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE,
|
||||
+};
|
||||
+
|
||||
+static const struct idle_cpu idle_cpu_snb = {
|
||||
+ .state_table = snb_cstates,
|
||||
+};
|
||||
+
|
||||
+#define ICPU(model, cpu) \
|
||||
+ { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu }
|
||||
+
|
||||
+static const struct x86_cpu_id intel_idle_ids[] = {
|
||||
+ ICPU(0x1a, idle_cpu_nehalem),
|
||||
+ ICPU(0x1e, idle_cpu_nehalem),
|
||||
+ ICPU(0x1f, idle_cpu_nehalem),
|
||||
+ ICPU(0x25, idle_cpu_westmere),
|
||||
+ ICPU(0x2c, idle_cpu_westmere),
|
||||
+ ICPU(0x2f, idle_cpu_westmere),
|
||||
+ ICPU(0x1c, idle_cpu_atom),
|
||||
+ ICPU(0x26, idle_cpu_lincroft),
|
||||
+ ICPU(0x2f, idle_cpu_westmere),
|
||||
+ ICPU(0x2a, idle_cpu_snb),
|
||||
+ ICPU(0x2d, idle_cpu_snb),
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids);
|
||||
+
|
||||
/*
|
||||
* intel_idle_probe()
|
||||
*/
|
||||
static int intel_idle_probe(void)
|
||||
{
|
||||
unsigned int eax, ebx, ecx;
|
||||
+ const struct x86_cpu_id *id;
|
||||
|
||||
if (max_cstate == 0) {
|
||||
pr_debug(PREFIX "disabled\n");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
- if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
|
||||
- return -ENODEV;
|
||||
-
|
||||
- if (!boot_cpu_has(X86_FEATURE_MWAIT))
|
||||
+ id = x86_match_cpu(intel_idle_ids);
|
||||
+ if (!id) {
|
||||
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
|
||||
+ boot_cpu_data.x86 == 6)
|
||||
+ pr_debug(PREFIX "does not run on family %d model %d\n",
|
||||
+ boot_cpu_data.x86, boot_cpu_data.x86_model);
|
||||
return -ENODEV;
|
||||
+ }
|
||||
|
||||
if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF)
|
||||
return -ENODEV;
|
||||
@@ -354,43 +405,8 @@
|
||||
|
||||
pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates);
|
||||
|
||||
-
|
||||
- if (boot_cpu_data.x86 != 6) /* family 6 */
|
||||
- return -ENODEV;
|
||||
-
|
||||
- switch (boot_cpu_data.x86_model) {
|
||||
-
|
||||
- case 0x1A: /* Core i7, Xeon 5500 series */
|
||||
- case 0x1E: /* Core i7 and i5 Processor - Lynnfield Jasper Forest */
|
||||
- case 0x1F: /* Core i7 and i5 Processor - Nehalem */
|
||||
- case 0x2E: /* Nehalem-EX Xeon */
|
||||
- case 0x2F: /* Westmere-EX Xeon */
|
||||
- case 0x25: /* Westmere */
|
||||
- case 0x2C: /* Westmere */
|
||||
- cpuidle_state_table = nehalem_cstates;
|
||||
- auto_demotion_disable_flags =
|
||||
- (NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE);
|
||||
- break;
|
||||
-
|
||||
- case 0x1C: /* 28 - Atom Processor */
|
||||
- cpuidle_state_table = atom_cstates;
|
||||
- break;
|
||||
-
|
||||
- case 0x26: /* 38 - Lincroft Atom Processor */
|
||||
- cpuidle_state_table = atom_cstates;
|
||||
- auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE;
|
||||
- break;
|
||||
-
|
||||
- case 0x2A: /* SNB */
|
||||
- case 0x2D: /* SNB Xeon */
|
||||
- cpuidle_state_table = snb_cstates;
|
||||
- break;
|
||||
-
|
||||
- default:
|
||||
- pr_debug(PREFIX "does not run on family %d model %d\n",
|
||||
- boot_cpu_data.x86, boot_cpu_data.x86_model);
|
||||
- return -ENODEV;
|
||||
- }
|
||||
+ icpu = (const struct idle_cpu *)id->driver_data;
|
||||
+ cpuidle_state_table = icpu->state_table;
|
||||
|
||||
if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */
|
||||
lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE;
|
||||
@@ -471,7 +487,7 @@
|
||||
drv->state_count += 1;
|
||||
}
|
||||
|
||||
- if (auto_demotion_disable_flags)
|
||||
+ if (icpu->auto_demotion_disable_flags)
|
||||
on_each_cpu(auto_demotion_disable, NULL, 1);
|
||||
|
||||
return 0;
|
|
@ -0,0 +1,32 @@
|
|||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Sat, 11 Feb 2012 22:57:38 +0000
|
||||
Subject: intel_idle: Fix ID for Nehalem-EX Xeon in device ID table
|
||||
|
||||
commit e668505c9811411c6096888b43ba104f35c9e9c3 upstream.
|
||||
|
||||
Commit b66b8b9a4a79087dde1b358a016e5c8739ccf186 ('intel-idle: convert
|
||||
to x86_cpu_id auto probing') put two entries for model 0x2f
|
||||
(Westmere-EX Xeon) in the device ID table and left out model 0x2e
|
||||
(Nehalem-EX Xeon).
|
||||
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
Acked-by: Thomas Renninger <trenn@suse.de>
|
||||
Acked-by: H. Peter Anvin <hpa@zytor.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/idle/intel_idle.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
|
||||
index 237fe57..a238649 100644
|
||||
--- a/drivers/idle/intel_idle.c
|
||||
+++ b/drivers/idle/intel_idle.c
|
||||
@@ -360,7 +360,7 @@ static const struct x86_cpu_id intel_idle_ids[] = {
|
||||
ICPU(0x1f, idle_cpu_nehalem),
|
||||
ICPU(0x25, idle_cpu_westmere),
|
||||
ICPU(0x2c, idle_cpu_westmere),
|
||||
- ICPU(0x2f, idle_cpu_westmere),
|
||||
+ ICPU(0x2e, idle_cpu_westmere),
|
||||
ICPU(0x1c, idle_cpu_atom),
|
||||
ICPU(0x26, idle_cpu_lincroft),
|
||||
ICPU(0x2f, idle_cpu_westmere),
|
|
@ -0,0 +1,52 @@
|
|||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Thu, 16 Feb 2012 04:13:14 +0000
|
||||
Subject: intel_idle: Revert change of auto_demotion_disable_flags for Nehalem
|
||||
|
||||
commit 8bf11938459ff8ceb8643258d0a35e0f2bc9be17 upstream.
|
||||
|
||||
Commit b66b8b9a4a79087dde1b358a016e5c8739ccf186 ('intel-idle: convert
|
||||
to x86_cpu_id auto probing') added a distinction between Nehalem and
|
||||
Westemere processors and changed auto_demotion_disable_flags for the
|
||||
former to 0. This was not explained in the commit message, so change
|
||||
it back.
|
||||
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
Acked-by: Thomas Renninger <trenn@suse.de>
|
||||
Acked-by: H. Peter Anvin <hpa@zytor.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/idle/intel_idle.c | 12 ++++--------
|
||||
1 file changed, 4 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
|
||||
index a238649..1c15e9b 100644
|
||||
--- a/drivers/idle/intel_idle.c
|
||||
+++ b/drivers/idle/intel_idle.c
|
||||
@@ -331,10 +331,6 @@ static void auto_demotion_disable(void *dummy)
|
||||
|
||||
static const struct idle_cpu idle_cpu_nehalem = {
|
||||
.state_table = nehalem_cstates,
|
||||
-};
|
||||
-
|
||||
-static const struct idle_cpu idle_cpu_westmere = {
|
||||
- .state_table = nehalem_cstates,
|
||||
.auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE,
|
||||
};
|
||||
|
||||
@@ -358,12 +354,12 @@ static const struct x86_cpu_id intel_idle_ids[] = {
|
||||
ICPU(0x1a, idle_cpu_nehalem),
|
||||
ICPU(0x1e, idle_cpu_nehalem),
|
||||
ICPU(0x1f, idle_cpu_nehalem),
|
||||
- ICPU(0x25, idle_cpu_westmere),
|
||||
- ICPU(0x2c, idle_cpu_westmere),
|
||||
- ICPU(0x2e, idle_cpu_westmere),
|
||||
+ ICPU(0x25, idle_cpu_nehalem),
|
||||
+ ICPU(0x2c, idle_cpu_nehalem),
|
||||
+ ICPU(0x2e, idle_cpu_nehalem),
|
||||
ICPU(0x1c, idle_cpu_atom),
|
||||
ICPU(0x26, idle_cpu_lincroft),
|
||||
- ICPU(0x2f, idle_cpu_westmere),
|
||||
+ ICPU(0x2f, idle_cpu_nehalem),
|
||||
ICPU(0x2a, idle_cpu_snb),
|
||||
ICPU(0x2d, idle_cpu_snb),
|
||||
{}
|
31
debian/patches/features/all/cpu-devices/powernow-k6-Really-enable-auto-loading.patch
vendored
Normal file
31
debian/patches/features/all/cpu-devices/powernow-k6-Really-enable-auto-loading.patch
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Sat, 11 Feb 2012 23:04:12 +0000
|
||||
Subject: powernow-k6: Really enable auto-loading
|
||||
|
||||
commit b4d2d23148b446f6853e711eb31c533c7385eba5 upstream.
|
||||
|
||||
Commit fa8031aefec0cf7ea6c2387c93610d99d9659aa2 ('cpufreq: Add support
|
||||
for x86 cpuinfo auto loading v4') added a device ID table to this
|
||||
driver, but didn't declare it as the module device ID table.
|
||||
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
Acked-by: Thomas Renninger <trenn@suse.de>
|
||||
Acked-by: H. Peter Anvin <hpa@zytor.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/cpufreq/powernow-k6.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c
|
||||
index 54dd031..af23e0b 100644
|
||||
--- a/drivers/cpufreq/powernow-k6.c
|
||||
+++ b/drivers/cpufreq/powernow-k6.c
|
||||
@@ -216,7 +216,7 @@ static const struct x86_cpu_id powernow_k6_ids[] = {
|
||||
{ X86_VENDOR_AMD, 5, 13 },
|
||||
{}
|
||||
};
|
||||
-
|
||||
+MODULE_DEVICE_TABLE(x86cpu, powernow_k6_ids);
|
||||
|
||||
/**
|
||||
* powernow_k6_init - initializes the k6 PowerNow! CPUFreq driver
|
31
debian/patches/features/all/cpu-devices/powernow-k7-Fix-CPU-family-number.patch
vendored
Normal file
31
debian/patches/features/all/cpu-devices/powernow-k7-Fix-CPU-family-number.patch
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Sat, 11 Feb 2012 22:58:14 +0000
|
||||
Subject: powernow-k7: Fix CPU family number
|
||||
|
||||
commit 30bcfff9bd41db5edab6420d0ae2e435609eb083 upstream.
|
||||
|
||||
Commit fa8031aefec0cf7ea6c2387c93610d99d9659aa2 ('cpufreq: Add support
|
||||
for x86 cpuinfo auto loading v4') seems to have inadvertently changed
|
||||
the matched CPU family number from 6 to 7. Change it back.
|
||||
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
Acked-by: Thomas Renninger <trenn@suse.de>
|
||||
Acked-by: H. Peter Anvin <hpa@zytor.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/cpufreq/powernow-k7.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c
|
||||
index 501d167..cf7e1ee 100644
|
||||
--- a/drivers/cpufreq/powernow-k7.c
|
||||
+++ b/drivers/cpufreq/powernow-k7.c
|
||||
@@ -112,7 +112,7 @@ static int check_fsb(unsigned int fsbspeed)
|
||||
}
|
||||
|
||||
static const struct x86_cpu_id powernow_k7_cpuids[] = {
|
||||
- { X86_VENDOR_AMD, 7, },
|
||||
+ { X86_VENDOR_AMD, 6, },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, powernow_k7_cpuids);
|
57
debian/patches/features/all/cpu-devices/x86-cpu-Clean-up-modalias-feature-matching.patch
vendored
Normal file
57
debian/patches/features/all/cpu-devices/x86-cpu-Clean-up-modalias-feature-matching.patch
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Sat, 11 Feb 2012 22:57:19 +0000
|
||||
Subject: x86/cpu: Clean up modalias feature matching
|
||||
|
||||
commit 5467bdda4a326513c2f14b712a22d59115b7ae94 upstream.
|
||||
|
||||
We currently include commas on both sides of the feature ID in a
|
||||
modalias, but this prevents the lowest numbered feature of a CPU from
|
||||
being matched. Since all feature IDs have the same length, we do not
|
||||
need to worry about substring matches, so omit commas from the
|
||||
modalias entirely.
|
||||
|
||||
Avoid generating multiple adjacent wildcards when there is no
|
||||
feature ID to match.
|
||||
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
Acked-by: Thomas Renninger <trenn@suse.de>
|
||||
Acked-by: H. Peter Anvin <hpa@zytor.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
arch/x86/kernel/cpu/match.c | 3 +--
|
||||
scripts/mod/file2alias.c | 5 +++--
|
||||
2 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/arch/x86/kernel/cpu/match.c
|
||||
+++ b/arch/x86/kernel/cpu/match.c
|
||||
@@ -63,7 +63,7 @@
|
||||
boot_cpu_data.x86_model);
|
||||
size -= n;
|
||||
buf += n;
|
||||
- size -= 2;
|
||||
+ size -= 1;
|
||||
for (i = 0; i < NCAPINTS*32; i++) {
|
||||
if (boot_cpu_has(i)) {
|
||||
n = snprintf(buf, size, ",%04X", i);
|
||||
@@ -75,7 +75,6 @@
|
||||
buf += n;
|
||||
}
|
||||
}
|
||||
- *buf++ = ',';
|
||||
*buf++ = '\n';
|
||||
return buf - bufptr;
|
||||
}
|
||||
--- a/scripts/mod/file2alias.c
|
||||
+++ b/scripts/mod/file2alias.c
|
||||
@@ -898,8 +898,9 @@
|
||||
ADD(alias, "vendor:", id->vendor != X86_VENDOR_ANY, id->vendor);
|
||||
ADD(alias, ":family:", id->family != X86_FAMILY_ANY, id->family);
|
||||
ADD(alias, ":model:", id->model != X86_MODEL_ANY, id->model);
|
||||
- ADD(alias, ":feature:*,", id->feature != X86_FEATURE_ANY, id->feature);
|
||||
- strcat(alias, ",*");
|
||||
+ strcat(alias, ":feature:*");
|
||||
+ if (id->feature != X86_FEATURE_ANY)
|
||||
+ sprintf(alias + strlen(alias), "%04X*", id->feature);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Sat, 11 Feb 2012 22:56:59 +0000
|
||||
Subject: x86/cpu: Fix overrun check in arch_print_cpu_modalias()
|
||||
|
||||
commit 70142a9dd154f54f7409871ead86f7d77f2c6576 upstream.
|
||||
|
||||
snprintf() does not return a negative value when truncating.
|
||||
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
Acked-by: Thomas Renninger <trenn@suse.de>
|
||||
Acked-by: H. Peter Anvin <hpa@zytor.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
arch/x86/kernel/cpu/match.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c
|
||||
index 940e2d4..2dfa52b 100644
|
||||
--- a/arch/x86/kernel/cpu/match.c
|
||||
+++ b/arch/x86/kernel/cpu/match.c
|
||||
@@ -67,7 +67,7 @@ ssize_t arch_print_cpu_modalias(struct device *dev,
|
||||
for (i = 0; i < NCAPINTS*32; i++) {
|
||||
if (boot_cpu_has(i)) {
|
||||
n = snprintf(buf, size, ",%04X", i);
|
||||
- if (n < 0) {
|
||||
+ if (n >= size) {
|
||||
WARN(1, "x86 features overflow page\n");
|
||||
break;
|
||||
}
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue