diff options
Diffstat (limited to 'drivers/hwtracing/coresight/coresight-etm3x.c')
-rw-r--r-- | drivers/hwtracing/coresight/coresight-etm3x.c | 90 |
1 files changed, 49 insertions, 41 deletions
diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c index d83ab82672e4..2de4cad9c5ed 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x.c +++ b/drivers/hwtracing/coresight/coresight-etm3x.c | |||
@@ -51,6 +51,8 @@ module_param_named(boot_enable, boot_enable, int, S_IRUGO); | |||
51 | static int etm_count; | 51 | static int etm_count; |
52 | static struct etm_drvdata *etmdrvdata[NR_CPUS]; | 52 | static struct etm_drvdata *etmdrvdata[NR_CPUS]; |
53 | 53 | ||
54 | static enum cpuhp_state hp_online; | ||
55 | |||
54 | /* | 56 | /* |
55 | * Memory mapped writes to clear os lock are not supported on some processors | 57 | * Memory mapped writes to clear os lock are not supported on some processors |
56 | * and OS lock must be unlocked before any memory mapped access on such | 58 | * and OS lock must be unlocked before any memory mapped access on such |
@@ -481,8 +483,7 @@ static int etm_enable_sysfs(struct coresight_device *csdev) | |||
481 | 483 | ||
482 | /* | 484 | /* |
483 | * Configure the ETM only if the CPU is online. If it isn't online | 485 | * Configure the ETM only if the CPU is online. If it isn't online |
484 | * hw configuration will take place when 'CPU_STARTING' is received | 486 | * hw configuration will take place on the local CPU during bring up. |
485 | * in @etm_cpu_callback. | ||
486 | */ | 487 | */ |
487 | if (cpu_online(drvdata->cpu)) { | 488 | if (cpu_online(drvdata->cpu)) { |
488 | ret = smp_call_function_single(drvdata->cpu, | 489 | ret = smp_call_function_single(drvdata->cpu, |
@@ -641,47 +642,44 @@ static const struct coresight_ops etm_cs_ops = { | |||
641 | .source_ops = &etm_source_ops, | 642 | .source_ops = &etm_source_ops, |
642 | }; | 643 | }; |
643 | 644 | ||
644 | static int etm_cpu_callback(struct notifier_block *nfb, unsigned long action, | 645 | static int etm_online_cpu(unsigned int cpu) |
645 | void *hcpu) | ||
646 | { | 646 | { |
647 | unsigned int cpu = (unsigned long)hcpu; | ||
648 | |||
649 | if (!etmdrvdata[cpu]) | 647 | if (!etmdrvdata[cpu]) |
650 | goto out; | 648 | return 0; |
651 | 649 | ||
652 | switch (action & (~CPU_TASKS_FROZEN)) { | 650 | if (etmdrvdata[cpu]->boot_enable && !etmdrvdata[cpu]->sticky_enable) |
653 | case CPU_STARTING: | 651 | coresight_enable(etmdrvdata[cpu]->csdev); |
654 | spin_lock(&etmdrvdata[cpu]->spinlock); | 652 | return 0; |
655 | if (!etmdrvdata[cpu]->os_unlock) { | 653 | } |
656 | etm_os_unlock(etmdrvdata[cpu]); | ||
657 | etmdrvdata[cpu]->os_unlock = true; | ||
658 | } | ||
659 | |||
660 | if (local_read(&etmdrvdata[cpu]->mode)) | ||
661 | etm_enable_hw(etmdrvdata[cpu]); | ||
662 | spin_unlock(&etmdrvdata[cpu]->spinlock); | ||
663 | break; | ||
664 | 654 | ||
665 | case CPU_ONLINE: | 655 | static int etm_starting_cpu(unsigned int cpu) |
666 | if (etmdrvdata[cpu]->boot_enable && | 656 | { |
667 | !etmdrvdata[cpu]->sticky_enable) | 657 | if (!etmdrvdata[cpu]) |
668 | coresight_enable(etmdrvdata[cpu]->csdev); | 658 | return 0; |
669 | break; | ||
670 | 659 | ||
671 | case CPU_DYING: | 660 | spin_lock(&etmdrvdata[cpu]->spinlock); |
672 | spin_lock(&etmdrvdata[cpu]->spinlock); | 661 | if (!etmdrvdata[cpu]->os_unlock) { |
673 | if (local_read(&etmdrvdata[cpu]->mode)) | 662 | etm_os_unlock(etmdrvdata[cpu]); |
674 | etm_disable_hw(etmdrvdata[cpu]); | 663 | etmdrvdata[cpu]->os_unlock = true; |
675 | spin_unlock(&etmdrvdata[cpu]->spinlock); | ||
676 | break; | ||
677 | } | 664 | } |
678 | out: | 665 | |
679 | return NOTIFY_OK; | 666 | if (local_read(&etmdrvdata[cpu]->mode)) |
667 | etm_enable_hw(etmdrvdata[cpu]); | ||
668 | spin_unlock(&etmdrvdata[cpu]->spinlock); | ||
669 | return 0; | ||
680 | } | 670 | } |
681 | 671 | ||
682 | static struct notifier_block etm_cpu_notifier = { | 672 | static int etm_dying_cpu(unsigned int cpu) |
683 | .notifier_call = etm_cpu_callback, | 673 | { |
684 | }; | 674 | if (!etmdrvdata[cpu]) |
675 | return 0; | ||
676 | |||
677 | spin_lock(&etmdrvdata[cpu]->spinlock); | ||
678 | if (local_read(&etmdrvdata[cpu]->mode)) | ||
679 | etm_disable_hw(etmdrvdata[cpu]); | ||
680 | spin_unlock(&etmdrvdata[cpu]->spinlock); | ||
681 | return 0; | ||
682 | } | ||
685 | 683 | ||
686 | static bool etm_arch_supported(u8 arch) | 684 | static bool etm_arch_supported(u8 arch) |
687 | { | 685 | { |
@@ -806,9 +804,17 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id) | |||
806 | etm_init_arch_data, drvdata, 1)) | 804 | etm_init_arch_data, drvdata, 1)) |
807 | dev_err(dev, "ETM arch init failed\n"); | 805 | dev_err(dev, "ETM arch init failed\n"); |
808 | 806 | ||
809 | if (!etm_count++) | 807 | if (!etm_count++) { |
810 | register_hotcpu_notifier(&etm_cpu_notifier); | 808 | cpuhp_setup_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING, |
811 | 809 | "AP_ARM_CORESIGHT_STARTING", | |
810 | etm_starting_cpu, etm_dying_cpu); | ||
811 | ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, | ||
812 | "AP_ARM_CORESIGHT_ONLINE", | ||
813 | etm_online_cpu, NULL); | ||
814 | if (ret < 0) | ||
815 | goto err_arch_supported; | ||
816 | hp_online = ret; | ||
817 | } | ||
812 | put_online_cpus(); | 818 | put_online_cpus(); |
813 | 819 | ||
814 | if (etm_arch_supported(drvdata->arch) == false) { | 820 | if (etm_arch_supported(drvdata->arch) == false) { |
@@ -839,7 +845,6 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id) | |||
839 | 845 | ||
840 | pm_runtime_put(&adev->dev); | 846 | pm_runtime_put(&adev->dev); |
841 | dev_info(dev, "%s initialized\n", (char *)id->data); | 847 | dev_info(dev, "%s initialized\n", (char *)id->data); |
842 | |||
843 | if (boot_enable) { | 848 | if (boot_enable) { |
844 | coresight_enable(drvdata->csdev); | 849 | coresight_enable(drvdata->csdev); |
845 | drvdata->boot_enable = true; | 850 | drvdata->boot_enable = true; |
@@ -848,8 +853,11 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id) | |||
848 | return 0; | 853 | return 0; |
849 | 854 | ||
850 | err_arch_supported: | 855 | err_arch_supported: |
851 | if (--etm_count == 0) | 856 | if (--etm_count == 0) { |
852 | unregister_hotcpu_notifier(&etm_cpu_notifier); | 857 | cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING); |
858 | if (hp_online) | ||
859 | cpuhp_remove_state_nocalls(hp_online); | ||
860 | } | ||
853 | return ret; | 861 | return ret; |
854 | } | 862 | } |
855 | 863 | ||