@@ -806,22 +806,63 @@ static const struct gpio_chip intel_gpio_chip = {
806
806
.set_config = gpiochip_generic_config ,
807
807
};
808
808
809
+ /**
810
+ * intel_gpio_to_pin() - Translate from GPIO offset to pin number
811
+ * @pctrl: Pinctrl structure
812
+ * @offset: GPIO offset from gpiolib
813
+ * @commmunity: Community is filled here if not %NULL
814
+ * @padgrp: Pad group is filled here if not %NULL
815
+ *
816
+ * When coming through gpiolib irqchip, the GPIO offset is not
817
+ * automatically translated to pinctrl pin number. This function can be
818
+ * used to find out the corresponding pinctrl pin.
819
+ */
820
+ static int intel_gpio_to_pin (struct intel_pinctrl * pctrl , unsigned offset ,
821
+ const struct intel_community * * community ,
822
+ const struct intel_padgroup * * padgrp )
823
+ {
824
+ int i ;
825
+
826
+ for (i = 0 ; i < pctrl -> ncommunities ; i ++ ) {
827
+ const struct intel_community * comm = & pctrl -> communities [i ];
828
+ int j ;
829
+
830
+ for (j = 0 ; j < comm -> ngpps ; j ++ ) {
831
+ const struct intel_padgroup * pgrp = & comm -> gpps [j ];
832
+
833
+ if (pgrp -> gpio_base < 0 )
834
+ continue ;
835
+
836
+ if (offset >= pgrp -> gpio_base &&
837
+ offset < pgrp -> gpio_base + pgrp -> size ) {
838
+ int pin ;
839
+
840
+ pin = pgrp -> base + offset - pgrp -> gpio_base ;
841
+ if (community )
842
+ * community = comm ;
843
+ if (padgrp )
844
+ * padgrp = pgrp ;
845
+
846
+ return pin ;
847
+ }
848
+ }
849
+ }
850
+
851
+ return - EINVAL ;
852
+ }
853
+
809
854
static void intel_gpio_irq_ack (struct irq_data * d )
810
855
{
811
856
struct gpio_chip * gc = irq_data_get_irq_chip_data (d );
812
857
struct intel_pinctrl * pctrl = gpiochip_get_data (gc );
813
858
const struct intel_community * community ;
814
- unsigned pin = irqd_to_hwirq (d );
859
+ const struct intel_padgroup * padgrp ;
860
+ int pin ;
815
861
816
- community = intel_get_community (pctrl , pin );
817
- if (community ) {
818
- const struct intel_padgroup * padgrp ;
862
+ pin = intel_gpio_to_pin (pctrl , irqd_to_hwirq (d ), & community , & padgrp );
863
+ if (pin >= 0 ) {
819
864
unsigned gpp , gpp_offset , is_offset ;
820
865
821
- padgrp = intel_community_get_padgroup (community , pin );
822
- if (!padgrp )
823
- return ;
824
-
825
866
gpp = padgrp -> reg_num ;
826
867
gpp_offset = padgroup_offset (padgrp , pin );
827
868
is_offset = community -> is_offset + gpp * 4 ;
@@ -837,19 +878,15 @@ static void intel_gpio_irq_enable(struct irq_data *d)
837
878
struct gpio_chip * gc = irq_data_get_irq_chip_data (d );
838
879
struct intel_pinctrl * pctrl = gpiochip_get_data (gc );
839
880
const struct intel_community * community ;
840
- unsigned pin = irqd_to_hwirq (d );
881
+ const struct intel_padgroup * padgrp ;
882
+ int pin ;
841
883
842
- community = intel_get_community (pctrl , pin );
843
- if (community ) {
844
- const struct intel_padgroup * padgrp ;
884
+ pin = intel_gpio_to_pin (pctrl , irqd_to_hwirq (d ), & community , & padgrp );
885
+ if (pin >= 0 ) {
845
886
unsigned gpp , gpp_offset , is_offset ;
846
887
unsigned long flags ;
847
888
u32 value ;
848
889
849
- padgrp = intel_community_get_padgroup (community , pin );
850
- if (!padgrp )
851
- return ;
852
-
853
890
gpp = padgrp -> reg_num ;
854
891
gpp_offset = padgroup_offset (padgrp , pin );
855
892
is_offset = community -> is_offset + gpp * 4 ;
@@ -870,20 +907,16 @@ static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
870
907
struct gpio_chip * gc = irq_data_get_irq_chip_data (d );
871
908
struct intel_pinctrl * pctrl = gpiochip_get_data (gc );
872
909
const struct intel_community * community ;
873
- unsigned pin = irqd_to_hwirq (d );
910
+ const struct intel_padgroup * padgrp ;
911
+ int pin ;
874
912
875
- community = intel_get_community (pctrl , pin );
876
- if (community ) {
877
- const struct intel_padgroup * padgrp ;
913
+ pin = intel_gpio_to_pin (pctrl , irqd_to_hwirq (d ), & community , & padgrp );
914
+ if (pin >= 0 ) {
878
915
unsigned gpp , gpp_offset ;
879
916
unsigned long flags ;
880
917
void __iomem * reg ;
881
918
u32 value ;
882
919
883
- padgrp = intel_community_get_padgroup (community , pin );
884
- if (!padgrp )
885
- return ;
886
-
887
920
gpp = padgrp -> reg_num ;
888
921
gpp_offset = padgroup_offset (padgrp , pin );
889
922
@@ -914,7 +947,7 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned type)
914
947
{
915
948
struct gpio_chip * gc = irq_data_get_irq_chip_data (d );
916
949
struct intel_pinctrl * pctrl = gpiochip_get_data (gc );
917
- unsigned pin = irqd_to_hwirq (d );
950
+ unsigned pin = intel_gpio_to_pin ( pctrl , irqd_to_hwirq (d ), NULL , NULL );
918
951
unsigned long flags ;
919
952
void __iomem * reg ;
920
953
u32 value ;
@@ -969,7 +1002,7 @@ static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on)
969
1002
{
970
1003
struct gpio_chip * gc = irq_data_get_irq_chip_data (d );
971
1004
struct intel_pinctrl * pctrl = gpiochip_get_data (gc );
972
- unsigned pin = irqd_to_hwirq (d );
1005
+ unsigned pin = intel_gpio_to_pin ( pctrl , irqd_to_hwirq (d ), NULL , NULL );
973
1006
974
1007
if (on )
975
1008
enable_irq_wake (pctrl -> irq );
@@ -1000,14 +1033,10 @@ static irqreturn_t intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl,
1000
1033
pending &= enabled ;
1001
1034
1002
1035
for_each_set_bit (gpp_offset , & pending , padgrp -> size ) {
1003
- unsigned padno , irq ;
1004
-
1005
- padno = padgrp -> base - community -> pin_base + gpp_offset ;
1006
- if (padno >= community -> npins )
1007
- break ;
1036
+ unsigned irq ;
1008
1037
1009
1038
irq = irq_find_mapping (gc -> irq .domain ,
1010
- community -> pin_base + padno );
1039
+ padgrp -> gpio_base + gpp_offset );
1011
1040
generic_handle_irq (irq );
1012
1041
1013
1042
ret |= IRQ_HANDLED ;
@@ -1044,13 +1073,56 @@ static struct irq_chip intel_gpio_irqchip = {
1044
1073
.flags = IRQCHIP_MASK_ON_SUSPEND ,
1045
1074
};
1046
1075
1076
+ static int intel_gpio_add_pin_ranges (struct intel_pinctrl * pctrl ,
1077
+ const struct intel_community * community )
1078
+ {
1079
+ int ret , i ;
1080
+
1081
+ for (i = 0 ; i < community -> ngpps ; i ++ ) {
1082
+ const struct intel_padgroup * gpp = & community -> gpps [i ];
1083
+
1084
+ if (gpp -> gpio_base < 0 )
1085
+ continue ;
1086
+
1087
+ ret = gpiochip_add_pin_range (& pctrl -> chip , dev_name (pctrl -> dev ),
1088
+ gpp -> gpio_base , gpp -> base ,
1089
+ gpp -> size );
1090
+ if (ret )
1091
+ return ret ;
1092
+ }
1093
+
1094
+ return ret ;
1095
+ }
1096
+
1097
+ static unsigned intel_gpio_ngpio (const struct intel_pinctrl * pctrl )
1098
+ {
1099
+ const struct intel_community * community ;
1100
+ unsigned ngpio = 0 ;
1101
+ int i , j ;
1102
+
1103
+ for (i = 0 ; i < pctrl -> ncommunities ; i ++ ) {
1104
+ community = & pctrl -> communities [i ];
1105
+ for (j = 0 ; j < community -> ngpps ; j ++ ) {
1106
+ const struct intel_padgroup * gpp = & community -> gpps [j ];
1107
+
1108
+ if (gpp -> gpio_base < 0 )
1109
+ continue ;
1110
+
1111
+ if (gpp -> gpio_base + gpp -> size > ngpio )
1112
+ ngpio = gpp -> gpio_base + gpp -> size ;
1113
+ }
1114
+ }
1115
+
1116
+ return ngpio ;
1117
+ }
1118
+
1047
1119
static int intel_gpio_probe (struct intel_pinctrl * pctrl , int irq )
1048
1120
{
1049
- int ret ;
1121
+ int ret , i ;
1050
1122
1051
1123
pctrl -> chip = intel_gpio_chip ;
1052
1124
1053
- pctrl -> chip .ngpio = pctrl -> soc -> npins ;
1125
+ pctrl -> chip .ngpio = intel_gpio_ngpio ( pctrl ) ;
1054
1126
pctrl -> chip .label = dev_name (pctrl -> dev );
1055
1127
pctrl -> chip .parent = pctrl -> dev ;
1056
1128
pctrl -> chip .base = -1 ;
@@ -1062,11 +1134,14 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
1062
1134
return ret ;
1063
1135
}
1064
1136
1065
- ret = gpiochip_add_pin_range (& pctrl -> chip , dev_name (pctrl -> dev ),
1066
- 0 , 0 , pctrl -> soc -> npins );
1067
- if (ret ) {
1068
- dev_err (pctrl -> dev , "failed to add GPIO pin range\n" );
1069
- return ret ;
1137
+ for (i = 0 ; i < pctrl -> ncommunities ; i ++ ) {
1138
+ struct intel_community * community = & pctrl -> communities [i ];
1139
+
1140
+ ret = intel_gpio_add_pin_ranges (pctrl , community );
1141
+ if (ret ) {
1142
+ dev_err (pctrl -> dev , "failed to add GPIO pin range\n" );
1143
+ return ret ;
1144
+ }
1070
1145
}
1071
1146
1072
1147
/*
@@ -1126,6 +1201,9 @@ static int intel_pinctrl_add_padgroups(struct intel_pinctrl *pctrl,
1126
1201
if (gpps [i ].size > 32 )
1127
1202
return - EINVAL ;
1128
1203
1204
+ if (!gpps [i ].gpio_base )
1205
+ gpps [i ].gpio_base = gpps [i ].base ;
1206
+
1129
1207
gpps [i ].padown_num = padown_num ;
1130
1208
1131
1209
/*
0 commit comments