diff options
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/cpu.h | 5 | ||||
| -rw-r--r-- | include/linux/cpufreq.h | 4 | ||||
| -rw-r--r-- | include/linux/device.h | 24 | ||||
| -rw-r--r-- | include/linux/kobject.h | 8 | ||||
| -rw-r--r-- | include/linux/list.h | 14 | ||||
| -rw-r--r-- | include/linux/node.h | 4 | ||||
| -rw-r--r-- | include/linux/sysdev.h | 98 |
7 files changed, 124 insertions, 33 deletions
diff --git a/include/linux/cpu.h b/include/linux/cpu.h index 93853448aeb9..2f374d79f157 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -19,7 +19,7 @@ #ifndef _LINUX_CPU_H_ #define _LINUX_CPU_H_ -#include <linux/device.h> +#include <linux/sysdev.h> #include <linux/node.h> #include <asm/semaphore.h> @@ -29,8 +29,6 @@ struct cpu { }; extern int register_cpu(struct cpu *, int, struct node *); -extern struct class cpu_class; - struct notifier_block; #ifdef CONFIG_SMP @@ -48,6 +46,7 @@ static inline void unregister_cpu_notifier(struct notifier_block *nb) { } #endif /* CONFIG_SMP */ +extern struct sysdev_class cpu_sysdev_class; /* Stop CPUs going up and down. */ extern struct semaphore cpucontrol; diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 3dc9062bd414..1bdb797bf9bd 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -205,10 +205,6 @@ struct freq_attr { int cpufreq_set_policy(struct cpufreq_policy *policy); int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu); -#ifdef CONFIG_PM -int cpufreq_restore(void); -#endif - /* the proc_intf.c needs this */ int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpufreq_governor **governor); diff --git a/include/linux/device.h b/include/linux/device.h index 3604d351f3f0..1bd92551c077 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -351,30 +351,6 @@ extern int (*platform_notify_remove)(struct device * dev); extern struct device * get_device(struct device * dev); extern void put_device(struct device * dev); -/* drivers/base/sys.c */ - -struct sys_root { - u32 id; - struct device dev; - struct device sysdev; -}; - -extern int sys_register_root(struct sys_root *); -extern void sys_unregister_root(struct sys_root *); - - -struct sys_device { - char * name; - u32 id; - struct sys_root * root; - struct device dev; - struct class_device class_dev; -}; - -extern int sys_device_register(struct sys_device *); -extern void sys_device_unregister(struct sys_device *); - -extern struct bus_type system_bus_type; /* drivers/base/platform.c */ diff --git a/include/linux/kobject.h b/include/linux/kobject.h index c982391cf8d6..5d42248dd95f 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -118,6 +118,14 @@ static inline struct kobj_type * get_ktype(struct kobject * k) extern struct kobject * kset_find_obj(struct kset *, const char *); +/** + * Use this when initializing an embedded kset with no other + * fields to initialize. + */ +#define set_kset_name(str) .kset = { .kobj = { .name = str } } + + + struct subsystem { struct kset kset; struct rw_semaphore rwsem; diff --git a/include/linux/list.h b/include/linux/list.h index d6305f84bfe6..eed55ea5860a 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -310,6 +310,20 @@ static inline void list_splice_init(struct list_head *list, prefetch(pos->member.next)) /** + * list_for_each_entry_reverse - iterate backwards over list of given type. + * @pos: the type * to use as a loop counter. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry_reverse(pos, head, member) \ + for (pos = list_entry((head)->prev, typeof(*pos), member), \ + prefetch(pos->member.prev); \ + &pos->member != (head); \ + pos = list_entry(pos->member.prev, typeof(*pos), member), \ + prefetch(pos->member.prev)) + + +/** * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry * @pos: the type * to use as a loop counter. * @n: another type * to use as temporary storage diff --git a/include/linux/node.h b/include/linux/node.h index 294606bbff5a..90543a94b86e 100644 --- a/include/linux/node.h +++ b/include/linux/node.h @@ -19,11 +19,11 @@ #ifndef _LINUX_NODE_H_ #define _LINUX_NODE_H_ -#include <linux/device.h> +#include <linux/sysdev.h> struct node { unsigned long cpumap; /* Bitmap of CPUs on the Node */ - struct sys_root sysroot; + struct sys_device sysdev; }; extern int register_node(struct node *, int, struct node *); diff --git a/include/linux/sysdev.h b/include/linux/sysdev.h new file mode 100644 index 000000000000..4bc3e22b5104 --- /dev/null +++ b/include/linux/sysdev.h @@ -0,0 +1,98 @@ +/** + * System devices follow a slightly different driver model. + * They don't need to do dynammic driver binding, can't be probed, + * and don't reside on any type of peripheral bus. + * So, we represent and treat them a little differently. + * + * We still have a notion of a driver for a system device, because we still + * want to perform basic operations on these devices. + * + * We also support auxillary drivers binding to devices of a certain class. + * + * This allows configurable drivers to register themselves for devices of + * a certain type. And, it allows class definitions to reside in generic + * code while arch-specific code can register specific drivers. + * + * Auxillary drivers registered with a NULL cls are registered as drivers + * for all system devices, and get notification calls for each device. + */ + + +#ifndef _SYSDEV_H_ +#define _SYSDEV_H_ + +#include <linux/kobject.h> + + +struct sys_device; + +struct sysdev_class { + struct list_head drivers; + + /* Default operations for these types of devices */ + int (*shutdown)(struct sys_device *); + int (*save)(struct sys_device *, u32 state); + int (*suspend)(struct sys_device *, u32 state); + int (*resume)(struct sys_device *); + int (*restore)(struct sys_device *); + struct kset kset; +}; + + +extern int sysdev_class_register(struct sysdev_class *); +extern void sysdev_class_unregister(struct sysdev_class *); + + +/** + * Auxillary system device drivers. + */ + +struct sysdev_driver { + struct list_head entry; + int (*add)(struct sys_device *); + int (*remove)(struct sys_device *); + int (*shutdown)(struct sys_device *); + int (*save)(struct sys_device *, u32 state); + int (*suspend)(struct sys_device *, u32 state); + int (*resume)(struct sys_device *); + int (*restore)(struct sys_device *); +}; + + +extern int sysdev_driver_register(struct sysdev_class *, struct sysdev_driver *); +extern void sysdev_driver_unregister(struct sysdev_class *, struct sysdev_driver *); + + +/** + * sys_devices can be simplified a lot from regular devices, because they're + * simply not as versatile. + */ + +struct sys_device { + u32 id; + struct sysdev_class * cls; + struct kobject kobj; +}; + +extern int sys_device_register(struct sys_device *); +extern void sys_device_unregister(struct sys_device *); + + +struct sysdev_attribute { + struct attribute attr; + ssize_t (*show)(struct sys_device *, char *); + ssize_t (*store)(struct sys_device *, const char *, size_t); +}; + + +#define SYSDEV_ATTR(_name,_mode,_show,_store) \ +struct sysdev_attribute attr_##_name = { \ + .attr = {.name = __stringify(_name), .mode = _mode }, \ + .show = _show, \ + .store = _store, \ +}; + +extern int sysdev_create_file(struct sys_device *, struct sysdev_attribute *); +extern void sysdev_remove_file(struct sys_device *, struct sysdev_attribute *); + +#endif /* _SYSDEV_H_ */ |
