diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2016-08-18 08:57:28 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2016-09-06 12:30:25 -0400 |
commit | e8483b578b229774382a95891439b2ebd9c92fc5 (patch) | |
tree | 00546623d7f2aaf8f04a7f80a8fb895cf78bf21f | |
parent | dfc616d8b3df3013c579e023e67f29ada60bdd50 (diff) |
MIPS/BUS/CDMM: Convert to hotplug state machine
Install the callbacks via the state machine and let the core invoke
the callbacks on the already online CPUs.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: James Hogan <james.hogan@imgtec.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: rt@linutronix.de
Link: http://lkml.kernel.org/r/20160818125731.27256-14-bigeasy@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | drivers/bus/mips_cdmm.c | 70 |
1 files changed, 12 insertions, 58 deletions
diff --git a/drivers/bus/mips_cdmm.c b/drivers/bus/mips_cdmm.c index cad49bc38b3e..1b14256376d2 100644 --- a/drivers/bus/mips_cdmm.c +++ b/drivers/bus/mips_cdmm.c | |||
@@ -596,19 +596,20 @@ BUILD_PERDEV_HELPER(cpu_down) /* int mips_cdmm_cpu_down_helper(...) */ | |||
596 | BUILD_PERDEV_HELPER(cpu_up) /* int mips_cdmm_cpu_up_helper(...) */ | 596 | BUILD_PERDEV_HELPER(cpu_up) /* int mips_cdmm_cpu_up_helper(...) */ |
597 | 597 | ||
598 | /** | 598 | /** |
599 | * mips_cdmm_bus_down() - Tear down the CDMM bus. | 599 | * mips_cdmm_cpu_down_prep() - Callback for CPUHP DOWN_PREP: |
600 | * @data: Pointer to unsigned int CPU number. | 600 | * Tear down the CDMM bus. |
601 | * @cpu: unsigned int CPU number. | ||
601 | * | 602 | * |
602 | * This function is executed on the hotplugged CPU and calls the CDMM | 603 | * This function is executed on the hotplugged CPU and calls the CDMM |
603 | * driver cpu_down callback for all devices on that CPU. | 604 | * driver cpu_down callback for all devices on that CPU. |
604 | */ | 605 | */ |
605 | static long mips_cdmm_bus_down(void *data) | 606 | static int mips_cdmm_cpu_down_prep(unsigned int cpu) |
606 | { | 607 | { |
607 | struct mips_cdmm_bus *bus; | 608 | struct mips_cdmm_bus *bus; |
608 | long ret; | 609 | long ret; |
609 | 610 | ||
610 | /* Inform all the devices on the bus */ | 611 | /* Inform all the devices on the bus */ |
611 | ret = bus_for_each_dev(&mips_cdmm_bustype, NULL, data, | 612 | ret = bus_for_each_dev(&mips_cdmm_bustype, NULL, &cpu, |
612 | mips_cdmm_cpu_down_helper); | 613 | mips_cdmm_cpu_down_helper); |
613 | 614 | ||
614 | /* | 615 | /* |
@@ -623,8 +624,8 @@ static long mips_cdmm_bus_down(void *data) | |||
623 | } | 624 | } |
624 | 625 | ||
625 | /** | 626 | /** |
626 | * mips_cdmm_bus_up() - Bring up the CDMM bus. | 627 | * mips_cdmm_cpu_online() - Callback for CPUHP ONLINE: Bring up the CDMM bus. |
627 | * @data: Pointer to unsigned int CPU number. | 628 | * @cpu: unsigned int CPU number. |
628 | * | 629 | * |
629 | * This work_on_cpu callback function is executed on a given CPU to discover | 630 | * This work_on_cpu callback function is executed on a given CPU to discover |
630 | * CDMM devices on that CPU, or to call the CDMM driver cpu_up callback for all | 631 | * CDMM devices on that CPU, or to call the CDMM driver cpu_up callback for all |
@@ -634,7 +635,7 @@ static long mips_cdmm_bus_down(void *data) | |||
634 | * initialisation. When CPUs are brought online the function is | 635 | * initialisation. When CPUs are brought online the function is |
635 | * invoked directly on the hotplugged CPU. | 636 | * invoked directly on the hotplugged CPU. |
636 | */ | 637 | */ |
637 | static long mips_cdmm_bus_up(void *data) | 638 | static int mips_cdmm_cpu_online(unsigned int cpu) |
638 | { | 639 | { |
639 | struct mips_cdmm_bus *bus; | 640 | struct mips_cdmm_bus *bus; |
640 | long ret; | 641 | long ret; |
@@ -651,51 +652,13 @@ static long mips_cdmm_bus_up(void *data) | |||
651 | mips_cdmm_bus_discover(bus); | 652 | mips_cdmm_bus_discover(bus); |
652 | else | 653 | else |
653 | /* Inform all the devices on the bus */ | 654 | /* Inform all the devices on the bus */ |
654 | ret = bus_for_each_dev(&mips_cdmm_bustype, NULL, data, | 655 | ret = bus_for_each_dev(&mips_cdmm_bustype, NULL, &cpu, |
655 | mips_cdmm_cpu_up_helper); | 656 | mips_cdmm_cpu_up_helper); |
656 | 657 | ||
657 | return ret; | 658 | return ret; |
658 | } | 659 | } |
659 | 660 | ||
660 | /** | 661 | /** |
661 | * mips_cdmm_cpu_notify() - Take action when a CPU is going online or offline. | ||
662 | * @nb: CPU notifier block . | ||
663 | * @action: Event that has taken place (CPU_*). | ||
664 | * @data: CPU number. | ||
665 | * | ||
666 | * This notifier is used to keep the CDMM buses updated as CPUs are offlined and | ||
667 | * onlined. When CPUs go offline or come back online, so does their CDMM bus, so | ||
668 | * devices must be informed. Also when CPUs come online for the first time the | ||
669 | * devices on the CDMM bus need discovering. | ||
670 | * | ||
671 | * Returns: NOTIFY_OK if event was used. | ||
672 | * NOTIFY_DONE if we didn't care. | ||
673 | */ | ||
674 | static int mips_cdmm_cpu_notify(struct notifier_block *nb, | ||
675 | unsigned long action, void *data) | ||
676 | { | ||
677 | unsigned int cpu = (unsigned int)data; | ||
678 | |||
679 | switch (action & ~CPU_TASKS_FROZEN) { | ||
680 | case CPU_ONLINE: | ||
681 | case CPU_DOWN_FAILED: | ||
682 | mips_cdmm_bus_up(&cpu); | ||
683 | break; | ||
684 | case CPU_DOWN_PREPARE: | ||
685 | mips_cdmm_bus_down(&cpu); | ||
686 | break; | ||
687 | default: | ||
688 | return NOTIFY_DONE; | ||
689 | } | ||
690 | |||
691 | return NOTIFY_OK; | ||
692 | } | ||
693 | |||
694 | static struct notifier_block mips_cdmm_cpu_nb = { | ||
695 | .notifier_call = mips_cdmm_cpu_notify, | ||
696 | }; | ||
697 | |||
698 | /** | ||
699 | * mips_cdmm_init() - Initialise CDMM bus. | 662 | * mips_cdmm_init() - Initialise CDMM bus. |
700 | * | 663 | * |
701 | * Initialise CDMM bus, discover CDMM devices for online CPUs, and arrange for | 664 | * Initialise CDMM bus, discover CDMM devices for online CPUs, and arrange for |
@@ -703,7 +666,6 @@ static struct notifier_block mips_cdmm_cpu_nb = { | |||
703 | */ | 666 | */ |
704 | static int __init mips_cdmm_init(void) | 667 | static int __init mips_cdmm_init(void) |
705 | { | 668 | { |
706 | unsigned int cpu; | ||
707 | int ret; | 669 | int ret; |
708 | 670 | ||
709 | /* Register the bus */ | 671 | /* Register the bus */ |
@@ -712,19 +674,11 @@ static int __init mips_cdmm_init(void) | |||
712 | return ret; | 674 | return ret; |
713 | 675 | ||
714 | /* We want to be notified about new CPUs */ | 676 | /* We want to be notified about new CPUs */ |
715 | ret = register_cpu_notifier(&mips_cdmm_cpu_nb); | 677 | ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "bus/cdmm:online", |
716 | if (ret) { | 678 | mips_cdmm_cpu_online, mips_cdmm_cpu_down_prep); |
679 | if (ret < 0) | ||
717 | pr_warn("cdmm: Failed to register CPU notifier\n"); | 680 | pr_warn("cdmm: Failed to register CPU notifier\n"); |
718 | goto out; | ||
719 | } | ||
720 | |||
721 | /* Discover devices on CDMM of online CPUs */ | ||
722 | for_each_online_cpu(cpu) | ||
723 | work_on_cpu(cpu, mips_cdmm_bus_up, &cpu); | ||
724 | 681 | ||
725 | return 0; | ||
726 | out: | ||
727 | bus_unregister(&mips_cdmm_bustype); | ||
728 | return ret; | 682 | return ret; |
729 | } | 683 | } |
730 | subsys_initcall(mips_cdmm_init); | 684 | subsys_initcall(mips_cdmm_init); |