diff options
author | James Bottomley <James.Bottomley@suse.de> | 2010-07-05 16:53:06 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2010-07-18 20:00:34 -0400 |
commit | 82f682514a5df89ffb3890627eebf0897b7a84ec (patch) | |
tree | 27a3dba7a179102ac5bfdd5935679bd2abd3f70f | |
parent | 5f279845f9d684661563894d44729a0c706375b4 (diff) |
pm_qos: Get rid of the allocation in pm_qos_add_request()
All current users of pm_qos_add_request() have the ability to supply
the memory required by the pm_qos routines, so make them do this and
eliminate the kmalloc() with pm_qos_add_request(). This has the
double benefit of making the call never fail and allowing it to be
called from atomic context.
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Signed-off-by: mark gross <markgross@thegnar.org>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
-rw-r--r-- | drivers/net/e1000e/netdev.c | 17 | ||||
-rw-r--r-- | drivers/net/igbvf/netdev.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/ipw2x00/ipw2100.c | 12 | ||||
-rw-r--r-- | include/linux/netdevice.h | 2 | ||||
-rw-r--r-- | include/linux/pm_qos_params.h | 13 | ||||
-rw-r--r-- | include/sound/pcm.h | 2 | ||||
-rw-r--r-- | kernel/pm_qos_params.c | 67 | ||||
-rw-r--r-- | sound/core/pcm_native.c | 13 |
8 files changed, 74 insertions, 61 deletions
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 57a7e41da69e..9f13b660b801 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -2901,10 +2901,10 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) | |||
2901 | * dropped transactions. | 2901 | * dropped transactions. |
2902 | */ | 2902 | */ |
2903 | pm_qos_update_request( | 2903 | pm_qos_update_request( |
2904 | adapter->netdev->pm_qos_req, 55); | 2904 | &adapter->netdev->pm_qos_req, 55); |
2905 | } else { | 2905 | } else { |
2906 | pm_qos_update_request( | 2906 | pm_qos_update_request( |
2907 | adapter->netdev->pm_qos_req, | 2907 | &adapter->netdev->pm_qos_req, |
2908 | PM_QOS_DEFAULT_VALUE); | 2908 | PM_QOS_DEFAULT_VALUE); |
2909 | } | 2909 | } |
2910 | } | 2910 | } |
@@ -3196,9 +3196,9 @@ int e1000e_up(struct e1000_adapter *adapter) | |||
3196 | 3196 | ||
3197 | /* DMA latency requirement to workaround early-receive/jumbo issue */ | 3197 | /* DMA latency requirement to workaround early-receive/jumbo issue */ |
3198 | if (adapter->flags & FLAG_HAS_ERT) | 3198 | if (adapter->flags & FLAG_HAS_ERT) |
3199 | adapter->netdev->pm_qos_req = | 3199 | pm_qos_add_request(&adapter->netdev->pm_qos_req, |
3200 | pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY, | 3200 | PM_QOS_CPU_DMA_LATENCY, |
3201 | PM_QOS_DEFAULT_VALUE); | 3201 | PM_QOS_DEFAULT_VALUE); |
3202 | 3202 | ||
3203 | /* hardware has been reset, we need to reload some things */ | 3203 | /* hardware has been reset, we need to reload some things */ |
3204 | e1000_configure(adapter); | 3204 | e1000_configure(adapter); |
@@ -3263,11 +3263,8 @@ void e1000e_down(struct e1000_adapter *adapter) | |||
3263 | e1000_clean_tx_ring(adapter); | 3263 | e1000_clean_tx_ring(adapter); |
3264 | e1000_clean_rx_ring(adapter); | 3264 | e1000_clean_rx_ring(adapter); |
3265 | 3265 | ||
3266 | if (adapter->flags & FLAG_HAS_ERT) { | 3266 | if (adapter->flags & FLAG_HAS_ERT) |
3267 | pm_qos_remove_request( | 3267 | pm_qos_remove_request(&adapter->netdev->pm_qos_req); |
3268 | adapter->netdev->pm_qos_req); | ||
3269 | adapter->netdev->pm_qos_req = NULL; | ||
3270 | } | ||
3271 | 3268 | ||
3272 | /* | 3269 | /* |
3273 | * TODO: for power management, we could drop the link and | 3270 | * TODO: for power management, we could drop the link and |
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index 5e2b2a8c56c6..add6197d3bcb 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c | |||
@@ -48,7 +48,7 @@ | |||
48 | #define DRV_VERSION "1.0.0-k0" | 48 | #define DRV_VERSION "1.0.0-k0" |
49 | char igbvf_driver_name[] = "igbvf"; | 49 | char igbvf_driver_name[] = "igbvf"; |
50 | const char igbvf_driver_version[] = DRV_VERSION; | 50 | const char igbvf_driver_version[] = DRV_VERSION; |
51 | struct pm_qos_request_list *igbvf_driver_pm_qos_req; | 51 | static struct pm_qos_request_list igbvf_driver_pm_qos_req; |
52 | static const char igbvf_driver_string[] = | 52 | static const char igbvf_driver_string[] = |
53 | "Intel(R) Virtual Function Network Driver"; | 53 | "Intel(R) Virtual Function Network Driver"; |
54 | static const char igbvf_copyright[] = "Copyright (c) 2009 Intel Corporation."; | 54 | static const char igbvf_copyright[] = "Copyright (c) 2009 Intel Corporation."; |
@@ -2902,8 +2902,8 @@ static int __init igbvf_init_module(void) | |||
2902 | printk(KERN_INFO "%s\n", igbvf_copyright); | 2902 | printk(KERN_INFO "%s\n", igbvf_copyright); |
2903 | 2903 | ||
2904 | ret = pci_register_driver(&igbvf_driver); | 2904 | ret = pci_register_driver(&igbvf_driver); |
2905 | igbvf_driver_pm_qos_req = pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY, | 2905 | pm_qos_add_request(&igbvf_driver_pm_qos_req, PM_QOS_CPU_DMA_LATENCY, |
2906 | PM_QOS_DEFAULT_VALUE); | 2906 | PM_QOS_DEFAULT_VALUE); |
2907 | 2907 | ||
2908 | return ret; | 2908 | return ret; |
2909 | } | 2909 | } |
@@ -2918,8 +2918,7 @@ module_init(igbvf_init_module); | |||
2918 | static void __exit igbvf_exit_module(void) | 2918 | static void __exit igbvf_exit_module(void) |
2919 | { | 2919 | { |
2920 | pci_unregister_driver(&igbvf_driver); | 2920 | pci_unregister_driver(&igbvf_driver); |
2921 | pm_qos_remove_request(igbvf_driver_pm_qos_req); | 2921 | pm_qos_remove_request(&igbvf_driver_pm_qos_req); |
2922 | igbvf_driver_pm_qos_req = NULL; | ||
2923 | } | 2922 | } |
2924 | module_exit(igbvf_exit_module); | 2923 | module_exit(igbvf_exit_module); |
2925 | 2924 | ||
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 0bd4dfa59a8a..7f0d98b885bc 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c | |||
@@ -174,7 +174,7 @@ that only one external action is invoked at a time. | |||
174 | #define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver" | 174 | #define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver" |
175 | #define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation" | 175 | #define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation" |
176 | 176 | ||
177 | struct pm_qos_request_list *ipw2100_pm_qos_req; | 177 | struct pm_qos_request_list ipw2100_pm_qos_req; |
178 | 178 | ||
179 | /* Debugging stuff */ | 179 | /* Debugging stuff */ |
180 | #ifdef CONFIG_IPW2100_DEBUG | 180 | #ifdef CONFIG_IPW2100_DEBUG |
@@ -1741,7 +1741,7 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred) | |||
1741 | /* the ipw2100 hardware really doesn't want power management delays | 1741 | /* the ipw2100 hardware really doesn't want power management delays |
1742 | * longer than 175usec | 1742 | * longer than 175usec |
1743 | */ | 1743 | */ |
1744 | pm_qos_update_request(ipw2100_pm_qos_req, 175); | 1744 | pm_qos_update_request(&ipw2100_pm_qos_req, 175); |
1745 | 1745 | ||
1746 | /* If the interrupt is enabled, turn it off... */ | 1746 | /* If the interrupt is enabled, turn it off... */ |
1747 | spin_lock_irqsave(&priv->low_lock, flags); | 1747 | spin_lock_irqsave(&priv->low_lock, flags); |
@@ -1889,7 +1889,7 @@ static void ipw2100_down(struct ipw2100_priv *priv) | |||
1889 | ipw2100_disable_interrupts(priv); | 1889 | ipw2100_disable_interrupts(priv); |
1890 | spin_unlock_irqrestore(&priv->low_lock, flags); | 1890 | spin_unlock_irqrestore(&priv->low_lock, flags); |
1891 | 1891 | ||
1892 | pm_qos_update_request(ipw2100_pm_qos_req, PM_QOS_DEFAULT_VALUE); | 1892 | pm_qos_update_request(&ipw2100_pm_qos_req, PM_QOS_DEFAULT_VALUE); |
1893 | 1893 | ||
1894 | /* We have to signal any supplicant if we are disassociating */ | 1894 | /* We have to signal any supplicant if we are disassociating */ |
1895 | if (associated) | 1895 | if (associated) |
@@ -6669,8 +6669,8 @@ static int __init ipw2100_init(void) | |||
6669 | if (ret) | 6669 | if (ret) |
6670 | goto out; | 6670 | goto out; |
6671 | 6671 | ||
6672 | ipw2100_pm_qos_req = pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY, | 6672 | pm_qos_add_request(&ipw2100_pm_qos_req, PM_QOS_CPU_DMA_LATENCY, |
6673 | PM_QOS_DEFAULT_VALUE); | 6673 | PM_QOS_DEFAULT_VALUE); |
6674 | #ifdef CONFIG_IPW2100_DEBUG | 6674 | #ifdef CONFIG_IPW2100_DEBUG |
6675 | ipw2100_debug_level = debug; | 6675 | ipw2100_debug_level = debug; |
6676 | ret = driver_create_file(&ipw2100_pci_driver.driver, | 6676 | ret = driver_create_file(&ipw2100_pci_driver.driver, |
@@ -6692,7 +6692,7 @@ static void __exit ipw2100_exit(void) | |||
6692 | &driver_attr_debug_level); | 6692 | &driver_attr_debug_level); |
6693 | #endif | 6693 | #endif |
6694 | pci_unregister_driver(&ipw2100_pci_driver); | 6694 | pci_unregister_driver(&ipw2100_pci_driver); |
6695 | pm_qos_remove_request(ipw2100_pm_qos_req); | 6695 | pm_qos_remove_request(&ipw2100_pm_qos_req); |
6696 | } | 6696 | } |
6697 | 6697 | ||
6698 | module_init(ipw2100_init); | 6698 | module_init(ipw2100_init); |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index b21e4054c12c..2f22119b4b08 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -779,7 +779,7 @@ struct net_device { | |||
779 | */ | 779 | */ |
780 | char name[IFNAMSIZ]; | 780 | char name[IFNAMSIZ]; |
781 | 781 | ||
782 | struct pm_qos_request_list *pm_qos_req; | 782 | struct pm_qos_request_list pm_qos_req; |
783 | 783 | ||
784 | /* device name hash chain */ | 784 | /* device name hash chain */ |
785 | struct hlist_node name_hlist; | 785 | struct hlist_node name_hlist; |
diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h index 8ba440e5eb7f..77cbddb3784c 100644 --- a/include/linux/pm_qos_params.h +++ b/include/linux/pm_qos_params.h | |||
@@ -1,8 +1,10 @@ | |||
1 | #ifndef _LINUX_PM_QOS_PARAMS_H | ||
2 | #define _LINUX_PM_QOS_PARAMS_H | ||
1 | /* interface for the pm_qos_power infrastructure of the linux kernel. | 3 | /* interface for the pm_qos_power infrastructure of the linux kernel. |
2 | * | 4 | * |
3 | * Mark Gross <mgross@linux.intel.com> | 5 | * Mark Gross <mgross@linux.intel.com> |
4 | */ | 6 | */ |
5 | #include <linux/list.h> | 7 | #include <linux/plist.h> |
6 | #include <linux/notifier.h> | 8 | #include <linux/notifier.h> |
7 | #include <linux/miscdevice.h> | 9 | #include <linux/miscdevice.h> |
8 | 10 | ||
@@ -14,9 +16,12 @@ | |||
14 | #define PM_QOS_NUM_CLASSES 4 | 16 | #define PM_QOS_NUM_CLASSES 4 |
15 | #define PM_QOS_DEFAULT_VALUE -1 | 17 | #define PM_QOS_DEFAULT_VALUE -1 |
16 | 18 | ||
17 | struct pm_qos_request_list; | 19 | struct pm_qos_request_list { |
20 | struct plist_node list; | ||
21 | int pm_qos_class; | ||
22 | }; | ||
18 | 23 | ||
19 | struct pm_qos_request_list *pm_qos_add_request(int pm_qos_class, s32 value); | 24 | void pm_qos_add_request(struct pm_qos_request_list *l, int pm_qos_class, s32 value); |
20 | void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req, | 25 | void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req, |
21 | s32 new_value); | 26 | s32 new_value); |
22 | void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req); | 27 | void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req); |
@@ -24,4 +29,6 @@ void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req); | |||
24 | int pm_qos_request(int pm_qos_class); | 29 | int pm_qos_request(int pm_qos_class); |
25 | int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier); | 30 | int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier); |
26 | int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier); | 31 | int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier); |
32 | int pm_qos_request_active(struct pm_qos_request_list *req); | ||
27 | 33 | ||
34 | #endif | ||
diff --git a/include/sound/pcm.h b/include/sound/pcm.h index dd76cdede64d..6e3a29732dc4 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h | |||
@@ -366,7 +366,7 @@ struct snd_pcm_substream { | |||
366 | int number; | 366 | int number; |
367 | char name[32]; /* substream name */ | 367 | char name[32]; /* substream name */ |
368 | int stream; /* stream (direction) */ | 368 | int stream; /* stream (direction) */ |
369 | struct pm_qos_request_list *latency_pm_qos_req; /* pm_qos request */ | 369 | struct pm_qos_request_list latency_pm_qos_req; /* pm_qos request */ |
370 | size_t buffer_bytes_max; /* limit ring buffer size */ | 370 | size_t buffer_bytes_max; /* limit ring buffer size */ |
371 | struct snd_dma_buffer dma_buffer; | 371 | struct snd_dma_buffer dma_buffer; |
372 | unsigned int dma_buf_id; | 372 | unsigned int dma_buf_id; |
diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c index db8e51d7f392..996a4dec5f96 100644 --- a/kernel/pm_qos_params.c +++ b/kernel/pm_qos_params.c | |||
@@ -30,7 +30,6 @@ | |||
30 | /*#define DEBUG*/ | 30 | /*#define DEBUG*/ |
31 | 31 | ||
32 | #include <linux/pm_qos_params.h> | 32 | #include <linux/pm_qos_params.h> |
33 | #include <linux/plist.h> | ||
34 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
35 | #include <linux/spinlock.h> | 34 | #include <linux/spinlock.h> |
36 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
@@ -49,11 +48,6 @@ | |||
49 | * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock | 48 | * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock |
50 | * held, taken with _irqsave. One lock to rule them all | 49 | * held, taken with _irqsave. One lock to rule them all |
51 | */ | 50 | */ |
52 | struct pm_qos_request_list { | ||
53 | struct plist_node list; | ||
54 | int pm_qos_class; | ||
55 | }; | ||
56 | |||
57 | enum pm_qos_type { | 51 | enum pm_qos_type { |
58 | PM_QOS_MAX, /* return the largest value */ | 52 | PM_QOS_MAX, /* return the largest value */ |
59 | PM_QOS_MIN /* return the smallest value */ | 53 | PM_QOS_MIN /* return the smallest value */ |
@@ -210,6 +204,12 @@ int pm_qos_request(int pm_qos_class) | |||
210 | } | 204 | } |
211 | EXPORT_SYMBOL_GPL(pm_qos_request); | 205 | EXPORT_SYMBOL_GPL(pm_qos_request); |
212 | 206 | ||
207 | int pm_qos_request_active(struct pm_qos_request_list *req) | ||
208 | { | ||
209 | return req->pm_qos_class != 0; | ||
210 | } | ||
211 | EXPORT_SYMBOL_GPL(pm_qos_request_active); | ||
212 | |||
213 | /** | 213 | /** |
214 | * pm_qos_add_request - inserts new qos request into the list | 214 | * pm_qos_add_request - inserts new qos request into the list |
215 | * @pm_qos_class: identifies which list of qos request to us | 215 | * @pm_qos_class: identifies which list of qos request to us |
@@ -221,25 +221,23 @@ EXPORT_SYMBOL_GPL(pm_qos_request); | |||
221 | * element as a handle for use in updating and removal. Call needs to save | 221 | * element as a handle for use in updating and removal. Call needs to save |
222 | * this handle for later use. | 222 | * this handle for later use. |
223 | */ | 223 | */ |
224 | struct pm_qos_request_list *pm_qos_add_request(int pm_qos_class, s32 value) | 224 | void pm_qos_add_request(struct pm_qos_request_list *dep, |
225 | int pm_qos_class, s32 value) | ||
225 | { | 226 | { |
226 | struct pm_qos_request_list *dep; | 227 | struct pm_qos_object *o = pm_qos_array[pm_qos_class]; |
227 | 228 | int new_value; | |
228 | dep = kzalloc(sizeof(struct pm_qos_request_list), GFP_KERNEL); | ||
229 | if (dep) { | ||
230 | struct pm_qos_object *o = pm_qos_array[pm_qos_class]; | ||
231 | int new_value; | ||
232 | |||
233 | if (value == PM_QOS_DEFAULT_VALUE) | ||
234 | new_value = o->default_value; | ||
235 | else | ||
236 | new_value = value; | ||
237 | plist_node_init(&dep->list, new_value); | ||
238 | dep->pm_qos_class = pm_qos_class; | ||
239 | update_target(o, &dep->list, 0, PM_QOS_DEFAULT_VALUE); | ||
240 | } | ||
241 | 229 | ||
242 | return dep; | 230 | if (pm_qos_request_active(dep)) { |
231 | WARN(1, KERN_ERR "pm_qos_add_request() called for already added request\n"); | ||
232 | return; | ||
233 | } | ||
234 | if (value == PM_QOS_DEFAULT_VALUE) | ||
235 | new_value = o->default_value; | ||
236 | else | ||
237 | new_value = value; | ||
238 | plist_node_init(&dep->list, new_value); | ||
239 | dep->pm_qos_class = pm_qos_class; | ||
240 | update_target(o, &dep->list, 0, PM_QOS_DEFAULT_VALUE); | ||
243 | } | 241 | } |
244 | EXPORT_SYMBOL_GPL(pm_qos_add_request); | 242 | EXPORT_SYMBOL_GPL(pm_qos_add_request); |
245 | 243 | ||
@@ -262,6 +260,11 @@ void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req, | |||
262 | if (!pm_qos_req) /*guard against callers passing in null */ | 260 | if (!pm_qos_req) /*guard against callers passing in null */ |
263 | return; | 261 | return; |
264 | 262 | ||
263 | if (!pm_qos_request_active(pm_qos_req)) { | ||
264 | WARN(1, KERN_ERR "pm_qos_update_request() called for unknown object\n"); | ||
265 | return; | ||
266 | } | ||
267 | |||
265 | o = pm_qos_array[pm_qos_req->pm_qos_class]; | 268 | o = pm_qos_array[pm_qos_req->pm_qos_class]; |
266 | 269 | ||
267 | if (new_value == PM_QOS_DEFAULT_VALUE) | 270 | if (new_value == PM_QOS_DEFAULT_VALUE) |
@@ -290,9 +293,14 @@ void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req) | |||
290 | return; | 293 | return; |
291 | /* silent return to keep pcm code cleaner */ | 294 | /* silent return to keep pcm code cleaner */ |
292 | 295 | ||
296 | if (!pm_qos_request_active(pm_qos_req)) { | ||
297 | WARN(1, KERN_ERR "pm_qos_remove_request() called for unknown object\n"); | ||
298 | return; | ||
299 | } | ||
300 | |||
293 | o = pm_qos_array[pm_qos_req->pm_qos_class]; | 301 | o = pm_qos_array[pm_qos_req->pm_qos_class]; |
294 | update_target(o, &pm_qos_req->list, 1, PM_QOS_DEFAULT_VALUE); | 302 | update_target(o, &pm_qos_req->list, 1, PM_QOS_DEFAULT_VALUE); |
295 | kfree(pm_qos_req); | 303 | memset(pm_qos_req, 0, sizeof(*pm_qos_req)); |
296 | } | 304 | } |
297 | EXPORT_SYMBOL_GPL(pm_qos_remove_request); | 305 | EXPORT_SYMBOL_GPL(pm_qos_remove_request); |
298 | 306 | ||
@@ -340,8 +348,12 @@ static int pm_qos_power_open(struct inode *inode, struct file *filp) | |||
340 | 348 | ||
341 | pm_qos_class = find_pm_qos_object_by_minor(iminor(inode)); | 349 | pm_qos_class = find_pm_qos_object_by_minor(iminor(inode)); |
342 | if (pm_qos_class >= 0) { | 350 | if (pm_qos_class >= 0) { |
343 | filp->private_data = (void *) pm_qos_add_request(pm_qos_class, | 351 | struct pm_qos_request_list *req = kzalloc(GFP_KERNEL, sizeof(*req)); |
344 | PM_QOS_DEFAULT_VALUE); | 352 | if (!req) |
353 | return -ENOMEM; | ||
354 | |||
355 | pm_qos_add_request(req, pm_qos_class, PM_QOS_DEFAULT_VALUE); | ||
356 | filp->private_data = req; | ||
345 | 357 | ||
346 | if (filp->private_data) | 358 | if (filp->private_data) |
347 | return 0; | 359 | return 0; |
@@ -353,8 +365,9 @@ static int pm_qos_power_release(struct inode *inode, struct file *filp) | |||
353 | { | 365 | { |
354 | struct pm_qos_request_list *req; | 366 | struct pm_qos_request_list *req; |
355 | 367 | ||
356 | req = (struct pm_qos_request_list *)filp->private_data; | 368 | req = filp->private_data; |
357 | pm_qos_remove_request(req); | 369 | pm_qos_remove_request(req); |
370 | kfree(req); | ||
358 | 371 | ||
359 | return 0; | 372 | return 0; |
360 | } | 373 | } |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 303ac04ff6e4..a3b2a6479246 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -451,13 +451,11 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, | |||
451 | snd_pcm_timer_resolution_change(substream); | 451 | snd_pcm_timer_resolution_change(substream); |
452 | runtime->status->state = SNDRV_PCM_STATE_SETUP; | 452 | runtime->status->state = SNDRV_PCM_STATE_SETUP; |
453 | 453 | ||
454 | if (substream->latency_pm_qos_req) { | 454 | if (pm_qos_request_active(&substream->latency_pm_qos_req)) |
455 | pm_qos_remove_request(substream->latency_pm_qos_req); | 455 | pm_qos_remove_request(&substream->latency_pm_qos_req); |
456 | substream->latency_pm_qos_req = NULL; | ||
457 | } | ||
458 | if ((usecs = period_to_usecs(runtime)) >= 0) | 456 | if ((usecs = period_to_usecs(runtime)) >= 0) |
459 | substream->latency_pm_qos_req = pm_qos_add_request( | 457 | pm_qos_add_request(&substream->latency_pm_qos_req, |
460 | PM_QOS_CPU_DMA_LATENCY, usecs); | 458 | PM_QOS_CPU_DMA_LATENCY, usecs); |
461 | return 0; | 459 | return 0; |
462 | _error: | 460 | _error: |
463 | /* hardware might be unuseable from this time, | 461 | /* hardware might be unuseable from this time, |
@@ -512,8 +510,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream) | |||
512 | if (substream->ops->hw_free) | 510 | if (substream->ops->hw_free) |
513 | result = substream->ops->hw_free(substream); | 511 | result = substream->ops->hw_free(substream); |
514 | runtime->status->state = SNDRV_PCM_STATE_OPEN; | 512 | runtime->status->state = SNDRV_PCM_STATE_OPEN; |
515 | pm_qos_remove_request(substream->latency_pm_qos_req); | 513 | pm_qos_remove_request(&substream->latency_pm_qos_req); |
516 | substream->latency_pm_qos_req = NULL; | ||
517 | return result; | 514 | return result; |
518 | } | 515 | } |
519 | 516 | ||