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 | ||
