diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/power/qos.c | 91 | ||||
-rw-r--r-- | kernel/power/snapshot.c | 11 | ||||
-rw-r--r-- | kernel/resource.c | 25 | ||||
-rw-r--r-- | kernel/trace/power-traces.c | 1 |
4 files changed, 121 insertions, 7 deletions
diff --git a/kernel/power/qos.c b/kernel/power/qos.c index 5f4c006c4b1e..97b0df71303e 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c | |||
@@ -41,6 +41,8 @@ | |||
41 | #include <linux/platform_device.h> | 41 | #include <linux/platform_device.h> |
42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
43 | #include <linux/kernel.h> | 43 | #include <linux/kernel.h> |
44 | #include <linux/debugfs.h> | ||
45 | #include <linux/seq_file.h> | ||
44 | 46 | ||
45 | #include <linux/uaccess.h> | 47 | #include <linux/uaccess.h> |
46 | #include <linux/export.h> | 48 | #include <linux/export.h> |
@@ -182,6 +184,81 @@ static inline void pm_qos_set_value(struct pm_qos_constraints *c, s32 value) | |||
182 | c->target_value = value; | 184 | c->target_value = value; |
183 | } | 185 | } |
184 | 186 | ||
187 | static inline int pm_qos_get_value(struct pm_qos_constraints *c); | ||
188 | static int pm_qos_dbg_show_requests(struct seq_file *s, void *unused) | ||
189 | { | ||
190 | struct pm_qos_object *qos = (struct pm_qos_object *)s->private; | ||
191 | struct pm_qos_constraints *c; | ||
192 | struct pm_qos_request *req; | ||
193 | char *type; | ||
194 | unsigned long flags; | ||
195 | int tot_reqs = 0; | ||
196 | int active_reqs = 0; | ||
197 | |||
198 | if (IS_ERR_OR_NULL(qos)) { | ||
199 | pr_err("%s: bad qos param!\n", __func__); | ||
200 | return -EINVAL; | ||
201 | } | ||
202 | c = qos->constraints; | ||
203 | if (IS_ERR_OR_NULL(c)) { | ||
204 | pr_err("%s: Bad constraints on qos?\n", __func__); | ||
205 | return -EINVAL; | ||
206 | } | ||
207 | |||
208 | /* Lock to ensure we have a snapshot */ | ||
209 | spin_lock_irqsave(&pm_qos_lock, flags); | ||
210 | if (plist_head_empty(&c->list)) { | ||
211 | seq_puts(s, "Empty!\n"); | ||
212 | goto out; | ||
213 | } | ||
214 | |||
215 | switch (c->type) { | ||
216 | case PM_QOS_MIN: | ||
217 | type = "Minimum"; | ||
218 | break; | ||
219 | case PM_QOS_MAX: | ||
220 | type = "Maximum"; | ||
221 | break; | ||
222 | case PM_QOS_SUM: | ||
223 | type = "Sum"; | ||
224 | break; | ||
225 | default: | ||
226 | type = "Unknown"; | ||
227 | } | ||
228 | |||
229 | plist_for_each_entry(req, &c->list, node) { | ||
230 | char *state = "Default"; | ||
231 | |||
232 | if ((req->node).prio != c->default_value) { | ||
233 | active_reqs++; | ||
234 | state = "Active"; | ||
235 | } | ||
236 | tot_reqs++; | ||
237 | seq_printf(s, "%d: %d: %s\n", tot_reqs, | ||
238 | (req->node).prio, state); | ||
239 | } | ||
240 | |||
241 | seq_printf(s, "Type=%s, Value=%d, Requests: active=%d / total=%d\n", | ||
242 | type, pm_qos_get_value(c), active_reqs, tot_reqs); | ||
243 | |||
244 | out: | ||
245 | spin_unlock_irqrestore(&pm_qos_lock, flags); | ||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | static int pm_qos_dbg_open(struct inode *inode, struct file *file) | ||
250 | { | ||
251 | return single_open(file, pm_qos_dbg_show_requests, | ||
252 | inode->i_private); | ||
253 | } | ||
254 | |||
255 | static const struct file_operations pm_qos_debug_fops = { | ||
256 | .open = pm_qos_dbg_open, | ||
257 | .read = seq_read, | ||
258 | .llseek = seq_lseek, | ||
259 | .release = single_release, | ||
260 | }; | ||
261 | |||
185 | /** | 262 | /** |
186 | * pm_qos_update_target - manages the constraints list and calls the notifiers | 263 | * pm_qos_update_target - manages the constraints list and calls the notifiers |
187 | * if needed | 264 | * if needed |
@@ -509,12 +586,17 @@ int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier) | |||
509 | EXPORT_SYMBOL_GPL(pm_qos_remove_notifier); | 586 | EXPORT_SYMBOL_GPL(pm_qos_remove_notifier); |
510 | 587 | ||
511 | /* User space interface to PM QoS classes via misc devices */ | 588 | /* User space interface to PM QoS classes via misc devices */ |
512 | static int register_pm_qos_misc(struct pm_qos_object *qos) | 589 | static int register_pm_qos_misc(struct pm_qos_object *qos, struct dentry *d) |
513 | { | 590 | { |
514 | qos->pm_qos_power_miscdev.minor = MISC_DYNAMIC_MINOR; | 591 | qos->pm_qos_power_miscdev.minor = MISC_DYNAMIC_MINOR; |
515 | qos->pm_qos_power_miscdev.name = qos->name; | 592 | qos->pm_qos_power_miscdev.name = qos->name; |
516 | qos->pm_qos_power_miscdev.fops = &pm_qos_power_fops; | 593 | qos->pm_qos_power_miscdev.fops = &pm_qos_power_fops; |
517 | 594 | ||
595 | if (d) { | ||
596 | (void)debugfs_create_file(qos->name, S_IRUGO, d, | ||
597 | (void *)qos, &pm_qos_debug_fops); | ||
598 | } | ||
599 | |||
518 | return misc_register(&qos->pm_qos_power_miscdev); | 600 | return misc_register(&qos->pm_qos_power_miscdev); |
519 | } | 601 | } |
520 | 602 | ||
@@ -608,11 +690,16 @@ static int __init pm_qos_power_init(void) | |||
608 | { | 690 | { |
609 | int ret = 0; | 691 | int ret = 0; |
610 | int i; | 692 | int i; |
693 | struct dentry *d; | ||
611 | 694 | ||
612 | BUILD_BUG_ON(ARRAY_SIZE(pm_qos_array) != PM_QOS_NUM_CLASSES); | 695 | BUILD_BUG_ON(ARRAY_SIZE(pm_qos_array) != PM_QOS_NUM_CLASSES); |
613 | 696 | ||
697 | d = debugfs_create_dir("pm_qos", NULL); | ||
698 | if (IS_ERR_OR_NULL(d)) | ||
699 | d = NULL; | ||
700 | |||
614 | for (i = PM_QOS_CPU_DMA_LATENCY; i < PM_QOS_NUM_CLASSES; i++) { | 701 | for (i = PM_QOS_CPU_DMA_LATENCY; i < PM_QOS_NUM_CLASSES; i++) { |
615 | ret = register_pm_qos_misc(pm_qos_array[i]); | 702 | ret = register_pm_qos_misc(pm_qos_array[i], d); |
616 | if (ret < 0) { | 703 | if (ret < 0) { |
617 | printk(KERN_ERR "pm_qos_param: %s setup failed\n", | 704 | printk(KERN_ERR "pm_qos_param: %s setup failed\n", |
618 | pm_qos_array[i]->name); | 705 | pm_qos_array[i]->name); |
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 0c40c16174b4..c24d5a23bf93 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c | |||
@@ -1472,9 +1472,9 @@ static inline unsigned long preallocate_highmem_fraction(unsigned long nr_pages, | |||
1472 | /** | 1472 | /** |
1473 | * free_unnecessary_pages - Release preallocated pages not needed for the image | 1473 | * free_unnecessary_pages - Release preallocated pages not needed for the image |
1474 | */ | 1474 | */ |
1475 | static void free_unnecessary_pages(void) | 1475 | static unsigned long free_unnecessary_pages(void) |
1476 | { | 1476 | { |
1477 | unsigned long save, to_free_normal, to_free_highmem; | 1477 | unsigned long save, to_free_normal, to_free_highmem, free; |
1478 | 1478 | ||
1479 | save = count_data_pages(); | 1479 | save = count_data_pages(); |
1480 | if (alloc_normal >= save) { | 1480 | if (alloc_normal >= save) { |
@@ -1495,6 +1495,7 @@ static void free_unnecessary_pages(void) | |||
1495 | else | 1495 | else |
1496 | to_free_normal = 0; | 1496 | to_free_normal = 0; |
1497 | } | 1497 | } |
1498 | free = to_free_normal + to_free_highmem; | ||
1498 | 1499 | ||
1499 | memory_bm_position_reset(©_bm); | 1500 | memory_bm_position_reset(©_bm); |
1500 | 1501 | ||
@@ -1518,6 +1519,8 @@ static void free_unnecessary_pages(void) | |||
1518 | swsusp_unset_page_free(page); | 1519 | swsusp_unset_page_free(page); |
1519 | __free_page(page); | 1520 | __free_page(page); |
1520 | } | 1521 | } |
1522 | |||
1523 | return free; | ||
1521 | } | 1524 | } |
1522 | 1525 | ||
1523 | /** | 1526 | /** |
@@ -1707,7 +1710,7 @@ int hibernate_preallocate_memory(void) | |||
1707 | * pages in memory, but we have allocated more. Release the excessive | 1710 | * pages in memory, but we have allocated more. Release the excessive |
1708 | * ones now. | 1711 | * ones now. |
1709 | */ | 1712 | */ |
1710 | free_unnecessary_pages(); | 1713 | pages -= free_unnecessary_pages(); |
1711 | 1714 | ||
1712 | out: | 1715 | out: |
1713 | stop = ktime_get(); | 1716 | stop = ktime_get(); |
@@ -2310,8 +2313,6 @@ static inline void free_highmem_data(void) | |||
2310 | free_image_page(buffer, PG_UNSAFE_CLEAR); | 2313 | free_image_page(buffer, PG_UNSAFE_CLEAR); |
2311 | } | 2314 | } |
2312 | #else | 2315 | #else |
2313 | static inline int get_safe_write_buffer(void) { return 0; } | ||
2314 | |||
2315 | static unsigned int | 2316 | static unsigned int |
2316 | count_highmem_image_pages(struct memory_bitmap *bm) { return 0; } | 2317 | count_highmem_image_pages(struct memory_bitmap *bm) { return 0; } |
2317 | 2318 | ||
diff --git a/kernel/resource.c b/kernel/resource.c index 0bcebffc4e77..19f2357dfda3 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/device.h> | 22 | #include <linux/device.h> |
23 | #include <linux/pfn.h> | 23 | #include <linux/pfn.h> |
24 | #include <linux/mm.h> | 24 | #include <linux/mm.h> |
25 | #include <linux/resource_ext.h> | ||
25 | #include <asm/io.h> | 26 | #include <asm/io.h> |
26 | 27 | ||
27 | 28 | ||
@@ -1529,6 +1530,30 @@ int iomem_is_exclusive(u64 addr) | |||
1529 | return err; | 1530 | return err; |
1530 | } | 1531 | } |
1531 | 1532 | ||
1533 | struct resource_entry *resource_list_create_entry(struct resource *res, | ||
1534 | size_t extra_size) | ||
1535 | { | ||
1536 | struct resource_entry *entry; | ||
1537 | |||
1538 | entry = kzalloc(sizeof(*entry) + extra_size, GFP_KERNEL); | ||
1539 | if (entry) { | ||
1540 | INIT_LIST_HEAD(&entry->node); | ||
1541 | entry->res = res ? res : &entry->__res; | ||
1542 | } | ||
1543 | |||
1544 | return entry; | ||
1545 | } | ||
1546 | EXPORT_SYMBOL(resource_list_create_entry); | ||
1547 | |||
1548 | void resource_list_free(struct list_head *head) | ||
1549 | { | ||
1550 | struct resource_entry *entry, *tmp; | ||
1551 | |||
1552 | list_for_each_entry_safe(entry, tmp, head, node) | ||
1553 | resource_list_destroy_entry(entry); | ||
1554 | } | ||
1555 | EXPORT_SYMBOL(resource_list_free); | ||
1556 | |||
1532 | static int __init strict_iomem(char *str) | 1557 | static int __init strict_iomem(char *str) |
1533 | { | 1558 | { |
1534 | if (strstr(str, "relaxed")) | 1559 | if (strstr(str, "relaxed")) |
diff --git a/kernel/trace/power-traces.c b/kernel/trace/power-traces.c index 1c71382b283d..eb4220a132ec 100644 --- a/kernel/trace/power-traces.c +++ b/kernel/trace/power-traces.c | |||
@@ -13,5 +13,6 @@ | |||
13 | #define CREATE_TRACE_POINTS | 13 | #define CREATE_TRACE_POINTS |
14 | #include <trace/events/power.h> | 14 | #include <trace/events/power.h> |
15 | 15 | ||
16 | EXPORT_TRACEPOINT_SYMBOL_GPL(suspend_resume); | ||
16 | EXPORT_TRACEPOINT_SYMBOL_GPL(cpu_idle); | 17 | EXPORT_TRACEPOINT_SYMBOL_GPL(cpu_idle); |
17 | 18 | ||