diff options
| author | Jeff Garzik <jgarzik@pobox.com> | 2006-02-09 00:58:59 -0500 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@pobox.com> | 2006-02-09 00:58:59 -0500 |
| commit | cac0e8e8bb2e7a086643bdd00c41d900a79bb4fa (patch) | |
| tree | 73cd85e5529a01fa2338ab6d58b99c36dd666cbe /drivers/base | |
| parent | ddef9bb367b19383df627e388cb4c01c86ddba6c (diff) | |
| parent | 0bdd340c092b0936f78a54bdbd3927463ed4fca3 (diff) | |
Merge branch 'master'
Diffstat (limited to 'drivers/base')
| -rw-r--r-- | drivers/base/Makefile | 1 | ||||
| -rw-r--r-- | drivers/base/base.h | 4 | ||||
| -rw-r--r-- | drivers/base/bus.c | 3 | ||||
| -rw-r--r-- | drivers/base/memory.c | 2 | ||||
| -rw-r--r-- | drivers/base/power/resume.c | 3 | ||||
| -rw-r--r-- | drivers/base/power/shutdown.c | 2 | ||||
| -rw-r--r-- | drivers/base/power/suspend.c | 3 | ||||
| -rw-r--r-- | drivers/base/power/sysfs.c | 24 | ||||
| -rw-r--r-- | drivers/base/sys.c | 3 | ||||
| -rw-r--r-- | drivers/base/topology.c | 148 |
10 files changed, 179 insertions, 14 deletions
diff --git a/drivers/base/Makefile b/drivers/base/Makefile index f12898d53078..e99471d3232b 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile | |||
| @@ -8,6 +8,7 @@ obj-y += power/ | |||
| 8 | obj-$(CONFIG_FW_LOADER) += firmware_class.o | 8 | obj-$(CONFIG_FW_LOADER) += firmware_class.o |
| 9 | obj-$(CONFIG_NUMA) += node.o | 9 | obj-$(CONFIG_NUMA) += node.o |
| 10 | obj-$(CONFIG_MEMORY_HOTPLUG) += memory.o | 10 | obj-$(CONFIG_MEMORY_HOTPLUG) += memory.o |
| 11 | obj-$(CONFIG_SMP) += topology.o | ||
| 11 | 12 | ||
| 12 | ifeq ($(CONFIG_DEBUG_DRIVER),y) | 13 | ifeq ($(CONFIG_DEBUG_DRIVER),y) |
| 13 | EXTRA_CFLAGS += -DDEBUG | 14 | EXTRA_CFLAGS += -DDEBUG |
diff --git a/drivers/base/base.h b/drivers/base/base.h index e3b548d46cff..5735b38582d0 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
| @@ -19,6 +19,10 @@ extern void bus_remove_driver(struct device_driver *); | |||
| 19 | extern void driver_detach(struct device_driver * drv); | 19 | extern void driver_detach(struct device_driver * drv); |
| 20 | extern int driver_probe_device(struct device_driver *, struct device *); | 20 | extern int driver_probe_device(struct device_driver *, struct device *); |
| 21 | 21 | ||
| 22 | extern void sysdev_shutdown(void); | ||
| 23 | extern int sysdev_suspend(pm_message_t state); | ||
| 24 | extern int sysdev_resume(void); | ||
| 25 | |||
| 22 | static inline struct class_device *to_class_dev(struct kobject *obj) | 26 | static inline struct class_device *to_class_dev(struct kobject *obj) |
| 23 | { | 27 | { |
| 24 | return container_of(obj, struct class_device, kobj); | 28 | return container_of(obj, struct class_device, kobj); |
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 29f6af554e71..c3141565d59d 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
| @@ -133,6 +133,8 @@ static struct kobj_type ktype_bus = { | |||
| 133 | decl_subsys(bus, &ktype_bus, NULL); | 133 | decl_subsys(bus, &ktype_bus, NULL); |
| 134 | 134 | ||
| 135 | 135 | ||
| 136 | #ifdef CONFIG_HOTPLUG | ||
| 137 | |||
| 136 | /* Manually detach a device from its associated driver. */ | 138 | /* Manually detach a device from its associated driver. */ |
| 137 | static int driver_helper(struct device *dev, void *data) | 139 | static int driver_helper(struct device *dev, void *data) |
| 138 | { | 140 | { |
| @@ -193,6 +195,7 @@ static ssize_t driver_bind(struct device_driver *drv, | |||
| 193 | } | 195 | } |
| 194 | static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); | 196 | static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); |
| 195 | 197 | ||
| 198 | #endif | ||
| 196 | 199 | ||
| 197 | static struct device * next_device(struct klist_iter * i) | 200 | static struct device * next_device(struct klist_iter * i) |
| 198 | { | 201 | { |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index d1a05224627e..105a0d61eb1f 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
| @@ -303,7 +303,7 @@ static int block_size_init(void) | |||
| 303 | */ | 303 | */ |
| 304 | #ifdef CONFIG_ARCH_MEMORY_PROBE | 304 | #ifdef CONFIG_ARCH_MEMORY_PROBE |
| 305 | static ssize_t | 305 | static ssize_t |
| 306 | memory_probe_store(struct class *class, const char __user *buf, size_t count) | 306 | memory_probe_store(struct class *class, const char *buf, size_t count) |
| 307 | { | 307 | { |
| 308 | u64 phys_addr; | 308 | u64 phys_addr; |
| 309 | int ret; | 309 | int ret; |
diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c index 0a7aa07b9a2a..317edbf0feca 100644 --- a/drivers/base/power/resume.c +++ b/drivers/base/power/resume.c | |||
| @@ -9,10 +9,9 @@ | |||
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <linux/device.h> | 11 | #include <linux/device.h> |
| 12 | #include "../base.h" | ||
| 12 | #include "power.h" | 13 | #include "power.h" |
| 13 | 14 | ||
| 14 | extern int sysdev_resume(void); | ||
| 15 | |||
| 16 | 15 | ||
| 17 | /** | 16 | /** |
| 18 | * resume_device - Restore state for one device. | 17 | * resume_device - Restore state for one device. |
diff --git a/drivers/base/power/shutdown.c b/drivers/base/power/shutdown.c index c2475f3134ea..8826a5b6673e 100644 --- a/drivers/base/power/shutdown.c +++ b/drivers/base/power/shutdown.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/device.h> | 12 | #include <linux/device.h> |
| 13 | #include <asm/semaphore.h> | 13 | #include <asm/semaphore.h> |
| 14 | 14 | ||
| 15 | #include "../base.h" | ||
| 15 | #include "power.h" | 16 | #include "power.h" |
| 16 | 17 | ||
| 17 | #define to_dev(node) container_of(node, struct device, kobj.entry) | 18 | #define to_dev(node) container_of(node, struct device, kobj.entry) |
| @@ -28,7 +29,6 @@ extern struct subsystem devices_subsys; | |||
| 28 | * they only get one called once when interrupts are disabled. | 29 | * they only get one called once when interrupts are disabled. |
| 29 | */ | 30 | */ |
| 30 | 31 | ||
| 31 | extern int sysdev_shutdown(void); | ||
| 32 | 32 | ||
| 33 | /** | 33 | /** |
| 34 | * device_shutdown - call ->shutdown() on each device to shutdown. | 34 | * device_shutdown - call ->shutdown() on each device to shutdown. |
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c index 50501764d050..8660779fb288 100644 --- a/drivers/base/power/suspend.c +++ b/drivers/base/power/suspend.c | |||
| @@ -9,10 +9,9 @@ | |||
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <linux/device.h> | 11 | #include <linux/device.h> |
| 12 | #include "../base.h" | ||
| 12 | #include "power.h" | 13 | #include "power.h" |
| 13 | 14 | ||
| 14 | extern int sysdev_suspend(pm_message_t state); | ||
| 15 | |||
| 16 | /* | 15 | /* |
| 17 | * The entries in the dpm_active list are in a depth first order, simply | 16 | * The entries in the dpm_active list are in a depth first order, simply |
| 18 | * because children are guaranteed to be discovered after parents, and | 17 | * because children are guaranteed to be discovered after parents, and |
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index f3a0c562bcb5..40d7242a07c1 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c | |||
| @@ -27,22 +27,30 @@ | |||
| 27 | 27 | ||
| 28 | static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf) | 28 | static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf) |
| 29 | { | 29 | { |
| 30 | return sprintf(buf, "%u\n", dev->power.power_state.event); | 30 | if (dev->power.power_state.event) |
| 31 | return sprintf(buf, "2\n"); | ||
| 32 | else | ||
| 33 | return sprintf(buf, "0\n"); | ||
| 31 | } | 34 | } |
| 32 | 35 | ||
| 33 | static ssize_t state_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t n) | 36 | static ssize_t state_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t n) |
| 34 | { | 37 | { |
| 35 | pm_message_t state; | 38 | pm_message_t state; |
| 36 | char * rest; | 39 | int error = -EINVAL; |
| 37 | int error = 0; | ||
| 38 | 40 | ||
| 39 | state.event = simple_strtoul(buf, &rest, 10); | 41 | state.event = PM_EVENT_SUSPEND; |
| 40 | if (*rest) | 42 | /* Older apps expected to write "3" here - confused with PCI D3 */ |
| 41 | return -EINVAL; | 43 | if ((n == 1) && !strcmp(buf, "3")) |
| 42 | if (state.event) | ||
| 43 | error = dpm_runtime_suspend(dev, state); | 44 | error = dpm_runtime_suspend(dev, state); |
| 44 | else | 45 | |
| 46 | if ((n == 1) && !strcmp(buf, "2")) | ||
| 47 | error = dpm_runtime_suspend(dev, state); | ||
| 48 | |||
| 49 | if ((n == 1) && !strcmp(buf, "0")) { | ||
| 45 | dpm_runtime_resume(dev); | 50 | dpm_runtime_resume(dev); |
| 51 | error = 0; | ||
| 52 | } | ||
| 53 | |||
| 46 | return error ? error : n; | 54 | return error ? error : n; |
| 47 | } | 55 | } |
| 48 | 56 | ||
diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 66ed8f2fece5..6fc23ab127bd 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c | |||
| @@ -21,8 +21,11 @@ | |||
| 21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
| 22 | #include <linux/string.h> | 22 | #include <linux/string.h> |
| 23 | #include <linux/pm.h> | 23 | #include <linux/pm.h> |
| 24 | #include <linux/device.h> | ||
| 24 | #include <asm/semaphore.h> | 25 | #include <asm/semaphore.h> |
| 25 | 26 | ||
| 27 | #include "base.h" | ||
| 28 | |||
| 26 | extern struct subsystem devices_subsys; | 29 | extern struct subsystem devices_subsys; |
| 27 | 30 | ||
| 28 | #define to_sysdev(k) container_of(k, struct sys_device, kobj) | 31 | #define to_sysdev(k) container_of(k, struct sys_device, kobj) |
diff --git a/drivers/base/topology.c b/drivers/base/topology.c new file mode 100644 index 000000000000..915810f6237e --- /dev/null +++ b/drivers/base/topology.c | |||
| @@ -0,0 +1,148 @@ | |||
| 1 | /* | ||
| 2 | * driver/base/topology.c - Populate sysfs with cpu topology information | ||
| 3 | * | ||
| 4 | * Written by: Zhang Yanmin, Intel Corporation | ||
| 5 | * | ||
| 6 | * Copyright (C) 2006, Intel Corp. | ||
| 7 | * | ||
| 8 | * All rights reserved. | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, but | ||
| 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
| 18 | * NON INFRINGEMENT. See the GNU General Public License for more | ||
| 19 | * details. | ||
| 20 | * | ||
| 21 | * You should have received a copy of the GNU General Public License | ||
| 22 | * along with this program; if not, write to the Free Software | ||
| 23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 24 | * | ||
| 25 | */ | ||
| 26 | #include <linux/sysdev.h> | ||
| 27 | #include <linux/init.h> | ||
| 28 | #include <linux/mm.h> | ||
| 29 | #include <linux/cpu.h> | ||
| 30 | #include <linux/module.h> | ||
| 31 | #include <linux/topology.h> | ||
| 32 | |||
| 33 | #define define_one_ro(_name) \ | ||
| 34 | static SYSDEV_ATTR(_name, 0444, show_##_name, NULL) | ||
| 35 | |||
| 36 | #define define_id_show_func(name) \ | ||
| 37 | static ssize_t show_##name(struct sys_device *dev, char *buf) \ | ||
| 38 | { \ | ||
| 39 | unsigned int cpu = dev->id; \ | ||
| 40 | return sprintf(buf, "%d\n", topology_##name(cpu)); \ | ||
| 41 | } | ||
| 42 | |||
| 43 | #define define_siblings_show_func(name) \ | ||
| 44 | static ssize_t show_##name(struct sys_device *dev, char *buf) \ | ||
| 45 | { \ | ||
| 46 | ssize_t len = -1; \ | ||
| 47 | unsigned int cpu = dev->id; \ | ||
| 48 | len = cpumask_scnprintf(buf, NR_CPUS+1, topology_##name(cpu)); \ | ||
| 49 | return (len + sprintf(buf + len, "\n")); \ | ||
| 50 | } | ||
| 51 | |||
| 52 | #ifdef topology_physical_package_id | ||
| 53 | define_id_show_func(physical_package_id); | ||
| 54 | define_one_ro(physical_package_id); | ||
| 55 | #define ref_physical_package_id_attr &attr_physical_package_id.attr, | ||
| 56 | #else | ||
| 57 | #define ref_physical_package_id_attr | ||
| 58 | #endif | ||
| 59 | |||
| 60 | #ifdef topology_core_id | ||
| 61 | define_id_show_func(core_id); | ||
| 62 | define_one_ro(core_id); | ||
| 63 | #define ref_core_id_attr &attr_core_id.attr, | ||
| 64 | #else | ||
| 65 | #define ref_core_id_attr | ||
| 66 | #endif | ||
| 67 | |||
| 68 | #ifdef topology_thread_siblings | ||
| 69 | define_siblings_show_func(thread_siblings); | ||
| 70 | define_one_ro(thread_siblings); | ||
| 71 | #define ref_thread_siblings_attr &attr_thread_siblings.attr, | ||
| 72 | #else | ||
| 73 | #define ref_thread_siblings_attr | ||
| 74 | #endif | ||
| 75 | |||
| 76 | #ifdef topology_core_siblings | ||
| 77 | define_siblings_show_func(core_siblings); | ||
| 78 | define_one_ro(core_siblings); | ||
| 79 | #define ref_core_siblings_attr &attr_core_siblings.attr, | ||
| 80 | #else | ||
| 81 | #define ref_core_siblings_attr | ||
| 82 | #endif | ||
| 83 | |||
| 84 | static struct attribute *default_attrs[] = { | ||
| 85 | ref_physical_package_id_attr | ||
| 86 | ref_core_id_attr | ||
| 87 | ref_thread_siblings_attr | ||
| 88 | ref_core_siblings_attr | ||
| 89 | NULL | ||
| 90 | }; | ||
| 91 | |||
| 92 | static struct attribute_group topology_attr_group = { | ||
| 93 | .attrs = default_attrs, | ||
| 94 | .name = "topology" | ||
| 95 | }; | ||
| 96 | |||
| 97 | /* Add/Remove cpu_topology interface for CPU device */ | ||
| 98 | static int __cpuinit topology_add_dev(struct sys_device * sys_dev) | ||
| 99 | { | ||
| 100 | sysfs_create_group(&sys_dev->kobj, &topology_attr_group); | ||
| 101 | return 0; | ||
| 102 | } | ||
| 103 | |||
| 104 | static int __cpuinit topology_remove_dev(struct sys_device * sys_dev) | ||
| 105 | { | ||
| 106 | sysfs_remove_group(&sys_dev->kobj, &topology_attr_group); | ||
| 107 | return 0; | ||
| 108 | } | ||
| 109 | |||
| 110 | static int __cpuinit topology_cpu_callback(struct notifier_block *nfb, | ||
| 111 | unsigned long action, void *hcpu) | ||
| 112 | { | ||
| 113 | unsigned int cpu = (unsigned long)hcpu; | ||
| 114 | struct sys_device *sys_dev; | ||
| 115 | |||
| 116 | sys_dev = get_cpu_sysdev(cpu); | ||
| 117 | switch (action) { | ||
| 118 | case CPU_ONLINE: | ||
| 119 | topology_add_dev(sys_dev); | ||
| 120 | break; | ||
| 121 | case CPU_DEAD: | ||
| 122 | topology_remove_dev(sys_dev); | ||
| 123 | break; | ||
| 124 | } | ||
| 125 | return NOTIFY_OK; | ||
| 126 | } | ||
| 127 | |||
| 128 | static struct notifier_block topology_cpu_notifier = | ||
| 129 | { | ||
| 130 | .notifier_call = topology_cpu_callback, | ||
| 131 | }; | ||
| 132 | |||
| 133 | static int __cpuinit topology_sysfs_init(void) | ||
| 134 | { | ||
| 135 | int i; | ||
| 136 | |||
| 137 | for_each_online_cpu(i) { | ||
| 138 | topology_cpu_callback(&topology_cpu_notifier, CPU_ONLINE, | ||
| 139 | (void *)(long)i); | ||
| 140 | } | ||
| 141 | |||
| 142 | register_cpu_notifier(&topology_cpu_notifier); | ||
| 143 | |||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | |||
| 147 | device_initcall(topology_sysfs_init); | ||
| 148 | |||
