aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwtracing/stm
diff options
context:
space:
mode:
authorAlexander Shishkin <alexander.shishkin@linux.intel.com>2016-06-28 04:35:02 -0400
committerAlexander Shishkin <alexander.shishkin@linux.intel.com>2016-07-01 04:00:14 -0400
commit8e0469a4f3e647059c0ef8db961140ee25246fbd (patch)
treee98b5e24ba140a035f3e36243a041788dcd83009 /drivers/hwtracing/stm
parentaf8c34ce6ae32addda3788d54a7e340cad22516b (diff)
stm class: Add runtime power management handling
Currently, there's no runtime pm in stm class devices, which makes it harder for the underlying hardware drivers to handle their power management. This patch applies the following runtime pm policy to stm class devices, which their parents can rely on for their power management tracking: * device is in use during character device writes, * delayed autosuspend is used to keep it active between adjacent writes, * device is in use while mmio regions are mapped, * device is is use while any stm_source devices are linked to it. Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org> Cc: Chunyan Zhang <zhang.chunyan@linaro.org>
Diffstat (limited to 'drivers/hwtracing/stm')
-rw-r--r--drivers/hwtracing/stm/core.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c
index ff31108b066f..51f81d64ca37 100644
--- a/drivers/hwtracing/stm/core.c
+++ b/drivers/hwtracing/stm/core.c
@@ -15,6 +15,7 @@
15 * as defined in MIPI STPv2 specification. 15 * as defined in MIPI STPv2 specification.
16 */ 16 */
17 17
18#include <linux/pm_runtime.h>
18#include <linux/uaccess.h> 19#include <linux/uaccess.h>
19#include <linux/kernel.h> 20#include <linux/kernel.h>
20#include <linux/module.h> 21#include <linux/module.h>
@@ -482,14 +483,40 @@ static ssize_t stm_char_write(struct file *file, const char __user *buf,
482 return -EFAULT; 483 return -EFAULT;
483 } 484 }
484 485
486 pm_runtime_get_sync(&stm->dev);
487
485 count = stm_write(stm->data, stmf->output.master, stmf->output.channel, 488 count = stm_write(stm->data, stmf->output.master, stmf->output.channel,
486 kbuf, count); 489 kbuf, count);
487 490
491 pm_runtime_mark_last_busy(&stm->dev);
492 pm_runtime_put_autosuspend(&stm->dev);
488 kfree(kbuf); 493 kfree(kbuf);
489 494
490 return count; 495 return count;
491} 496}
492 497
498static void stm_mmap_open(struct vm_area_struct *vma)
499{
500 struct stm_file *stmf = vma->vm_file->private_data;
501 struct stm_device *stm = stmf->stm;
502
503 pm_runtime_get(&stm->dev);
504}
505
506static void stm_mmap_close(struct vm_area_struct *vma)
507{
508 struct stm_file *stmf = vma->vm_file->private_data;
509 struct stm_device *stm = stmf->stm;
510
511 pm_runtime_mark_last_busy(&stm->dev);
512 pm_runtime_put_autosuspend(&stm->dev);
513}
514
515static const struct vm_operations_struct stm_mmap_vmops = {
516 .open = stm_mmap_open,
517 .close = stm_mmap_close,
518};
519
493static int stm_char_mmap(struct file *file, struct vm_area_struct *vma) 520static int stm_char_mmap(struct file *file, struct vm_area_struct *vma)
494{ 521{
495 struct stm_file *stmf = file->private_data; 522 struct stm_file *stmf = file->private_data;
@@ -514,8 +541,11 @@ static int stm_char_mmap(struct file *file, struct vm_area_struct *vma)
514 if (!phys) 541 if (!phys)
515 return -EINVAL; 542 return -EINVAL;
516 543
544 pm_runtime_get_sync(&stm->dev);
545
517 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 546 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
518 vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; 547 vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
548 vma->vm_ops = &stm_mmap_vmops;
519 vm_iomap_memory(vma, phys, size); 549 vm_iomap_memory(vma, phys, size);
520 550
521 return 0; 551 return 0;
@@ -701,6 +731,17 @@ int stm_register_device(struct device *parent, struct stm_data *stm_data,
701 if (err) 731 if (err)
702 goto err_device; 732 goto err_device;
703 733
734 /*
735 * Use delayed autosuspend to avoid bouncing back and forth
736 * on recurring character device writes, with the initial
737 * delay time of 2 seconds.
738 */
739 pm_runtime_no_callbacks(&stm->dev);
740 pm_runtime_use_autosuspend(&stm->dev);
741 pm_runtime_set_autosuspend_delay(&stm->dev, 2000);
742 pm_runtime_set_suspended(&stm->dev);
743 pm_runtime_enable(&stm->dev);
744
704 return 0; 745 return 0;
705 746
706err_device: 747err_device:
@@ -724,6 +765,9 @@ void stm_unregister_device(struct stm_data *stm_data)
724 struct stm_source_device *src, *iter; 765 struct stm_source_device *src, *iter;
725 int i, ret; 766 int i, ret;
726 767
768 pm_runtime_dont_use_autosuspend(&stm->dev);
769 pm_runtime_disable(&stm->dev);
770
727 mutex_lock(&stm->link_mutex); 771 mutex_lock(&stm->link_mutex);
728 list_for_each_entry_safe(src, iter, &stm->link_list, link_entry) { 772 list_for_each_entry_safe(src, iter, &stm->link_list, link_entry) {
729 ret = __stm_source_link_drop(src, stm); 773 ret = __stm_source_link_drop(src, stm);
@@ -878,6 +922,8 @@ static int __stm_source_link_drop(struct stm_source_device *src,
878 922
879 stm_output_free(link, &src->output); 923 stm_output_free(link, &src->output);
880 list_del_init(&src->link_entry); 924 list_del_init(&src->link_entry);
925 pm_runtime_mark_last_busy(&link->dev);
926 pm_runtime_put_autosuspend(&link->dev);
881 /* matches stm_find_device() from stm_source_link_store() */ 927 /* matches stm_find_device() from stm_source_link_store() */
882 stm_put_device(link); 928 stm_put_device(link);
883 rcu_assign_pointer(src->link, NULL); 929 rcu_assign_pointer(src->link, NULL);
@@ -971,8 +1017,11 @@ static ssize_t stm_source_link_store(struct device *dev,
971 if (!link) 1017 if (!link)
972 return -EINVAL; 1018 return -EINVAL;
973 1019
1020 pm_runtime_get(&link->dev);
1021
974 err = stm_source_link_add(src, link); 1022 err = stm_source_link_add(src, link);
975 if (err) { 1023 if (err) {
1024 pm_runtime_put_autosuspend(&link->dev);
976 /* matches the stm_find_device() above */ 1025 /* matches the stm_find_device() above */
977 stm_put_device(link); 1026 stm_put_device(link);
978 } 1027 }
@@ -1033,6 +1082,9 @@ int stm_source_register_device(struct device *parent,
1033 if (err) 1082 if (err)
1034 goto err; 1083 goto err;
1035 1084
1085 pm_runtime_no_callbacks(&src->dev);
1086 pm_runtime_forbid(&src->dev);
1087
1036 err = device_add(&src->dev); 1088 err = device_add(&src->dev);
1037 if (err) 1089 if (err)
1038 goto err; 1090 goto err;