aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorArjan van de Ven <arjan@linux.intel.com>2006-10-01 02:27:17 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-01 03:39:19 -0400
commit5c87579e65ee4f419b2369407f82326d38b5d2d8 (patch)
tree3e015ba93eb6eefb7ed4318daf95be0771d596a8 /drivers/net
parent130c6b98984a058068ea595c465fba2beb48b9ef (diff)
[PATCH] maximum latency tracking infrastructure
Add infrastructure to track "maximum allowable latency" for power saving policies. The reason for adding this infrastructure is that power management in the idle loop needs to make a tradeoff between latency and power savings (deeper power save modes have a longer latency to running code again). The code that today makes this tradeoff just does a rather simple algorithm; however this is not good enough: There are devices and use cases where a lower latency is required than that the higher power saving states provide. An example would be audio playback, but another example is the ipw2100 wireless driver that right now has a very direct and ugly acpi hook to disable some higher power states randomly when it gets certain types of error. The proposed solution is to have an interface where drivers can * announce the maximum latency (in microseconds) that they can deal with * modify this latency * give up their constraint and a function where the code that decides on power saving strategy can query the current global desired maximum. This patch has a user of each side: on the consumer side, ACPI is patched to use this, on the producer side the ipw2100 driver is patched. A generic maximum latency is also registered of 2 timer ticks (more and you lose accurate time tracking after all). While the existing users of the patch are x86 specific, the infrastructure is not. I'd like to ask the arch maintainers of other architectures if the infrastructure is generic enough for their use (assuming the architecture has such a tradeoff as concept at all), and the sound/multimedia driver owners to look at the driver facing API to see if this is something they can use. [akpm@osdl.org: cleanups] Signed-off-by: Arjan van de Ven <arjan@linux.intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Acked-by: Jesse Barnes <jesse.barnes@intel.com> Cc: "Brown, Len" <len.brown@intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ipw2100.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 6c5add701a6f..97937809de09 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -163,6 +163,7 @@ that only one external action is invoked at a time.
163#include <linux/firmware.h> 163#include <linux/firmware.h>
164#include <linux/acpi.h> 164#include <linux/acpi.h>
165#include <linux/ctype.h> 165#include <linux/ctype.h>
166#include <linux/latency.h>
166 167
167#include "ipw2100.h" 168#include "ipw2100.h"
168 169
@@ -1697,6 +1698,11 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1697 return 0; 1698 return 0;
1698 } 1699 }
1699 1700
1701 /* the ipw2100 hardware really doesn't want power management delays
1702 * longer than 175usec
1703 */
1704 modify_acceptable_latency("ipw2100", 175);
1705
1700 /* If the interrupt is enabled, turn it off... */ 1706 /* If the interrupt is enabled, turn it off... */
1701 spin_lock_irqsave(&priv->low_lock, flags); 1707 spin_lock_irqsave(&priv->low_lock, flags);
1702 ipw2100_disable_interrupts(priv); 1708 ipw2100_disable_interrupts(priv);
@@ -1849,6 +1855,8 @@ static void ipw2100_down(struct ipw2100_priv *priv)
1849 ipw2100_disable_interrupts(priv); 1855 ipw2100_disable_interrupts(priv);
1850 spin_unlock_irqrestore(&priv->low_lock, flags); 1856 spin_unlock_irqrestore(&priv->low_lock, flags);
1851 1857
1858 modify_acceptable_latency("ipw2100", INFINITE_LATENCY);
1859
1852#ifdef ACPI_CSTATE_LIMIT_DEFINED 1860#ifdef ACPI_CSTATE_LIMIT_DEFINED
1853 if (priv->config & CFG_C3_DISABLED) { 1861 if (priv->config & CFG_C3_DISABLED) {
1854 IPW_DEBUG_INFO(": Resetting C3 transitions.\n"); 1862 IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
@@ -6534,6 +6542,7 @@ static int __init ipw2100_init(void)
6534 6542
6535 ret = pci_register_driver(&ipw2100_pci_driver); 6543 ret = pci_register_driver(&ipw2100_pci_driver);
6536 6544
6545 set_acceptable_latency("ipw2100", INFINITE_LATENCY);
6537#ifdef CONFIG_IPW2100_DEBUG 6546#ifdef CONFIG_IPW2100_DEBUG
6538 ipw2100_debug_level = debug; 6547 ipw2100_debug_level = debug;
6539 driver_create_file(&ipw2100_pci_driver.driver, 6548 driver_create_file(&ipw2100_pci_driver.driver,
@@ -6554,6 +6563,7 @@ static void __exit ipw2100_exit(void)
6554 &driver_attr_debug_level); 6563 &driver_attr_debug_level);
6555#endif 6564#endif
6556 pci_unregister_driver(&ipw2100_pci_driver); 6565 pci_unregister_driver(&ipw2100_pci_driver);
6566 remove_acceptable_latency("ipw2100");
6557} 6567}
6558 6568
6559module_init(ipw2100_init); 6569module_init(ipw2100_init);