gpiolib-cdev.c (3c0d9c635ae2b2c6416928271a452017b60e3f98) | gpiolib-cdev.c (aad955842d1cdf56d31e600112137d82fd431140) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2 3#include <linux/anon_inodes.h> 4#include <linux/atomic.h> 5#include <linux/bitmap.h> 6#include <linux/build_bug.h> 7#include <linux/cdev.h> 8#include <linux/compat.h> --- 167 unchanged lines hidden (view full) --- 176 return ret; 177 } else if (lflags & GPIOHANDLE_REQUEST_INPUT) { 178 ret = gpiod_direction_input(desc); 179 if (ret) 180 return ret; 181 } 182 183 blocking_notifier_call_chain(&desc->gdev->notifier, | 1// SPDX-License-Identifier: GPL-2.0 2 3#include <linux/anon_inodes.h> 4#include <linux/atomic.h> 5#include <linux/bitmap.h> 6#include <linux/build_bug.h> 7#include <linux/cdev.h> 8#include <linux/compat.h> --- 167 unchanged lines hidden (view full) --- 176 return ret; 177 } else if (lflags & GPIOHANDLE_REQUEST_INPUT) { 178 ret = gpiod_direction_input(desc); 179 if (ret) 180 return ret; 181 } 182 183 blocking_notifier_call_chain(&desc->gdev->notifier, |
184 GPIOLINE_CHANGED_CONFIG, desc); | 184 GPIO_V2_LINE_CHANGED_CONFIG, 185 desc); |
185 } 186 return 0; 187} 188 189static long linehandle_ioctl(struct file *file, unsigned int cmd, 190 unsigned long arg) 191{ 192 struct linehandle_state *lh = file->private_data; --- 155 unchanged lines hidden (view full) --- 348 goto out_free_lh; 349 } else if (lflags & GPIOHANDLE_REQUEST_INPUT) { 350 ret = gpiod_direction_input(desc); 351 if (ret) 352 goto out_free_lh; 353 } 354 355 blocking_notifier_call_chain(&desc->gdev->notifier, | 186 } 187 return 0; 188} 189 190static long linehandle_ioctl(struct file *file, unsigned int cmd, 191 unsigned long arg) 192{ 193 struct linehandle_state *lh = file->private_data; --- 155 unchanged lines hidden (view full) --- 349 goto out_free_lh; 350 } else if (lflags & GPIOHANDLE_REQUEST_INPUT) { 351 ret = gpiod_direction_input(desc); 352 if (ret) 353 goto out_free_lh; 354 } 355 356 blocking_notifier_call_chain(&desc->gdev->notifier, |
356 GPIOLINE_CHANGED_REQUESTED, desc); | 357 GPIO_V2_LINE_CHANGED_REQUESTED, desc); |
357 358 dev_dbg(&gdev->dev, "registered chardev handle for line %d\n", 359 offset); 360 } 361 362 fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC); 363 if (fd < 0) { 364 ret = fd; --- 379 unchanged lines hidden (view full) --- 744 goto out_free_linereq; 745 } else if (flags & GPIO_V2_LINE_FLAG_INPUT) { 746 ret = gpiod_direction_input(desc); 747 if (ret) 748 goto out_free_linereq; 749 } 750 751 blocking_notifier_call_chain(&desc->gdev->notifier, | 358 359 dev_dbg(&gdev->dev, "registered chardev handle for line %d\n", 360 offset); 361 } 362 363 fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC); 364 if (fd < 0) { 365 ret = fd; --- 379 unchanged lines hidden (view full) --- 745 goto out_free_linereq; 746 } else if (flags & GPIO_V2_LINE_FLAG_INPUT) { 747 ret = gpiod_direction_input(desc); 748 if (ret) 749 goto out_free_linereq; 750 } 751 752 blocking_notifier_call_chain(&desc->gdev->notifier, |
752 GPIOLINE_CHANGED_REQUESTED, desc); | 753 GPIO_V2_LINE_CHANGED_REQUESTED, desc); |
753 754 dev_dbg(&gdev->dev, "registered chardev handle for line %d\n", 755 offset); 756 } 757 758 fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC); 759 if (fd < 0) { 760 ret = fd; --- 330 unchanged lines hidden (view full) --- 1091 1092 linehandle_flags_to_desc_flags(lflags, &desc->flags); 1093 1094 ret = gpiod_direction_input(desc); 1095 if (ret) 1096 goto out_free_le; 1097 1098 blocking_notifier_call_chain(&desc->gdev->notifier, | 754 755 dev_dbg(&gdev->dev, "registered chardev handle for line %d\n", 756 offset); 757 } 758 759 fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC); 760 if (fd < 0) { 761 ret = fd; --- 330 unchanged lines hidden (view full) --- 1092 1093 linehandle_flags_to_desc_flags(lflags, &desc->flags); 1094 1095 ret = gpiod_direction_input(desc); 1096 if (ret) 1097 goto out_free_le; 1098 1099 blocking_notifier_call_chain(&desc->gdev->notifier, |
1099 GPIOLINE_CHANGED_REQUESTED, desc); | 1100 GPIO_V2_LINE_CHANGED_REQUESTED, desc); |
1100 1101 irq = gpiod_to_irq(desc); 1102 if (irq <= 0) { 1103 ret = -ENODEV; 1104 goto out_free_le; 1105 } 1106 le->irq = irq; 1107 --- 50 unchanged lines hidden (view full) --- 1158 1159out_put_unused_fd: 1160 put_unused_fd(fd); 1161out_free_le: 1162 lineevent_free(le); 1163 return ret; 1164} 1165 | 1101 1102 irq = gpiod_to_irq(desc); 1103 if (irq <= 0) { 1104 ret = -ENODEV; 1105 goto out_free_le; 1106 } 1107 le->irq = irq; 1108 --- 50 unchanged lines hidden (view full) --- 1159 1160out_put_unused_fd: 1161 put_unused_fd(fd); 1162out_free_le: 1163 lineevent_free(le); 1164 return ret; 1165} 1166 |
1167static void gpio_v2_line_info_to_v1(struct gpio_v2_line_info *info_v2, 1168 struct gpioline_info *info_v1) 1169{ 1170 u64 flagsv2 = info_v2->flags; 1171 1172 memcpy(info_v1->name, info_v2->name, sizeof(info_v1->name)); 1173 memcpy(info_v1->consumer, info_v2->consumer, sizeof(info_v1->consumer)); 1174 info_v1->line_offset = info_v2->offset; 1175 info_v1->flags = 0; 1176 1177 if (flagsv2 & GPIO_V2_LINE_FLAG_USED) 1178 info_v1->flags |= GPIOLINE_FLAG_KERNEL; 1179 1180 if (flagsv2 & GPIO_V2_LINE_FLAG_OUTPUT) 1181 info_v1->flags |= GPIOLINE_FLAG_IS_OUT; 1182 1183 if (flagsv2 & GPIO_V2_LINE_FLAG_ACTIVE_LOW) 1184 info_v1->flags |= GPIOLINE_FLAG_ACTIVE_LOW; 1185 1186 if (flagsv2 & GPIO_V2_LINE_FLAG_OPEN_DRAIN) 1187 info_v1->flags |= GPIOLINE_FLAG_OPEN_DRAIN; 1188 if (flagsv2 & GPIO_V2_LINE_FLAG_OPEN_SOURCE) 1189 info_v1->flags |= GPIOLINE_FLAG_OPEN_SOURCE; 1190 1191 if (flagsv2 & GPIO_V2_LINE_FLAG_BIAS_PULL_UP) 1192 info_v1->flags |= GPIOLINE_FLAG_BIAS_PULL_UP; 1193 if (flagsv2 & GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN) 1194 info_v1->flags |= GPIOLINE_FLAG_BIAS_PULL_DOWN; 1195 if (flagsv2 & GPIO_V2_LINE_FLAG_BIAS_DISABLED) 1196 info_v1->flags |= GPIOLINE_FLAG_BIAS_DISABLE; 1197} 1198 1199static void gpio_v2_line_info_changed_to_v1( 1200 struct gpio_v2_line_info_changed *lic_v2, 1201 struct gpioline_info_changed *lic_v1) 1202{ 1203 gpio_v2_line_info_to_v1(&lic_v2->info, &lic_v1->info); 1204 lic_v1->timestamp = lic_v2->timestamp_ns; 1205 lic_v1->event_type = lic_v2->event_type; 1206} 1207 |
|
1166#endif /* CONFIG_GPIO_CDEV_V1 */ 1167 1168static void gpio_desc_to_lineinfo(struct gpio_desc *desc, | 1208#endif /* CONFIG_GPIO_CDEV_V1 */ 1209 1210static void gpio_desc_to_lineinfo(struct gpio_desc *desc, |
1169 struct gpioline_info *info) | 1211 struct gpio_v2_line_info *info) |
1170{ 1171 struct gpio_chip *gc = desc->gdev->chip; 1172 bool ok_for_pinctrl; 1173 unsigned long flags; 1174 1175 memset(info, 0, sizeof(*info)); | 1212{ 1213 struct gpio_chip *gc = desc->gdev->chip; 1214 bool ok_for_pinctrl; 1215 unsigned long flags; 1216 1217 memset(info, 0, sizeof(*info)); |
1176 info->line_offset = gpio_chip_hwgpio(desc); | 1218 info->offset = gpio_chip_hwgpio(desc); |
1177 1178 /* 1179 * This function takes a mutex so we must check this before taking 1180 * the spinlock. 1181 * 1182 * FIXME: find a non-racy way to retrieve this information. Maybe a 1183 * lock common to both frameworks? 1184 */ 1185 ok_for_pinctrl = | 1219 1220 /* 1221 * This function takes a mutex so we must check this before taking 1222 * the spinlock. 1223 * 1224 * FIXME: find a non-racy way to retrieve this information. Maybe a 1225 * lock common to both frameworks? 1226 */ 1227 ok_for_pinctrl = |
1186 pinctrl_gpio_can_use_line(gc->base + info->line_offset); | 1228 pinctrl_gpio_can_use_line(gc->base + info->offset); |
1187 1188 spin_lock_irqsave(&gpio_lock, flags); 1189 1190 if (desc->name) 1191 strscpy(info->name, desc->name, sizeof(info->name)); 1192 1193 if (desc->label) 1194 strscpy(info->consumer, desc->label, sizeof(info->consumer)); --- 4 unchanged lines hidden (view full) --- 1199 */ 1200 info->flags = 0; 1201 if (test_bit(FLAG_REQUESTED, &desc->flags) || 1202 test_bit(FLAG_IS_HOGGED, &desc->flags) || 1203 test_bit(FLAG_USED_AS_IRQ, &desc->flags) || 1204 test_bit(FLAG_EXPORT, &desc->flags) || 1205 test_bit(FLAG_SYSFS, &desc->flags) || 1206 !ok_for_pinctrl) | 1229 1230 spin_lock_irqsave(&gpio_lock, flags); 1231 1232 if (desc->name) 1233 strscpy(info->name, desc->name, sizeof(info->name)); 1234 1235 if (desc->label) 1236 strscpy(info->consumer, desc->label, sizeof(info->consumer)); --- 4 unchanged lines hidden (view full) --- 1241 */ 1242 info->flags = 0; 1243 if (test_bit(FLAG_REQUESTED, &desc->flags) || 1244 test_bit(FLAG_IS_HOGGED, &desc->flags) || 1245 test_bit(FLAG_USED_AS_IRQ, &desc->flags) || 1246 test_bit(FLAG_EXPORT, &desc->flags) || 1247 test_bit(FLAG_SYSFS, &desc->flags) || 1248 !ok_for_pinctrl) |
1207 info->flags |= GPIOLINE_FLAG_KERNEL; | 1249 info->flags |= GPIO_V2_LINE_FLAG_USED; 1250 |
1208 if (test_bit(FLAG_IS_OUT, &desc->flags)) | 1251 if (test_bit(FLAG_IS_OUT, &desc->flags)) |
1209 info->flags |= GPIOLINE_FLAG_IS_OUT; | 1252 info->flags |= GPIO_V2_LINE_FLAG_OUTPUT; 1253 else 1254 info->flags |= GPIO_V2_LINE_FLAG_INPUT; 1255 |
1210 if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) | 1256 if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) |
1211 info->flags |= GPIOLINE_FLAG_ACTIVE_LOW; | 1257 info->flags |= GPIO_V2_LINE_FLAG_ACTIVE_LOW; 1258 |
1212 if (test_bit(FLAG_OPEN_DRAIN, &desc->flags)) | 1259 if (test_bit(FLAG_OPEN_DRAIN, &desc->flags)) |
1213 info->flags |= (GPIOLINE_FLAG_OPEN_DRAIN | 1214 GPIOLINE_FLAG_IS_OUT); | 1260 info->flags |= GPIO_V2_LINE_FLAG_OPEN_DRAIN; |
1215 if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) | 1261 if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) |
1216 info->flags |= (GPIOLINE_FLAG_OPEN_SOURCE | 1217 GPIOLINE_FLAG_IS_OUT); | 1262 info->flags |= GPIO_V2_LINE_FLAG_OPEN_SOURCE; 1263 |
1218 if (test_bit(FLAG_BIAS_DISABLE, &desc->flags)) | 1264 if (test_bit(FLAG_BIAS_DISABLE, &desc->flags)) |
1219 info->flags |= GPIOLINE_FLAG_BIAS_DISABLE; | 1265 info->flags |= GPIO_V2_LINE_FLAG_BIAS_DISABLED; |
1220 if (test_bit(FLAG_PULL_DOWN, &desc->flags)) | 1266 if (test_bit(FLAG_PULL_DOWN, &desc->flags)) |
1221 info->flags |= GPIOLINE_FLAG_BIAS_PULL_DOWN; | 1267 info->flags |= GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN; |
1222 if (test_bit(FLAG_PULL_UP, &desc->flags)) | 1268 if (test_bit(FLAG_PULL_UP, &desc->flags)) |
1223 info->flags |= GPIOLINE_FLAG_BIAS_PULL_UP; | 1269 info->flags |= GPIO_V2_LINE_FLAG_BIAS_PULL_UP; |
1224 1225 spin_unlock_irqrestore(&gpio_lock, flags); 1226} 1227 1228struct gpio_chardev_data { 1229 struct gpio_device *gdev; 1230 wait_queue_head_t wait; | 1270 1271 spin_unlock_irqrestore(&gpio_lock, flags); 1272} 1273 1274struct gpio_chardev_data { 1275 struct gpio_device *gdev; 1276 wait_queue_head_t wait; |
1231 DECLARE_KFIFO(events, struct gpioline_info_changed, 32); | 1277 DECLARE_KFIFO(events, struct gpio_v2_line_info_changed, 32); |
1232 struct notifier_block lineinfo_changed_nb; 1233 unsigned long *watched_lines; | 1278 struct notifier_block lineinfo_changed_nb; 1279 unsigned long *watched_lines; |
1280#ifdef CONFIG_GPIO_CDEV_V1 1281 atomic_t watch_abi_version; 1282#endif |
|
1234}; 1235 | 1283}; 1284 |
1285#ifdef CONFIG_GPIO_CDEV_V1 |
|
1236/* | 1286/* |
1287 * returns 0 if the versions match, else the previously selected ABI version 1288 */ 1289static int lineinfo_ensure_abi_version(struct gpio_chardev_data *cdata, 1290 unsigned int version) 1291{ 1292 int abiv = atomic_cmpxchg(&cdata->watch_abi_version, 0, version); 1293 1294 if (abiv == version) 1295 return 0; 1296 1297 return abiv; 1298} 1299#endif 1300 1301static int lineinfo_get(struct gpio_chardev_data *cdev, void __user *ip, 1302 bool watch) 1303{ 1304 struct gpio_desc *desc; 1305 struct gpio_v2_line_info lineinfo; 1306 1307 if (copy_from_user(&lineinfo, ip, sizeof(lineinfo))) 1308 return -EFAULT; 1309 1310 if (memchr_inv(lineinfo.padding, 0, sizeof(lineinfo.padding))) 1311 return -EINVAL; 1312 1313 desc = gpiochip_get_desc(cdev->gdev->chip, lineinfo.offset); 1314 if (IS_ERR(desc)) 1315 return PTR_ERR(desc); 1316 1317 if (watch) { 1318#ifdef CONFIG_GPIO_CDEV_V1 1319 if (lineinfo_ensure_abi_version(cdev, 2)) 1320 return -EPERM; 1321#endif 1322 if (test_and_set_bit(lineinfo.offset, cdev->watched_lines)) 1323 return -EBUSY; 1324 } 1325 gpio_desc_to_lineinfo(desc, &lineinfo); 1326 1327 if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) { 1328 if (watch) 1329 clear_bit(lineinfo.offset, cdev->watched_lines); 1330 return -EFAULT; 1331 } 1332 1333 return 0; 1334} 1335 1336/* |
|
1237 * gpio_ioctl() - ioctl handler for the GPIO chardev 1238 */ 1239static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 1240{ 1241 struct gpio_chardev_data *cdev = file->private_data; 1242 struct gpio_device *gdev = cdev->gdev; 1243 struct gpio_chip *gc = gdev->chip; 1244 void __user *ip = (void __user *)arg; | 1337 * gpio_ioctl() - ioctl handler for the GPIO chardev 1338 */ 1339static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 1340{ 1341 struct gpio_chardev_data *cdev = file->private_data; 1342 struct gpio_device *gdev = cdev->gdev; 1343 struct gpio_chip *gc = gdev->chip; 1344 void __user *ip = (void __user *)arg; |
1245 struct gpio_desc *desc; | |
1246 __u32 offset; 1247 1248 /* We fail any subsequent ioctl():s when the chip is gone */ 1249 if (!gc) 1250 return -ENODEV; 1251 1252 /* Fill in the struct and pass to userspace */ 1253 if (cmd == GPIO_GET_CHIPINFO_IOCTL) { --- 6 unchanged lines hidden (view full) --- 1260 strscpy(chipinfo.label, gdev->label, 1261 sizeof(chipinfo.label)); 1262 chipinfo.lines = gdev->ngpio; 1263 if (copy_to_user(ip, &chipinfo, sizeof(chipinfo))) 1264 return -EFAULT; 1265 return 0; 1266#ifdef CONFIG_GPIO_CDEV_V1 1267 } else if (cmd == GPIO_GET_LINEINFO_IOCTL) { | 1345 __u32 offset; 1346 1347 /* We fail any subsequent ioctl():s when the chip is gone */ 1348 if (!gc) 1349 return -ENODEV; 1350 1351 /* Fill in the struct and pass to userspace */ 1352 if (cmd == GPIO_GET_CHIPINFO_IOCTL) { --- 6 unchanged lines hidden (view full) --- 1359 strscpy(chipinfo.label, gdev->label, 1360 sizeof(chipinfo.label)); 1361 chipinfo.lines = gdev->ngpio; 1362 if (copy_to_user(ip, &chipinfo, sizeof(chipinfo))) 1363 return -EFAULT; 1364 return 0; 1365#ifdef CONFIG_GPIO_CDEV_V1 1366 } else if (cmd == GPIO_GET_LINEINFO_IOCTL) { |
1367 struct gpio_desc *desc; |
|
1268 struct gpioline_info lineinfo; | 1368 struct gpioline_info lineinfo; |
1369 struct gpio_v2_line_info lineinfo_v2; |
|
1269 1270 if (copy_from_user(&lineinfo, ip, sizeof(lineinfo))) 1271 return -EFAULT; 1272 1273 /* this doubles as a range check on line_offset */ 1274 desc = gpiochip_get_desc(gc, lineinfo.line_offset); 1275 if (IS_ERR(desc)) 1276 return PTR_ERR(desc); 1277 | 1370 1371 if (copy_from_user(&lineinfo, ip, sizeof(lineinfo))) 1372 return -EFAULT; 1373 1374 /* this doubles as a range check on line_offset */ 1375 desc = gpiochip_get_desc(gc, lineinfo.line_offset); 1376 if (IS_ERR(desc)) 1377 return PTR_ERR(desc); 1378 |
1278 gpio_desc_to_lineinfo(desc, &lineinfo); | 1379 gpio_desc_to_lineinfo(desc, &lineinfo_v2); 1380 gpio_v2_line_info_to_v1(&lineinfo_v2, &lineinfo); |
1279 1280 if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) 1281 return -EFAULT; 1282 return 0; 1283 } else if (cmd == GPIO_GET_LINEHANDLE_IOCTL) { 1284 return linehandle_create(gdev, ip); 1285 } else if (cmd == GPIO_GET_LINEEVENT_IOCTL) { 1286 return lineevent_create(gdev, ip); 1287 } else if (cmd == GPIO_GET_LINEINFO_WATCH_IOCTL) { | 1381 1382 if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) 1383 return -EFAULT; 1384 return 0; 1385 } else if (cmd == GPIO_GET_LINEHANDLE_IOCTL) { 1386 return linehandle_create(gdev, ip); 1387 } else if (cmd == GPIO_GET_LINEEVENT_IOCTL) { 1388 return lineevent_create(gdev, ip); 1389 } else if (cmd == GPIO_GET_LINEINFO_WATCH_IOCTL) { |
1390 struct gpio_desc *desc; |
|
1288 struct gpioline_info lineinfo; | 1391 struct gpioline_info lineinfo; |
1392 struct gpio_v2_line_info lineinfo_v2; |
|
1289 1290 if (copy_from_user(&lineinfo, ip, sizeof(lineinfo))) 1291 return -EFAULT; 1292 1293 /* this doubles as a range check on line_offset */ 1294 desc = gpiochip_get_desc(gc, lineinfo.line_offset); 1295 if (IS_ERR(desc)) 1296 return PTR_ERR(desc); 1297 | 1393 1394 if (copy_from_user(&lineinfo, ip, sizeof(lineinfo))) 1395 return -EFAULT; 1396 1397 /* this doubles as a range check on line_offset */ 1398 desc = gpiochip_get_desc(gc, lineinfo.line_offset); 1399 if (IS_ERR(desc)) 1400 return PTR_ERR(desc); 1401 |
1402 if (lineinfo_ensure_abi_version(cdev, 1)) 1403 return -EPERM; 1404 |
|
1298 if (test_and_set_bit(lineinfo.line_offset, cdev->watched_lines)) 1299 return -EBUSY; 1300 | 1405 if (test_and_set_bit(lineinfo.line_offset, cdev->watched_lines)) 1406 return -EBUSY; 1407 |
1301 gpio_desc_to_lineinfo(desc, &lineinfo); | 1408 gpio_desc_to_lineinfo(desc, &lineinfo_v2); 1409 gpio_v2_line_info_to_v1(&lineinfo_v2, &lineinfo); |
1302 1303 if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) { 1304 clear_bit(lineinfo.line_offset, cdev->watched_lines); 1305 return -EFAULT; 1306 } 1307 1308 return 0; 1309#endif /* CONFIG_GPIO_CDEV_V1 */ | 1410 1411 if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) { 1412 clear_bit(lineinfo.line_offset, cdev->watched_lines); 1413 return -EFAULT; 1414 } 1415 1416 return 0; 1417#endif /* CONFIG_GPIO_CDEV_V1 */ |
1418 } else if (cmd == GPIO_V2_GET_LINEINFO_IOCTL || 1419 cmd == GPIO_V2_GET_LINEINFO_WATCH_IOCTL) { 1420 return lineinfo_get(cdev, ip, 1421 cmd == GPIO_V2_GET_LINEINFO_WATCH_IOCTL); |
|
1310 } else if (cmd == GPIO_V2_GET_LINE_IOCTL) { 1311 return linereq_create(gdev, ip); 1312 } else if (cmd == GPIO_GET_LINEINFO_UNWATCH_IOCTL) { 1313 if (copy_from_user(&offset, ip, sizeof(offset))) 1314 return -EFAULT; 1315 1316 if (offset >= cdev->gdev->ngpio) 1317 return -EINVAL; --- 19 unchanged lines hidden (view full) --- 1337{ 1338 return container_of(nb, struct gpio_chardev_data, lineinfo_changed_nb); 1339} 1340 1341static int lineinfo_changed_notify(struct notifier_block *nb, 1342 unsigned long action, void *data) 1343{ 1344 struct gpio_chardev_data *cdev = to_gpio_chardev_data(nb); | 1422 } else if (cmd == GPIO_V2_GET_LINE_IOCTL) { 1423 return linereq_create(gdev, ip); 1424 } else if (cmd == GPIO_GET_LINEINFO_UNWATCH_IOCTL) { 1425 if (copy_from_user(&offset, ip, sizeof(offset))) 1426 return -EFAULT; 1427 1428 if (offset >= cdev->gdev->ngpio) 1429 return -EINVAL; --- 19 unchanged lines hidden (view full) --- 1449{ 1450 return container_of(nb, struct gpio_chardev_data, lineinfo_changed_nb); 1451} 1452 1453static int lineinfo_changed_notify(struct notifier_block *nb, 1454 unsigned long action, void *data) 1455{ 1456 struct gpio_chardev_data *cdev = to_gpio_chardev_data(nb); |
1345 struct gpioline_info_changed chg; | 1457 struct gpio_v2_line_info_changed chg; |
1346 struct gpio_desc *desc = data; 1347 int ret; 1348 1349 if (!test_bit(gpio_chip_hwgpio(desc), cdev->watched_lines)) 1350 return NOTIFY_DONE; 1351 1352 memset(&chg, 0, sizeof(chg)); 1353 chg.event_type = action; | 1458 struct gpio_desc *desc = data; 1459 int ret; 1460 1461 if (!test_bit(gpio_chip_hwgpio(desc), cdev->watched_lines)) 1462 return NOTIFY_DONE; 1463 1464 memset(&chg, 0, sizeof(chg)); 1465 chg.event_type = action; |
1354 chg.timestamp = ktime_get_ns(); | 1466 chg.timestamp_ns = ktime_get_ns(); |
1355 gpio_desc_to_lineinfo(desc, &chg.info); 1356 1357 ret = kfifo_in_spinlocked(&cdev->events, &chg, 1, &cdev->wait.lock); 1358 if (ret) 1359 wake_up_poll(&cdev->wait, EPOLLIN); 1360 else 1361 pr_debug_ratelimited("lineinfo event FIFO is full - event dropped\n"); 1362 --- 14 unchanged lines hidden (view full) --- 1377 1378 return events; 1379} 1380 1381static ssize_t lineinfo_watch_read(struct file *file, char __user *buf, 1382 size_t count, loff_t *off) 1383{ 1384 struct gpio_chardev_data *cdev = file->private_data; | 1467 gpio_desc_to_lineinfo(desc, &chg.info); 1468 1469 ret = kfifo_in_spinlocked(&cdev->events, &chg, 1, &cdev->wait.lock); 1470 if (ret) 1471 wake_up_poll(&cdev->wait, EPOLLIN); 1472 else 1473 pr_debug_ratelimited("lineinfo event FIFO is full - event dropped\n"); 1474 --- 14 unchanged lines hidden (view full) --- 1489 1490 return events; 1491} 1492 1493static ssize_t lineinfo_watch_read(struct file *file, char __user *buf, 1494 size_t count, loff_t *off) 1495{ 1496 struct gpio_chardev_data *cdev = file->private_data; |
1385 struct gpioline_info_changed event; | 1497 struct gpio_v2_line_info_changed event; |
1386 ssize_t bytes_read = 0; 1387 int ret; | 1498 ssize_t bytes_read = 0; 1499 int ret; |
1500 size_t event_size; |
|
1388 | 1501 |
1389 if (count < sizeof(event)) | 1502#ifndef CONFIG_GPIO_CDEV_V1 1503 event_size = sizeof(struct gpio_v2_line_info_changed); 1504 if (count < event_size) |
1390 return -EINVAL; | 1505 return -EINVAL; |
1506#endif |
|
1391 1392 do { 1393 spin_lock(&cdev->wait.lock); 1394 if (kfifo_is_empty(&cdev->events)) { 1395 if (bytes_read) { 1396 spin_unlock(&cdev->wait.lock); 1397 return bytes_read; 1398 } --- 5 unchanged lines hidden (view full) --- 1404 1405 ret = wait_event_interruptible_locked(cdev->wait, 1406 !kfifo_is_empty(&cdev->events)); 1407 if (ret) { 1408 spin_unlock(&cdev->wait.lock); 1409 return ret; 1410 } 1411 } | 1507 1508 do { 1509 spin_lock(&cdev->wait.lock); 1510 if (kfifo_is_empty(&cdev->events)) { 1511 if (bytes_read) { 1512 spin_unlock(&cdev->wait.lock); 1513 return bytes_read; 1514 } --- 5 unchanged lines hidden (view full) --- 1520 1521 ret = wait_event_interruptible_locked(cdev->wait, 1522 !kfifo_is_empty(&cdev->events)); 1523 if (ret) { 1524 spin_unlock(&cdev->wait.lock); 1525 return ret; 1526 } 1527 } |
1412 | 1528#ifdef CONFIG_GPIO_CDEV_V1 1529 /* must be after kfifo check so watch_abi_version is set */ 1530 if (atomic_read(&cdev->watch_abi_version) == 2) 1531 event_size = sizeof(struct gpio_v2_line_info_changed); 1532 else 1533 event_size = sizeof(struct gpioline_info_changed); 1534 if (count < event_size) { 1535 spin_unlock(&cdev->wait.lock); 1536 return -EINVAL; 1537 } 1538#endif |
1413 ret = kfifo_out(&cdev->events, &event, 1); 1414 spin_unlock(&cdev->wait.lock); 1415 if (ret != 1) { 1416 ret = -EIO; 1417 break; 1418 /* We should never get here. See lineevent_read(). */ 1419 } 1420 | 1539 ret = kfifo_out(&cdev->events, &event, 1); 1540 spin_unlock(&cdev->wait.lock); 1541 if (ret != 1) { 1542 ret = -EIO; 1543 break; 1544 /* We should never get here. See lineevent_read(). */ 1545 } 1546 |
1421 if (copy_to_user(buf + bytes_read, &event, sizeof(event))) | 1547#ifdef CONFIG_GPIO_CDEV_V1 1548 if (event_size == sizeof(struct gpio_v2_line_info_changed)) { 1549 if (copy_to_user(buf + bytes_read, &event, event_size)) 1550 return -EFAULT; 1551 } else { 1552 struct gpioline_info_changed event_v1; 1553 1554 gpio_v2_line_info_changed_to_v1(&event, &event_v1); 1555 if (copy_to_user(buf + bytes_read, &event_v1, 1556 event_size)) 1557 return -EFAULT; 1558 } 1559#else 1560 if (copy_to_user(buf + bytes_read, &event, event_size)) |
1422 return -EFAULT; | 1561 return -EFAULT; |
1423 bytes_read += sizeof(event); | 1562#endif 1563 bytes_read += event_size; |
1424 } while (count >= bytes_read + sizeof(event)); 1425 1426 return bytes_read; 1427} 1428 1429/** 1430 * gpio_chrdev_open() - open the chardev for ioctl operations 1431 * @inode: inode for this chardev --- 106 unchanged lines hidden --- | 1564 } while (count >= bytes_read + sizeof(event)); 1565 1566 return bytes_read; 1567} 1568 1569/** 1570 * gpio_chrdev_open() - open the chardev for ioctl operations 1571 * @inode: inode for this chardev --- 106 unchanged lines hidden --- |