diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-07-29 16:55:30 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-07-29 16:55:30 -0400 |
commit | a6408f6cb63ac0958fee7dbce7861ffb540d8a49 (patch) | |
tree | c94a835d343974171951e3b805e6bbbb02852ebc /drivers/hwtracing | |
parent | 1a81a8f2a5918956e214bb718099a89e500e7ec5 (diff) | |
parent | 4fae16dffb812f0e0d98a0b2b0856ca48ca63e6c (diff) |
Merge branch 'smp-hotplug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull smp hotplug updates from Thomas Gleixner:
"This is the next part of the hotplug rework.
- Convert all notifiers with a priority assigned
- Convert all CPU_STARTING/DYING notifiers
The final removal of the STARTING/DYING infrastructure will happen
when the merge window closes.
Another 700 hundred line of unpenetrable maze gone :)"
* 'smp-hotplug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (70 commits)
timers/core: Correct callback order during CPU hot plug
leds/trigger/cpu: Move from CPU_STARTING to ONLINE level
powerpc/numa: Convert to hotplug state machine
arm/perf: Fix hotplug state machine conversion
irqchip/armada: Avoid unused function warnings
ARC/time: Convert to hotplug state machine
clocksource/atlas7: Convert to hotplug state machine
clocksource/armada-370-xp: Convert to hotplug state machine
clocksource/exynos_mct: Convert to hotplug state machine
clocksource/arm_global_timer: Convert to hotplug state machine
rcu: Convert rcutree to hotplug state machine
KVM/arm/arm64/vgic-new: Convert to hotplug state machine
smp/cfd: Convert core to hotplug state machine
x86/x2apic: Convert to CPU hotplug state machine
profile: Convert to hotplug state machine
timers/core: Convert to hotplug state machine
hrtimer: Convert to hotplug state machine
x86/tboot: Convert to hotplug state machine
arm64/armv8 deprecated: Convert to hotplug state machine
hwtracing/coresight-etm4x: Convert to hotplug state machine
...
Diffstat (limited to 'drivers/hwtracing')
-rw-r--r-- | drivers/hwtracing/coresight/coresight-etm3x.c | 90 | ||||
-rw-r--r-- | drivers/hwtracing/coresight/coresight-etm4x.c | 87 |
2 files changed, 98 insertions, 79 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 | ||
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index 462f0dc15757..1a5e0d14c1dd 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c | |||
@@ -48,6 +48,8 @@ static int etm4_count; | |||
48 | static struct etmv4_drvdata *etmdrvdata[NR_CPUS]; | 48 | static struct etmv4_drvdata *etmdrvdata[NR_CPUS]; |
49 | static void etm4_set_default(struct etmv4_config *config); | 49 | static void etm4_set_default(struct etmv4_config *config); |
50 | 50 | ||
51 | static enum cpuhp_state hp_online; | ||
52 | |||
51 | static void etm4_os_unlock(struct etmv4_drvdata *drvdata) | 53 | static void etm4_os_unlock(struct etmv4_drvdata *drvdata) |
52 | { | 54 | { |
53 | /* Writing any value to ETMOSLAR unlocks the trace registers */ | 55 | /* Writing any value to ETMOSLAR unlocks the trace registers */ |
@@ -673,47 +675,44 @@ void etm4_config_trace_mode(struct etmv4_config *config) | |||
673 | config->addr_acc[ETM_DEFAULT_ADDR_COMP + 1] = addr_acc; | 675 | config->addr_acc[ETM_DEFAULT_ADDR_COMP + 1] = addr_acc; |
674 | } | 676 | } |
675 | 677 | ||
676 | static int etm4_cpu_callback(struct notifier_block *nfb, unsigned long action, | 678 | static int etm4_online_cpu(unsigned int cpu) |
677 | void *hcpu) | ||
678 | { | 679 | { |
679 | unsigned int cpu = (unsigned long)hcpu; | ||
680 | |||
681 | if (!etmdrvdata[cpu]) | 680 | if (!etmdrvdata[cpu]) |
682 | goto out; | 681 | return 0; |
683 | |||
684 | switch (action & (~CPU_TASKS_FROZEN)) { | ||
685 | case CPU_STARTING: | ||
686 | spin_lock(&etmdrvdata[cpu]->spinlock); | ||
687 | if (!etmdrvdata[cpu]->os_unlock) { | ||
688 | etm4_os_unlock(etmdrvdata[cpu]); | ||
689 | etmdrvdata[cpu]->os_unlock = true; | ||
690 | } | ||
691 | |||
692 | if (local_read(&etmdrvdata[cpu]->mode)) | ||
693 | etm4_enable_hw(etmdrvdata[cpu]); | ||
694 | spin_unlock(&etmdrvdata[cpu]->spinlock); | ||
695 | break; | ||
696 | 682 | ||
697 | case CPU_ONLINE: | 683 | if (etmdrvdata[cpu]->boot_enable && !etmdrvdata[cpu]->sticky_enable) |
698 | if (etmdrvdata[cpu]->boot_enable && | 684 | coresight_enable(etmdrvdata[cpu]->csdev); |
699 | !etmdrvdata[cpu]->sticky_enable) | 685 | return 0; |
700 | coresight_enable(etmdrvdata[cpu]->csdev); | 686 | } |
701 | break; | ||
702 | 687 | ||
703 | case CPU_DYING: | 688 | static int etm4_starting_cpu(unsigned int cpu) |
704 | spin_lock(&etmdrvdata[cpu]->spinlock); | 689 | { |
705 | if (local_read(&etmdrvdata[cpu]->mode)) | 690 | if (!etmdrvdata[cpu]) |
706 | etm4_disable_hw(etmdrvdata[cpu]); | 691 | return 0; |
707 | spin_unlock(&etmdrvdata[cpu]->spinlock); | 692 | |
708 | break; | 693 | spin_lock(&etmdrvdata[cpu]->spinlock); |
694 | if (!etmdrvdata[cpu]->os_unlock) { | ||
695 | etm4_os_unlock(etmdrvdata[cpu]); | ||
696 | etmdrvdata[cpu]->os_unlock = true; | ||
709 | } | 697 | } |
710 | out: | 698 | |
711 | return NOTIFY_OK; | 699 | if (local_read(&etmdrvdata[cpu]->mode)) |
700 | etm4_enable_hw(etmdrvdata[cpu]); | ||
701 | spin_unlock(&etmdrvdata[cpu]->spinlock); | ||
702 | return 0; | ||
712 | } | 703 | } |
713 | 704 | ||
714 | static struct notifier_block etm4_cpu_notifier = { | 705 | static int etm4_dying_cpu(unsigned int cpu) |
715 | .notifier_call = etm4_cpu_callback, | 706 | { |
716 | }; | 707 | if (!etmdrvdata[cpu]) |
708 | return 0; | ||
709 | |||
710 | spin_lock(&etmdrvdata[cpu]->spinlock); | ||
711 | if (local_read(&etmdrvdata[cpu]->mode)) | ||
712 | etm4_disable_hw(etmdrvdata[cpu]); | ||
713 | spin_unlock(&etmdrvdata[cpu]->spinlock); | ||
714 | return 0; | ||
715 | } | ||
717 | 716 | ||
718 | static void etm4_init_trace_id(struct etmv4_drvdata *drvdata) | 717 | static void etm4_init_trace_id(struct etmv4_drvdata *drvdata) |
719 | { | 718 | { |
@@ -767,8 +766,17 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) | |||
767 | etm4_init_arch_data, drvdata, 1)) | 766 | etm4_init_arch_data, drvdata, 1)) |
768 | dev_err(dev, "ETM arch init failed\n"); | 767 | dev_err(dev, "ETM arch init failed\n"); |
769 | 768 | ||
770 | if (!etm4_count++) | 769 | if (!etm4_count++) { |
771 | register_hotcpu_notifier(&etm4_cpu_notifier); | 770 | cpuhp_setup_state_nocalls(CPUHP_AP_ARM_CORESIGHT4_STARTING, |
771 | "AP_ARM_CORESIGHT4_STARTING", | ||
772 | etm4_starting_cpu, etm4_dying_cpu); | ||
773 | ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, | ||
774 | "AP_ARM_CORESIGHT4_ONLINE", | ||
775 | etm4_online_cpu, NULL); | ||
776 | if (ret < 0) | ||
777 | goto err_arch_supported; | ||
778 | hp_online = ret; | ||
779 | } | ||
772 | 780 | ||
773 | put_online_cpus(); | 781 | put_online_cpus(); |
774 | 782 | ||
@@ -809,8 +817,11 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) | |||
809 | return 0; | 817 | return 0; |
810 | 818 | ||
811 | err_arch_supported: | 819 | err_arch_supported: |
812 | if (--etm4_count == 0) | 820 | if (--etm4_count == 0) { |
813 | unregister_hotcpu_notifier(&etm4_cpu_notifier); | 821 | cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT4_STARTING); |
822 | if (hp_online) | ||
823 | cpuhp_remove_state_nocalls(hp_online); | ||
824 | } | ||
814 | return ret; | 825 | return ret; |
815 | } | 826 | } |
816 | 827 | ||