Dynamic power management may require devices and drivers to transition
between various physical and logical states. I would like to start a
discussion on how these might be defined at the bus, driver, and class
levels.
Bus Level
=========
At the bus level, there are two state attributes, power and
enable/disable. Enable/disable may mean different things on different
buses, but they generally refer to resource decoding. A device can only
be enabled during a non-off power state.
A possible API:
struct bus_type {
char * name;
struct subsystem subsys;
struct kset drivers;
struct kset devices;
struct bus_attribute * bus_attrs;
struct device_attribute * dev_attrs;
struct driver_attribute * drv_attrs;
int (*match)(struct device * dev, struct device_driver * drv);
int (*hotplug) (struct device *dev, char **envp,
int num_envp, char *buffer, int buffer_size);
int (*suspend)(struct device * dev, pm_message_t state);
int (*resume)(struct device * dev);
int (*enable)(struct device * dev);
int (*disable)(struct device * dev);
};
Driver Level
============
At the driver level there are two areas of interest, physical and
logical state. There is an additional concern of transitioning between
these states multiple times. Because a driver acts as a bridge between
physical and logical components, I think separating these steps seems
natural.
A possible API:
struct device_driver {
char * name;
struct bus_type * bus;
struct semaphore unload_sem;
struct kobject kobj;
struct list_head devices;
struct module * owner;
int (*attach) (struct device * dev);
int (*start) (struct device * dev);
int (*open) (struct device * dev);
int (*close) (struct device * dev);
void (*stop) (struct device * dev);
void (*detach) (struct device * dev);
void (*shutdown) (struct device * dev);
int (*suspend) (struct device * dev, u32 state, u32 level);
int (*resume) (struct device * dev, u32 level);
};
*attach - allocates data structures, creates sysfs entries, prepares driver
to handle the hardware.
*start - Sets up device resources and configures the hardware. Loads
firmware, etc.
(physical)
*open - engages the hardware, and makes it usable by the class device.
(logical and physical)
*close - disengages the hardware, and stops class level access
(logical and physical)
*stop - physically disables the hardware
(physical)
*detach - tears down the driver and releases it from the "struct device"
The idea behind *attach and *detach is to move code that would only need
to be called once out of *probe and *remove.
A table could be defined that indicates what should be called for each
power level transition. *suspend and *resume could handle any extra
steps (ex. saving state). As an example, *start and *stop may only be
called when power is going to be lost entirely.
Additional states are class specific and would only be used after *open
is called.
Class Level
===========
At the class level, we could have a simple start/stop mechanism.
A possible API:
struct class_device {
struct list_head node;
struct kobject kobj;
struct class * class;
struct device * dev;
void * class_data;
char class_id[BUS_ID_SIZE];
int (*attach) (struct device * dev);
int (*start) (struct device * dev);
void (*stop) (struct device * dev);
void (*detach) (struct device * dev);
};
*attach - allocates data structures, creates sysfs entries, prepares
class to handle the device.
*start - start the logical class device, accept userspace interaction
*stop - stop the logical class device, deny userspace interaction
*detach - tear down the class driver's bindings with this class device
These are just rough ideas. I look forward to any comments or
alternative approaches.
Thanks,
Adam
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]