29
29
30
30
#include <linux/irqchip.h>
31
31
#include <linux/irqchip/arm-gic-v3.h>
32
+ #include <linux/irqchip/irq-partition-percpu.h>
32
33
33
34
#include <asm/cputype.h>
34
35
#include <asm/exception.h>
@@ -44,13 +45,15 @@ struct redist_region {
44
45
};
45
46
46
47
struct gic_chip_data {
48
+ struct fwnode_handle * fwnode ;
47
49
void __iomem * dist_base ;
48
50
struct redist_region * redist_regions ;
49
51
struct rdists rdists ;
50
52
struct irq_domain * domain ;
51
53
u64 redist_stride ;
52
54
u32 nr_redist_regions ;
53
55
unsigned int irq_nr ;
56
+ struct partition_desc * ppi_descs [16 ];
54
57
};
55
58
56
59
static struct gic_chip_data gic_data __read_mostly ;
@@ -812,10 +815,62 @@ static void gic_irq_domain_free(struct irq_domain *domain, unsigned int virq,
812
815
}
813
816
}
814
817
818
+ static int gic_irq_domain_select (struct irq_domain * d ,
819
+ struct irq_fwspec * fwspec ,
820
+ enum irq_domain_bus_token bus_token )
821
+ {
822
+ /* Not for us */
823
+ if (fwspec -> fwnode != d -> fwnode )
824
+ return 0 ;
825
+
826
+ /* If this is not DT, then we have a single domain */
827
+ if (!is_of_node (fwspec -> fwnode ))
828
+ return 1 ;
829
+
830
+ /*
831
+ * If this is a PPI and we have a 4th (non-null) parameter,
832
+ * then we need to match the partition domain.
833
+ */
834
+ if (fwspec -> param_count >= 4 &&
835
+ fwspec -> param [0 ] == 1 && fwspec -> param [3 ] != 0 )
836
+ return d == partition_get_domain (gic_data .ppi_descs [fwspec -> param [1 ]]);
837
+
838
+ return d == gic_data .domain ;
839
+ }
840
+
815
841
static const struct irq_domain_ops gic_irq_domain_ops = {
816
842
.translate = gic_irq_domain_translate ,
817
843
.alloc = gic_irq_domain_alloc ,
818
844
.free = gic_irq_domain_free ,
845
+ .select = gic_irq_domain_select ,
846
+ };
847
+
848
+ static int partition_domain_translate (struct irq_domain * d ,
849
+ struct irq_fwspec * fwspec ,
850
+ unsigned long * hwirq ,
851
+ unsigned int * type )
852
+ {
853
+ struct device_node * np ;
854
+ int ret ;
855
+
856
+ np = of_find_node_by_phandle (fwspec -> param [3 ]);
857
+ if (WARN_ON (!np ))
858
+ return - EINVAL ;
859
+
860
+ ret = partition_translate_id (gic_data .ppi_descs [fwspec -> param [1 ]],
861
+ of_node_to_fwnode (np ));
862
+ if (ret < 0 )
863
+ return ret ;
864
+
865
+ * hwirq = ret ;
866
+ * type = fwspec -> param [2 ] & IRQ_TYPE_SENSE_MASK ;
867
+
868
+ return 0 ;
869
+ }
870
+
871
+ static const struct irq_domain_ops partition_domain_ops = {
872
+ .translate = partition_domain_translate ,
873
+ .select = gic_irq_domain_select ,
819
874
};
820
875
821
876
static void gicv3_enable_quirks (void )
@@ -843,6 +898,7 @@ static int __init gic_init_bases(void __iomem *dist_base,
843
898
if (static_key_true (& supports_deactivate ))
844
899
pr_info ("GIC: Using split EOI/Deactivate mode\n" );
845
900
901
+ gic_data .fwnode = handle ;
846
902
gic_data .dist_base = dist_base ;
847
903
gic_data .redist_regions = rdist_regs ;
848
904
gic_data .nr_redist_regions = nr_redist_regions ;
@@ -901,6 +957,119 @@ static int __init gic_validate_dist_version(void __iomem *dist_base)
901
957
return 0 ;
902
958
}
903
959
960
+ static int get_cpu_number (struct device_node * dn )
961
+ {
962
+ const __be32 * cell ;
963
+ u64 hwid ;
964
+ int i ;
965
+
966
+ cell = of_get_property (dn , "reg" , NULL );
967
+ if (!cell )
968
+ return -1 ;
969
+
970
+ hwid = of_read_number (cell , of_n_addr_cells (dn ));
971
+
972
+ /*
973
+ * Non affinity bits must be set to 0 in the DT
974
+ */
975
+ if (hwid & ~MPIDR_HWID_BITMASK )
976
+ return -1 ;
977
+
978
+ for (i = 0 ; i < num_possible_cpus (); i ++ )
979
+ if (cpu_logical_map (i ) == hwid )
980
+ return i ;
981
+
982
+ return -1 ;
983
+ }
984
+
985
+ /* Create all possible partitions at boot time */
986
+ static void gic_populate_ppi_partitions (struct device_node * gic_node )
987
+ {
988
+ struct device_node * parts_node , * child_part ;
989
+ int part_idx = 0 , i ;
990
+ int nr_parts ;
991
+ struct partition_affinity * parts ;
992
+
993
+ parts_node = of_find_node_by_name (gic_node , "ppi-partitions" );
994
+ if (!parts_node )
995
+ return ;
996
+
997
+ nr_parts = of_get_child_count (parts_node );
998
+
999
+ if (!nr_parts )
1000
+ return ;
1001
+
1002
+ parts = kzalloc (sizeof (* parts ) * nr_parts , GFP_KERNEL );
1003
+ if (WARN_ON (!parts ))
1004
+ return ;
1005
+
1006
+ for_each_child_of_node (parts_node , child_part ) {
1007
+ struct partition_affinity * part ;
1008
+ int n ;
1009
+
1010
+ part = & parts [part_idx ];
1011
+
1012
+ part -> partition_id = of_node_to_fwnode (child_part );
1013
+
1014
+ pr_info ("GIC: PPI partition %s[%d] { " ,
1015
+ child_part -> name , part_idx );
1016
+
1017
+ n = of_property_count_elems_of_size (child_part , "affinity" ,
1018
+ sizeof (u32 ));
1019
+ WARN_ON (n <= 0 );
1020
+
1021
+ for (i = 0 ; i < n ; i ++ ) {
1022
+ int err , cpu ;
1023
+ u32 cpu_phandle ;
1024
+ struct device_node * cpu_node ;
1025
+
1026
+ err = of_property_read_u32_index (child_part , "affinity" ,
1027
+ i , & cpu_phandle );
1028
+ if (WARN_ON (err ))
1029
+ continue ;
1030
+
1031
+ cpu_node = of_find_node_by_phandle (cpu_phandle );
1032
+ if (WARN_ON (!cpu_node ))
1033
+ continue ;
1034
+
1035
+ cpu = get_cpu_number (cpu_node );
1036
+ if (WARN_ON (cpu == -1 ))
1037
+ continue ;
1038
+
1039
+ pr_cont ("%s[%d] " , cpu_node -> full_name , cpu );
1040
+
1041
+ cpumask_set_cpu (cpu , & part -> mask );
1042
+ }
1043
+
1044
+ pr_cont ("}\n" );
1045
+ part_idx ++ ;
1046
+ }
1047
+
1048
+ for (i = 0 ; i < 16 ; i ++ ) {
1049
+ unsigned int irq ;
1050
+ struct partition_desc * desc ;
1051
+ struct irq_fwspec ppi_fwspec = {
1052
+ .fwnode = gic_data .fwnode ,
1053
+ .param_count = 3 ,
1054
+ .param = {
1055
+ [0 ] = 1 ,
1056
+ [1 ] = i ,
1057
+ [2 ] = IRQ_TYPE_NONE ,
1058
+ },
1059
+ };
1060
+
1061
+ irq = irq_create_fwspec_mapping (& ppi_fwspec );
1062
+ if (WARN_ON (!irq ))
1063
+ continue ;
1064
+ desc = partition_create_desc (gic_data .fwnode , parts , nr_parts ,
1065
+ irq , & partition_domain_ops );
1066
+ if (WARN_ON (!desc ))
1067
+ continue ;
1068
+
1069
+ gic_data .ppi_descs [i ] = desc ;
1070
+ }
1071
+ }
1072
+
904
1073
static int __init gic_of_init (struct device_node * node , struct device_node * parent )
905
1074
{
906
1075
void __iomem * dist_base ;
@@ -952,8 +1121,11 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
952
1121
953
1122
err = gic_init_bases (dist_base , rdist_regs , nr_redist_regions ,
954
1123
redist_stride , & node -> fwnode );
955
- if (!err )
956
- return 0 ;
1124
+ if (err )
1125
+ goto out_unmap_rdist ;
1126
+
1127
+ gic_populate_ppi_partitions (node );
1128
+ return 0 ;
957
1129
958
1130
out_unmap_rdist :
959
1131
for (i = 0 ; i < nr_redist_regions ; i ++ )
0 commit comments