@@ -800,14 +800,28 @@ static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev,
800
800
pm_runtime_put (vg -> dev );
801
801
}
802
802
803
+ static void byt_gpio_direct_irq_check (struct intel_pinctrl * vg ,
804
+ unsigned int offset )
805
+ {
806
+ void __iomem * conf_reg = byt_gpio_reg (vg , offset , BYT_CONF0_REG );
807
+
808
+ /*
809
+ * Before making any direction modifications, do a check if gpio is set
810
+ * for direct IRQ. On Bay Trail, setting GPIO to output does not make
811
+ * sense, so let's at least inform the caller before they shoot
812
+ * themselves in the foot.
813
+ */
814
+ if (readl (conf_reg ) & BYT_DIRECT_IRQ_EN )
815
+ dev_info_once (vg -> dev , "Potential Error: Setting GPIO with direct_irq_en to output" );
816
+ }
817
+
803
818
static int byt_gpio_set_direction (struct pinctrl_dev * pctl_dev ,
804
819
struct pinctrl_gpio_range * range ,
805
820
unsigned int offset ,
806
821
bool input )
807
822
{
808
823
struct intel_pinctrl * vg = pinctrl_dev_get_drvdata (pctl_dev );
809
824
void __iomem * val_reg = byt_gpio_reg (vg , offset , BYT_VAL_REG );
810
- void __iomem * conf_reg = byt_gpio_reg (vg , offset , BYT_CONF0_REG );
811
825
unsigned long flags ;
812
826
u32 value ;
813
827
@@ -817,14 +831,8 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
817
831
value &= ~BYT_DIR_MASK ;
818
832
if (input )
819
833
value |= BYT_OUTPUT_EN ;
820
- else if (readl (conf_reg ) & BYT_DIRECT_IRQ_EN )
821
- /*
822
- * Before making any direction modifications, do a check if gpio
823
- * is set for direct IRQ. On baytrail, setting GPIO to output
824
- * does not make sense, so let's at least inform the caller before
825
- * they shoot themselves in the foot.
826
- */
827
- dev_info_once (vg -> dev , "Potential Error: Setting GPIO with direct_irq_en to output" );
834
+ else
835
+ byt_gpio_direct_irq_check (vg , offset );
828
836
829
837
writel (value , val_reg );
830
838
@@ -1165,19 +1173,50 @@ static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
1165
1173
1166
1174
static int byt_gpio_direction_input (struct gpio_chip * chip , unsigned int offset )
1167
1175
{
1168
- return pinctrl_gpio_direction_input (chip -> base + offset );
1176
+ struct intel_pinctrl * vg = gpiochip_get_data (chip );
1177
+ void __iomem * val_reg = byt_gpio_reg (vg , offset , BYT_VAL_REG );
1178
+ unsigned long flags ;
1179
+ u32 reg ;
1180
+
1181
+ raw_spin_lock_irqsave (& byt_lock , flags );
1182
+
1183
+ reg = readl (val_reg );
1184
+ reg &= ~BYT_DIR_MASK ;
1185
+ reg |= BYT_OUTPUT_EN ;
1186
+ writel (reg , val_reg );
1187
+
1188
+ raw_spin_unlock_irqrestore (& byt_lock , flags );
1189
+ return 0 ;
1169
1190
}
1170
1191
1192
+ /*
1193
+ * Note despite the temptation this MUST NOT be converted into a call to
1194
+ * pinctrl_gpio_direction_output() + byt_gpio_set() that does not work this
1195
+ * MUST be done as a single BYT_VAL_REG register write.
1196
+ * See the commit message of the commit adding this comment for details.
1197
+ */
1171
1198
static int byt_gpio_direction_output (struct gpio_chip * chip ,
1172
1199
unsigned int offset , int value )
1173
1200
{
1174
- int ret = pinctrl_gpio_direction_output (chip -> base + offset );
1201
+ struct intel_pinctrl * vg = gpiochip_get_data (chip );
1202
+ void __iomem * val_reg = byt_gpio_reg (vg , offset , BYT_VAL_REG );
1203
+ unsigned long flags ;
1204
+ u32 reg ;
1175
1205
1176
- if (ret )
1177
- return ret ;
1206
+ raw_spin_lock_irqsave (& byt_lock , flags );
1207
+
1208
+ byt_gpio_direct_irq_check (vg , offset );
1178
1209
1179
- byt_gpio_set (chip , offset , value );
1210
+ reg = readl (val_reg );
1211
+ reg &= ~BYT_DIR_MASK ;
1212
+ if (value )
1213
+ reg |= BYT_LEVEL ;
1214
+ else
1215
+ reg &= ~BYT_LEVEL ;
1180
1216
1217
+ writel (reg , val_reg );
1218
+
1219
+ raw_spin_unlock_irqrestore (& byt_lock , flags );
1181
1220
return 0 ;
1182
1221
}
1183
1222
0 commit comments