mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6: (47 commits) Driver core: Don't call put methods while holding a spinlock Driver core: Remove unneeded routines from driver core Driver core: Fix potential deadlock in driver core PCI: enable driver multi-threaded probe Driver Core: add ability for drivers to do a threaded probe sysfs: add proper sysfs_init() prototype drivers/base: check errors drivers/base: Platform notify needs to occur before drivers attach to the device v4l-dev2: handle __must_check add CONFIG_ENABLE_MUST_CHECK add __must_check to device management code Driver core: fixed add_bind_files() definition Driver core: fix comments in drivers/base/power/resume.c sysfs_remove_bin_file: no return value, dump_stack on error kobject: must_check fixes Driver core: add ability for devices to create and remove bin files Class: add support for class interfaces for devices Driver core: create devices/virtual/ tree Driver core: add device_rename function Driver core: add ability for classes to handle devices properly ...
This commit is contained in:
commit
dd77a4ee0f
55 changed files with 1624 additions and 542 deletions
|
@ -99,6 +99,11 @@ extern void __chk_io_ptr(void __iomem *);
|
|||
#define __must_check
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ENABLE_MUST_CHECK
|
||||
#undef __must_check
|
||||
#define __must_check
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Allow us to avoid 'defined but not used' warnings on functions and data,
|
||||
* as well as force them to be emitted to the assembly file.
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <linux/kobject.h>
|
||||
#include <linux/klist.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm.h>
|
||||
|
@ -51,14 +52,17 @@ struct bus_type {
|
|||
int (*probe)(struct device * dev);
|
||||
int (*remove)(struct device * dev);
|
||||
void (*shutdown)(struct device * dev);
|
||||
int (*suspend)(struct device * dev, pm_message_t state);
|
||||
int (*resume)(struct device * dev);
|
||||
|
||||
int (*suspend)(struct device * dev, pm_message_t state);
|
||||
int (*suspend_late)(struct device * dev, pm_message_t state);
|
||||
int (*resume_early)(struct device * dev);
|
||||
int (*resume)(struct device * dev);
|
||||
};
|
||||
|
||||
extern int bus_register(struct bus_type * bus);
|
||||
extern int __must_check bus_register(struct bus_type * bus);
|
||||
extern void bus_unregister(struct bus_type * bus);
|
||||
|
||||
extern void bus_rescan_devices(struct bus_type * bus);
|
||||
extern int __must_check bus_rescan_devices(struct bus_type * bus);
|
||||
|
||||
/* iterator helpers for buses */
|
||||
|
||||
|
@ -67,9 +71,9 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data,
|
|||
struct device * bus_find_device(struct bus_type *bus, struct device *start,
|
||||
void *data, int (*match)(struct device *, void *));
|
||||
|
||||
int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
|
||||
void * data, int (*fn)(struct device_driver *, void *));
|
||||
|
||||
int __must_check bus_for_each_drv(struct bus_type *bus,
|
||||
struct device_driver *start, void *data,
|
||||
int (*fn)(struct device_driver *, void *));
|
||||
|
||||
/* driverfs interface for exporting bus attributes */
|
||||
|
||||
|
@ -82,7 +86,8 @@ struct bus_attribute {
|
|||
#define BUS_ATTR(_name,_mode,_show,_store) \
|
||||
struct bus_attribute bus_attr_##_name = __ATTR(_name,_mode,_show,_store)
|
||||
|
||||
extern int bus_create_file(struct bus_type *, struct bus_attribute *);
|
||||
extern int __must_check bus_create_file(struct bus_type *,
|
||||
struct bus_attribute *);
|
||||
extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
|
||||
|
||||
struct device_driver {
|
||||
|
@ -101,16 +106,18 @@ struct device_driver {
|
|||
void (*shutdown) (struct device * dev);
|
||||
int (*suspend) (struct device * dev, pm_message_t state);
|
||||
int (*resume) (struct device * dev);
|
||||
|
||||
unsigned int multithread_probe:1;
|
||||
};
|
||||
|
||||
|
||||
extern int driver_register(struct device_driver * drv);
|
||||
extern int __must_check driver_register(struct device_driver * drv);
|
||||
extern void driver_unregister(struct device_driver * drv);
|
||||
|
||||
extern struct device_driver * get_driver(struct device_driver * drv);
|
||||
extern void put_driver(struct device_driver * drv);
|
||||
extern struct device_driver *driver_find(const char *name, struct bus_type *bus);
|
||||
|
||||
extern int driver_probe_done(void);
|
||||
|
||||
/* driverfs interface for exporting driver attributes */
|
||||
|
||||
|
@ -123,16 +130,17 @@ struct driver_attribute {
|
|||
#define DRIVER_ATTR(_name,_mode,_show,_store) \
|
||||
struct driver_attribute driver_attr_##_name = __ATTR(_name,_mode,_show,_store)
|
||||
|
||||
extern int driver_create_file(struct device_driver *, struct driver_attribute *);
|
||||
extern int __must_check driver_create_file(struct device_driver *,
|
||||
struct driver_attribute *);
|
||||
extern void driver_remove_file(struct device_driver *, struct driver_attribute *);
|
||||
|
||||
extern int driver_for_each_device(struct device_driver * drv, struct device * start,
|
||||
void * data, int (*fn)(struct device *, void *));
|
||||
extern int __must_check driver_for_each_device(struct device_driver * drv,
|
||||
struct device *start, void *data,
|
||||
int (*fn)(struct device *, void *));
|
||||
struct device * driver_find_device(struct device_driver *drv,
|
||||
struct device *start, void *data,
|
||||
int (*match)(struct device *, void *));
|
||||
|
||||
|
||||
/*
|
||||
* device classes
|
||||
*/
|
||||
|
@ -146,17 +154,26 @@ struct class {
|
|||
struct list_head interfaces;
|
||||
struct semaphore sem; /* locks both the children and interfaces lists */
|
||||
|
||||
struct kobject *virtual_dir;
|
||||
|
||||
struct class_attribute * class_attrs;
|
||||
struct class_device_attribute * class_dev_attrs;
|
||||
struct device_attribute * dev_attrs;
|
||||
|
||||
int (*uevent)(struct class_device *dev, char **envp,
|
||||
int num_envp, char *buffer, int buffer_size);
|
||||
int (*dev_uevent)(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size);
|
||||
|
||||
void (*release)(struct class_device *dev);
|
||||
void (*class_release)(struct class *class);
|
||||
void (*dev_release)(struct device *dev);
|
||||
|
||||
int (*suspend)(struct device *, pm_message_t state);
|
||||
int (*resume)(struct device *);
|
||||
};
|
||||
|
||||
extern int class_register(struct class *);
|
||||
extern int __must_check class_register(struct class *);
|
||||
extern void class_unregister(struct class *);
|
||||
|
||||
|
||||
|
@ -169,7 +186,8 @@ struct class_attribute {
|
|||
#define CLASS_ATTR(_name,_mode,_show,_store) \
|
||||
struct class_attribute class_attr_##_name = __ATTR(_name,_mode,_show,_store)
|
||||
|
||||
extern int class_create_file(struct class *, const struct class_attribute *);
|
||||
extern int __must_check class_create_file(struct class *,
|
||||
const struct class_attribute *);
|
||||
extern void class_remove_file(struct class *, const struct class_attribute *);
|
||||
|
||||
struct class_device_attribute {
|
||||
|
@ -182,7 +200,7 @@ struct class_device_attribute {
|
|||
struct class_device_attribute class_device_attr_##_name = \
|
||||
__ATTR(_name,_mode,_show,_store)
|
||||
|
||||
extern int class_device_create_file(struct class_device *,
|
||||
extern int __must_check class_device_create_file(struct class_device *,
|
||||
const struct class_device_attribute *);
|
||||
|
||||
/**
|
||||
|
@ -242,10 +260,10 @@ class_set_devdata (struct class_device *dev, void *data)
|
|||
}
|
||||
|
||||
|
||||
extern int class_device_register(struct class_device *);
|
||||
extern int __must_check class_device_register(struct class_device *);
|
||||
extern void class_device_unregister(struct class_device *);
|
||||
extern void class_device_initialize(struct class_device *);
|
||||
extern int class_device_add(struct class_device *);
|
||||
extern int __must_check class_device_add(struct class_device *);
|
||||
extern void class_device_del(struct class_device *);
|
||||
|
||||
extern int class_device_rename(struct class_device *, char *);
|
||||
|
@ -255,7 +273,7 @@ extern void class_device_put(struct class_device *);
|
|||
|
||||
extern void class_device_remove_file(struct class_device *,
|
||||
const struct class_device_attribute *);
|
||||
extern int class_device_create_bin_file(struct class_device *,
|
||||
extern int __must_check class_device_create_bin_file(struct class_device *,
|
||||
struct bin_attribute *);
|
||||
extern void class_device_remove_bin_file(struct class_device *,
|
||||
struct bin_attribute *);
|
||||
|
@ -266,22 +284,23 @@ struct class_interface {
|
|||
|
||||
int (*add) (struct class_device *, struct class_interface *);
|
||||
void (*remove) (struct class_device *, struct class_interface *);
|
||||
int (*add_dev) (struct device *, struct class_interface *);
|
||||
void (*remove_dev) (struct device *, struct class_interface *);
|
||||
};
|
||||
|
||||
extern int class_interface_register(struct class_interface *);
|
||||
extern int __must_check class_interface_register(struct class_interface *);
|
||||
extern void class_interface_unregister(struct class_interface *);
|
||||
|
||||
extern struct class *class_create(struct module *owner, char *name);
|
||||
extern struct class *class_create(struct module *owner, const char *name);
|
||||
extern void class_destroy(struct class *cls);
|
||||
extern struct class_device *class_device_create(struct class *cls,
|
||||
struct class_device *parent,
|
||||
dev_t devt,
|
||||
struct device *device,
|
||||
char *fmt, ...)
|
||||
const char *fmt, ...)
|
||||
__attribute__((format(printf,5,6)));
|
||||
extern void class_device_destroy(struct class *cls, dev_t devt);
|
||||
|
||||
|
||||
/* interface for exporting device attributes */
|
||||
struct device_attribute {
|
||||
struct attribute attr;
|
||||
|
@ -294,8 +313,13 @@ struct device_attribute {
|
|||
#define DEVICE_ATTR(_name,_mode,_show,_store) \
|
||||
struct device_attribute dev_attr_##_name = __ATTR(_name,_mode,_show,_store)
|
||||
|
||||
extern int device_create_file(struct device *device, struct device_attribute * entry);
|
||||
extern int __must_check device_create_file(struct device *device,
|
||||
struct device_attribute * entry);
|
||||
extern void device_remove_file(struct device * dev, struct device_attribute * attr);
|
||||
extern int __must_check device_create_bin_file(struct device *dev,
|
||||
struct bin_attribute *attr);
|
||||
extern void device_remove_bin_file(struct device *dev,
|
||||
struct bin_attribute *attr);
|
||||
struct device {
|
||||
struct klist klist_children;
|
||||
struct klist_node knode_parent; /* node in sibling list */
|
||||
|
@ -305,6 +329,7 @@ struct device {
|
|||
|
||||
struct kobject kobj;
|
||||
char bus_id[BUS_ID_SIZE]; /* position on parent bus */
|
||||
unsigned is_registered:1;
|
||||
struct device_attribute uevent_attr;
|
||||
struct device_attribute *devt_attr;
|
||||
|
||||
|
@ -338,6 +363,7 @@ struct device {
|
|||
struct list_head node;
|
||||
struct class *class; /* optional*/
|
||||
dev_t devt; /* dev_t, creates the sysfs "dev" */
|
||||
struct attribute_group **groups; /* optional groups */
|
||||
|
||||
void (*release)(struct device * dev);
|
||||
};
|
||||
|
@ -356,38 +382,41 @@ dev_set_drvdata (struct device *dev, void *data)
|
|||
|
||||
static inline int device_is_registered(struct device *dev)
|
||||
{
|
||||
return klist_node_attached(&dev->knode_bus);
|
||||
return dev->is_registered;
|
||||
}
|
||||
|
||||
/*
|
||||
* High level routines for use by the bus drivers
|
||||
*/
|
||||
extern int device_register(struct device * dev);
|
||||
extern int __must_check device_register(struct device * dev);
|
||||
extern void device_unregister(struct device * dev);
|
||||
extern void device_initialize(struct device * dev);
|
||||
extern int device_add(struct device * dev);
|
||||
extern int __must_check device_add(struct device * dev);
|
||||
extern void device_del(struct device * dev);
|
||||
extern int device_for_each_child(struct device *, void *,
|
||||
extern int __must_check device_for_each_child(struct device *, void *,
|
||||
int (*fn)(struct device *, void *));
|
||||
extern int device_rename(struct device *dev, char *new_name);
|
||||
|
||||
/*
|
||||
* Manual binding of a device to driver. See drivers/base/bus.c
|
||||
* for information on use.
|
||||
*/
|
||||
extern void device_bind_driver(struct device * dev);
|
||||
extern int __must_check device_bind_driver(struct device *dev);
|
||||
extern void device_release_driver(struct device * dev);
|
||||
extern int device_attach(struct device * dev);
|
||||
extern void driver_attach(struct device_driver * drv);
|
||||
extern void device_reprobe(struct device *dev);
|
||||
extern int __must_check device_attach(struct device * dev);
|
||||
extern int __must_check driver_attach(struct device_driver *drv);
|
||||
extern int __must_check device_reprobe(struct device *dev);
|
||||
|
||||
/*
|
||||
* Easy functions for dynamically creating devices on the fly
|
||||
*/
|
||||
extern struct device *device_create(struct class *cls, struct device *parent,
|
||||
dev_t devt, char *fmt, ...)
|
||||
dev_t devt, const char *fmt, ...)
|
||||
__attribute__((format(printf,4,5)));
|
||||
extern void device_destroy(struct class *cls, dev_t devt);
|
||||
|
||||
extern int virtual_device_parent(struct device *dev);
|
||||
|
||||
/*
|
||||
* Platform "fixup" functions - allow the platform to have their say
|
||||
* about devices and actions that the general device layer doesn't
|
||||
|
@ -412,7 +441,7 @@ extern void device_shutdown(void);
|
|||
|
||||
|
||||
/* drivers/base/firmware.c */
|
||||
extern int firmware_register(struct subsystem *);
|
||||
extern int __must_check firmware_register(struct subsystem *);
|
||||
extern void firmware_unregister(struct subsystem *);
|
||||
|
||||
/* debugging and troubleshooting/diagnostic helpers. */
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/types.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/rwsem.h>
|
||||
#include <linux/kref.h>
|
||||
|
@ -71,12 +72,12 @@ static inline const char * kobject_name(const struct kobject * kobj)
|
|||
extern void kobject_init(struct kobject *);
|
||||
extern void kobject_cleanup(struct kobject *);
|
||||
|
||||
extern int kobject_add(struct kobject *);
|
||||
extern int __must_check kobject_add(struct kobject *);
|
||||
extern void kobject_del(struct kobject *);
|
||||
|
||||
extern int kobject_rename(struct kobject *, const char *new_name);
|
||||
extern int __must_check kobject_rename(struct kobject *, const char *new_name);
|
||||
|
||||
extern int kobject_register(struct kobject *);
|
||||
extern int __must_check kobject_register(struct kobject *);
|
||||
extern void kobject_unregister(struct kobject *);
|
||||
|
||||
extern struct kobject * kobject_get(struct kobject *);
|
||||
|
@ -128,8 +129,8 @@ struct kset {
|
|||
|
||||
|
||||
extern void kset_init(struct kset * k);
|
||||
extern int kset_add(struct kset * k);
|
||||
extern int kset_register(struct kset * k);
|
||||
extern int __must_check kset_add(struct kset * k);
|
||||
extern int __must_check kset_register(struct kset * k);
|
||||
extern void kset_unregister(struct kset * k);
|
||||
|
||||
static inline struct kset * to_kset(struct kobject * kobj)
|
||||
|
@ -239,7 +240,7 @@ extern struct subsystem hypervisor_subsys;
|
|||
(obj)->subsys.kset.kobj.kset = &(_subsys).kset
|
||||
|
||||
extern void subsystem_init(struct subsystem *);
|
||||
extern int subsystem_register(struct subsystem *);
|
||||
extern int __must_check subsystem_register(struct subsystem *);
|
||||
extern void subsystem_unregister(struct subsystem *);
|
||||
|
||||
static inline struct subsystem * subsys_get(struct subsystem * s)
|
||||
|
@ -258,7 +259,8 @@ struct subsys_attribute {
|
|||
ssize_t (*store)(struct subsystem *, const char *, size_t);
|
||||
};
|
||||
|
||||
extern int subsys_create_file(struct subsystem * , struct subsys_attribute *);
|
||||
extern int __must_check subsys_create_file(struct subsystem * ,
|
||||
struct subsys_attribute *);
|
||||
|
||||
#if defined(CONFIG_HOTPLUG)
|
||||
void kobject_uevent(struct kobject *kobj, enum kobject_action action);
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include <linux/types.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
|
@ -346,6 +347,8 @@ struct pci_driver {
|
|||
int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */
|
||||
void (*remove) (struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */
|
||||
int (*suspend) (struct pci_dev *dev, pm_message_t state); /* Device suspended */
|
||||
int (*suspend_late) (struct pci_dev *dev, pm_message_t state);
|
||||
int (*resume_early) (struct pci_dev *dev);
|
||||
int (*resume) (struct pci_dev *dev); /* Device woken up */
|
||||
int (*enable_wake) (struct pci_dev *dev, pci_power_t state, int enable); /* Enable wake event */
|
||||
void (*shutdown) (struct pci_dev *dev);
|
||||
|
@ -401,7 +404,7 @@ extern struct list_head pci_root_buses; /* list of all known PCI buses */
|
|||
extern struct list_head pci_devices; /* list of all devices */
|
||||
|
||||
void pcibios_fixup_bus(struct pci_bus *);
|
||||
int pcibios_enable_device(struct pci_dev *, int mask);
|
||||
int __must_check pcibios_enable_device(struct pci_dev *, int mask);
|
||||
char *pcibios_setup (char *str);
|
||||
|
||||
/* Used only when drivers/pci/setup.c is used */
|
||||
|
@ -488,19 +491,19 @@ static inline int pci_write_config_dword(struct pci_dev *dev, int where, u32 val
|
|||
return pci_bus_write_config_dword (dev->bus, dev->devfn, where, val);
|
||||
}
|
||||
|
||||
int pci_enable_device(struct pci_dev *dev);
|
||||
int pci_enable_device_bars(struct pci_dev *dev, int mask);
|
||||
int __must_check pci_enable_device(struct pci_dev *dev);
|
||||
int __must_check pci_enable_device_bars(struct pci_dev *dev, int mask);
|
||||
void pci_disable_device(struct pci_dev *dev);
|
||||
void pci_set_master(struct pci_dev *dev);
|
||||
#define HAVE_PCI_SET_MWI
|
||||
int pci_set_mwi(struct pci_dev *dev);
|
||||
int __must_check pci_set_mwi(struct pci_dev *dev);
|
||||
void pci_clear_mwi(struct pci_dev *dev);
|
||||
void pci_intx(struct pci_dev *dev, int enable);
|
||||
int pci_set_dma_mask(struct pci_dev *dev, u64 mask);
|
||||
int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask);
|
||||
void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno);
|
||||
int pci_assign_resource(struct pci_dev *dev, int i);
|
||||
int pci_assign_resource_fixed(struct pci_dev *dev, int i);
|
||||
int __must_check pci_assign_resource(struct pci_dev *dev, int i);
|
||||
int __must_check pci_assign_resource_fixed(struct pci_dev *dev, int i);
|
||||
void pci_restore_bars(struct pci_dev *dev);
|
||||
|
||||
/* ROM control related routines */
|
||||
|
@ -526,23 +529,24 @@ void pdev_sort_resources(struct pci_dev *, struct resource_list *);
|
|||
void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *),
|
||||
int (*)(struct pci_dev *, u8, u8));
|
||||
#define HAVE_PCI_REQ_REGIONS 2
|
||||
int pci_request_regions(struct pci_dev *, const char *);
|
||||
int __must_check pci_request_regions(struct pci_dev *, const char *);
|
||||
void pci_release_regions(struct pci_dev *);
|
||||
int pci_request_region(struct pci_dev *, int, const char *);
|
||||
int __must_check pci_request_region(struct pci_dev *, int, const char *);
|
||||
void pci_release_region(struct pci_dev *, int);
|
||||
|
||||
/* drivers/pci/bus.c */
|
||||
int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
|
||||
resource_size_t size, resource_size_t align,
|
||||
resource_size_t min, unsigned int type_mask,
|
||||
void (*alignf)(void *, struct resource *,
|
||||
resource_size_t, resource_size_t),
|
||||
void *alignf_data);
|
||||
int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
|
||||
struct resource *res, resource_size_t size,
|
||||
resource_size_t align, resource_size_t min,
|
||||
unsigned int type_mask,
|
||||
void (*alignf)(void *, struct resource *,
|
||||
resource_size_t, resource_size_t),
|
||||
void *alignf_data);
|
||||
void pci_enable_bridges(struct pci_bus *bus);
|
||||
|
||||
/* Proper probing supporting hot-pluggable devices */
|
||||
int __pci_register_driver(struct pci_driver *, struct module *);
|
||||
static inline int pci_register_driver(struct pci_driver *driver)
|
||||
int __must_check __pci_register_driver(struct pci_driver *, struct module *);
|
||||
static inline int __must_check pci_register_driver(struct pci_driver *driver)
|
||||
{
|
||||
return __pci_register_driver(driver, THIS_MODULE);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,8 @@ struct platform_driver {
|
|||
int (*remove)(struct platform_device *);
|
||||
void (*shutdown)(struct platform_device *);
|
||||
int (*suspend)(struct platform_device *, pm_message_t state);
|
||||
int (*suspend_late)(struct platform_device *, pm_message_t state);
|
||||
int (*resume_early)(struct platform_device *);
|
||||
int (*resume)(struct platform_device *);
|
||||
struct device_driver driver;
|
||||
};
|
||||
|
|
|
@ -142,29 +142,61 @@ typedef struct pm_message {
|
|||
} pm_message_t;
|
||||
|
||||
/*
|
||||
* There are 4 important states driver can be in:
|
||||
* ON -- driver is working
|
||||
* FREEZE -- stop operations and apply whatever policy is applicable to a
|
||||
* suspended driver of that class, freeze queues for block like IDE
|
||||
* does, drop packets for ethernet, etc... stop DMA engine too etc...
|
||||
* so a consistent image can be saved; but do not power any hardware
|
||||
* down.
|
||||
* SUSPEND - like FREEZE, but hardware is doing as much powersaving as
|
||||
* possible. Roughly pci D3.
|
||||
* Several driver power state transitions are externally visible, affecting
|
||||
* the state of pending I/O queues and (for drivers that touch hardware)
|
||||
* interrupts, wakeups, DMA, and other hardware state. There may also be
|
||||
* internal transitions to various low power modes, which are transparent
|
||||
* to the rest of the driver stack (such as a driver that's ON gating off
|
||||
* clocks which are not in active use).
|
||||
*
|
||||
* Unfortunately, current drivers only recognize numeric values 0 (ON) and 3
|
||||
* (SUSPEND). We'll need to fix the drivers. So yes, putting 3 to all different
|
||||
* defines is intentional, and will go away as soon as drivers are fixed. Also
|
||||
* note that typedef is neccessary, we'll probably want to switch to
|
||||
* typedef struct pm_message_t { int event; int flags; } pm_message_t
|
||||
* or something similar soon.
|
||||
* One transition is triggered by resume(), after a suspend() call; the
|
||||
* message is implicit:
|
||||
*
|
||||
* ON Driver starts working again, responding to hardware events
|
||||
* and software requests. The hardware may have gone through
|
||||
* a power-off reset, or it may have maintained state from the
|
||||
* previous suspend() which the driver will rely on while
|
||||
* resuming. On most platforms, there are no restrictions on
|
||||
* availability of resources like clocks during resume().
|
||||
*
|
||||
* Other transitions are triggered by messages sent using suspend(). All
|
||||
* these transitions quiesce the driver, so that I/O queues are inactive.
|
||||
* That commonly entails turning off IRQs and DMA; there may be rules
|
||||
* about how to quiesce that are specific to the bus or the device's type.
|
||||
* (For example, network drivers mark the link state.) Other details may
|
||||
* differ according to the message:
|
||||
*
|
||||
* SUSPEND Quiesce, enter a low power device state appropriate for
|
||||
* the upcoming system state (such as PCI_D3hot), and enable
|
||||
* wakeup events as appropriate.
|
||||
*
|
||||
* FREEZE Quiesce operations so that a consistent image can be saved;
|
||||
* but do NOT otherwise enter a low power device state, and do
|
||||
* NOT emit system wakeup events.
|
||||
*
|
||||
* PRETHAW Quiesce as if for FREEZE; additionally, prepare for restoring
|
||||
* the system from a snapshot taken after an earlier FREEZE.
|
||||
* Some drivers will need to reset their hardware state instead
|
||||
* of preserving it, to ensure that it's never mistaken for the
|
||||
* state which that earlier snapshot had set up.
|
||||
*
|
||||
* A minimally power-aware driver treats all messages as SUSPEND, fully
|
||||
* reinitializes its device during resume() -- whether or not it was reset
|
||||
* during the suspend/resume cycle -- and can't issue wakeup events.
|
||||
*
|
||||
* More power-aware drivers may also use low power states at runtime as
|
||||
* well as during system sleep states like PM_SUSPEND_STANDBY. They may
|
||||
* be able to use wakeup events to exit from runtime low-power states,
|
||||
* or from system low-power states such as standby or suspend-to-RAM.
|
||||
*/
|
||||
|
||||
#define PM_EVENT_ON 0
|
||||
#define PM_EVENT_FREEZE 1
|
||||
#define PM_EVENT_SUSPEND 2
|
||||
#define PM_EVENT_PRETHAW 3
|
||||
|
||||
#define PMSG_FREEZE ((struct pm_message){ .event = PM_EVENT_FREEZE, })
|
||||
#define PMSG_PRETHAW ((struct pm_message){ .event = PM_EVENT_PRETHAW, })
|
||||
#define PMSG_SUSPEND ((struct pm_message){ .event = PM_EVENT_SUSPEND, })
|
||||
#define PMSG_ON ((struct pm_message){ .event = PM_EVENT_ON, })
|
||||
|
||||
|
@ -190,6 +222,7 @@ extern void device_resume(void);
|
|||
extern suspend_disk_method_t pm_disk_mode;
|
||||
|
||||
extern int device_suspend(pm_message_t state);
|
||||
extern int device_prepare_suspend(pm_message_t state);
|
||||
|
||||
#define device_set_wakeup_enable(dev,val) \
|
||||
((dev)->power.should_wakeup = !!(val))
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#ifndef _SYSFS_H_
|
||||
#define _SYSFS_H_
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/atomic.h>
|
||||
|
||||
struct kobject;
|
||||
|
@ -86,40 +87,44 @@ struct sysfs_dirent {
|
|||
|
||||
#ifdef CONFIG_SYSFS
|
||||
|
||||
extern int
|
||||
extern int __must_check
|
||||
sysfs_create_dir(struct kobject *);
|
||||
|
||||
extern void
|
||||
sysfs_remove_dir(struct kobject *);
|
||||
|
||||
extern int
|
||||
extern int __must_check
|
||||
sysfs_rename_dir(struct kobject *, const char *new_name);
|
||||
|
||||
extern int
|
||||
extern int __must_check
|
||||
sysfs_create_file(struct kobject *, const struct attribute *);
|
||||
|
||||
extern int
|
||||
extern int __must_check
|
||||
sysfs_update_file(struct kobject *, const struct attribute *);
|
||||
|
||||
extern int
|
||||
extern int __must_check
|
||||
sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode);
|
||||
|
||||
extern void
|
||||
sysfs_remove_file(struct kobject *, const struct attribute *);
|
||||
|
||||
extern int
|
||||
extern int __must_check
|
||||
sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name);
|
||||
|
||||
extern void
|
||||
sysfs_remove_link(struct kobject *, const char * name);
|
||||
|
||||
int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr);
|
||||
int sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr);
|
||||
int __must_check sysfs_create_bin_file(struct kobject *kobj,
|
||||
struct bin_attribute *attr);
|
||||
void sysfs_remove_bin_file(struct kobject *kobj, struct bin_attribute *attr);
|
||||
|
||||
int sysfs_create_group(struct kobject *, const struct attribute_group *);
|
||||
int __must_check sysfs_create_group(struct kobject *,
|
||||
const struct attribute_group *);
|
||||
void sysfs_remove_group(struct kobject *, const struct attribute_group *);
|
||||
void sysfs_notify(struct kobject * k, char *dir, char *attr);
|
||||
|
||||
extern int __must_check sysfs_init(void);
|
||||
|
||||
#else /* CONFIG_SYSFS */
|
||||
|
||||
static inline int sysfs_create_dir(struct kobject * k)
|
||||
|
@ -191,6 +196,11 @@ static inline void sysfs_notify(struct kobject * k, char *dir, char *attr)
|
|||
{
|
||||
}
|
||||
|
||||
static inline int __must_check sysfs_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SYSFS */
|
||||
|
||||
#endif /* _SYSFS_H_ */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue