You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6: PM: PM QOS update fix Freezer / cgroup freezer: Update stale locking comments PM / platform_bus: Allow runtime PM by default i2c: Fix bus-level power management callbacks PM QOS update PM / Hibernate: Fix block_io.c printk warning PM / Hibernate: Group swap ops PM / Hibernate: Move the first_sector out of swsusp_write PM / Hibernate: Separate block_io PM / Hibernate: Snapshot cleanup FS / libfs: Implement simple_write_to_buffer PM / Hibernate: document open(/dev/snapshot) side effects PM / Runtime: Add sysfs debug files PM: Improve device power management document PM: Update device power management document PM: Allow runtime_suspend methods to call pm_schedule_suspend() PM: pm_wakeup - switch to using bool
This commit is contained in:
+467
-348
File diff suppressed because it is too large
Load Diff
@@ -18,44 +18,46 @@ and pm_qos_params.h. This is done because having the available parameters
|
||||
being runtime configurable or changeable from a driver was seen as too easy to
|
||||
abuse.
|
||||
|
||||
For each parameter a list of performance requirements is maintained along with
|
||||
For each parameter a list of performance requests is maintained along with
|
||||
an aggregated target value. The aggregated target value is updated with
|
||||
changes to the requirement list or elements of the list. Typically the
|
||||
aggregated target value is simply the max or min of the requirement values held
|
||||
changes to the request list or elements of the list. Typically the
|
||||
aggregated target value is simply the max or min of the request values held
|
||||
in the parameter list elements.
|
||||
|
||||
From kernel mode the use of this interface is simple:
|
||||
pm_qos_add_requirement(param_id, name, target_value):
|
||||
Will insert a named element in the list for that identified PM_QOS parameter
|
||||
with the target value. Upon change to this list the new target is recomputed
|
||||
and any registered notifiers are called only if the target value is now
|
||||
different.
|
||||
|
||||
pm_qos_update_requirement(param_id, name, new_target_value):
|
||||
Will search the list identified by the param_id for the named list element and
|
||||
then update its target value, calling the notification tree if the aggregated
|
||||
target is changed. with that name is already registered.
|
||||
handle = pm_qos_add_request(param_class, target_value):
|
||||
Will insert an element into the list for that identified PM_QOS class with the
|
||||
target value. Upon change to this list the new target is recomputed and any
|
||||
registered notifiers are called only if the target value is now different.
|
||||
Clients of pm_qos need to save the returned handle.
|
||||
|
||||
pm_qos_remove_requirement(param_id, name):
|
||||
Will search the identified list for the named element and remove it, after
|
||||
removal it will update the aggregate target and call the notification tree if
|
||||
the target was changed as a result of removing the named requirement.
|
||||
void pm_qos_update_request(handle, new_target_value):
|
||||
Will update the list element pointed to by the handle with the new target value
|
||||
and recompute the new aggregated target, calling the notification tree if the
|
||||
target is changed.
|
||||
|
||||
void pm_qos_remove_request(handle):
|
||||
Will remove the element. After removal it will update the aggregate target and
|
||||
call the notification tree if the target was changed as a result of removing
|
||||
the request.
|
||||
|
||||
|
||||
From user mode:
|
||||
Only processes can register a pm_qos requirement. To provide for automatic
|
||||
cleanup for process the interface requires the process to register its
|
||||
parameter requirements in the following way:
|
||||
Only processes can register a pm_qos request. To provide for automatic
|
||||
cleanup of a process, the interface requires the process to register its
|
||||
parameter requests in the following way:
|
||||
|
||||
To register the default pm_qos target for the specific parameter, the process
|
||||
must open one of /dev/[cpu_dma_latency, network_latency, network_throughput]
|
||||
|
||||
As long as the device node is held open that process has a registered
|
||||
requirement on the parameter. The name of the requirement is "process_<PID>"
|
||||
derived from the current->pid from within the open system call.
|
||||
request on the parameter.
|
||||
|
||||
To change the requested target value the process needs to write a s32 value to
|
||||
the open device node. This translates to a pm_qos_update_requirement call.
|
||||
To change the requested target value the process needs to write an s32 value to
|
||||
the open device node. Alternatively the user mode program could write a hex
|
||||
string for the value using 10 char long format e.g. "0x12345678". This
|
||||
translates to a pm_qos_update_request call.
|
||||
|
||||
To remove the user mode request for a target value simply close the device
|
||||
node.
|
||||
|
||||
@@ -24,6 +24,10 @@ assumed to be in the resume mode. The device cannot be open for simultaneous
|
||||
reading and writing. It is also impossible to have the device open more than
|
||||
once at a time.
|
||||
|
||||
Even opening the device has side effects. Data structures are
|
||||
allocated, and PM_HIBERNATION_PREPARE / PM_RESTORE_PREPARE chains are
|
||||
called.
|
||||
|
||||
The ioctl() commands recognized by the device are:
|
||||
|
||||
SNAPSHOT_FREEZE - freeze user space processes (the current process is
|
||||
|
||||
@@ -698,7 +698,7 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
|
||||
"max_cstate: C%d\n"
|
||||
"maximum allowed latency: %d usec\n",
|
||||
pr->power.state ? pr->power.state - pr->power.states : 0,
|
||||
max_cstate, pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY));
|
||||
max_cstate, pm_qos_request(PM_QOS_CPU_DMA_LATENCY));
|
||||
|
||||
seq_puts(seq, "states:\n");
|
||||
|
||||
|
||||
@@ -967,17 +967,17 @@ static int platform_pm_restore_noirq(struct device *dev)
|
||||
|
||||
int __weak platform_pm_runtime_suspend(struct device *dev)
|
||||
{
|
||||
return -ENOSYS;
|
||||
return pm_generic_runtime_suspend(dev);
|
||||
};
|
||||
|
||||
int __weak platform_pm_runtime_resume(struct device *dev)
|
||||
{
|
||||
return -ENOSYS;
|
||||
return pm_generic_runtime_resume(dev);
|
||||
};
|
||||
|
||||
int __weak platform_pm_runtime_idle(struct device *dev)
|
||||
{
|
||||
return -ENOSYS;
|
||||
return pm_generic_runtime_idle(dev);
|
||||
};
|
||||
|
||||
#else /* !CONFIG_PM_RUNTIME */
|
||||
|
||||
@@ -229,14 +229,16 @@ int __pm_runtime_suspend(struct device *dev, bool from_wq)
|
||||
|
||||
if (retval) {
|
||||
dev->power.runtime_status = RPM_ACTIVE;
|
||||
pm_runtime_cancel_pending(dev);
|
||||
|
||||
if (retval == -EAGAIN || retval == -EBUSY) {
|
||||
notify = true;
|
||||
if (dev->power.timer_expires == 0)
|
||||
notify = true;
|
||||
dev->power.runtime_error = 0;
|
||||
} else {
|
||||
pm_runtime_cancel_pending(dev);
|
||||
}
|
||||
} else {
|
||||
dev->power.runtime_status = RPM_SUSPENDED;
|
||||
pm_runtime_deactivate_timer(dev);
|
||||
|
||||
if (dev->parent) {
|
||||
parent = dev->parent;
|
||||
@@ -659,8 +661,6 @@ int pm_schedule_suspend(struct device *dev, unsigned int delay)
|
||||
|
||||
if (dev->power.runtime_status == RPM_SUSPENDED)
|
||||
retval = 1;
|
||||
else if (dev->power.runtime_status == RPM_SUSPENDING)
|
||||
retval = -EINPROGRESS;
|
||||
else if (atomic_read(&dev->power.usage_count) > 0
|
||||
|| dev->power.disable_depth > 0)
|
||||
retval = -EAGAIN;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <asm/atomic.h>
|
||||
#include "power.h"
|
||||
|
||||
/*
|
||||
@@ -143,7 +144,59 @@ wake_store(struct device * dev, struct device_attribute *attr,
|
||||
|
||||
static DEVICE_ATTR(wakeup, 0644, wake_show, wake_store);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP_ADVANCED_DEBUG
|
||||
#ifdef CONFIG_PM_ADVANCED_DEBUG
|
||||
#ifdef CONFIG_PM_RUNTIME
|
||||
|
||||
static ssize_t rtpm_usagecount_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", atomic_read(&dev->power.usage_count));
|
||||
}
|
||||
|
||||
static ssize_t rtpm_children_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", dev->power.ignore_children ?
|
||||
0 : atomic_read(&dev->power.child_count));
|
||||
}
|
||||
|
||||
static ssize_t rtpm_enabled_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
if ((dev->power.disable_depth) && (dev->power.runtime_auto == false))
|
||||
return sprintf(buf, "disabled & forbidden\n");
|
||||
else if (dev->power.disable_depth)
|
||||
return sprintf(buf, "disabled\n");
|
||||
else if (dev->power.runtime_auto == false)
|
||||
return sprintf(buf, "forbidden\n");
|
||||
return sprintf(buf, "enabled\n");
|
||||
}
|
||||
|
||||
static ssize_t rtpm_status_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
if (dev->power.runtime_error)
|
||||
return sprintf(buf, "error\n");
|
||||
switch (dev->power.runtime_status) {
|
||||
case RPM_SUSPENDED:
|
||||
return sprintf(buf, "suspended\n");
|
||||
case RPM_SUSPENDING:
|
||||
return sprintf(buf, "suspending\n");
|
||||
case RPM_RESUMING:
|
||||
return sprintf(buf, "resuming\n");
|
||||
case RPM_ACTIVE:
|
||||
return sprintf(buf, "active\n");
|
||||
}
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(runtime_usage, 0444, rtpm_usagecount_show, NULL);
|
||||
static DEVICE_ATTR(runtime_active_kids, 0444, rtpm_children_show, NULL);
|
||||
static DEVICE_ATTR(runtime_status, 0444, rtpm_status_show, NULL);
|
||||
static DEVICE_ATTR(runtime_enabled, 0444, rtpm_enabled_show, NULL);
|
||||
|
||||
#endif
|
||||
|
||||
static ssize_t async_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
@@ -170,15 +223,21 @@ static ssize_t async_store(struct device *dev, struct device_attribute *attr,
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(async, 0644, async_show, async_store);
|
||||
#endif /* CONFIG_PM_SLEEP_ADVANCED_DEBUG */
|
||||
#endif /* CONFIG_PM_ADVANCED_DEBUG */
|
||||
|
||||
static struct attribute * power_attrs[] = {
|
||||
#ifdef CONFIG_PM_RUNTIME
|
||||
&dev_attr_control.attr,
|
||||
#endif
|
||||
&dev_attr_wakeup.attr,
|
||||
#ifdef CONFIG_PM_SLEEP_ADVANCED_DEBUG
|
||||
#ifdef CONFIG_PM_ADVANCED_DEBUG
|
||||
&dev_attr_async.attr,
|
||||
#ifdef CONFIG_PM_RUNTIME
|
||||
&dev_attr_runtime_usage.attr,
|
||||
&dev_attr_runtime_active_kids.attr,
|
||||
&dev_attr_runtime_status.attr,
|
||||
&dev_attr_runtime_enabled.attr,
|
||||
#endif
|
||||
#endif
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -67,7 +67,7 @@ static int ladder_select_state(struct cpuidle_device *dev)
|
||||
struct ladder_device *ldev = &__get_cpu_var(ladder_devices);
|
||||
struct ladder_device_state *last_state;
|
||||
int last_residency, last_idx = ldev->last_state_idx;
|
||||
int latency_req = pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY);
|
||||
int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
|
||||
|
||||
/* Special case when user has set very strict latency requirement */
|
||||
if (unlikely(latency_req == 0)) {
|
||||
|
||||
@@ -182,7 +182,7 @@ static u64 div_round64(u64 dividend, u32 divisor)
|
||||
static int menu_select(struct cpuidle_device *dev)
|
||||
{
|
||||
struct menu_device *data = &__get_cpu_var(menu_devices);
|
||||
int latency_req = pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY);
|
||||
int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
|
||||
int i;
|
||||
int multiplier;
|
||||
|
||||
|
||||
+110
-82
@@ -159,82 +159,8 @@ static void i2c_device_shutdown(struct device *dev)
|
||||
driver->shutdown(client);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SUSPEND
|
||||
static int i2c_device_pm_suspend(struct device *dev)
|
||||
{
|
||||
const struct dev_pm_ops *pm;
|
||||
|
||||
if (!dev->driver)
|
||||
return 0;
|
||||
pm = dev->driver->pm;
|
||||
if (!pm || !pm->suspend)
|
||||
return 0;
|
||||
return pm->suspend(dev);
|
||||
}
|
||||
|
||||
static int i2c_device_pm_resume(struct device *dev)
|
||||
{
|
||||
const struct dev_pm_ops *pm;
|
||||
|
||||
if (!dev->driver)
|
||||
return 0;
|
||||
pm = dev->driver->pm;
|
||||
if (!pm || !pm->resume)
|
||||
return 0;
|
||||
return pm->resume(dev);
|
||||
}
|
||||
#else
|
||||
#define i2c_device_pm_suspend NULL
|
||||
#define i2c_device_pm_resume NULL
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM_RUNTIME
|
||||
static int i2c_device_runtime_suspend(struct device *dev)
|
||||
{
|
||||
const struct dev_pm_ops *pm;
|
||||
|
||||
if (!dev->driver)
|
||||
return 0;
|
||||
pm = dev->driver->pm;
|
||||
if (!pm || !pm->runtime_suspend)
|
||||
return 0;
|
||||
return pm->runtime_suspend(dev);
|
||||
}
|
||||
|
||||
static int i2c_device_runtime_resume(struct device *dev)
|
||||
{
|
||||
const struct dev_pm_ops *pm;
|
||||
|
||||
if (!dev->driver)
|
||||
return 0;
|
||||
pm = dev->driver->pm;
|
||||
if (!pm || !pm->runtime_resume)
|
||||
return 0;
|
||||
return pm->runtime_resume(dev);
|
||||
}
|
||||
|
||||
static int i2c_device_runtime_idle(struct device *dev)
|
||||
{
|
||||
const struct dev_pm_ops *pm = NULL;
|
||||
int ret;
|
||||
|
||||
if (dev->driver)
|
||||
pm = dev->driver->pm;
|
||||
if (pm && pm->runtime_idle) {
|
||||
ret = pm->runtime_idle(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return pm_runtime_suspend(dev);
|
||||
}
|
||||
#else
|
||||
#define i2c_device_runtime_suspend NULL
|
||||
#define i2c_device_runtime_resume NULL
|
||||
#define i2c_device_runtime_idle NULL
|
||||
#endif
|
||||
|
||||
static int i2c_device_suspend(struct device *dev, pm_message_t mesg)
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int i2c_legacy_suspend(struct device *dev, pm_message_t mesg)
|
||||
{
|
||||
struct i2c_client *client = i2c_verify_client(dev);
|
||||
struct i2c_driver *driver;
|
||||
@@ -247,7 +173,7 @@ static int i2c_device_suspend(struct device *dev, pm_message_t mesg)
|
||||
return driver->suspend(client, mesg);
|
||||
}
|
||||
|
||||
static int i2c_device_resume(struct device *dev)
|
||||
static int i2c_legacy_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = i2c_verify_client(dev);
|
||||
struct i2c_driver *driver;
|
||||
@@ -260,6 +186,104 @@ static int i2c_device_resume(struct device *dev)
|
||||
return driver->resume(client);
|
||||
}
|
||||
|
||||
static int i2c_device_pm_suspend(struct device *dev)
|
||||
{
|
||||
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
|
||||
|
||||
if (pm_runtime_suspended(dev))
|
||||
return 0;
|
||||
|
||||
if (pm)
|
||||
return pm->suspend ? pm->suspend(dev) : 0;
|
||||
|
||||
return i2c_legacy_suspend(dev, PMSG_SUSPEND);
|
||||
}
|
||||
|
||||
static int i2c_device_pm_resume(struct device *dev)
|
||||
{
|
||||
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
|
||||
int ret;
|
||||
|
||||
if (pm)
|
||||
ret = pm->resume ? pm->resume(dev) : 0;
|
||||
else
|
||||
ret = i2c_legacy_resume(dev);
|
||||
|
||||
if (!ret) {
|
||||
pm_runtime_disable(dev);
|
||||
pm_runtime_set_active(dev);
|
||||
pm_runtime_enable(dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int i2c_device_pm_freeze(struct device *dev)
|
||||
{
|
||||
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
|
||||
|
||||
if (pm_runtime_suspended(dev))
|
||||
return 0;
|
||||
|
||||
if (pm)
|
||||
return pm->freeze ? pm->freeze(dev) : 0;
|
||||
|
||||
return i2c_legacy_suspend(dev, PMSG_FREEZE);
|
||||
}
|
||||
|
||||
static int i2c_device_pm_thaw(struct device *dev)
|
||||
{
|
||||
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
|
||||
|
||||
if (pm_runtime_suspended(dev))
|
||||
return 0;
|
||||
|
||||
if (pm)
|
||||
return pm->thaw ? pm->thaw(dev) : 0;
|
||||
|
||||
return i2c_legacy_resume(dev);
|
||||
}
|
||||
|
||||
static int i2c_device_pm_poweroff(struct device *dev)
|
||||
{
|
||||
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
|
||||
|
||||
if (pm_runtime_suspended(dev))
|
||||
return 0;
|
||||
|
||||
if (pm)
|
||||
return pm->poweroff ? pm->poweroff(dev) : 0;
|
||||
|
||||
return i2c_legacy_suspend(dev, PMSG_HIBERNATE);
|
||||
}
|
||||
|
||||
static int i2c_device_pm_restore(struct device *dev)
|
||||
{
|
||||
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
|
||||
int ret;
|
||||
|
||||
if (pm)
|
||||
ret = pm->restore ? pm->restore(dev) : 0;
|
||||
else
|
||||
ret = i2c_legacy_resume(dev);
|
||||
|
||||
if (!ret) {
|
||||
pm_runtime_disable(dev);
|
||||
pm_runtime_set_active(dev);
|
||||
pm_runtime_enable(dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else /* !CONFIG_PM_SLEEP */
|
||||
#define i2c_device_pm_suspend NULL
|
||||
#define i2c_device_pm_resume NULL
|
||||
#define i2c_device_pm_freeze NULL
|
||||
#define i2c_device_pm_thaw NULL
|
||||
#define i2c_device_pm_poweroff NULL
|
||||
#define i2c_device_pm_restore NULL
|
||||
#endif /* !CONFIG_PM_SLEEP */
|
||||
|
||||
static void i2c_client_dev_release(struct device *dev)
|
||||
{
|
||||
kfree(to_i2c_client(dev));
|
||||
@@ -301,9 +325,15 @@ static const struct attribute_group *i2c_dev_attr_groups[] = {
|
||||
static const struct dev_pm_ops i2c_device_pm_ops = {
|
||||
.suspend = i2c_device_pm_suspend,
|
||||
.resume = i2c_device_pm_resume,
|
||||
.runtime_suspend = i2c_device_runtime_suspend,
|
||||
.runtime_resume = i2c_device_runtime_resume,
|
||||
.runtime_idle = i2c_device_runtime_idle,
|
||||
.freeze = i2c_device_pm_freeze,
|
||||
.thaw = i2c_device_pm_thaw,
|
||||
.poweroff = i2c_device_pm_poweroff,
|
||||
.restore = i2c_device_pm_restore,
|
||||
SET_RUNTIME_PM_OPS(
|
||||
pm_generic_runtime_suspend,
|
||||
pm_generic_runtime_resume,
|
||||
pm_generic_runtime_idle
|
||||
)
|
||||
};
|
||||
|
||||
struct bus_type i2c_bus_type = {
|
||||
@@ -312,8 +342,6 @@ struct bus_type i2c_bus_type = {
|
||||
.probe = i2c_device_probe,
|
||||
.remove = i2c_device_remove,
|
||||
.shutdown = i2c_device_shutdown,
|
||||
.suspend = i2c_device_suspend,
|
||||
.resume = i2c_device_resume,
|
||||
.pm = &i2c_device_pm_ops,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(i2c_bus_type);
|
||||
|
||||
+12
-10
@@ -2524,12 +2524,12 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
|
||||
* excessive C-state transition latencies result in
|
||||
* dropped transactions.
|
||||
*/
|
||||
pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY,
|
||||
adapter->netdev->name, 55);
|
||||
pm_qos_update_request(
|
||||
adapter->netdev->pm_qos_req, 55);
|
||||
} else {
|
||||
pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY,
|
||||
adapter->netdev->name,
|
||||
PM_QOS_DEFAULT_VALUE);
|
||||
pm_qos_update_request(
|
||||
adapter->netdev->pm_qos_req,
|
||||
PM_QOS_DEFAULT_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2824,8 +2824,8 @@ int e1000e_up(struct e1000_adapter *adapter)
|
||||
|
||||
/* DMA latency requirement to workaround early-receive/jumbo issue */
|
||||
if (adapter->flags & FLAG_HAS_ERT)
|
||||
pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY,
|
||||
adapter->netdev->name,
|
||||
adapter->netdev->pm_qos_req =
|
||||
pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY,
|
||||
PM_QOS_DEFAULT_VALUE);
|
||||
|
||||
/* hardware has been reset, we need to reload some things */
|
||||
@@ -2887,9 +2887,11 @@ void e1000e_down(struct e1000_adapter *adapter)
|
||||
e1000_clean_tx_ring(adapter);
|
||||
e1000_clean_rx_ring(adapter);
|
||||
|
||||
if (adapter->flags & FLAG_HAS_ERT)
|
||||
pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY,
|
||||
adapter->netdev->name);
|
||||
if (adapter->flags & FLAG_HAS_ERT) {
|
||||
pm_qos_remove_request(
|
||||
adapter->netdev->pm_qos_req);
|
||||
adapter->netdev->pm_qos_req = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: for power management, we could drop the link and
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#define DRV_VERSION "1.0.0-k0"
|
||||
char igbvf_driver_name[] = "igbvf";
|
||||
const char igbvf_driver_version[] = DRV_VERSION;
|
||||
struct pm_qos_request_list *igbvf_driver_pm_qos_req;
|
||||
static const char igbvf_driver_string[] =
|
||||
"Intel(R) Virtual Function Network Driver";
|
||||
static const char igbvf_copyright[] = "Copyright (c) 2009 Intel Corporation.";
|
||||
@@ -2899,7 +2900,7 @@ static int __init igbvf_init_module(void)
|
||||
printk(KERN_INFO "%s\n", igbvf_copyright);
|
||||
|
||||
ret = pci_register_driver(&igbvf_driver);
|
||||
pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, igbvf_driver_name,
|
||||
igbvf_driver_pm_qos_req = pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY,
|
||||
PM_QOS_DEFAULT_VALUE);
|
||||
|
||||
return ret;
|
||||
@@ -2915,7 +2916,8 @@ module_init(igbvf_init_module);
|
||||
static void __exit igbvf_exit_module(void)
|
||||
{
|
||||
pci_unregister_driver(&igbvf_driver);
|
||||
pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, igbvf_driver_name);
|
||||
pm_qos_remove_request(igbvf_driver_pm_qos_req);
|
||||
igbvf_driver_pm_qos_req = NULL;
|
||||
}
|
||||
module_exit(igbvf_exit_module);
|
||||
|
||||
|
||||
@@ -174,6 +174,8 @@ that only one external action is invoked at a time.
|
||||
#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver"
|
||||
#define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation"
|
||||
|
||||
struct pm_qos_request_list *ipw2100_pm_qos_req;
|
||||
|
||||
/* Debugging stuff */
|
||||
#ifdef CONFIG_IPW2100_DEBUG
|
||||
#define IPW2100_RX_DEBUG /* Reception debugging */
|
||||
@@ -1739,7 +1741,7 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
|
||||
/* the ipw2100 hardware really doesn't want power management delays
|
||||
* longer than 175usec
|
||||
*/
|
||||
pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100", 175);
|
||||
pm_qos_update_request(ipw2100_pm_qos_req, 175);
|
||||
|
||||
/* If the interrupt is enabled, turn it off... */
|
||||
spin_lock_irqsave(&priv->low_lock, flags);
|
||||
@@ -1887,8 +1889,7 @@ static void ipw2100_down(struct ipw2100_priv *priv)
|
||||
ipw2100_disable_interrupts(priv);
|
||||
spin_unlock_irqrestore(&priv->low_lock, flags);
|
||||
|
||||
pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100",
|
||||
PM_QOS_DEFAULT_VALUE);
|
||||
pm_qos_update_request(ipw2100_pm_qos_req, PM_QOS_DEFAULT_VALUE);
|
||||
|
||||
/* We have to signal any supplicant if we are disassociating */
|
||||
if (associated)
|
||||
@@ -6669,7 +6670,7 @@ static int __init ipw2100_init(void)
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100",
|
||||
ipw2100_pm_qos_req = pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY,
|
||||
PM_QOS_DEFAULT_VALUE);
|
||||
#ifdef CONFIG_IPW2100_DEBUG
|
||||
ipw2100_debug_level = debug;
|
||||
@@ -6692,7 +6693,7 @@ static void __exit ipw2100_exit(void)
|
||||
&driver_attr_debug_level);
|
||||
#endif
|
||||
pci_unregister_driver(&ipw2100_pci_driver);
|
||||
pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100");
|
||||
pm_qos_remove_request(ipw2100_pm_qos_req);
|
||||
}
|
||||
|
||||
module_init(ipw2100_init);
|
||||
|
||||
+35
@@ -546,6 +546,40 @@ ssize_t simple_read_from_buffer(void __user *to, size_t count, loff_t *ppos,
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* simple_write_to_buffer - copy data from user space to the buffer
|
||||
* @to: the buffer to write to
|
||||
* @available: the size of the buffer
|
||||
* @ppos: the current position in the buffer
|
||||
* @from: the user space buffer to read from
|
||||
* @count: the maximum number of bytes to read
|
||||
*
|
||||
* The simple_write_to_buffer() function reads up to @count bytes from the user
|
||||
* space address starting at @from into the buffer @to at offset @ppos.
|
||||
*
|
||||
* On success, the number of bytes written is returned and the offset @ppos is
|
||||
* advanced by this number, or negative value is returned on error.
|
||||
**/
|
||||
ssize_t simple_write_to_buffer(void *to, size_t available, loff_t *ppos,
|
||||
const void __user *from, size_t count)
|
||||
{
|
||||
loff_t pos = *ppos;
|
||||
size_t res;
|
||||
|
||||
if (pos < 0)
|
||||
return -EINVAL;
|
||||
if (pos >= available || !count)
|
||||
return 0;
|
||||
if (count > available - pos)
|
||||
count = available - pos;
|
||||
res = copy_from_user(to + pos, from, count);
|
||||
if (res == count)
|
||||
return -EFAULT;
|
||||
count -= res;
|
||||
*ppos = pos + count;
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* memory_read_from_buffer - copy data from the buffer
|
||||
* @to: the kernel space buffer to read to
|
||||
@@ -864,6 +898,7 @@ EXPORT_SYMBOL(simple_statfs);
|
||||
EXPORT_SYMBOL(simple_sync_file);
|
||||
EXPORT_SYMBOL(simple_unlink);
|
||||
EXPORT_SYMBOL(simple_read_from_buffer);
|
||||
EXPORT_SYMBOL(simple_write_to_buffer);
|
||||
EXPORT_SYMBOL(memory_read_from_buffer);
|
||||
EXPORT_SYMBOL(simple_transaction_set);
|
||||
EXPORT_SYMBOL(simple_transaction_get);
|
||||
|
||||
@@ -2362,6 +2362,8 @@ extern void simple_release_fs(struct vfsmount **mount, int *count);
|
||||
|
||||
extern ssize_t simple_read_from_buffer(void __user *to, size_t count,
|
||||
loff_t *ppos, const void *from, size_t available);
|
||||
extern ssize_t simple_write_to_buffer(void *to, size_t available, loff_t *ppos,
|
||||
const void __user *from, size_t count);
|
||||
|
||||
extern int simple_fsync(struct file *, struct dentry *, int);
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <linux/if_link.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/pm_qos_params.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mm.h>
|
||||
@@ -711,6 +712,9 @@ struct net_device {
|
||||
* the interface.
|
||||
*/
|
||||
char name[IFNAMSIZ];
|
||||
|
||||
struct pm_qos_request_list *pm_qos_req;
|
||||
|
||||
/* device name hash chain */
|
||||
struct hlist_node name_hlist;
|
||||
/* snmp alias */
|
||||
|
||||
@@ -14,12 +14,14 @@
|
||||
#define PM_QOS_NUM_CLASSES 4
|
||||
#define PM_QOS_DEFAULT_VALUE -1
|
||||
|
||||
int pm_qos_add_requirement(int qos, char *name, s32 value);
|
||||
int pm_qos_update_requirement(int qos, char *name, s32 new_value);
|
||||
void pm_qos_remove_requirement(int qos, char *name);
|
||||
struct pm_qos_request_list;
|
||||
|
||||
int pm_qos_requirement(int qos);
|
||||
struct pm_qos_request_list *pm_qos_add_request(int pm_qos_class, s32 value);
|
||||
void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
|
||||
s32 new_value);
|
||||
void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req);
|
||||
|
||||
int pm_qos_add_notifier(int qos, struct notifier_block *notifier);
|
||||
int pm_qos_remove_notifier(int qos, struct notifier_block *notifier);
|
||||
int pm_qos_request(int pm_qos_class);
|
||||
int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier);
|
||||
int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier);
|
||||
|
||||
|
||||
@@ -30,6 +30,9 @@ extern void pm_runtime_enable(struct device *dev);
|
||||
extern void __pm_runtime_disable(struct device *dev, bool check_resume);
|
||||
extern void pm_runtime_allow(struct device *dev);
|
||||
extern void pm_runtime_forbid(struct device *dev);
|
||||
extern int pm_generic_runtime_idle(struct device *dev);
|
||||
extern int pm_generic_runtime_suspend(struct device *dev);
|
||||
extern int pm_generic_runtime_resume(struct device *dev);
|
||||
|
||||
static inline bool pm_children_suspended(struct device *dev)
|
||||
{
|
||||
@@ -96,6 +99,10 @@ static inline bool device_run_wake(struct device *dev) { return false; }
|
||||
static inline void device_set_run_wake(struct device *dev, bool enable) {}
|
||||
static inline bool pm_runtime_suspended(struct device *dev) { return false; }
|
||||
|
||||
static inline int pm_generic_runtime_idle(struct device *dev) { return 0; }
|
||||
static inline int pm_generic_runtime_suspend(struct device *dev) { return 0; }
|
||||
static inline int pm_generic_runtime_resume(struct device *dev) { return 0; }
|
||||
|
||||
#endif /* !CONFIG_PM_RUNTIME */
|
||||
|
||||
static inline int pm_runtime_get(struct device *dev)
|
||||
|
||||
+24
-14
@@ -25,32 +25,34 @@
|
||||
# error "please don't include this file directly"
|
||||
#endif
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
/* changes to device_may_wakeup take effect on the next pm state change.
|
||||
* by default, devices should wakeup if they can.
|
||||
*/
|
||||
static inline void device_init_wakeup(struct device *dev, int val)
|
||||
static inline void device_init_wakeup(struct device *dev, bool val)
|
||||
{
|
||||
dev->power.can_wakeup = dev->power.should_wakeup = !!val;
|
||||
dev->power.can_wakeup = dev->power.should_wakeup = val;
|
||||
}
|
||||
|
||||
static inline void device_set_wakeup_capable(struct device *dev, int val)
|
||||
static inline void device_set_wakeup_capable(struct device *dev, bool capable)
|
||||
{
|
||||
dev->power.can_wakeup = !!val;
|
||||
dev->power.can_wakeup = capable;
|
||||
}
|
||||
|
||||
static inline int device_can_wakeup(struct device *dev)
|
||||
static inline bool device_can_wakeup(struct device *dev)
|
||||
{
|
||||
return dev->power.can_wakeup;
|
||||
}
|
||||
|
||||
static inline void device_set_wakeup_enable(struct device *dev, int val)
|
||||
static inline void device_set_wakeup_enable(struct device *dev, bool enable)
|
||||
{
|
||||
dev->power.should_wakeup = !!val;
|
||||
dev->power.should_wakeup = enable;
|
||||
}
|
||||
|
||||
static inline int device_may_wakeup(struct device *dev)
|
||||
static inline bool device_may_wakeup(struct device *dev)
|
||||
{
|
||||
return dev->power.can_wakeup && dev->power.should_wakeup;
|
||||
}
|
||||
@@ -58,20 +60,28 @@ static inline int device_may_wakeup(struct device *dev)
|
||||
#else /* !CONFIG_PM */
|
||||
|
||||
/* For some reason the next two routines work even without CONFIG_PM */
|
||||
static inline void device_init_wakeup(struct device *dev, int val)
|
||||
static inline void device_init_wakeup(struct device *dev, bool val)
|
||||
{
|
||||
dev->power.can_wakeup = !!val;
|
||||
dev->power.can_wakeup = val;
|
||||
}
|
||||
|
||||
static inline void device_set_wakeup_capable(struct device *dev, int val) { }
|
||||
static inline void device_set_wakeup_capable(struct device *dev, bool capable)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int device_can_wakeup(struct device *dev)
|
||||
static inline bool device_can_wakeup(struct device *dev)
|
||||
{
|
||||
return dev->power.can_wakeup;
|
||||
}
|
||||
|
||||
#define device_set_wakeup_enable(dev, val) do {} while (0)
|
||||
#define device_may_wakeup(dev) 0
|
||||
static inline void device_set_wakeup_enable(struct device *dev, bool enable)
|
||||
{
|
||||
}
|
||||
|
||||
static inline bool device_may_wakeup(struct device *dev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_PM */
|
||||
|
||||
|
||||
+2
-1
@@ -29,6 +29,7 @@
|
||||
#include <linux/poll.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/pm_qos_params.h>
|
||||
|
||||
#define snd_pcm_substream_chip(substream) ((substream)->private_data)
|
||||
#define snd_pcm_chip(pcm) ((pcm)->private_data)
|
||||
@@ -365,7 +366,7 @@ struct snd_pcm_substream {
|
||||
int number;
|
||||
char name[32]; /* substream name */
|
||||
int stream; /* stream (direction) */
|
||||
char latency_id[20]; /* latency identifier */
|
||||
struct pm_qos_request_list *latency_pm_qos_req; /* pm_qos request */
|
||||
size_t buffer_bytes_max; /* limit ring buffer size */
|
||||
struct snd_dma_buffer dma_buffer;
|
||||
unsigned int dma_buf_id;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user