mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-03-28 01:45:45 +00:00
Automatic merge of rsync://rsync.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-2.6.git/
This commit is contained in:
commit
05d3794aa8
13 changed files with 37 additions and 122 deletions
|
@ -7,7 +7,6 @@ that support it. For example, a given bus might look like this:
|
||||||
|-- 0000:17:00.0
|
|-- 0000:17:00.0
|
||||||
| |-- class
|
| |-- class
|
||||||
| |-- config
|
| |-- config
|
||||||
| |-- detach_state
|
|
||||||
| |-- device
|
| |-- device
|
||||||
| |-- irq
|
| |-- irq
|
||||||
| |-- local_cpus
|
| |-- local_cpus
|
||||||
|
@ -19,7 +18,7 @@ that support it. For example, a given bus might look like this:
|
||||||
| |-- subsystem_device
|
| |-- subsystem_device
|
||||||
| |-- subsystem_vendor
|
| |-- subsystem_vendor
|
||||||
| `-- vendor
|
| `-- vendor
|
||||||
`-- detach_state
|
`-- ...
|
||||||
|
|
||||||
The topmost element describes the PCI domain and bus number. In this case,
|
The topmost element describes the PCI domain and bus number. In this case,
|
||||||
the domain number is 0000 and the bus number is 17 (both values are in hex).
|
the domain number is 0000 and the bus number is 17 (both values are in hex).
|
||||||
|
@ -31,7 +30,6 @@ files, each with their own function.
|
||||||
---- --------
|
---- --------
|
||||||
class PCI class (ascii, ro)
|
class PCI class (ascii, ro)
|
||||||
config PCI config space (binary, rw)
|
config PCI config space (binary, rw)
|
||||||
detach_state connection status (bool, rw)
|
|
||||||
device PCI device (ascii, ro)
|
device PCI device (ascii, ro)
|
||||||
irq IRQ number (ascii, ro)
|
irq IRQ number (ascii, ro)
|
||||||
local_cpus nearby CPU mask (cpumask, ro)
|
local_cpus nearby CPU mask (cpumask, ro)
|
||||||
|
@ -85,4 +83,4 @@ useful return codes should be provided.
|
||||||
|
|
||||||
Legacy resources are protected by the HAVE_PCI_LEGACY define. Platforms
|
Legacy resources are protected by the HAVE_PCI_LEGACY define. Platforms
|
||||||
wishing to support legacy functionality should define it and provide
|
wishing to support legacy functionality should define it and provide
|
||||||
pci_legacy_read, pci_legacy_write and pci_mmap_legacy_page_range functions.
|
pci_legacy_read, pci_legacy_write and pci_mmap_legacy_page_range functions.
|
||||||
|
|
|
@ -207,27 +207,6 @@ SYSTEM_SHUTDOWN, I do not understand this one too much. probably event
|
||||||
#READY_AFTER_RESUME
|
#READY_AFTER_RESUME
|
||||||
#
|
#
|
||||||
|
|
||||||
Driver Detach Power Management
|
|
||||||
|
|
||||||
The kernel now supports the ability to place a device in a low-power
|
|
||||||
state when it is detached from its driver, which happens when its
|
|
||||||
module is removed.
|
|
||||||
|
|
||||||
Each device contains a 'detach_state' file in its sysfs directory
|
|
||||||
which can be used to control this state. Reading from this file
|
|
||||||
displays what the current detach state is set to. This is 0 (On) by
|
|
||||||
default. A user may write a positive integer value to this file in the
|
|
||||||
range of 1-4 inclusive.
|
|
||||||
|
|
||||||
A value of 1-3 will indicate the device should be placed in that
|
|
||||||
low-power state, which will cause ->suspend() to be called for that
|
|
||||||
device. A value of 4 indicates that the device should be shutdown, so
|
|
||||||
->shutdown() will be called for that device.
|
|
||||||
|
|
||||||
The driver is responsible for reinitializing the device when the
|
|
||||||
module is re-inserted during it's ->probe() (or equivalent) method.
|
|
||||||
The driver core will not call any extra functions when binding the
|
|
||||||
device to the driver.
|
|
||||||
|
|
||||||
pm_message_t meaning
|
pm_message_t meaning
|
||||||
|
|
||||||
|
|
|
@ -347,8 +347,8 @@ address that is created by firmware. An example vty-server sysfs entry
|
||||||
looks like the following:
|
looks like the following:
|
||||||
|
|
||||||
Pow5:/sys/bus/vio/drivers/hvcs/30000004 # ls
|
Pow5:/sys/bus/vio/drivers/hvcs/30000004 # ls
|
||||||
. current_vty devspec name partner_vtys
|
. current_vty devspec name partner_vtys
|
||||||
.. detach_state index partner_clcs vterm_state
|
.. index partner_clcs vterm_state
|
||||||
|
|
||||||
Each entry is provided, by default with a "name" attribute. Reading the
|
Each entry is provided, by default with a "name" attribute. Reading the
|
||||||
"name" attribute will reveal the device type as shown in the following
|
"name" attribute will reveal the device type as shown in the following
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Makefile for the Linux device tree
|
# Makefile for the Linux device tree
|
||||||
|
|
||||||
obj-y := core.o sys.o interface.o bus.o \
|
obj-y := core.o sys.o bus.o \
|
||||||
driver.o class.o class_simple.o platform.o \
|
driver.o class.o class_simple.o platform.o \
|
||||||
cpu.o firmware.o init.o map.o dmapool.o \
|
cpu.o firmware.o init.o map.o dmapool.o \
|
||||||
attribute_container.o transport_class.o
|
attribute_container.o transport_class.o
|
||||||
|
|
|
@ -390,7 +390,6 @@ void device_release_driver(struct device * dev)
|
||||||
sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj));
|
sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj));
|
||||||
sysfs_remove_link(&dev->kobj, "driver");
|
sysfs_remove_link(&dev->kobj, "driver");
|
||||||
list_del_init(&dev->driver_list);
|
list_del_init(&dev->driver_list);
|
||||||
device_detach_shutdown(dev);
|
|
||||||
if (drv->remove)
|
if (drv->remove)
|
||||||
drv->remove(dev);
|
drv->remove(dev);
|
||||||
dev->driver = NULL;
|
dev->driver = NULL;
|
||||||
|
|
|
@ -31,8 +31,6 @@ int (*platform_notify_remove)(struct device * dev) = NULL;
|
||||||
#define to_dev(obj) container_of(obj, struct device, kobj)
|
#define to_dev(obj) container_of(obj, struct device, kobj)
|
||||||
#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
|
#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
|
||||||
|
|
||||||
extern struct attribute * dev_default_attrs[];
|
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
|
dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
|
||||||
{
|
{
|
||||||
|
@ -89,7 +87,6 @@ static void device_release(struct kobject * kobj)
|
||||||
static struct kobj_type ktype_device = {
|
static struct kobj_type ktype_device = {
|
||||||
.release = device_release,
|
.release = device_release,
|
||||||
.sysfs_ops = &dev_sysfs_ops,
|
.sysfs_ops = &dev_sysfs_ops,
|
||||||
.default_attrs = dev_default_attrs,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
/*
|
|
||||||
* drivers/base/interface.c - common driverfs interface that's exported to
|
|
||||||
* the world for all devices.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2002-3 Patrick Mochel
|
|
||||||
* Copyright (c) 2002-3 Open Source Development Labs
|
|
||||||
*
|
|
||||||
* This file is released under the GPLv2
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/device.h>
|
|
||||||
#include <linux/err.h>
|
|
||||||
#include <linux/stat.h>
|
|
||||||
#include <linux/string.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* detach_state - control the default power state for the device.
|
|
||||||
*
|
|
||||||
* This is the state the device enters when it's driver module is
|
|
||||||
* unloaded. The value is an unsigned integer, in the range of 0-4.
|
|
||||||
* '0' indicates 'On', so no action will be taken when the driver is
|
|
||||||
* unloaded. This is the default behavior.
|
|
||||||
* '4' indicates 'Off', meaning the driver core will call the driver's
|
|
||||||
* shutdown method to quiesce the device.
|
|
||||||
* 1-3 indicate a low-power state for the device to enter via the
|
|
||||||
* driver's suspend method.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static ssize_t detach_show(struct device * dev, char * buf)
|
|
||||||
{
|
|
||||||
return sprintf(buf, "%u\n", dev->detach_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t detach_store(struct device * dev, const char * buf, size_t n)
|
|
||||||
{
|
|
||||||
u32 state;
|
|
||||||
state = simple_strtoul(buf, NULL, 10);
|
|
||||||
if (state > 4)
|
|
||||||
return -EINVAL;
|
|
||||||
dev->detach_state = state;
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
static DEVICE_ATTR(detach_state, 0644, detach_show, detach_store);
|
|
||||||
|
|
||||||
|
|
||||||
struct attribute * dev_default_attrs[] = {
|
|
||||||
&dev_attr_detach_state.attr,
|
|
||||||
NULL,
|
|
||||||
};
|
|
|
@ -1,18 +1,7 @@
|
||||||
|
|
||||||
|
|
||||||
enum {
|
|
||||||
DEVICE_PM_ON,
|
|
||||||
DEVICE_PM1,
|
|
||||||
DEVICE_PM2,
|
|
||||||
DEVICE_PM3,
|
|
||||||
DEVICE_PM_OFF,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* shutdown.c
|
* shutdown.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern int device_detach_shutdown(struct device *);
|
|
||||||
extern void device_shutdown(void);
|
extern void device_shutdown(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,17 @@ extern int sysdev_resume(void);
|
||||||
|
|
||||||
int resume_device(struct device * dev)
|
int resume_device(struct device * dev)
|
||||||
{
|
{
|
||||||
if (dev->bus && dev->bus->resume)
|
if (dev->power.pm_parent
|
||||||
|
&& dev->power.pm_parent->power.power_state) {
|
||||||
|
dev_err(dev, "PM: resume from %d, parent %s still %d\n",
|
||||||
|
dev->power.power_state,
|
||||||
|
dev->power.pm_parent->bus_id,
|
||||||
|
dev->power.pm_parent->power.power_state);
|
||||||
|
}
|
||||||
|
if (dev->bus && dev->bus->resume) {
|
||||||
|
dev_dbg(dev,"resuming\n");
|
||||||
return dev->bus->resume(dev);
|
return dev->bus->resume(dev);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,20 +19,6 @@
|
||||||
extern struct subsystem devices_subsys;
|
extern struct subsystem devices_subsys;
|
||||||
|
|
||||||
|
|
||||||
int device_detach_shutdown(struct device * dev)
|
|
||||||
{
|
|
||||||
if (!dev->detach_state)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (dev->detach_state == DEVICE_PM_OFF) {
|
|
||||||
if (dev->driver && dev->driver->shutdown)
|
|
||||||
dev->driver->shutdown(dev);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return dpm_runtime_suspend(dev, dev->detach_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We handle system devices differently - we suspend and shut them
|
* We handle system devices differently - we suspend and shut them
|
||||||
* down last and resume them first. That way, we don't do anything stupid like
|
* down last and resume them first. That way, we don't do anything stupid like
|
||||||
|
@ -52,13 +38,12 @@ void device_shutdown(void)
|
||||||
struct device * dev;
|
struct device * dev;
|
||||||
|
|
||||||
down_write(&devices_subsys.rwsem);
|
down_write(&devices_subsys.rwsem);
|
||||||
list_for_each_entry_reverse(dev, &devices_subsys.kset.list, kobj.entry) {
|
list_for_each_entry_reverse(dev, &devices_subsys.kset.list,
|
||||||
pr_debug("shutting down %s: ", dev->bus_id);
|
kobj.entry) {
|
||||||
if (dev->driver && dev->driver->shutdown) {
|
if (dev->driver && dev->driver->shutdown) {
|
||||||
pr_debug("Ok\n");
|
dev_dbg(dev, "shutdown\n");
|
||||||
dev->driver->shutdown(dev);
|
dev->driver->shutdown(dev);
|
||||||
} else
|
}
|
||||||
pr_debug("Ignored.\n");
|
|
||||||
}
|
}
|
||||||
up_write(&devices_subsys.rwsem);
|
up_write(&devices_subsys.rwsem);
|
||||||
|
|
||||||
|
|
|
@ -39,12 +39,25 @@ int suspend_device(struct device * dev, pm_message_t state)
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
dev_dbg(dev, "suspending\n");
|
if (dev->power.power_state) {
|
||||||
|
dev_dbg(dev, "PM: suspend %d-->%d\n",
|
||||||
|
dev->power.power_state, state);
|
||||||
|
}
|
||||||
|
if (dev->power.pm_parent
|
||||||
|
&& dev->power.pm_parent->power.power_state) {
|
||||||
|
dev_err(dev,
|
||||||
|
"PM: suspend %d->%d, parent %s already %d\n",
|
||||||
|
dev->power.power_state, state,
|
||||||
|
dev->power.pm_parent->bus_id,
|
||||||
|
dev->power.pm_parent->power.power_state);
|
||||||
|
}
|
||||||
|
|
||||||
dev->power.prev_state = dev->power.power_state;
|
dev->power.prev_state = dev->power.power_state;
|
||||||
|
|
||||||
if (dev->bus && dev->bus->suspend && !dev->power.power_state)
|
if (dev->bus && dev->bus->suspend && !dev->power.power_state) {
|
||||||
|
dev_dbg(dev, "suspending\n");
|
||||||
error = dev->bus->suspend(dev, state);
|
error = dev->bus->suspend(dev, state);
|
||||||
|
}
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -273,9 +273,6 @@ struct device {
|
||||||
BIOS data relevant to device) */
|
BIOS data relevant to device) */
|
||||||
struct dev_pm_info power;
|
struct dev_pm_info power;
|
||||||
|
|
||||||
u32 detach_state; /* State to enter when device is
|
|
||||||
detached from its driver. */
|
|
||||||
|
|
||||||
u64 *dma_mask; /* dma mask (if dma'able device) */
|
u64 *dma_mask; /* dma mask (if dma'able device) */
|
||||||
u64 coherent_dma_mask;/* Like dma_mask, but for
|
u64 coherent_dma_mask;/* Like dma_mask, but for
|
||||||
alloc_coherent mappings as
|
alloc_coherent mappings as
|
||||||
|
|
|
@ -156,14 +156,14 @@ static int enter_state(suspend_state_t state)
|
||||||
goto Unlock;
|
goto Unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_debug("PM: Preparing system for suspend\n");
|
pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]);
|
||||||
if ((error = suspend_prepare(state)))
|
if ((error = suspend_prepare(state)))
|
||||||
goto Unlock;
|
goto Unlock;
|
||||||
|
|
||||||
pr_debug("PM: Entering state.\n");
|
pr_debug("PM: Entering %s sleep\n", pm_states[state]);
|
||||||
error = suspend_enter(state);
|
error = suspend_enter(state);
|
||||||
|
|
||||||
pr_debug("PM: Finishing up.\n");
|
pr_debug("PM: Finishing wakeup.\n");
|
||||||
suspend_finish(state);
|
suspend_finish(state);
|
||||||
Unlock:
|
Unlock:
|
||||||
up(&pm_sem);
|
up(&pm_sem);
|
||||||
|
|
Loading…
Add table
Reference in a new issue