@@ -1158,8 +1158,19 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
1158
1158
struct gpioline_info * info )
1159
1159
{
1160
1160
struct gpio_chip * gc = desc -> gdev -> chip ;
1161
+ bool ok_for_pinctrl ;
1161
1162
unsigned long flags ;
1162
1163
1164
+ /*
1165
+ * This function takes a mutex so we must check this before taking
1166
+ * the spinlock.
1167
+ *
1168
+ * FIXME: find a non-racy way to retrieve this information. Maybe a
1169
+ * lock common to both frameworks?
1170
+ */
1171
+ ok_for_pinctrl =
1172
+ pinctrl_gpio_can_use_line (gc -> base + info -> line_offset );
1173
+
1163
1174
spin_lock_irqsave (& gpio_lock , flags );
1164
1175
1165
1176
if (desc -> name ) {
@@ -1186,7 +1197,7 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
1186
1197
test_bit (FLAG_USED_AS_IRQ , & desc -> flags ) ||
1187
1198
test_bit (FLAG_EXPORT , & desc -> flags ) ||
1188
1199
test_bit (FLAG_SYSFS , & desc -> flags ) ||
1189
- !pinctrl_gpio_can_use_line ( gc -> base + info -> line_offset ) )
1200
+ !ok_for_pinctrl )
1190
1201
info -> flags |= GPIOLINE_FLAG_KERNEL ;
1191
1202
if (test_bit (FLAG_IS_OUT , & desc -> flags ))
1192
1203
info -> flags |= GPIOLINE_FLAG_IS_OUT ;
@@ -1227,6 +1238,7 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1227
1238
void __user * ip = (void __user * )arg ;
1228
1239
struct gpio_desc * desc ;
1229
1240
__u32 offset ;
1241
+ int hwgpio ;
1230
1242
1231
1243
/* We fail any subsequent ioctl():s when the chip is gone */
1232
1244
if (!gc )
@@ -1259,13 +1271,19 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1259
1271
if (IS_ERR (desc ))
1260
1272
return PTR_ERR (desc );
1261
1273
1274
+ hwgpio = gpio_chip_hwgpio (desc );
1275
+
1276
+ if (cmd == GPIO_GET_LINEINFO_WATCH_IOCTL &&
1277
+ test_bit (hwgpio , priv -> watched_lines ))
1278
+ return - EBUSY ;
1279
+
1262
1280
gpio_desc_to_lineinfo (desc , & lineinfo );
1263
1281
1264
1282
if (copy_to_user (ip , & lineinfo , sizeof (lineinfo )))
1265
1283
return - EFAULT ;
1266
1284
1267
1285
if (cmd == GPIO_GET_LINEINFO_WATCH_IOCTL )
1268
- set_bit (gpio_chip_hwgpio ( desc ) , priv -> watched_lines );
1286
+ set_bit (hwgpio , priv -> watched_lines );
1269
1287
1270
1288
return 0 ;
1271
1289
} else if (cmd == GPIO_GET_LINEHANDLE_IOCTL ) {
@@ -1280,7 +1298,12 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1280
1298
if (IS_ERR (desc ))
1281
1299
return PTR_ERR (desc );
1282
1300
1283
- clear_bit (gpio_chip_hwgpio (desc ), priv -> watched_lines );
1301
+ hwgpio = gpio_chip_hwgpio (desc );
1302
+
1303
+ if (!test_bit (hwgpio , priv -> watched_lines ))
1304
+ return - EBUSY ;
1305
+
1306
+ clear_bit (hwgpio , priv -> watched_lines );
1284
1307
return 0 ;
1285
1308
}
1286
1309
return - EINVAL ;
0 commit comments