aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChen-Yu Tsai <wens@csie.org>2018-03-08 10:00:12 -0500
committerChen-Yu Tsai <wens@csie.org>2018-03-10 03:14:57 -0500
commit99e3a1e6fedd3b8713a1398772ad7da3796c6908 (patch)
treebc5616eec7576d10421dcbe24dbb8077c5025303
parent8591743f12636a247bdab56c8c355ea9686f2d97 (diff)
ARM: sunxi: mc-smp: Split out SoC-specific device node lookup sequence
The multi-cluster SMP code maps the address spaces of several hardware control blocks. The device nodes for them are SoC-specific. To help with supporting other SoCs to re-use this code, these bits should be split out to a separate function tied to the enable-method string. This patch splits out and groups the device node lookup sequence, and adds new data structures to have the newly created function tied to the enable method string. This structure can also be used to encode other differences between the SoCs. Acked-by: Maxime Ripard <maxime.ripard@bootlin.com> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
-rw-r--r--arch/arm/mach-sunxi/mc_smp.c126
1 files changed, 86 insertions, 40 deletions
diff --git a/arch/arm/mach-sunxi/mc_smp.c b/arch/arm/mach-sunxi/mc_smp.c
index 86e90b038555..c0246ec54a0a 100644
--- a/arch/arm/mach-sunxi/mc_smp.c
+++ b/arch/arm/mach-sunxi/mc_smp.c
@@ -684,11 +684,69 @@ static int __init sunxi_mc_smp_loopback(void)
684 return ret; 684 return ret;
685} 685}
686 686
687/*
688 * This holds any device nodes that we requested resources for,
689 * so that we may easily release resources in the error path.
690 */
691struct sunxi_mc_smp_nodes {
692 struct device_node *prcm_node;
693 struct device_node *cpucfg_node;
694 struct device_node *sram_node;
695};
696
697/* This structure holds SoC-specific bits tied to an enable-method string. */
698struct sunxi_mc_smp_data {
699 const char *enable_method;
700 int (*get_smp_nodes)(struct sunxi_mc_smp_nodes *nodes);
701};
702
703static void __init sunxi_mc_smp_put_nodes(struct sunxi_mc_smp_nodes *nodes)
704{
705 of_node_put(nodes->prcm_node);
706 of_node_put(nodes->cpucfg_node);
707 of_node_put(nodes->sram_node);
708 memset(nodes, 0, sizeof(*nodes));
709}
710
711static int __init sun9i_a80_get_smp_nodes(struct sunxi_mc_smp_nodes *nodes)
712{
713 nodes->prcm_node = of_find_compatible_node(NULL, NULL,
714 "allwinner,sun9i-a80-prcm");
715 if (!nodes->prcm_node) {
716 pr_err("%s: PRCM not available\n", __func__);
717 return -ENODEV;
718 }
719
720 nodes->cpucfg_node = of_find_compatible_node(NULL, NULL,
721 "allwinner,sun9i-a80-cpucfg");
722 if (!nodes->cpucfg_node) {
723 pr_err("%s: CPUCFG not available\n", __func__);
724 return -ENODEV;
725 }
726
727 nodes->sram_node = of_find_compatible_node(NULL, NULL,
728 "allwinner,sun9i-a80-smp-sram");
729 if (!nodes->sram_node) {
730 pr_err("%s: Secure SRAM not available\n", __func__);
731 return -ENODEV;
732 }
733
734 return 0;
735}
736
737static const struct sunxi_mc_smp_data sunxi_mc_smp_data[] __initconst = {
738 {
739 .enable_method = "allwinner,sun9i-a80-smp",
740 .get_smp_nodes = sun9i_a80_get_smp_nodes,
741 },
742};
743
687static int __init sunxi_mc_smp_init(void) 744static int __init sunxi_mc_smp_init(void)
688{ 745{
689 struct device_node *cpucfg_node, *sram_node, *node; 746 struct sunxi_mc_smp_nodes nodes = { 0 };
747 struct device_node *node;
690 struct resource res; 748 struct resource res;
691 int ret; 749 int i, ret;
692 750
693 /* 751 /*
694 * Don't bother checking the "cpus" node, as an enable-method 752 * Don't bother checking the "cpus" node, as an enable-method
@@ -706,8 +764,13 @@ static int __init sunxi_mc_smp_init(void)
706 * callbacks in smp_operations, which we would use if we were to 764 * callbacks in smp_operations, which we would use if we were to
707 * use CPU_METHOD_OF_DECLARE 765 * use CPU_METHOD_OF_DECLARE
708 */ 766 */
709 ret = of_property_match_string(node, "enable-method", 767 for (i = 0; i < ARRAY_SIZE(sunxi_mc_smp_data); i++) {
710 "allwinner,sun9i-a80-smp"); 768 ret = of_property_match_string(node, "enable-method",
769 sunxi_mc_smp_data[i].enable_method);
770 if (!ret)
771 break;
772 }
773
711 of_node_put(node); 774 of_node_put(node);
712 if (ret) 775 if (ret)
713 return -ENODEV; 776 return -ENODEV;
@@ -720,51 +783,37 @@ static int __init sunxi_mc_smp_init(void)
720 return -ENODEV; 783 return -ENODEV;
721 } 784 }
722 785
723 node = of_find_compatible_node(NULL, NULL, "allwinner,sun9i-a80-prcm"); 786 /* Get needed device tree nodes */
724 if (!node) { 787 ret = sunxi_mc_smp_data[i].get_smp_nodes(&nodes);
725 pr_err("%s: PRCM not available\n", __func__); 788 if (ret)
726 return -ENODEV; 789 goto err_put_nodes;
727 }
728 790
729 /* 791 /*
730 * Unfortunately we can not request the I/O region for the PRCM. 792 * Unfortunately we can not request the I/O region for the PRCM.
731 * It is shared with the PRCM clock. 793 * It is shared with the PRCM clock.
732 */ 794 */
733 prcm_base = of_iomap(node, 0); 795 prcm_base = of_iomap(nodes.prcm_node, 0);
734 of_node_put(node);
735 if (!prcm_base) { 796 if (!prcm_base) {
736 pr_err("%s: failed to map PRCM registers\n", __func__); 797 pr_err("%s: failed to map PRCM registers\n", __func__);
737 return -ENOMEM; 798 ret = -ENOMEM;
738 } 799 goto err_put_nodes;
739
740 cpucfg_node = of_find_compatible_node(NULL, NULL,
741 "allwinner,sun9i-a80-cpucfg");
742 if (!cpucfg_node) {
743 ret = -ENODEV;
744 pr_err("%s: CPUCFG not available\n", __func__);
745 goto err_unmap_prcm;
746 } 800 }
747 801
748 cpucfg_base = of_io_request_and_map(cpucfg_node, 0, "sunxi-mc-smp"); 802 cpucfg_base = of_io_request_and_map(nodes.cpucfg_node, 0,
803 "sunxi-mc-smp");
749 if (IS_ERR(cpucfg_base)) { 804 if (IS_ERR(cpucfg_base)) {
750 ret = PTR_ERR(cpucfg_base); 805 ret = PTR_ERR(cpucfg_base);
751 pr_err("%s: failed to map CPUCFG registers: %d\n", 806 pr_err("%s: failed to map CPUCFG registers: %d\n",
752 __func__, ret); 807 __func__, ret);
753 goto err_put_cpucfg_node; 808 goto err_unmap_prcm;
754 }
755
756 sram_node = of_find_compatible_node(NULL, NULL,
757 "allwinner,sun9i-a80-smp-sram");
758 if (!sram_node) {
759 ret = -ENODEV;
760 goto err_unmap_release_cpucfg;
761 } 809 }
762 810
763 sram_b_smp_base = of_io_request_and_map(sram_node, 0, "sunxi-mc-smp"); 811 sram_b_smp_base = of_io_request_and_map(nodes.sram_node, 0,
812 "sunxi-mc-smp");
764 if (IS_ERR(sram_b_smp_base)) { 813 if (IS_ERR(sram_b_smp_base)) {
765 ret = PTR_ERR(sram_b_smp_base); 814 ret = PTR_ERR(sram_b_smp_base);
766 pr_err("%s: failed to map secure SRAM\n", __func__); 815 pr_err("%s: failed to map secure SRAM\n", __func__);
767 goto err_put_sram_node; 816 goto err_unmap_release_cpucfg;
768 } 817 }
769 818
770 /* Configure CCI-400 for boot cluster */ 819 /* Configure CCI-400 for boot cluster */
@@ -775,9 +824,8 @@ static int __init sunxi_mc_smp_init(void)
775 goto err_unmap_release_secure_sram; 824 goto err_unmap_release_secure_sram;
776 } 825 }
777 826
778 /* We don't need the CPUCFG and SRAM device nodes anymore */ 827 /* We don't need the device nodes anymore */
779 of_node_put(cpucfg_node); 828 sunxi_mc_smp_put_nodes(&nodes);
780 of_node_put(sram_node);
781 829
782 /* Set the hardware entry point address */ 830 /* Set the hardware entry point address */
783 writel(__pa_symbol(sunxi_mc_smp_secondary_startup), 831 writel(__pa_symbol(sunxi_mc_smp_secondary_startup),
@@ -792,18 +840,16 @@ static int __init sunxi_mc_smp_init(void)
792 840
793err_unmap_release_secure_sram: 841err_unmap_release_secure_sram:
794 iounmap(sram_b_smp_base); 842 iounmap(sram_b_smp_base);
795 of_address_to_resource(sram_node, 0, &res); 843 of_address_to_resource(nodes.sram_node, 0, &res);
796 release_mem_region(res.start, resource_size(&res)); 844 release_mem_region(res.start, resource_size(&res));
797err_put_sram_node:
798 of_node_put(sram_node);
799err_unmap_release_cpucfg: 845err_unmap_release_cpucfg:
800 iounmap(cpucfg_base); 846 iounmap(cpucfg_base);
801 of_address_to_resource(cpucfg_node, 0, &res); 847 of_address_to_resource(nodes.cpucfg_node, 0, &res);
802 release_mem_region(res.start, resource_size(&res)); 848 release_mem_region(res.start, resource_size(&res));
803err_put_cpucfg_node:
804 of_node_put(cpucfg_node);
805err_unmap_prcm: 849err_unmap_prcm:
806 iounmap(prcm_base); 850 iounmap(prcm_base);
851err_put_nodes:
852 sunxi_mc_smp_put_nodes(&nodes);
807 return ret; 853 return ret;
808} 854}
809 855